Browse Source

Yet again significantly rewriting process state control

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@3136 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
David Srbecký 17 years ago
parent
commit
8759a05e66
  1. 2
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/Eval.cs
  2. 108
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/Process-StateControl.cs
  3. 7
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/Process.cs
  4. 11
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/StackFrame.cs
  5. 2
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/Thread.cs
  6. 38
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Internal/ManagedCallback.cs
  7. 3
      src/AddIns/Misc/Debugger/Debugger.Tests/Project/Src/TestPrograms/Breakpoint.cs

2
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/Eval.cs

@ -126,7 +126,7 @@ namespace Debugger @@ -126,7 +126,7 @@ namespace Debugger
}
process.NotifyEvaluationStarted(newEval);
process.AsyncContinue_KeepDebuggeeState();
process.AsyncContinue(DebuggeeStateAction.Keep);
return newEval;
}

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

@ -10,6 +10,8 @@ using System.Threading; @@ -10,6 +10,8 @@ using System.Threading;
namespace Debugger
{
internal enum DebuggeeStateAction { Keep, Clear }
public partial class Process
{
// Order:
@ -26,6 +28,8 @@ namespace Debugger @@ -26,6 +28,8 @@ namespace Debugger
public virtual void OnPaused()
{
AssertPaused();
// No real purpose
if (callbackInterface.IsInCallback) throw new DebuggerException("Can not raise event within callback.");
TraceMessage ("Debugger event: OnPaused()");
if (Paused != null) {
foreach(Delegate d in Paused.GetInvocationList()) {
@ -41,6 +45,8 @@ namespace Debugger @@ -41,6 +45,8 @@ namespace Debugger
protected virtual void OnResumed()
{
AssertRunning();
// No real purpose
if (callbackInterface.IsInCallback) throw new DebuggerException("Can not raise event within callback.");
TraceMessage ("Debugger event: OnResumed()");
if (Resumed != null) {
Resumed(this, new ProcessEventArgs(this));
@ -50,9 +56,10 @@ namespace Debugger @@ -50,9 +56,10 @@ namespace Debugger
#endregion
#region PauseSession
#region PauseSession & DebugeeState
PauseSession pauseSession;
DebuggeeState debuggeeState;
/// <summary>
/// Indentification of the current debugger session. This value changes whenever debugger is continued
@ -63,30 +70,6 @@ namespace Debugger @@ -63,30 +70,6 @@ namespace Debugger
}
}
internal void CreatePauseSession(PausedReason pauseReason)
{
if (pauseSession != null) {
throw new DebuggerException("Pause session already created");
}
pauseSession = new PauseSession(pauseReason);
}
internal void ExpirePauseSession()
{
if (pauseSession == null) {
throw new DebuggerException("Pause session already expired");
}
PauseSession oldPauseSession = pauseSession;
pauseSession = null;
oldPauseSession.NotifyHasExpired();
}
#endregion
#region DebugeeState
DebuggeeState debuggeeState;
/// <summary>
/// Indentification of the state of the debugee. This value changes whenever the state of the debugee significatntly changes
/// </summary>
@ -96,28 +79,47 @@ namespace Debugger @@ -96,28 +79,47 @@ namespace Debugger
}
}
internal void CreateDebuggeeState()
/// <summary> Puts the process into a paused state </summary>
internal void NotifyPaused(PausedReason pauseReason)
{
if (debuggeeState != null) {
throw new DebuggerException("Debugee state already created");
AssertRunning();
pauseSession = new PauseSession(pauseReason);
if (debuggeeState == null) {
debuggeeState = new DebuggeeState(this);
}
if (pauseSession == null) {
throw new DebuggerException("Pause session must exist (update order error)");
}
/// <summary> Puts the process into a resumed state </summary>
internal void NotifyResumed(DebuggeeStateAction action)
{
AssertPaused();
PauseSession oldPauseSession = pauseSession;
pauseSession = null;
oldPauseSession.NotifyHasExpired();
if (action == DebuggeeStateAction.Clear) {
if (debuggeeState == null) throw new DebuggerException("Debugee state already cleared");
DebuggeeState oldDebugeeState = debuggeeState;
debuggeeState = null;
oldDebugeeState.NotifyHasExpired();
}
debuggeeState = new DebuggeeState(this);
}
internal void ExpireDebuggeeState()
/// <summary> Sets up the eviroment and raises user events </summary>
internal void RaisePausedEvents()
{
if (debuggeeState == null) {
throw new DebuggerException("Debugee state already expired");
DisableAllSteppers();
SelectMostRecentStackFrameWithLoadedSymbols();
if (this.PauseSession.PausedReason == PausedReason.Exception) {
ExceptionEventArgs args = new ExceptionEventArgs(this, this.SelectedThread.CurrentException, this.SelectedThread.CurrentExceptionType, this.SelectedThread.CurrentExceptionIsUnhandled);
OnExceptionThrown(args);
// The event could have resumed or killed the process
}
if (pauseSession != null) {
throw new DebuggerException("Pause session must not exist (update order error)");
if (this.IsPaused && !this.HasExpired) {
OnPaused();
// The event could have resumed the process
}
DebuggeeState oldDebugeeState = debuggeeState;
debuggeeState = null;
oldDebugeeState.NotifyHasExpired();
}
#endregion
@ -179,13 +181,8 @@ namespace Debugger @@ -179,13 +181,8 @@ namespace Debugger
corProcess.Stop(uint.MaxValue); // Infinite; ignored anyway
CreatePauseSession(PausedReason.ForcedBreak);
CreateDebuggeeState();
SelectMostRecentStackFrameWithLoadedSymbols();
DisableAllSteppers();
OnPaused();
NotifyPaused(PausedReason.ForcedBreak);
RaisePausedEvents();
}
#region Convenience methods
@ -200,24 +197,19 @@ namespace Debugger @@ -200,24 +197,19 @@ namespace Debugger
public void AsyncContinue()
{
AssertPaused();
if (callbackInterface.IsInCallback) {
throw new DebuggerException("Can not continue from within callback.");
}
ExpirePauseSession();
ExpireDebuggeeState();
OnResumed();
corProcess.Continue(0);
AsyncContinue(DebuggeeStateAction.Clear);
}
internal void AsyncContinue_KeepDebuggeeState()
internal void AsyncContinue(DebuggeeStateAction action)
{
AssertPaused();
ExpirePauseSession();
NotifyResumed(action);
corProcess.Continue(0);
if (action == DebuggeeStateAction.Clear) {
OnResumed();
}
}
/// <summary> Terminates the execution of the process </summary>

7
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/Process.cs

@ -39,11 +39,8 @@ namespace Debugger @@ -39,11 +39,8 @@ namespace Debugger
Expired(this, new ProcessEventArgs(this));
}
// Expire pause seesion first
if (PauseSession != null) {
ExpirePauseSession();
}
if (DebuggeeState != null) {
ExpireDebuggeeState();
if (IsPaused) {
NotifyResumed(DebuggeeStateAction.Clear);
}
debugger.RemoveProcess(this);
}

11
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/StackFrame.cs

@ -152,7 +152,7 @@ namespace Debugger @@ -152,7 +152,7 @@ namespace Debugger
public void AsyncStepOut()
{
new Stepper(this, "StackFrame step out").StepOut();
process.AsyncContinue();
process.AsyncContinue(DebuggeeStateAction.Clear);
}
void AsyncStep(bool stepIn)
@ -177,7 +177,7 @@ namespace Debugger @@ -177,7 +177,7 @@ namespace Debugger
new Stepper(this, "StackFrame step over").StepOver(nextSt.StepRanges);
}
process.AsyncContinue();
process.AsyncContinue(DebuggeeStateAction.Clear);
}
/// <summary>
@ -314,10 +314,9 @@ namespace Debugger @@ -314,10 +314,9 @@ namespace Debugger
} else {
// invalidates all frames and chains for the current thread
CorILFrame.SetIP((uint)ilOffset);
process.ExpirePauseSession();
process.CreatePauseSession(PausedReason.SetIP);
process.SelectMostRecentStackFrameWithLoadedSymbols();
process.OnPaused();
process.NotifyResumed(DebuggeeStateAction.Keep);
process.NotifyPaused(PausedReason.SetIP);
process.RaisePausedEvents();
}
} catch {
return null;

2
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/Thread.cs

@ -225,7 +225,7 @@ namespace Debugger @@ -225,7 +225,7 @@ namespace Debugger
throw;
}
Process.AsyncContinue_KeepDebuggeeState();
Process.AsyncContinue(DebuggeeStateAction.Keep);
Process.WaitForPause();
return true;
}

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

