// // // // // $Revision: 2207 $ // using System; using System.Threading; namespace Debugger { public partial class Process { bool pauseOnHandledException = false; DebugeeState debugeeState; public event EventHandler ExceptionThrown; public event EventHandler DebuggingResumed; public event EventHandler DebuggingPaused; public event EventHandler DebuggeeStateChanged; public bool PauseOnHandledException { get { return pauseOnHandledException; } set { pauseOnHandledException = value; } } protected virtual void OnExceptionThrown(ExceptionEventArgs e) { if (ExceptionThrown != null) { ExceptionThrown(this, e); } } internal virtual void OnDebuggingResumed() { TraceMessage ("Debugger event: OnDebuggingResumed()"); if (DebuggingResumed != null) { DebuggingResumed(this, new ProcessEventArgs(this)); } } protected virtual void OnDebuggingPaused() { TraceMessage ("Debugger event: OnDebuggingPaused (" + PausedReason.ToString() + ")"); if (DebuggingPaused != null) { DebuggingPaused(this, new ProcessEventArgs(this)); } } // HACK: should not be public public virtual void OnDebuggeeStateChanged() { TraceMessage ("Debugger event: OnDebuggeeStateChanged (" + PausedReason.ToString() + ")"); if (DebuggeeStateChanged != null) { DebuggeeStateChanged(this, new ProcessEventArgs(this)); } } public Function SelectedFunction { get { if (SelectedThread == null) { return null; } else { return SelectedThread.SelectedFunction; } } } /// /// Indentification of the state of the debugee. This value changes whenever the state of the debugee significatntly changes /// public DebugeeState DebugeeState { get { return debugeeState; } } /// /// The reason why the debugger is paused. /// Thows an DebuggerException if debugger is not paused. /// public PausedReason PausedReason { get { AssertPaused(); return PauseSession.PausedReason; } } public void Pause(bool debuggeeStateChanged) { try { if (this.SelectedThread == null && this.Threads.Count > 0) { this.SelectedThread = this.Threads[0]; } if (this.SelectedThread != null) { // Disable all steppers - do not Deactivate since function tracking still needs them foreach(Stepper s in this.SelectedThread.Steppers) { s.PauseWhenComplete = false; } this.SelectedThread.SelectedFunction = this.SelectedThread.LastFunctionWithLoadedSymbols; } if (debuggeeStateChanged) { DebugeeState oldDebugeeState = debugeeState; debugeeState = new DebugeeState(this); OnDebuggeeStateChanged(); if (oldDebugeeState != null) { oldDebugeeState.NotifyHasExpired(); } } OnDebuggingPaused(); if (PausedReason == PausedReason.Exception) { ExceptionEventArgs args = new ExceptionEventArgs(this, SelectedThread.CurrentException); OnExceptionThrown(args); if (args.Continue) { this.Continue(); } } } catch(System.Exception e) { } } bool hasExited = false; public event EventHandler Exited; public bool HasExited { get { return hasExited; } } public void WaitForPause(TimeSpan timeout) { DateTime endTime = Util.HighPrecisionTimer.Now + timeout; while(this.IsRunning) { TimeSpan timeLeft = endTime - Util.HighPrecisionTimer.Now; if (timeLeft <= TimeSpan.FromMilliseconds(10)) break; //this.TraceMessage("Time left: " + timeLeft.TotalMilliseconds); debugger.MTA2STA.WaitForCall(timeLeft); debugger.MTA2STA.PerformCall(); } //if (this.HasExited) throw new ProcessExitedException(); } /// /// Waits until the debugger pauses unless it is already paused. /// Use PausedReason to find out why it paused. /// public void WaitForPause(out bool not_eval) { int ticks = Environment.TickCount; not_eval = false; if (!this.IsRunning || this.HasExpired) { not_eval = true; return; } while(this.IsRunning && !this.HasExpired) { debugger.MTA2STA.WaitForCall(); debugger.MTA2STA.PerformAllCalls(); if (Environment.TickCount-ticks > 100) { not_eval = true; return; } } if (this.HasExpired) throw new DebuggerException("Process exited before pausing"); } /// /// Waits until the precesses exits. /// public void WaitForExit() { while(!this.HasExpired) { debugger.MTA2STA.WaitForCall(); debugger.MTA2STA.PerformAllCalls(); } } public void StepInto() { SelectedFunction.StepInto(); } public void StepOver() { SelectedFunction.StepOver(); } public void StepOut() { SelectedFunction.StepOut(); } } }