From 8759a05e667ea98ce9a53fa275613ba95370385e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Srbeck=C3=BD?= Date: Wed, 25 Jun 2008 13:57:00 +0000 Subject: [PATCH] Yet again significantly rewriting process state control git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@3136 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61 --- .../Debugger.Core/Project/Src/Control/Eval.cs | 2 +- .../Src/Control/Process-StateControl.cs | 108 ++++++++---------- .../Project/Src/Control/Process.cs | 7 +- .../Project/Src/Control/StackFrame.cs | 11 +- .../Project/Src/Control/Thread.cs | 2 +- .../Project/Src/Internal/ManagedCallback.cs | 38 ++---- .../Project/Src/TestPrograms/Breakpoint.cs | 3 + 7 files changed, 70 insertions(+), 101 deletions(-) diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/Eval.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/Eval.cs index 6a6520451b..d4b9cd6299 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/Eval.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/Eval.cs @@ -126,7 +126,7 @@ namespace Debugger } process.NotifyEvaluationStarted(newEval); - process.AsyncContinue_KeepDebuggeeState(); + process.AsyncContinue(DebuggeeStateAction.Keep); return newEval; } diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/Process-StateControl.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/Process-StateControl.cs index a41afa9f08..dc974b2550 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/Process-StateControl.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/Process-StateControl.cs @@ -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 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 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 #endregion - #region PauseSession + #region PauseSession & DebugeeState PauseSession pauseSession; + DebuggeeState debuggeeState; /// /// Indentification of the current debugger session. This value changes whenever debugger is continued @@ -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; - /// /// Indentification of the state of the debugee. This value changes whenever the state of the debugee significatntly changes /// @@ -96,28 +79,47 @@ namespace Debugger } } - internal void CreateDebuggeeState() + /// Puts the process into a paused state + 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)"); + } + + /// Puts the process into a resumed state + 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() + /// Sets up the eviroment and raises user events + 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 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 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(); + } } /// Terminates the execution of the process diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/Process.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/Process.cs index d2ba6b2a7c..89cdeaf6e1 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/Process.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/Process.cs @@ -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); } diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/StackFrame.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/StackFrame.cs index bc7acc3c98..7824fc101a 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/StackFrame.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/StackFrame.cs @@ -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 new Stepper(this, "StackFrame step over").StepOver(nextSt.StepRanges); } - process.AsyncContinue(); + process.AsyncContinue(DebuggeeStateAction.Clear); } /// @@ -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; 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 e8baa741a6..0334ec4521 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 @@ -225,7 +225,7 @@ namespace Debugger throw; } - Process.AsyncContinue_KeepDebuggeeState(); + Process.AsyncContinue(DebuggeeStateAction.Keep); 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 fd5ba7197d..14bd68e569 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 @@ -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 // 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 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 // 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; diff --git a/src/AddIns/Misc/Debugger/Debugger.Tests/Project/Src/TestPrograms/Breakpoint.cs b/src/AddIns/Misc/Debugger/Debugger.Tests/Project/Src/TestPrograms/Breakpoint.cs index ab876f9c54..93790a7f15 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Tests/Project/Src/TestPrograms/Breakpoint.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Tests/Project/Src/TestPrograms/Breakpoint.cs @@ -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 { StartTest("Breakpoint.cs"); + Assert.IsTrue(breakpoint.HadBeenSet); ObjectDump(breakpoint); process.Continue(); process.Continue();