@ -54,16 +54,16 @@ namespace Debugger @@ -54,16 +54,16 @@ namespace Debugger
if (process.IsPaused && process.PauseSession.PausedReason == PausedReason.ForcedBreak) {
process.TraceMessage("Processing post-break callback");
// This compensates for the break call and we are in normal callback handling mode
process.AsyncContinue_KeepDebuggeeState();
process.AsyncContinue(DebuggeeStateAction.Keep);
// Start of call back - create new pause session (as usual)
process.CreatePauseSession(pausedReason);
process.NotifyPaused(pausedReason);
// Make sure we stay pause after the callback is handled
pauseOnNextExit = true;
return;
}
if (process.IsRunning) {
process.CreatePauseSession(pausedReason);
process.NotifyPaused(pausedReason);
return;
}
@ -90,8 +90,7 @@ namespace Debugger @@ -90,8 +90,7 @@ namespace Debugger
// Ignore events during property evaluation
if (!pauseOnNextExit || process.Evaluating || hasQueuedCallbacks) {
process.ExpirePauseSession();
process.CorProcess.Continue(0);
process.AsyncContinue(DebuggeeStateAction.Keep);
} else {
pauseOnNextExit = false;
Pause();
@ -102,36 +101,14 @@ namespace Debugger @@ -102,36 +101,14 @@ namespace Debugger
void Pause()
{
process.SelectMostRecentStackFrameWithLoadedSymbols();
process.DisableAllSteppers();
if (process.PauseSession.PausedReason == PausedReason.EvalComplete ||
process.PauseSession.PausedReason == PausedReason.ExceptionIntercepted) {
// Keep debugge state
process.SelectMostRecentStackFrameWithLoadedSymbols();
process.DisableAllSteppers();
// Do not raise events
} else {
process.CreateDebuggeeState();
// Raise the pause event outside the callback
process.Debugger.MTA2STA.AsyncCall(RaiseEvents);
}
}
void RaiseEvents()
{
if (process.PauseSession.PausedReason == PausedReason.Exception) {
// 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
}
if (process.IsPaused && !process.HasExpired) {
process.OnPaused();
// The event could have resumed the process
process.Debugger.MTA2STA.AsyncCall(process.RaisePausedEvents);
}
}
@ -467,6 +444,7 @@ namespace Debugger @@ -467,6 +444,7 @@ namespace Debugger
// Exception -> Exception2(pAppDomain, pThread, null, 0, exceptionType, 0);
process.SelectedThread.CurrentException = new Exception(new Value(process, new Expressions.CurrentExceptionExpression(), process.SelectedThread.CorThread.CurrentException));
process.SelectedThread.CurrentException_DebuggeeState = process.DebuggeeState;
process.SelectedThread.CurrentExceptionType = (ExceptionType)exceptionType;
process.SelectedThread.CurrentExceptionIsUnhandled = (ExceptionType)exceptionType == ExceptionType.Unhandled;

3
src/AddIns/Misc/Debugger/Debugger.Tests/Project/Src/TestPrograms/Breakpoint.cs

@ -23,6 +23,8 @@ namespace Debugger.Tests.TestPrograms @@ -23,6 +23,8 @@ namespace Debugger.Tests.TestPrograms
#if TEST_CODE
namespace Debugger.Tests {
using NUnit.Framework;
public partial class DebuggerTests
{
[NUnit.Framework.Test]
@ -32,6 +34,7 @@ namespace Debugger.Tests { @@ -32,6 +34,7 @@ namespace Debugger.Tests {
StartTest("Breakpoint.cs");
Assert.IsTrue(breakpoint.HadBeenSet);
ObjectDump(breakpoint);
process.Continue();
process.Continue();

Loading…
Cancel
Save