diff --git a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Debugger.AddIn.addin b/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Debugger.AddIn.addin
index e95e34555f..08060e5c91 100644
--- a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Debugger.AddIn.addin
+++ b/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Debugger.AddIn.addin
@@ -25,15 +25,6 @@
-
-
-
-
diff --git a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Debugger.AddIn.csproj b/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Debugger.AddIn.csproj
index 11d2747c72..99eb227ce4 100644
--- a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Debugger.AddIn.csproj
+++ b/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Debugger.AddIn.csproj
@@ -48,20 +48,19 @@
-
-
+
Form
-
- ExceptionForm.cs
+
+ DebuggerEventForm.cs
-
- ExceptionForm.cs
+
+ DebuggerEventForm.cs
@@ -73,11 +72,9 @@
-
-
diff --git a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Pads/ExceptionHistoryPad.cs b/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Pads/ExceptionHistoryPad.cs
deleted file mode 100644
index 0c42834b06..0000000000
--- a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Pads/ExceptionHistoryPad.cs
+++ /dev/null
@@ -1,157 +0,0 @@
-//
-//
-//
-// $Revision$
-//
-#region License
-//
-// Copyright (c) 2007, ic#code
-//
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-// 1. Redistributions of source code must retain the above copyright notice,
-// this list of conditions and the following disclaimer.
-//
-// 2. Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution.
-//
-// 3. Neither the name of the ic#code nor the names of its contributors may be
-// used to endorse or promote products derived from this software without
-// specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-// POSSIBILITY OF SUCH DAMAGE.
-//
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Drawing;
-using System.Windows.Forms;
-
-using Debugger;
-using ICSharpCode.Core;
-
-namespace ICSharpCode.SharpDevelop.Gui.Pads
-{
- public class ExceptionHistoryPad : DebuggerPad
- {
- ListView exceptionHistoryList;
- Debugger.Process debuggedProcess;
-
- List exceptions = new List();
-
- ColumnHeader time = new ColumnHeader();
- ColumnHeader exception = new ColumnHeader();
- ColumnHeader location = new ColumnHeader();
-
- public override Control Control {
- get {
- return exceptionHistoryList;
- }
- }
-
- protected override void InitializeComponents()
- {
- exceptionHistoryList = new ListView();
- exceptionHistoryList.FullRowSelect = true;
- exceptionHistoryList.AutoArrange = true;
- exceptionHistoryList.Alignment = ListViewAlignment.Left;
- exceptionHistoryList.View = View.Details;
- exceptionHistoryList.Dock = DockStyle.Fill;
- exceptionHistoryList.GridLines = false;
- exceptionHistoryList.Activation = ItemActivation.OneClick;
- exceptionHistoryList.Columns.AddRange(new ColumnHeader[] {time, exception, location} );
- exceptionHistoryList.ItemActivate += new EventHandler(ExceptionHistoryListItemActivate);
- exception.Width = 300;
- location.Width = 400;
- time.Width = 80;
-
- RedrawContent();
- }
-
- public override void RedrawContent()
- {
- time.Text = ResourceService.GetString("MainWindow.Windows.Debug.ExceptionHistory.Time");
- exception.Text = ResourceService.GetString("MainWindow.Windows.Debug.ExceptionHistory.Exception");
- location.Text = ResourceService.GetString("AddIns.HtmlHelp2.Location");
- }
-
- protected override void SelectProcess(Debugger.Process process)
- {
- if (debuggedProcess != null) {
- debuggedProcess.ExceptionThrown -= debuggedProcess_ExceptionThrown;
- }
- debuggedProcess = process;
- if (debuggedProcess != null) {
- debuggedProcess.ExceptionThrown += debuggedProcess_ExceptionThrown;
- }
- exceptions.Clear();
- RefreshPad();
- }
-
- void debuggedProcess_ExceptionThrown(object sender, ExceptionEventArgs e)
- {
- exceptions.Add(e.Exception);
- RefreshPad();
- }
-
- void ExceptionHistoryListItemActivate(object sender, EventArgs e)
- {
- SourcecodeSegment nextStatement = ((Debugger.Exception)(exceptionHistoryList.SelectedItems[0].Tag)).Location;
-
- if (nextStatement == null) {
- return;
- }
-
- FileService.OpenFile(nextStatement.SourceFullFilename);
- IViewContent content = FileService.GetOpenFile(nextStatement.SourceFullFilename);
-
- if (content is IPositionable) {
- ((IPositionable)content).JumpTo((int)nextStatement.StartLine - 1, (int)nextStatement.StartColumn - 1);
- }
- }
-
- public override void RefreshPad()
- {
- exceptionHistoryList.BeginUpdate();
- exceptionHistoryList.Items.Clear();
-
- foreach(Debugger.Exception exception in exceptions) {
- string location;
- if (exception.Location != null) {
- location = exception.Location.SourceFilename + ":" + exception.Location.StartLine;
- } else {
- location = ResourceService.GetString("Global.NA");
- }
- location += " (type=" + exception.ExceptionType.ToString() + ")";
- ListViewItem item = new ListViewItem(new string[] {"" , exception.Type + " - " + exception.Message, location});
- item.Tag = exception;
- item.ForeColor = Color.Black;
- if (exception.ExceptionType == ExceptionType.DEBUG_EXCEPTION_UNHANDLED) {
- item.ForeColor = Color.Red;
- }
- if (exception.ExceptionType == ExceptionType.DEBUG_EXCEPTION_FIRST_CHANCE ||
- exception.ExceptionType == ExceptionType.DEBUG_EXCEPTION_USER_FIRST_CHANCE) {
- item.ForeColor = Color.Blue;
- }
- exceptionHistoryList.Items.Add(item);
- }
-
- exceptionHistoryList.EndUpdate();
- }
- }
-}
diff --git a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Service/ExceptionForm.Designer.cs b/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Service/DebuggerEventForm.Designer.cs
similarity index 97%
rename from src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Service/ExceptionForm.Designer.cs
rename to src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Service/DebuggerEventForm.Designer.cs
index 29496d7913..24bb381df5 100644
--- a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Service/ExceptionForm.Designer.cs
+++ b/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Service/DebuggerEventForm.Designer.cs
@@ -43,7 +43,7 @@ using System.Windows.Forms;
namespace ICSharpCode.SharpDevelop.Services
{
- partial class ExceptionForm : System.Windows.Forms.Form
+ partial class DebuggerEventForm : System.Windows.Forms.Form
{
#region Windows Forms Designer generated code
///
@@ -128,7 +128,7 @@ namespace ICSharpCode.SharpDevelop.Services
this.MinimizeBox = false;
this.Name = "ExceptionForm";
this.ShowInTaskbar = false;
- this.Text = "${res:MainWindow.Windows.Debug.ExceptionForm.Title}";
+ this.Text = "";
this.TopMost = true;
((System.ComponentModel.ISupportInitialize)(this.pictureBox)).EndInit();
this.ResumeLayout(false);
diff --git a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Service/ExceptionForm.cs b/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Service/DebuggerEventForm.cs
similarity index 69%
rename from src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Service/ExceptionForm.cs
rename to src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Service/DebuggerEventForm.cs
index 8eac5dd42e..121314a752 100644
--- a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Service/ExceptionForm.cs
+++ b/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Service/DebuggerEventForm.cs
@@ -47,13 +47,13 @@ using ICSharpCode.Core;
namespace ICSharpCode.SharpDevelop.Services
{
- internal sealed partial class ExceptionForm
+ internal sealed partial class DebuggerEventForm
{
public enum Result {Break, Continue, Terminate};
private Result result = Result.Break; // Default
- private ExceptionForm()
+ private DebuggerEventForm()
{
InitializeComponent();
this.Text = StringParser.Parse(this.Text);
@@ -62,39 +62,18 @@ namespace ICSharpCode.SharpDevelop.Services
buttonTerminate.Text = StringParser.Parse(buttonTerminate.Text);
}
- public static Result Show(Debugger.Exception exception)
+ public static Result Show(string title, string message, System.Drawing.Bitmap icon, bool canContinue)
{
- IDebugeeException ex = exception;
- StringBuilder msg = new StringBuilder();
- msg.AppendFormat(ResourceService.GetString("MainWindow.Windows.Debug.ExceptionForm.Message"), ex.Type);
- msg.AppendLine();
- msg.AppendLine("Message:");
- msg.Append("\t");
- msg.AppendLine(ex.Message);
- msg.AppendLine();
- while(ex.InnerException != null) {
- ex = ex.InnerException;
- msg.AppendLine("Inner Exception:");
- msg.AppendFormat("Type: [{0}]", ex.Type);
- msg.AppendLine();
- msg.AppendLine("Message:");
- msg.Append("\t");
- if (ex.Message != "null") { msg.AppendLine(ex.Message); }
- msg.AppendLine();
- }
- msg.AppendLine("StackTrace:");
- msg.AppendLine(exception.Callstack.Replace("\n","\r\n"));
-
- using (ExceptionForm form = new ExceptionForm()) {
- form.textBox.Text = msg.ToString();
- form.pictureBox.Image = ResourceService.GetBitmap((exception.ExceptionType != ExceptionType.DEBUG_EXCEPTION_UNHANDLED)?"Icons.32x32.Warning":"Icons.32x32.Error");
- form.buttonContinue.Enabled = exception.ExceptionType != ExceptionType.DEBUG_EXCEPTION_UNHANDLED;
+ using (DebuggerEventForm form = new DebuggerEventForm()) {
+ form.Text = title;
+ form.textBox.Text = message;
+ form.pictureBox.Image = icon;
+ form.buttonContinue.Enabled = canContinue;
form.ShowDialog(ICSharpCode.SharpDevelop.Gui.WorkbenchSingleton.MainForm);
return form.result;
}
}
- #region Form Event Handlers
private void buttonBreak_Click(object sender, System.EventArgs e)
{
result = Result.Break;
@@ -112,6 +91,5 @@ namespace ICSharpCode.SharpDevelop.Services
result = Result.Terminate;
Close();
}
- #endregion Form Event Handlers
}
}
diff --git a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Service/ExceptionForm.resx b/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Service/DebuggerEventForm.resx
similarity index 100%
rename from src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Service/ExceptionForm.resx
rename to src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Service/DebuggerEventForm.resx
diff --git a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Service/WindowsDebugger.cs b/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Service/WindowsDebugger.cs
index 10867f3fad..63c220cc62 100644
--- a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Service/WindowsDebugger.cs
+++ b/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Service/WindowsDebugger.cs
@@ -39,7 +39,9 @@
using System;
using System.Diagnostics;
+using System.Text;
using System.Windows.Forms;
+using Bitmap = System.Drawing.Bitmap;
using Debugger;
using Debugger.Expressions;
@@ -476,7 +478,7 @@ namespace ICSharpCode.SharpDevelop.Services
void debuggedProcess_ExceptionThrown(object sender, ExceptionEventArgs e)
{
- if (!e.Exception.IsUnhandled) {
+ if (!e.IsUnhandled) {
// Ignore the exception
e.Process.AsyncContinue();
return;
@@ -484,23 +486,35 @@ namespace ICSharpCode.SharpDevelop.Services
JumpToCurrentLine();
- ExceptionForm.Result result = ExceptionForm.Show(e.Exception);
+ StringBuilder msg = new StringBuilder();
+
+ // Need to intercept now so that we can evaluate properties
+ if (e.Process.SelectedThread.InterceptCurrentException()) {
+ msg.Append(e.Exception.ToString(StringParser.Parse("${res:MainWindow.Windows.Debug.ExceptionForm.LineFormat.EndOfInnerException}")));
+ } else {
+ // For example, happens on stack overflow
+ msg.Append(e.Exception.ToString());
+ msg.AppendLine(StringParser.Parse("(${res:MainWindow.Windows.Debug.ExceptionForm.Error.CannotInterceptException})"));
+ msg.AppendLine(e.Process.SelectedThread.GetStackTrace(StringParser.Parse("${res:MainWindow.Windows.Debug.ExceptionForm.LineFormat.Symbols}"), StringParser.Parse("${res:MainWindow.Windows.Debug.ExceptionForm.LineFormat.NoSymbols}")));
+ }
+
+ string title = e.IsUnhandled ? StringParser.Parse("${res:MainWindow.Windows.Debug.ExceptionForm.Title.Unhandled}") : StringParser.Parse("${res:MainWindow.Windows.Debug.ExceptionForm.Title.Handled}");
+ string message = msg.ToString();
+ Bitmap icon = ResourceService.GetBitmap(e.IsUnhandled ? "Icons.32x32.Error" : "Icons.32x32.Warning");
+ bool canContinue = !e.IsUnhandled;
+
+ DebuggerEventForm.Result result = DebuggerEventForm.Show(title, message, icon, canContinue);
// If the process was killed while the exception form was shown
if (e.Process.HasExpired) return;
switch (result) {
- case ExceptionForm.Result.Break:
- // Need to intercept now so that we can evaluate properties in local variables pad
- if (!e.Process.SelectedThread.CurrentException.Intercept()) {
- // For example, happens on stack overflow
- MessageService.ShowMessage("${res:MainWindow.Windows.Debug.ExceptionForm.Error.CannotInterceptException}", "${res:MainWindow.Windows.Debug.ExceptionForm.Title}");
- }
+ case DebuggerEventForm.Result.Break:
break;
- case ExceptionForm.Result.Continue:
+ case DebuggerEventForm.Result.Continue:
e.Process.AsyncContinue();
break;
- case ExceptionForm.Result.Terminate:
+ case DebuggerEventForm.Result.Terminate:
e.Process.Terminate();
break;
}
diff --git a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/TreeModel/Adapters/TreeViewExceptionNode.cs b/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/TreeModel/Adapters/TreeViewExceptionNode.cs
deleted file mode 100644
index daf431d605..0000000000
--- a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/TreeModel/Adapters/TreeViewExceptionNode.cs
+++ /dev/null
@@ -1,52 +0,0 @@
-//
-//
-//
-// $Revision: 3047 $
-//
-
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Drawing;
-using System.Windows.Forms;
-
-using Aga.Controls.Tree;
-
-using Debugger.Util;
-
-using ICSharpCode.Core;
-using ICSharpCode.SharpDevelop.Gui.Pads;
-
-namespace Debugger.AddIn.TreeModel
-{
- ///
- /// This TreeNodeAdv displays exception data.
- ///
- public class TreeViewExceptionNode: TreeNodeAdv
- {
- private static Dictionary expandedNodes = new Dictionary();
-
- private TreeViewAdv localVarList;
-
- ///
- /// The content of the exception
- ///
- private AbstractNode content;
-
- // TODO: I don't know if I need localVarList
- private TreeViewExceptionNode(TreeViewAdv localVarList, ExceptionNode exception): base(localVarList, new object()) {
- this.localVarList = localVarList;
- SetContentRecursive(exception);
- }
-
- ///
- /// A simple form of SetContentRecursive that changes the current ChildViewNode to
- /// display the exception parameter passed to it. If the node had any children and is expanded,
- /// it will recureively set those as well.
- ///
- /// Contains the exception that will be stored in this particular TreeViewNode.
- public static void SetContentRecursive(ExceptionNode exception) {
- throw new NotImplementedException();
- }
- }
-}
\ No newline at end of file
diff --git a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/TreeModel/ExceptionNode.cs b/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/TreeModel/ExceptionNode.cs
deleted file mode 100644
index 913c237e01..0000000000
--- a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/TreeModel/ExceptionNode.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-//
-//
-//
-// $Revision: 2813 $
-//
-
-using System;
-
-
-namespace Debugger.AddIn.TreeModel
-{
- ///
- /// Represents a row in a TreeViewAdv that contains an IDebugeeException
- ///
- public class ExceptionNode : AbstractNode
- {
- private IDebugeeException exception;
- private ExceptionNode innerException = null;
-
- public static ExceptionNode Create(Debugger.Exception exception) {
- try {
- return new ExceptionNode(exception);
- } catch (GetValueException e) {
- // TODO: Fix this
- throw;
- //return new ErrorNode(expression, e);
- }
- }
-
- private ExceptionNode(IDebugeeException exception){
- this.exception = exception;
- this.Image = DebuggerIcons.ImageList.Images[0]; // Class
- this.Name = "Unhandled Exception";
- this.Type = exception.Type;
- this.Text = exception.Message;
- if (exception.InnerException != null) {
- innerException = new ExceptionNode(exception.InnerException);
- }
- }
-
-
- ExceptionNode InnerException {
- get { return innerException; }
- }
- }
-}
diff --git a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/TreeModel/StackFrameNode.cs b/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/TreeModel/StackFrameNode.cs
index c656e20325..a9f1a0c780 100644
--- a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/TreeModel/StackFrameNode.cs
+++ b/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/TreeModel/StackFrameNode.cs
@@ -34,6 +34,9 @@ namespace Debugger.AddIn.TreeModel
foreach(Expression expr in Expression.MethodVariables(stackFrame.MethodInfo)) {
yield return ValueNode.Create(expr);
}
+ if (stackFrame.Thread.CurrentException != null) {
+ yield return ValueNode.Create(new CurrentExceptionExpression());
+ }
}
}
}
diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Debugger.Core.csproj b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Debugger.Core.csproj
index bba9e553c3..0a1404deab 100644
--- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Debugger.Core.csproj
+++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Debugger.Core.csproj
@@ -59,13 +59,12 @@
-
-
+
diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/Thread.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/Thread.cs
index 214d0f2624..8701068746 100644
--- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/Thread.cs
+++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/Thread.cs
@@ -8,6 +8,7 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
+using System.Text;
using System.Threading;
using Debugger.Wrappers.CorDebug;
@@ -17,10 +18,13 @@ namespace Debugger
public partial class Thread: DebuggerObject
{
Process process;
-
+
ICorDebugThread corThread;
-
- Exception currentException;
+
+ Exception currentException;
+ DebuggeeState currentException_DebuggeeState;
+ ExceptionType currentExceptionType;
+ bool currentExceptionIsUnhandled;
List steppers = new List();
@@ -171,10 +175,58 @@ namespace Debugger
}
public Exception CurrentException {
- get { return currentException; }
+ get {
+ if (currentException_DebuggeeState == this.Process.DebuggeeState) {
+ return currentException;
+ } else {
+ return null;
+ }
+ }
internal set { currentException = value; }
}
+ internal DebuggeeState CurrentException_DebuggeeState {
+ get { return currentException_DebuggeeState; }
+ set { currentException_DebuggeeState = value; }
+ }
+
+ public ExceptionType CurrentExceptionType {
+ get { return currentExceptionType; }
+ internal set { currentExceptionType = value; }
+ }
+
+ public bool CurrentExceptionIsUnhandled {
+ get { return currentExceptionIsUnhandled; }
+ internal set { currentExceptionIsUnhandled = value; }
+ }
+
+ /// Tryies to intercept the current exception.
+ /// The intercepted expression stays available through the CurrentException property.
+ /// False, if the exception was already intercepted or
+ /// if it can not be intercepted.
+ public bool InterceptCurrentException()
+ {
+ if (!this.CorThread.Is()) return false; // Is the debuggee .NET 2.0?
+ if (this.CorThread.CurrentException == null) return false; // Is there any exception
+ if (this.MostRecentStackFrame == null) return false; // Is frame available? It is not at StackOverflow
+
+ try {
+ // Interception will expire the CorValue so keep permanent reference
+ currentException.MakeValuePermanent();
+ this.CorThread.CastTo().InterceptCurrentException(this.MostRecentStackFrame.CorILFrame.CastTo());
+ } catch (COMException e) {
+ // 0x80131C02: Cannot intercept this exception
+ if ((uint)e.ErrorCode == 0x80131C02) {
+ return false;
+ }
+ throw;
+ }
+
+ Process.AsyncContinue_KeepDebuggeeState();
+ Process.WaitForPause();
+ return true;
+ }
+
internal Stepper GetStepper(ICorDebugStepper corStepper)
{
foreach(Stepper stepper in steppers) {
@@ -248,6 +300,28 @@ namespace Debugger
}
}
+ public string GetStackTrace()
+ {
+ return GetStackTrace("at {0} in {1}:line {2}", "at {0} in {1}");
+ }
+
+ public string GetStackTrace(string formatSymbols, string formatNoSymbols)
+ {
+ StringBuilder stackTrace = new StringBuilder();
+ foreach(StackFrame stackFrame in this.GetCallstack(100)) {
+ SourcecodeSegment loc = stackFrame.NextStatement;
+ if (loc != null) {
+ stackTrace.Append(" ");
+ stackTrace.AppendFormat(formatSymbols, stackFrame.MethodInfo.FullName, loc.SourceFullFilename, loc.StartLine);
+ stackTrace.AppendLine();
+ } else {
+ stackTrace.AppendFormat(formatNoSymbols, stackFrame.MethodInfo.FullName);
+ stackTrace.AppendLine();
+ }
+ }
+ return stackTrace.ToString();
+ }
+
public StackFrame SelectedStackFrame {
get {
if (selectedStackFrame != null && selectedStackFrame.HasExpired) return null;
diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/DebugeeInnerException.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/DebugeeInnerException.cs
deleted file mode 100644
index bef33a7609..0000000000
--- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/DebugeeInnerException.cs
+++ /dev/null
@@ -1,69 +0,0 @@
-//
-//
-//
-//
-// $Revision: 2900 $
-//
-
-using System.Text;
-using Debugger.Wrappers.CorDebug;
-
-namespace Debugger
-{
- ///
- /// This contains the nested InnerExceptions of a Debugger.Exception class
- ///
- ///
- ///
- public class DebugeeInnerException : IDebugeeException
- {
- Debugger.Value exceptionValue;
-
- internal DebugeeInnerException (Debugger.Value exception)
- {
- this.exceptionValue = exception;
- }
-
- ///
- /// The InnerException property of the exception.
- ///
- ///
- public DebugeeInnerException InnerException {
- get {
- Debugger.Value exVal = this.exceptionValue.GetMemberValue("_innerException");
- return (exVal.IsNull) ? null : new DebugeeInnerException(exVal);
- }
- }
-
- ///
- /// The Message property of the exception.
- ///
- ///
- public string Message {
- get {
- return this.exceptionValue.GetMemberValue("_message").AsString;
- }
- }
-
- ///
- /// The GetType().FullName of the exception.
- ///
- ///
- public string Type {
- get {
- return this.exceptionValue.Type.FullName;
- }
- }
-
- public override string ToString()
- {
- StringBuilder sb = new StringBuilder();
- sb.AppendFormat("Type: {0}", this.Type);
- sb.AppendLine();
- sb.AppendLine("Message:");
- sb.Append(this.Message);
-
- return sb.ToString();
- }
- }
-}
diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/Exception.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/Exception.cs
index c8d8678bf8..a5bd504b74 100644
--- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/Exception.cs
+++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/Exception.cs
@@ -13,159 +13,113 @@ using Debugger.Wrappers.CorDebug;
namespace Debugger
{
- ///
- /// This class contains data from an Exception throw by an application
- /// being debugged. Since the System.Exception object being thrown
- /// lives in the debugged application and not in debugger, this class is
- /// neccessary.
- ///
+ /// This convenience class provides access to an exception within the debugee.
///
- public class Exception: DebuggerObject, IDebugeeException
+ public class Exception: DebuggerObject
{
- Thread thread;
- ExceptionType exceptionType;
+ Value exception;
- [Debugger.Tests.Ignore]
- public Process Process {
- get {
- return thread.Process;
- }
+ public Value Value {
+ get { return exception; }
}
- ICorDebugValue CorValue {
- get {
- return thread.CorThread.CurrentException;
- }
- }
-
- internal Exception(Thread thread, ExceptionType exceptionType)
+ public Exception(Value exception)
{
- this.thread = thread;
- this.exceptionType = exceptionType;
- }
-
- public Value RuntimeValue {
- get {
- return new Value(Process, CorValue);
- }
+ this.exception = exception;
}
-
- ///
- /// The GetType().FullName of the exception.
- ///
+ /// The GetType().FullName of the exception.
///
public string Type {
get {
- return this.RuntimeValue.Type.FullName;
+ return exception.Type.FullName;
}
}
-
- ///
- /// The InnerException property of the exception.
- ///
- ///
- public DebugeeInnerException InnerException {
- get {
- Debugger.Value exVal = this.RuntimeValue.GetMemberValue("_innerException");
- return (exVal.IsNull) ? null : new DebugeeInnerException(exVal);
- }
- }
-
- ///
- /// The Message property of the exception.
- ///
+ /// The Message property of the exception.
///
public string Message {
get {
- return this.RuntimeValue.GetMemberValue("_message").AsString;
+ Value message = exception.GetMemberValue("_message");
+ return message.IsNull ? string.Empty : message.AsString;
}
}
- public ExceptionType ExceptionType {
+ public string StackTrace {
get {
- return exceptionType;
+ try {
+ Value stackTrace = exception.GetMemberValue("StackTrace");
+ return stackTrace.IsNull ? string.Empty : stackTrace.AsString;
+ } catch (GetValueException) {
+ // Evaluation is not possible after a stackoverflow exception
+ return string.Empty;
+ }
}
}
- public bool IsUnhandled {
+ /// The InnerException property of the exception.
+ ///
+ public Exception InnerException {
get {
- return ExceptionType == ExceptionType.DEBUG_EXCEPTION_UNHANDLED;
+ Value innerException = exception.GetMemberValue("_innerException");
+ return innerException.IsNull ? null : new Exception(innerException);
}
}
- public SourcecodeSegment Location {
- get {
- if (thread.MostRecentStackFrameWithLoadedSymbols != null) {
- return thread.MostRecentStackFrameWithLoadedSymbols.NextStatement;
- } else {
- return null;
- }
- }
+ public void MakeValuePermanent()
+ {
+ exception = exception.GetPermanentReference();
}
- ///
- /// This is the call stack as represented by the Debugger.ThreadObject.
- ///
- ///
- ///
- public string Callstack {
- get {
- StringBuilder callstack = new StringBuilder();
- foreach(StackFrame stackFrame in thread.GetCallstack(100)) {
- callstack.Append(stackFrame.MethodInfo.Name);
- callstack.Append("()");
- SourcecodeSegment loc = stackFrame.NextStatement;
- if (loc != null) {
- callstack.Append(" - ");
- callstack.Append(loc.SourceFullFilename);
- callstack.Append(":");
- callstack.Append(loc.StartLine);
- callstack.Append(",");
- callstack.Append(loc.StartColumn);
- }
- callstack.Append("\n");
- }
- return callstack.ToString();
- }
+ public override string ToString()
+ {
+ return ToString("--- End of inner exception stack trace ---");
}
- public bool Intercept()
+ public string ToString(string endOfInnerExceptionFormat)
{
- if (!thread.CorThread.Is()) return false; // Is the debuggee .NET 2.0?
- if (thread.MostRecentStackFrame == null) return false; // Is frame available? It is not at StackOverflow
-
- try {
- thread.CorThread.CastTo().InterceptCurrentException(thread.MostRecentStackFrame.CorILFrame.CastTo());
- } catch (COMException e) {
- // 0x80131C02: Cannot intercept this exception
- if ((uint)e.ErrorCode == 0x80131C02) {
- return false;
- }
- throw;
+ StringBuilder sb = new StringBuilder();
+ sb.Append(this.Type);
+ if (!string.IsNullOrEmpty(this.Message)) {
+ sb.Append(": ");
+ sb.Append(this.Message);
}
-
- thread.CurrentException = null;
- Process.AsyncContinue_KeepDebuggeeState();
- Process.WaitForPause();
- return true;
+ if (this.InnerException != null) {
+ sb.Append(" ---> ");
+ sb.Append(this.InnerException.ToString(endOfInnerExceptionFormat));
+ sb.AppendLine();
+ sb.Append(" ");
+ sb.Append(endOfInnerExceptionFormat);
+ }
+ sb.AppendLine();
+ sb.Append(this.StackTrace);
+ return sb.ToString();
}
}
public class ExceptionEventArgs: ProcessEventArgs
{
Exception exception;
+ ExceptionType exceptionType;
+ bool isUnhandled;
public Exception Exception {
- get {
- return exception;
- }
+ get { return exception; }
}
- public ExceptionEventArgs(Process process, Exception exception):base(process)
+ public ExceptionType ExceptionType {
+ get { return exceptionType; }
+ }
+
+ public bool IsUnhandled {
+ get { return isUnhandled; }
+ }
+
+ public ExceptionEventArgs(Process process, Exception exception, ExceptionType exceptionType, bool isUnhandled):base(process)
{
this.exception = exception;
+ this.exceptionType = exceptionType;
+ this.isUnhandled = isUnhandled;
}
}
}
diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/ExceptionType.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/ExceptionType.cs
index 3db5329f65..390460a72f 100644
--- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/ExceptionType.cs
+++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/ExceptionType.cs
@@ -11,9 +11,9 @@ namespace Debugger
{
public enum ExceptionType
{
- DEBUG_EXCEPTION_FIRST_CHANCE = 1,
- DEBUG_EXCEPTION_UNHANDLED = 4,
- DEBUG_EXCEPTION_USER_FIRST_CHANCE = 2,
- DEBUG_EXCEPTION_CATCH_HANDLER_FOUND = 3,
+ FirstChance = 1,
+ UserFirstChance = 2,
+ CatchHandlerFound = 3,
+ Unhandled = 4,
}
}
diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/IDebugeeException.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/IDebugeeException.cs
deleted file mode 100644
index 86132edd84..0000000000
--- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/IDebugeeException.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-//
-//
-//
-//
-// $Revision: 3047 $
-//
-
-using System;
-
-namespace Debugger
-{
- ///
- /// Interface shared by Debugger.Exception and Debugger.DebugeeInnerException.
- ///
- public interface IDebugeeException
- {
- DebugeeInnerException InnerException { get; }
- string Message { get; }
- string Type { get; }
- }
-}
diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Expressions/Ast/CurrentExceptionExpression.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Expressions/Ast/CurrentExceptionExpression.cs
new file mode 100644
index 0000000000..fd96b30bcf
--- /dev/null
+++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Expressions/Ast/CurrentExceptionExpression.cs
@@ -0,0 +1,46 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+
+namespace Debugger.Expressions
+{
+ ///
+ /// An expression which returns the current exception on the thread
+ ///
+ public class CurrentExceptionExpression: Expression
+ {
+ public override string Code {
+ get {
+ return "$exception";
+ }
+ }
+
+ protected override Value EvaluateInternal(StackFrame context)
+ {
+ if (context.Thread.CurrentException != null) {
+ return context.Thread.CurrentException.Value;
+ } else {
+ throw new GetValueException("No current exception");
+ }
+ }
+
+ #region GetHashCode and Equals
+
+ public override int GetHashCode()
+ {
+ return typeof(CurrentExceptionExpression).GetHashCode();
+ }
+
+ public override bool Equals(object obj)
+ {
+ return obj is CurrentExceptionExpression;
+ }
+
+ #endregion
+ }
+}
diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Expressions/Ast/ThisReferenceExpression.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Expressions/Ast/ThisReferenceExpression.cs
index 3c5dae495b..75e39cd977 100644
--- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Expressions/Ast/ThisReferenceExpression.cs
+++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Expressions/Ast/ThisReferenceExpression.cs
@@ -10,7 +10,7 @@ using System;
namespace Debugger.Expressions
{
///
- /// 'this' regerence of a non-static method.
+ /// 'this' reference of a non-static method.
///
public class ThisReferenceExpression: Expression
{
diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Internal/ManagedCallback.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Internal/ManagedCallback.cs
index c9fe4c4359..e909335324 100644
--- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Internal/ManagedCallback.cs
+++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Internal/ManagedCallback.cs
@@ -119,7 +119,12 @@ namespace Debugger
void RaiseEvents()
{
if (process.PauseSession.PausedReason == PausedReason.Exception) {
- ExceptionEventArgs args = new ExceptionEventArgs(process, process.SelectedThread.CurrentException);
+ // Needs to be done after the debugge state is created
+ process.SelectedThread.CurrentException_DebuggeeState = process.DebuggeeState;
+ }
+
+ if (process.PauseSession.PausedReason == PausedReason.Exception) {
+ ExceptionEventArgs args = new ExceptionEventArgs(process, process.SelectedThread.CurrentException, process.SelectedThread.CurrentExceptionType, process.SelectedThread.CurrentExceptionIsUnhandled);
process.OnExceptionThrown(args);
// The event could have resumed or killed the process
}
@@ -209,7 +214,7 @@ namespace Debugger
if (process.DebuggeeVersion.StartsWith("v1.")) {
// Forward the call to Exception2, which handles EnterCallback and ExitCallback
- ExceptionType exceptionType = (unhandled != 0)?ExceptionType.DEBUG_EXCEPTION_UNHANDLED:ExceptionType.DEBUG_EXCEPTION_FIRST_CHANCE;
+ ExceptionType exceptionType = (unhandled != 0) ? ExceptionType.Unhandled : ExceptionType.FirstChance;
Exception2(pAppDomain, pThread, null, 0, (CorDebugExceptionCallbackType)exceptionType, 0);
} else {
// This callback should be ignored in v2 applications
@@ -462,9 +467,11 @@ namespace Debugger
// Watch out for the zeros and null!
// Exception -> Exception2(pAppDomain, pThread, null, 0, exceptionType, 0);
- process.SelectedThread.CurrentException = new Exception(process.SelectedThread, (ExceptionType)exceptionType);
+ process.SelectedThread.CurrentException = new Exception(new Value(process, new Expressions.CurrentExceptionExpression(), process.SelectedThread.CorThread.CurrentException));
+ process.SelectedThread.CurrentExceptionType = (ExceptionType)exceptionType;
+ process.SelectedThread.CurrentExceptionIsUnhandled = (ExceptionType)exceptionType == ExceptionType.Unhandled;
- if (process.SelectedThread.CurrentException.IsUnhandled ||
+ if (process.SelectedThread.CurrentExceptionIsUnhandled ||
process.PauseOnHandledException)
{
pauseOnNextExit = true;
diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Values/Value.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Values/Value.cs
index d5446491bd..a82fbc4db8 100644
--- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Values/Value.cs
+++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Values/Value.cs
@@ -115,6 +115,15 @@ namespace Debugger
}
}
+ public Value GetPermanentReference()
+ {
+ ICorDebugValue corValue;
+ corValue = this.RawCorValue;
+ corValue = DereferenceUnbox(corValue);
+ corValue = corValue.CastTo().CreateHandle(CorDebugHandleType.HANDLE_STRONG).CastTo();
+ return new Value(process, expression, corValue);
+ }
+
internal Value(Process process,
ICorDebugValue rawCorValue)
:this (process, new EmptyExpression(), rawCorValue)
diff --git a/src/Main/StartUp/Project/Resources/StringResources.resources b/src/Main/StartUp/Project/Resources/StringResources.resources
index f4d572ae59..01b84e1ac7 100644
Binary files a/src/Main/StartUp/Project/Resources/StringResources.resources and b/src/Main/StartUp/Project/Resources/StringResources.resources differ