From 24b75bf9a754ac95cdbd9e6a07bd91e435552d22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Srbeck=C3=BD?= Date: Sun, 20 Jan 2008 12:01:18 +0000 Subject: [PATCH] Rewritten Exception class git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@2898 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61 --- .../Project/Src/Pads/ExceptionHistoryPad.cs | 2 +- .../Project/Src/Service/WindowsDebugger.cs | 17 +-- .../Project/Src/Control/Thread.cs | 41 ++----- .../Project/Src/Debugger/Exception.cs | 115 +++++++++++------- .../Project/Src/Internal/ManagedCallback.cs | 10 +- 5 files changed, 93 insertions(+), 92 deletions(-) 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 index 83bbfb7227..0c42834b06 100644 --- a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Pads/ExceptionHistoryPad.cs +++ b/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Pads/ExceptionHistoryPad.cs @@ -138,7 +138,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads location = ResourceService.GetString("Global.NA"); } location += " (type=" + exception.ExceptionType.ToString() + ")"; - ListViewItem item = new ListViewItem(new string[] {exception.CreationTime.ToLongTimeString() , exception.Type + " - " + exception.Message, location}); + 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) { 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 dbdda83722..6dc49b18de 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 @@ -305,6 +305,12 @@ namespace ICSharpCode.SharpDevelop.Services public bool CanSetInstructionPointer(string filename, int line, int column) { + if (debuggedProcess.SelectedThread.CurrentException != null) { + if (!debuggedProcess.SelectedThread.CurrentException.Intercept()) { + // For example, happens on stack overflow + MessageService.ShowMessage("${res:MainWindow.Windows.Debug.ExceptionForm.Error.CannotInterceptException}", "${res:MainWindow.Windows.Debug.ExceptionForm.Title}"); + } + } if (debuggedProcess != null && debuggedProcess.IsPaused && debuggedProcess.SelectedStackFrame != null) { SourcecodeSegment seg = debuggedProcess.SelectedStackFrame.CanSetIP(filename, line, column); return seg != null; @@ -443,7 +449,7 @@ namespace ICSharpCode.SharpDevelop.Services void debuggedProcess_ExceptionThrown(object sender, ExceptionEventArgs e) { - if (e.Exception.ExceptionType != ExceptionType.DEBUG_EXCEPTION_UNHANDLED) { + if (!e.Exception.IsUnhandled) { // Ignore the exception e.Continue = true; return; @@ -460,16 +466,11 @@ namespace ICSharpCode.SharpDevelop.Services switch (result) { case ExceptionForm.Result.Break: - if (e.Process.SelectedThread.InterceptCurrentException()) { - e.Continue = true; // HACK: Start interception - } else { - // For example, happens on stack overflow - MessageService.ShowMessage("${res:MainWindow.Windows.Debug.ExceptionForm.Error.CannotInterceptException}", "${res:MainWindow.Windows.Debug.ExceptionForm.Title}"); - } + e.Continue = false; break; case ExceptionForm.Result.Continue: e.Continue = true; - return; + break; case ExceptionForm.Result.Terminate: process.Terminate(); break; 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 0a4ad42819..ba0cb9dfae 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 @@ -20,7 +20,7 @@ namespace Debugger ICorDebugThread corThread; - internal ExceptionType currentExceptionType; + Exception currentException; List steppers = new List(); @@ -68,16 +68,6 @@ namespace Debugger } } - [Debugger.Tests.Ignore] - public ExceptionType CurrentExceptionType { - get { - return currentExceptionType; - } - set { - currentExceptionType = value; - } - } - public bool IsAtSafePoint { get { return CorThread.UserState != CorDebugUserState.USER_UNSAFE_POINT; @@ -180,21 +170,9 @@ namespace Debugger } } - public bool InterceptCurrentException() - { - if (!CorThread.Is()) return false; // Is the debuggee .NET 2.0? - if (MostRecentStackFrame == null) return false; // Is frame available? It is not at StackOverflow - - try { - CorThread.CastTo().InterceptCurrentException(MostRecentStackFrame.CorILFrame.CastTo()); - return true; - } catch (COMException e) { - // 0x80131C02: Cannot intercept this exception - if ((uint)e.ErrorCode == 0x80131C02) { - return false; - } - throw; - } + public Exception CurrentException { + get { return currentException; } + internal set { currentException = value; } } internal Stepper GetStepper(ICorDebugStepper corStepper) @@ -228,13 +206,6 @@ namespace Debugger return String.Format("ID = {0,-10} Name = {1,-20} Suspended = {2,-8}", ID, Name, Suspended); } - - public Exception CurrentException { - get { - return new Exception(this); - } - } - /// /// Gets the whole callstack of the Thread. /// @@ -291,6 +262,8 @@ namespace Debugger } } + #region Convenience methods + public StackFrame MostRecentStackFrameWithLoadedSymbols { get { foreach (StackFrame stackFrame in CallstackEnum) { @@ -328,6 +301,8 @@ namespace Debugger } } + #endregion + public bool IsMostRecentStackFrameNative { get { process.AssertPaused(); 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 5626545f8d..198171a357 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 @@ -6,90 +6,117 @@ // using System; +using System.Runtime.InteropServices; +using System.Text; + using Debugger.Wrappers.CorDebug; namespace Debugger { public class Exception: DebuggerObject { - Process process; - Thread thread; - ICorDebugValue corValue; - ExceptionType exceptionType; - SourcecodeSegment location; - DateTime creationTime; - string callstack; - string type; - string message; + Thread thread; + ExceptionType exceptionType; [Debugger.Tests.Ignore] public Process Process { get { - return process; + return thread.Process; + } + } + + ICorDebugValue CorValue { + get { + return thread.CorThread.CurrentException; } } - internal Exception(Thread thread) + internal Exception(Thread thread, ExceptionType exceptionType) { - creationTime = DateTime.Now; - this.process = thread.Process; this.thread = thread; - corValue = thread.CorThread.CurrentException; - exceptionType = thread.CurrentExceptionType; - Value runtimeValue = new Value(process, corValue); - message = runtimeValue.GetMemberValue("_message").AsString; - - if (thread.MostRecentStackFrameWithLoadedSymbols != null) { - location = thread.MostRecentStackFrameWithLoadedSymbols.NextStatement; - } - - callstack = ""; - foreach(StackFrame stackFrame in thread.GetCallstack(100)) { - SourcecodeSegment loc = stackFrame.NextStatement; - callstack += stackFrame.MethodInfo.Name + "()"; - if (loc != null) { - callstack += " - " + loc.SourceFullFilename + ":" + loc.StartLine + "," + loc.StartColumn; - } - callstack += "\n"; + this.exceptionType = exceptionType; + } + + public Value RuntimeValue { + get { + return new Value(Process, CorValue); } - - type = runtimeValue.Type.FullName; } public string Type { get { - return type; + return this.RuntimeValue.Type.FullName; } } public string Message { get { - return message; + return this.RuntimeValue.GetMemberValue("_message").AsString; } } - public string Callstack { + public ExceptionType ExceptionType { get { - return callstack; + return exceptionType; } } - - public ExceptionType ExceptionType{ + + public bool IsUnhandled { get { - return exceptionType; + return ExceptionType == ExceptionType.DEBUG_EXCEPTION_UNHANDLED; } } - + public SourcecodeSegment Location { get { - return location; + if (thread.MostRecentStackFrameWithLoadedSymbols != null) { + return thread.MostRecentStackFrameWithLoadedSymbols.NextStatement; + } else { + return null; + } } } - - public DateTime CreationTime { + + public string Callstack { get { - return creationTime; + 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 bool Intercept() + { + 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; } + + thread.CurrentException = null; + Process.AsyncContinue(); + Process.WaitForPause(); + return true; } } 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 b5fe3c3104..1c2cb42d67 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 @@ -421,18 +421,16 @@ namespace Debugger // Whatch out for the zeros and null! // Exception -> Exception2(pAppDomain, pThread, null, 0, exceptionType, 0); - process.SelectedThread.CurrentExceptionType = (ExceptionType)exceptionType; + process.SelectedThread.CurrentException = new Exception(process.SelectedThread, (ExceptionType)exceptionType); - if (ExceptionType.DEBUG_EXCEPTION_UNHANDLED != (ExceptionType)exceptionType) { - // Handled exception + if (process.SelectedThread.CurrentException.IsUnhandled) { + ExitCallback_Paused(); + } else { if (process.PauseOnHandledException) { ExitCallback_Paused(); } else { ExitCallback_Continue(); } - } else { - // Unhandled exception - ExitCallback_Paused(); } }