diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/Internal/ManagedCallback.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/Internal/ManagedCallback.cs index 548f860fcd..5ba869e747 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/Internal/ManagedCallback.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/Internal/ManagedCallback.cs @@ -61,19 +61,17 @@ namespace DebuggerLibrary callingProcess = debugger.GetProcess(pProcess); callingProcess.IsRunning = false; } - - // Sets CurrentProcess, CurrentThread and CurrentFunction - // (CurrentFunction will be set to null if there are no symbols) + void EnterCallback(string name, ICorDebugThread pThread) { EnterCallback(name); - + callingThread = debugger.GetThread(pThread); callingProcess = callingThread.Process; callingProcess.IsRunning = false; } - + void EnterCallback(string name) { handlingCallback = true; diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/NDebugger-StateControl.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/NDebugger-StateControl.cs index 329a2812c9..bead939516 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/NDebugger-StateControl.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/NDebugger-StateControl.cs @@ -19,8 +19,11 @@ namespace DebuggerLibrary { public partial class NDebugger { - bool isPaused; + PausedReason? pausedReason = null; bool pauseOnHandledException = false; + EventWaitHandle waitForPauseHandle = new EventWaitHandle(false, EventResetMode.ManualReset); + + Process currentProcess; public event EventHandler DebuggingPaused; public event EventHandler DebuggingResumed; @@ -101,13 +104,24 @@ namespace DebuggerLibrary public bool IsPaused { get { - return isPaused; + return (pausedReason != null); } } public bool IsRunning { get { - return !isPaused; + return (pausedReason == null); + } + } + + /// + /// The reason why the debugger is paused. + /// Thows an DebuggerException if debugger is not paused. + /// + public PausedReason PausedReason { + get { + AssertPaused(); + return (PausedReason)pausedReason; } } @@ -116,9 +130,23 @@ namespace DebuggerLibrary if (IsPaused) { throw new DebuggerException("Already paused"); } - isPaused = true; - SetUpEnvironment(process, thread, function); + if (process == null) { + throw new DebuggerException("Process can not be null"); + } + if (thread == null && function != null) { + throw new DebuggerException("Function can not be set without thread"); + } + + currentProcess = process; + currentProcess.CurrentThread = thread; + if (currentProcess.CurrentThread != null) { + currentProcess.CurrentThread.CurrentFunction = function; + } + + pausedReason = reason; + OnDebuggingPaused(reason); + waitForPauseHandle.Set(); } internal void FakePause(PausedReason reason, bool keepCurrentFunction) @@ -132,63 +160,44 @@ namespace DebuggerLibrary internal void Resume() { - if (!IsPaused) { + if (IsRunning) { throw new DebuggerException("Already resumed"); } + OnDebuggingResumed(); - isPaused = false; - } - - void SetUpEnvironment(Process process, Thread thread, Function function) - { - CleanEnvironment(); - - // Set the CurrentProcess - if (process == null) { - if (thread != null) { - process = thread.Process; - } - } - currentProcess = process; + waitForPauseHandle.Reset(); - // Set the CurrentThread - if (process != null) { - if (thread != null) { - process.CurrentThread = thread; - } else { - IList threads = process.Threads; - if (threads.Count > 0) { - process.CurrentThread = threads[0]; - } else { - process.CurrentThread = null; - } - } - } + pausedReason = null; - // Set the CurrentFunction - // Other CurrentFunctions in threads are fetched on request - if (thread != null && function != null) { - thread.CurrentFunction = function; - } - } - - void CleanEnvironment() - { - // Remove all stored functions, - // they are disponsed between callbacks and - // they need to be regenerated + // Remove all stored functions, they are disponsed between callbacks and they need to be regenerated foreach(Thread t in Threads) { t.CurrentFunction = null; } - // Clear current thread - if (currentProcess != null) { - currentProcess.CurrentThread = null; - } // Clear current process currentProcess = null; } + /// + /// Waits until the debugger pauses unless it is already paused. + /// Use PausedReason to find out why it paused. + /// + public void WaitForPause() + { + if (IsRunning) { + WaitForPauseHandle.WaitOne(); + } + } + + /// + /// Wait handle, which will be set as long as the debugger is paused + /// + public WaitHandle WaitForPauseHandle { + get { + return waitForPauseHandle; + } + } + public void Break() { foreach(Process p in Processes) { diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/NDebugger-Processes.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/NDebugger-Processes.cs index 047583d884..9752c335b1 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/NDebugger-Processes.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/NDebugger-Processes.cs @@ -16,8 +16,6 @@ namespace DebuggerLibrary { List processCollection = new List(); - Process currentProcess; - public event EventHandler ProcessStarted; public event EventHandler ProcessExited; diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Process.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Process.cs index 40736b5bb8..337075e561 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Process.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Process.cs @@ -38,6 +38,12 @@ namespace DebuggerLibrary public Thread CurrentThread { get { + if (currentThread == null) { + IList threads = Threads; + if (threads.Count > 0) { + currentThread = threads[0]; + } + } return currentThread; } internal set {