Browse Source

Terminate command does 'Break+Terminate' rather then 'Continue+Break+Terminate'. I think this was left over from .NET 1.1 hack.

Changed the way callbacks are handled - it uses pauseOnNextExit flag now rather then two different exit procedures.  
Queued callback are drained from the process queue.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@2921 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
David Srbecký 18 years ago
parent
commit
ee7edd15b7
  1. 1
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Debugger.Core.csproj
  2. 10
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/Process-StateControl.cs
  3. 133
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Internal/ManagedCallback.cs
  4. 23
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/CorDebug/ICorDebugProcess.cs

1
src/AddIns/Misc/Debugger/Debugger.Core/Project/Debugger.Core.csproj

@ -318,6 +318,7 @@
<Compile Include="Src\Wrappers\CorDebug\ICorDebugFrameEnum.cs" /> <Compile Include="Src\Wrappers\CorDebug\ICorDebugFrameEnum.cs" />
<Compile Include="Src\Wrappers\CorDebug\ICorDebugGenericValue.cs" /> <Compile Include="Src\Wrappers\CorDebug\ICorDebugGenericValue.cs" />
<Compile Include="Src\Wrappers\CorDebug\ICorDebugModule.cs" /> <Compile Include="Src\Wrappers\CorDebug\ICorDebugModule.cs" />
<Compile Include="Src\Wrappers\CorDebug\ICorDebugProcess.cs" />
<Compile Include="Src\Wrappers\CorDebug\ICorDebugStepper.cs" /> <Compile Include="Src\Wrappers\CorDebug\ICorDebugStepper.cs" />
<Compile Include="Src\Wrappers\CorDebug\ICorDebugStringValue.cs" /> <Compile Include="Src\Wrappers\CorDebug\ICorDebugStringValue.cs" />
<Compile Include="Src\Wrappers\CorDebug\ICorDebugTypeEnum.cs" /> <Compile Include="Src\Wrappers\CorDebug\ICorDebugTypeEnum.cs" />

10
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/Process-StateControl.cs

@ -177,7 +177,7 @@ namespace Debugger
{ {
AssertRunning(); AssertRunning();
corProcess.Stop(5000); // TODO: Hardcoded value corProcess.Stop(uint.MaxValue); // Infinite; ignored anyway
CreatePauseSession(PausedReason.ForcedBreak); CreatePauseSession(PausedReason.ForcedBreak);
CreateDebuggeeState(); CreateDebuggeeState();
@ -216,10 +216,6 @@ namespace Debugger
{ {
AssertPaused(); AssertPaused();
if (callbackInterface.IsInCallback) {
throw new DebuggerException("Can not continue from within callback.");
}
ExpirePauseSession(); ExpirePauseSession();
corProcess.Continue(0); corProcess.Continue(0);
} }
@ -229,14 +225,14 @@ namespace Debugger
// Resume stoped tread // Resume stoped tread
if (this.IsPaused) { if (this.IsPaused) {
// We might get more callbacks so we should maintain consistent sate // We might get more callbacks so we should maintain consistent sate
AsyncContinue(); // TODO: Remove this... //AsyncContinue(); // Continue the process to get remaining callbacks
} }
// Expose race condition - drain callback queue // Expose race condition - drain callback queue
System.Threading.Thread.Sleep(0); System.Threading.Thread.Sleep(0);
// Stop&terminate - both must be called // Stop&terminate - both must be called
corProcess.Stop(5000); // TODO: ...and this corProcess.Stop(uint.MaxValue);
corProcess.Terminate(0); corProcess.Terminate(0);
} }

133
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Internal/ManagedCallback.cs

