Skip to content

Commit f9ae991

Browse files
fix icsharpcode#385 - DebuggerExceptions while stepping through code
1 parent af1e958 commit f9ae991

File tree

2 files changed

+21
-27
lines changed

2 files changed

+21
-27
lines changed

src/AddIns/Debugger/Debugger.AddIn/Service/WindowsDebugger.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -463,7 +463,10 @@ void debuggedProcess_DebuggingPaused(object sender, DebuggerPausedEventArgs e)
463463
OnIsProcessRunningChanged(EventArgs.Empty);
464464

465465
CurrentProcess = e.Process;
466-
CurrentThread = e.Thread;
466+
if (e.Thread != null)
467+
CurrentThread = e.Thread;
468+
else if (CurrentThread != null && CurrentThread.HasExited)
469+
CurrentThread = null;
467470
CurrentStackFrame = CurrentThread != null ? CurrentThread.MostRecentStackFrame : null;
468471

469472
// We can have several events happening at the same time

src/AddIns/Debugger/Debugger.Core/ManagedCallback.cs

Lines changed: 17 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,6 @@ class ManagedCallback
4141
bool isInCallback;
4242
DebuggerPausedEventArgs pausedEventArgs;
4343

44-
Thread threadToReport; // TODO: Remove
45-
4644
[Debugger.Tests.Ignore]
4745
public Process Process {
4846
get { return process; }
@@ -61,9 +59,14 @@ public ManagedCallback(Process process)
6159
// The reason for the accumulation is that several pause callbacks
6260
// can happen "at the same time" in the debugee.
6361
// The event will be raised as soon as the callback queue is drained.
64-
DebuggerPausedEventArgs GetPausedEventArgs()
62+
DebuggerPausedEventArgs RequestPause(Thread thread)
6563
{
66-
return pausedEventArgs ?? (pausedEventArgs = new DebuggerPausedEventArgs(process));
64+
pauseOnNextExit = true;
65+
if (pausedEventArgs == null) {
66+
pausedEventArgs = new DebuggerPausedEventArgs(process);
67+
pausedEventArgs.Thread = thread;
68+
}
69+
return pausedEventArgs;
6770
}
6871

6972
void EnterCallback(string name, ICorDebugProcess pProcess)
@@ -100,7 +103,6 @@ void EnterCallback(string name, ICorDebugAppDomain pAppDomain)
100103
void EnterCallback(string name, ICorDebugThread pThread)
101104
{
102105
EnterCallback(name, pThread.GetProcess());
103-
threadToReport = process.GetThread(pThread);
104106
}
105107

106108
void ExitCallback()
@@ -120,9 +122,6 @@ void ExitCallback()
120122

121123
process.DisableAllSteppers();
122124
if (pausedEventArgs != null) {
123-
pausedEventArgs.Thread = threadToReport;
124-
threadToReport = null;
125-
126125
// Raise the pause event outside the callback
127126
// Warning: Make sure that process in not resumed in the meantime
128127
DebuggerPausedEventArgs e = pausedEventArgs; // Copy for capture
@@ -173,8 +172,7 @@ public void StepComplete(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread,
173172
}
174173
} else {
175174
// User-code method
176-
pauseOnNextExit = true;
177-
GetPausedEventArgs().Break = true;
175+
RequestPause(thread).Break = true;
178176
process.TraceMessage(" - pausing in user code");
179177
}
180178

@@ -187,16 +185,16 @@ public void Breakpoint(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, I
187185
EnterCallback("Breakpoint", pThread);
188186

189187
Breakpoint breakpoint = process.Debugger.GetBreakpoint(corBreakpoint);
188+
Thread thread = process.GetThread(pThread);
189+
190190
// Could be one of Process.tempBreakpoints
191191
// The breakpoint might have just been removed
192192
if (breakpoint != null) {
193-
GetPausedEventArgs().BreakpointsHit.Add(breakpoint);
193+
RequestPause(thread).BreakpointsHit.Add(breakpoint);
194194
} else {
195-
GetPausedEventArgs().Break = true;
195+
RequestPause(thread).Break = true;
196196
}
197197

198-
pauseOnNextExit = true;
199-
200198
ExitCallback();
201199
}
202200

@@ -210,26 +208,22 @@ public void BreakpointSetError(ICorDebugAppDomain pAppDomain, ICorDebugThread pT
210208
public void Break(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread)
211209
{
212210
EnterCallback("Break", pThread);
213-
214-
pauseOnNextExit = true;
215-
GetPausedEventArgs().Break = true;
211+
RequestPause(process.GetThread(pThread)).Break = true;
216212
ExitCallback();
217213
}
218214

219215
public void ControlCTrap(ICorDebugProcess pProcess)
220216
{
221217
EnterCallback("ControlCTrap", pProcess);
222-
223-
pauseOnNextExit = true;
224-
GetPausedEventArgs().Break = true;
218+
RequestPause(null).Break = true;
225219
ExitCallback();
226220
}
227221

228222
public void Exception(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, int unhandled)
229223
{
230224
// Exception2 is used in .NET Framework 2.0
231225

232-
if (process.DebuggeeVersion.StartsWith("v1.")) {
226+
if (process.DebuggeeVersion.StartsWith("v1.", StringComparison.Ordinal)) {
233227
// Forward the call to Exception2, which handles EnterCallback and ExitCallback
234228
ExceptionType exceptionType = (unhandled != 0) ? ExceptionType.Unhandled : ExceptionType.FirstChance;
235229
Exception2(pAppDomain, pThread, null, 0, (CorDebugExceptionCallbackType)exceptionType, 0);
@@ -311,8 +305,7 @@ public void DebuggerError(ICorDebugProcess pProcess, int errorHR, uint errorCode
311305
throw new DebuggerException(errorText);
312306

313307
try {
314-
pauseOnNextExit = true;
315-
GetPausedEventArgs().Break = true;
308+
RequestPause(null).Break = true;
316309
ExitCallback();
317310
} catch (COMException) {
318311
} catch (InvalidComObjectException) {
@@ -550,9 +543,7 @@ public void Exception2(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, I
550543
// (I have managed to create a test application to trigger it)
551544
Thread thread = process.GetThread(pThread);
552545
thread.CurrentExceptionType = exceptionType;
553-
GetPausedEventArgs().ExceptionsThrown.Add(thread);
554-
555-
pauseOnNextExit = true;
546+
RequestPause(thread).ExceptionsThrown.Add(thread);
556547
}
557548

558549
ExitCallback();

0 commit comments

Comments
 (0)