From a6289b3df03f1ababf5e0031258ac629060026cb Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Mon, 27 Feb 2012 17:39:42 +0100 Subject: [PATCH] fixed SD-1889 - NullReferenceException when pausing debugger --- src/AddIns/Debugger/Debugger.Core/ManagedCallback.cs | 8 +++++++- src/AddIns/Debugger/Debugger.Core/Process.cs | 5 ++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/AddIns/Debugger/Debugger.Core/ManagedCallback.cs b/src/AddIns/Debugger/Debugger.Core/ManagedCallback.cs index cd3fe58868..0d0f002649 100644 --- a/src/AddIns/Debugger/Debugger.Core/ManagedCallback.cs +++ b/src/AddIns/Debugger/Debugger.Core/ManagedCallback.cs @@ -2,6 +2,7 @@ // This code is distributed under the GNU LGPL (for details please see \doc\license.txt) using System; +using System.Diagnostics; using System.Runtime.InteropServices; using Debugger.Interop; using Debugger.Interop.CorDebug; @@ -82,7 +83,9 @@ namespace Debugger if (hasQueuedCallbacks) process.TraceMessage("Process has queued callbacks"); - if (hasQueuedCallbacks) { + // only process callbacks if no exception occurred + // if no thread is selected CurrentException must be null + if (hasQueuedCallbacks && (process.SelectedThread == null || process.SelectedThread.CurrentException == null)) { // Exception has Exception2 queued after it process.AsyncContinue(DebuggeeStateAction.Keep, null, null); } else if (process.Evaluating) { @@ -513,6 +516,9 @@ namespace Debugger bool pauseOnHandled = process.Options != null && process.Options.PauseOnHandledExceptions; if (exceptionType == ExceptionType.Unhandled || (pauseOnHandled && exceptionType == ExceptionType.CatchHandlerFound)) { + // sanity check: we can only handle one exception after another + // TODO : create Exception queue if CLR throws multiple exceptions + Debug.Assert(process.SelectedThread.CurrentException == null); process.SelectedThread.CurrentException = new Exception(new Value(process.AppDomains[pAppDomain], process.SelectedThread.CorThread.GetCurrentException()).GetPermanentReference()); process.SelectedThread.CurrentException_DebuggeeState = process.DebuggeeState; process.SelectedThread.CurrentExceptionType = exceptionType; diff --git a/src/AddIns/Debugger/Debugger.Core/Process.cs b/src/AddIns/Debugger/Debugger.Core/Process.cs index 07d0e57280..6ae85168fd 100644 --- a/src/AddIns/Debugger/Debugger.Core/Process.cs +++ b/src/AddIns/Debugger/Debugger.Core/Process.cs @@ -342,8 +342,11 @@ namespace Debugger CheckSelectedStackFrames(); SelectMostRecentStackFrameWithLoadedSymbols(); - if (this.PauseSession.PausedReason == PausedReason.Exception) { + // if CurrentException is set an exception has occurred. + if (SelectedThread.CurrentException != null) { ExceptionEventArgs args = new ExceptionEventArgs(this, this.SelectedThread.CurrentException, this.SelectedThread.CurrentExceptionType, this.SelectedThread.CurrentExceptionIsUnhandled); + // clear exception, it is being processed by the debugger. + this.SelectedThread.CurrentException = null; OnExceptionThrown(args); // The event could have resumed or killed the process if (this.IsRunning || this.TerminateCommandIssued || this.HasExited) return;