@ -24,7 +24,7 @@ namespace Debugger
class ManagedCallback class ManagedCallback
{ {
Process process; Process process;
bool pauseProcessInsteadOfContinue; bool pauseOnNextExit;
bool isInCallback = false; bool isInCallback = false;
[Debugger.Tests.Ignore] [Debugger.Tests.Ignore]
@ -53,11 +53,12 @@ namespace Debugger
// After break is pressed we may receive some messages that were already queued // After break is pressed we may receive some messages that were already queued
if (process.IsPaused && process.PauseSession.PausedReason == PausedReason.ForcedBreak) { if (process.IsPaused && process.PauseSession.PausedReason == PausedReason.ForcedBreak) {
process.TraceMessage("Processing post-break callback"); process.TraceMessage("Processing post-break callback");
// Continue the break, process is still breaked because of the callback // This compensates for the break call and we are in normal callback handling mode
process.ExpirePauseSession(); process.AsyncContinue_KeepDebuggeeState();
process.CorProcess.Continue(0); // Start of call back - create new pause session (as usual)
pauseProcessInsteadOfContinue = true;
process.CreatePauseSession(pausedReason); process.CreatePauseSession(pausedReason);
// Make sure we stay pause after the callback is handled
pauseOnNextExit = true;
return; return;
} }
@ -80,28 +81,27 @@ namespace Debugger
process.SelectedThread = process.GetThread(pThread); process.SelectedThread = process.GetThread(pThread);
} }
void ExitCallback_Continue() void ExitCallback()
{ {
if (pauseProcessInsteadOfContinue) { bool hasQueuedCallbacks = process.CorProcess.HasQueuedCallbacks();
pauseProcessInsteadOfContinue = false; if (hasQueuedCallbacks) {
ExitCallback_Paused(); process.TraceMessage("Process has queued callbacks");
return;
} }
process.ExpirePauseSession(); // Ignore events during property evaluation
process.CorProcess.Continue(0); if (!pauseOnNextExit || process.Evaluating || hasQueuedCallbacks) {
process.ExpirePauseSession();
process.CorProcess.Continue(0);
} else {
pauseOnNextExit = false;
Pause();
}
isInCallback = false; isInCallback = false;
} }
void ExitCallback_Paused() void Pause()
{ {
if (process.Evaluating) {
// Ignore events during property evaluation
ExitCallback_Continue();
return;
}
process.SelectMostRecentStackFrameWithLoadedSymbols(); process.SelectMostRecentStackFrameWithLoadedSymbols();
process.DisableAllSteppers(); process.DisableAllSteppers();
@ -114,8 +114,6 @@ namespace Debugger
// Raise the pause event outside the callback // Raise the pause event outside the callback
process.Debugger.MTA2STA.AsyncCall(RaiseEvents); process.Debugger.MTA2STA.AsyncCall(RaiseEvents);
} }
isInCallback = false;
} }
void RaiseEvents() void RaiseEvents()
@ -149,23 +147,21 @@ namespace Debugger
if (stepper.PauseWhenComplete) { if (stepper.PauseWhenComplete) {
if (process.SelectedThread.MostRecentStackFrame.HasSymbols) { if (process.SelectedThread.MostRecentStackFrame.HasSymbols) {
ExitCallback_Paused(); pauseOnNextExit = true;
} else { } else {
// This can only happen when JMC is disabled (ie NET1.1 or StepOut) // This can only happen when JMC is disabled (ie NET1.1 or StepOut)
if (stepper.Operation == Stepper.StepperOperation.StepOut) { if (stepper.Operation == Stepper.StepperOperation.StepOut) {
// Create new stepper and keep going // Create new stepper and keep going
process.TraceMessage(" - stepping out of code without symbols at " + process.SelectedThread.MostRecentStackFrame.ToString()); process.TraceMessage(" - stepping out of code without symbols at " + process.SelectedThread.MostRecentStackFrame.ToString());
new Stepper(process.SelectedThread.MostRecentStackFrame, "Stepper out of code without symbols").StepOut(); new Stepper(process.SelectedThread.MostRecentStackFrame, "Stepper out of code without symbols").StepOut();
ExitCallback_Continue();
} else { } else {
// NET1.1: There is extra step over stepper, just keep going // NET1.1: There is extra step over stepper, just keep going
process.TraceMessage(" - leaving code without symbols"); process.TraceMessage(" - leaving code without symbols");
ExitCallback_Continue();
} }
} }
} else {
ExitCallback_Continue();
} }
ExitCallback();
} }
// Do not pass the pBreakpoint parameter as ICorDebugBreakpoint - marshaling of it fails in .NET 1.1 // Do not pass the pBreakpoint parameter as ICorDebugBreakpoint - marshaling of it fails in .NET 1.1
@ -173,7 +169,8 @@ namespace Debugger
{ {
EnterCallback(PausedReason.Breakpoint, "Breakpoint", pThread); EnterCallback(PausedReason.Breakpoint, "Breakpoint", pThread);
ExitCallback_Paused(); pauseOnNextExit = true;
ExitCallback();
// foreach (Breakpoint b in debugger.Breakpoints) { // foreach (Breakpoint b in debugger.Breakpoints) {
// if (b.Equals(pBreakpoint)) { // if (b.Equals(pBreakpoint)) {
@ -187,21 +184,23 @@ namespace Debugger
{ {
EnterCallback(PausedReason.Other, "BreakpointSetError", pThread); EnterCallback(PausedReason.Other, "BreakpointSetError", pThread);
ExitCallback_Continue(); ExitCallback();
} }
public unsafe void Break(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread) public void Break(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread)
{ {
EnterCallback(PausedReason.Break, "Break", pThread); EnterCallback(PausedReason.Break, "Break", pThread);
ExitCallback_Paused(); pauseOnNextExit = true;
ExitCallback();
} }
public void ControlCTrap(ICorDebugProcess pProcess) public void ControlCTrap(ICorDebugProcess pProcess)
{ {
EnterCallback(PausedReason.ControlCTrap, "ControlCTrap", pProcess); EnterCallback(PausedReason.ControlCTrap, "ControlCTrap", pProcess);
ExitCallback_Paused(); pauseOnNextExit = true;
ExitCallback();
} }
public unsafe void Exception(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, int unhandled) public unsafe void Exception(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, int unhandled)
@ -216,7 +215,7 @@ namespace Debugger
// This callback should be ignored in v2 applications // This callback should be ignored in v2 applications
EnterCallback(PausedReason.Other, "Exception", pThread); EnterCallback(PausedReason.Other, "Exception", pThread);
ExitCallback_Continue(); ExitCallback();
} }
} }
@ -228,7 +227,7 @@ namespace Debugger
{ {
EnterCallback(PausedReason.Other, "LogSwitch", pThread); EnterCallback(PausedReason.Other, "LogSwitch", pThread);
ExitCallback_Continue(); ExitCallback();
} }
public void LogMessage(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, int lLevel, string pLogSwitchName, string pMessage) public void LogMessage(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, int lLevel, string pLogSwitchName, string pMessage)
@ -237,14 +236,14 @@ namespace Debugger
process.OnLogMessage(new MessageEventArgs(process, lLevel, pMessage, pLogSwitchName)); process.OnLogMessage(new MessageEventArgs(process, lLevel, pMessage, pLogSwitchName));
ExitCallback_Continue(); ExitCallback();
} }
public void EditAndContinueRemap(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugFunction pFunction, int fAccurate) public void EditAndContinueRemap(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugFunction pFunction, int fAccurate)
{ {
EnterCallback(PausedReason.Other, "EditAndContinueRemap", pThread); EnterCallback(PausedReason.Other, "EditAndContinueRemap", pThread);
ExitCallback_Continue(); ExitCallback();
} }
public void EvalException(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugEval corEval) public void EvalException(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugEval corEval)
@ -268,7 +267,8 @@ namespace Debugger
eval.NotifyEvaluationComplete(!exception); eval.NotifyEvaluationComplete(!exception);
process.NotifyEvaluationComplete(eval); process.NotifyEvaluationComplete(eval);
ExitCallback_Paused(); pauseOnNextExit = true;
ExitCallback();
} }
public void DebuggerError(ICorDebugProcess pProcess, int errorHR, uint errorCode) public void DebuggerError(ICorDebugProcess pProcess, int errorHR, uint errorCode)
@ -283,14 +283,15 @@ namespace Debugger
System.Windows.Forms.MessageBox.Show(errorText); System.Windows.Forms.MessageBox.Show(errorText);
ExitCallback_Paused(); pauseOnNextExit = true;
ExitCallback();
} }
public void UpdateModuleSymbols(ICorDebugAppDomain pAppDomain, ICorDebugModule pModule, IStream pSymbolStream) public void UpdateModuleSymbols(ICorDebugAppDomain pAppDomain, ICorDebugModule pModule, IStream pSymbolStream)
{ {
EnterCallback(PausedReason.Other, "UpdateModuleSymbols", pAppDomain); EnterCallback(PausedReason.Other, "UpdateModuleSymbols", pAppDomain);
ExitCallback_Continue(); ExitCallback();
} }
#endregion #endregion
@ -303,7 +304,7 @@ namespace Debugger
// Process is added in NDebugger.Start // Process is added in NDebugger.Start
ExitCallback_Continue(); ExitCallback();
} }
public void CreateAppDomain(ICorDebugProcess pProcess, ICorDebugAppDomain pAppDomain) public void CreateAppDomain(ICorDebugProcess pProcess, ICorDebugAppDomain pAppDomain)
@ -312,14 +313,14 @@ namespace Debugger
pAppDomain.Attach(); pAppDomain.Attach();
ExitCallback_Continue(); ExitCallback();
} }
public void LoadAssembly(ICorDebugAppDomain pAppDomain, ICorDebugAssembly pAssembly) public void LoadAssembly(ICorDebugAppDomain pAppDomain, ICorDebugAssembly pAssembly)
{ {
EnterCallback(PausedReason.Other, "LoadAssembly", pAppDomain); EnterCallback(PausedReason.Other, "LoadAssembly", pAppDomain);
ExitCallback_Continue(); ExitCallback();
} }
public unsafe void LoadModule(ICorDebugAppDomain pAppDomain, ICorDebugModule pModule) public unsafe void LoadModule(ICorDebugAppDomain pAppDomain, ICorDebugModule pModule)
@ -328,7 +329,7 @@ namespace Debugger
process.AddModule(pModule); process.AddModule(pModule);
ExitCallback_Continue(); ExitCallback();
} }
public void NameChange(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread) public void NameChange(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread)
@ -337,7 +338,7 @@ namespace Debugger
EnterCallback(PausedReason.Other, "NameChange: pAppDomain", pAppDomain); EnterCallback(PausedReason.Other, "NameChange: pAppDomain", pAppDomain);
ExitCallback_Continue(); ExitCallback();
} }
if (pThread != null) { if (pThread != null) {
@ -347,7 +348,7 @@ namespace Debugger
Thread thread = process.GetThread(pThread); Thread thread = process.GetThread(pThread);
thread.HasBeenLoaded = true; thread.HasBeenLoaded = true;
ExitCallback_Continue(); ExitCallback();
} }
} }
@ -360,14 +361,14 @@ namespace Debugger
process.AddThread(pThread); process.AddThread(pThread);
ExitCallback_Continue(); ExitCallback();
} }
public void LoadClass(ICorDebugAppDomain pAppDomain, ICorDebugClass c) public void LoadClass(ICorDebugAppDomain pAppDomain, ICorDebugClass c)
{ {
EnterCallback(PausedReason.Other, "LoadClass", pAppDomain); EnterCallback(PausedReason.Other, "LoadClass", pAppDomain);
ExitCallback_Continue(); ExitCallback();
} }
#endregion #endregion
@ -378,7 +379,7 @@ namespace Debugger
{ {
EnterCallback(PausedReason.Other, "UnloadClass", pAppDomain); EnterCallback(PausedReason.Other, "UnloadClass", pAppDomain);
ExitCallback_Continue(); ExitCallback();
} }
public void UnloadModule(ICorDebugAppDomain pAppDomain, ICorDebugModule pModule) public void UnloadModule(ICorDebugAppDomain pAppDomain, ICorDebugModule pModule)
@ -387,14 +388,14 @@ namespace Debugger
process.RemoveModule(pModule); process.RemoveModule(pModule);
ExitCallback_Continue(); ExitCallback();
} }
public void UnloadAssembly(ICorDebugAppDomain pAppDomain, ICorDebugAssembly pAssembly) public void UnloadAssembly(ICorDebugAppDomain pAppDomain, ICorDebugAssembly pAssembly)
{ {
EnterCallback(PausedReason.Other, "UnloadAssembly", pAppDomain); EnterCallback(PausedReason.Other, "UnloadAssembly", pAppDomain);
ExitCallback_Continue(); ExitCallback();
} }
public void ExitThread(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread) public void ExitThread(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread)
@ -405,7 +406,7 @@ namespace Debugger
process.GetThread(pThread).NotifyNativeThreadExited(); process.GetThread(pThread).NotifyNativeThreadExited();
try { try {
ExitCallback_Continue(); ExitCallback();
} catch (COMException e) { } catch (COMException e) {
// For some reason this sometimes happens in .NET 1.1 // For some reason this sometimes happens in .NET 1.1
process.TraceMessage("Continue failed in ExitThread callback: " + e.Message); process.TraceMessage("Continue failed in ExitThread callback: " + e.Message);
@ -416,7 +417,7 @@ namespace Debugger
{ {
EnterCallback(PausedReason.Other, "ExitAppDomain", pAppDomain); EnterCallback(PausedReason.Other, "ExitAppDomain", pAppDomain);
ExitCallback_Continue(); ExitCallback();
} }
public void ExitProcess(ICorDebugProcess pProcess) public void ExitProcess(ICorDebugProcess pProcess)
@ -435,21 +436,21 @@ namespace Debugger
{ {
EnterCallback(PausedReason.Other, "ChangeConnection", pProcess); EnterCallback(PausedReason.Other, "ChangeConnection", pProcess);
ExitCallback_Continue(); ExitCallback();
} }
public void CreateConnection(ICorDebugProcess pProcess, uint dwConnectionId, IntPtr pConnName) public void CreateConnection(ICorDebugProcess pProcess, uint dwConnectionId, IntPtr pConnName)
{ {
EnterCallback(PausedReason.Other, "CreateConnection", pProcess); EnterCallback(PausedReason.Other, "CreateConnection", pProcess);
ExitCallback_Continue(); ExitCallback();
} }
public void DestroyConnection(ICorDebugProcess pProcess, uint dwConnectionId) public void DestroyConnection(ICorDebugProcess pProcess, uint dwConnectionId)
{ {
EnterCallback(PausedReason.Other, "DestroyConnection", pProcess); EnterCallback(PausedReason.Other, "DestroyConnection", pProcess);
ExitCallback_Continue(); ExitCallback();
} }
public void Exception2(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugFrame pFrame, uint nOffset, CorDebugExceptionCallbackType exceptionType, uint dwFlags) public void Exception2(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugFrame pFrame, uint nOffset, CorDebugExceptionCallbackType exceptionType, uint dwFlags)
@ -462,15 +463,12 @@ namespace Debugger
process.SelectedThread.CurrentException = new Exception(process.SelectedThread, (ExceptionType)exceptionType); process.SelectedThread.CurrentException = new Exception(process.SelectedThread, (ExceptionType)exceptionType);
if (process.SelectedThread.CurrentException.IsUnhandled) { if (process.SelectedThread.CurrentException.IsUnhandled ||
ExitCallback_Paused(); process.PauseOnHandledException)
} else { {
if (process.PauseOnHandledException) { pauseOnNextExit = true;
ExitCallback_Paused();
} else {
ExitCallback_Continue();
}
} }
ExitCallback();
} }
public void ExceptionUnwind(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, CorDebugExceptionUnwindCallbackType dwEventType, uint dwFlags) public void ExceptionUnwind(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, CorDebugExceptionUnwindCallbackType dwEventType, uint dwFlags)
@ -478,24 +476,23 @@ namespace Debugger
EnterCallback(PausedReason.ExceptionIntercepted, "ExceptionUnwind", pThread); EnterCallback(PausedReason.ExceptionIntercepted, "ExceptionUnwind", pThread);
if (dwEventType == CorDebugExceptionUnwindCallbackType.DEBUG_EXCEPTION_INTERCEPTED) { if (dwEventType == CorDebugExceptionUnwindCallbackType.DEBUG_EXCEPTION_INTERCEPTED) {
ExitCallback_Paused(); pauseOnNextExit = true;
} else {
ExitCallback_Continue();
} }
ExitCallback();
} }
public void FunctionRemapComplete(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugFunction pFunction) public void FunctionRemapComplete(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugFunction pFunction)
{ {
EnterCallback(PausedReason.Other, "FunctionRemapComplete", pThread); EnterCallback(PausedReason.Other, "FunctionRemapComplete", pThread);
ExitCallback_Continue(); ExitCallback();
} }
public void FunctionRemapOpportunity(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugFunction pOldFunction, ICorDebugFunction pNewFunction, uint oldILOffset) public void FunctionRemapOpportunity(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugFunction pOldFunction, ICorDebugFunction pNewFunction, uint oldILOffset)
{ {
EnterCallback(PausedReason.Other, "FunctionRemapOpportunity", pThread); EnterCallback(PausedReason.Other, "FunctionRemapOpportunity", pThread);
ExitCallback_Continue(); ExitCallback();
} }
public void MDANotification(ICorDebugController c, ICorDebugThread t, ICorDebugMDA mda) public void MDANotification(ICorDebugController c, ICorDebugThread t, ICorDebugMDA mda)
@ -508,7 +505,7 @@ namespace Debugger
throw new System.Exception("Unknown callback argument"); throw new System.Exception("Unknown callback argument");
} }
ExitCallback_Continue(); ExitCallback();
} }
#endregion #endregion

23
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/CorDebug/ICorDebugProcess.cs

@ -0,0 +1,23 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="David Srbecký" email="dsrbecky@gmail.com"/>
// <version>$Revision$</version>
// </file>
#pragma warning disable 1591
namespace Debugger.Wrappers.CorDebug
{
using System;
public partial class ICorDebugProcess
{
public bool HasQueuedCallbacks()
{
int pbQueued;
this.WrappedObject.HasQueuedCallbacks(null, out pbQueued);
return pbQueued != 0;
}
}
}
Loading…
Cancel
Save