Browse Source

Reworked debugger state control

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@258 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
David Srbecký 20 years ago
parent
commit
eaa5f40de3
  1. 4
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Pads/CallStackPad.cs
  2. 6
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Pads/LocalVarPad.cs
  3. 2
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Pads/RunningThreadsPad.cs
  4. 2
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Service/WindowsDebugger.cs
  5. 1
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Debugger.Core.csproj
  6. 56
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/Internal/ManagedCallback.cs
  7. 236
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/NDebugger-StateControl.cs
  8. 110
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/NDebugger.cs
  9. 7
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Function.cs
  10. 31
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/NDebugger-Processes.cs
  11. 16
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/NDebugger-Threads.cs
  12. 57
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Process.cs
  13. 29
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Thread.cs
  14. 2
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/Eval.cs

4
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Pads/CallStackPad.cs

@ -86,7 +86,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
void CallStackListItemActivate(object sender, EventArgs e) void CallStackListItemActivate(object sender, EventArgs e)
{ {
if (debuggerCore.IsCurrentThreadSafeForInspection) { if (debuggerCore.IsPaused) {
Function f = (Function)(callStackList.SelectedItems[0].Tag); Function f = (Function)(callStackList.SelectedItems[0].Tag);
if (f.HasSymbols) { if (f.HasSymbols) {
debuggerCore.CurrentFunction = f; debuggerCore.CurrentFunction = f;
@ -108,7 +108,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
{ {
callStackList.BeginUpdate(); callStackList.BeginUpdate();
callStackList.Items.Clear(); callStackList.Items.Clear();
if (debuggerCore.IsCurrentThreadSafeForInspection) { if (debuggerCore.CurrentThread != null) {
foreach (Function f in debuggerCore.CurrentThread.Callstack) { foreach (Function f in debuggerCore.CurrentThread.Callstack) {
ListViewItem item = new ListViewItem(new string[] { f.Name, "" }); ListViewItem item = new ListViewItem(new string[] { f.Name, "" });
item.Tag = f; item.Tag = f;

6
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Pads/LocalVarPad.cs

@ -107,14 +107,12 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
void RefreshList() void RefreshList()
{ {
if (debuggerCore.IsCurrentProcessSafeForInspection) { UpdateVariables(localVarList.Items, debuggerCore.LocalVariables);
UpdateVariables(localVarList.Items, debuggerCore.LocalVariables);
}
} }
private void localVarList_BeforeExpand(object sender, TreeListViewCancelEventArgs e) private void localVarList_BeforeExpand(object sender, TreeListViewCancelEventArgs e)
{ {
if (debuggerCore.IsCurrentProcessSafeForInspection) { if (debuggerCore.IsPaused) {
((VariableListItem)e.Item).PrepareForExpansion(); ((VariableListItem)e.Item).PrepareForExpansion();
} else { } else {
// TODO: Some message telling user that he can not explore variable since // TODO: Some message telling user that he can not explore variable since

2
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Pads/RunningThreadsPad.cs

@ -97,7 +97,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
void RunningThreadsListItemActivate(object sender, EventArgs e) void RunningThreadsListItemActivate(object sender, EventArgs e)
{ {
if (debuggerCore.IsCurrentProcessSafeForInspection) { if (debuggerCore.IsPaused) {
debuggerCore.CurrentThread = (Thread)(runningThreadsList.SelectedItems[0].Tag); debuggerCore.CurrentThread = (Thread)(runningThreadsList.SelectedItems[0].Tag);
} }
} }

2
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Service/WindowsDebugger.cs

@ -208,7 +208,7 @@ namespace ICSharpCode.SharpDevelop.Services
/// </summary> /// </summary>
public string GetValueAsString(string variableName) public string GetValueAsString(string variableName)
{ {
if (debugger == null || !debugger.IsCurrentProcessSafeForInspection) return null; if (debugger == null || debugger.IsRunning) return null;
VariableCollection collection = debugger.LocalVariables; VariableCollection collection = debugger.LocalVariables;
if (collection == null) if (collection == null)
return null; return null;

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

@ -100,6 +100,7 @@
<Compile Include="Src\RemotingSinks\PrivateEventHandlersSink\PrivateEventHandlersClientChannelSinkProvider.cs" /> <Compile Include="Src\RemotingSinks\PrivateEventHandlersSink\PrivateEventHandlersClientChannelSinkProvider.cs" />
<Compile Include="Src\RemotingSinks\PrivateEventHandlersSink\EventForwarder.cs" /> <Compile Include="Src\RemotingSinks\PrivateEventHandlersSink\EventForwarder.cs" />
<Compile Include="Src\RemotingSinks\PrivateEventHandlersSink\PrivateEventHandlersClientChannelSink.cs" /> <Compile Include="Src\RemotingSinks\PrivateEventHandlersSink\PrivateEventHandlersClientChannelSink.cs" />
<Compile Include="Src\Debugger\NDebugger-StateControl.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Content Include="README.TXT" /> <Content Include="README.TXT" />

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

@ -24,6 +24,9 @@ namespace DebuggerLibrary
NDebugger debugger; NDebugger debugger;
bool handlingCallback = false; bool handlingCallback = false;
Process callingProcess;
Thread callingThread;
public event EventHandler<CorDebugEvalEventArgs> CorDebugEvalCompleted; public event EventHandler<CorDebugEvalEventArgs> CorDebugEvalCompleted;
@ -32,7 +35,7 @@ namespace DebuggerLibrary
this.debugger = debugger; this.debugger = debugger;
} }
public bool HandlingCallback { bool HandlingCallback {
get { get {
return handlingCallback; return handlingCallback;
} }
@ -43,12 +46,8 @@ namespace DebuggerLibrary
{ {
EnterCallback(name); EnterCallback(name);
Process process = debugger.GetProcess(pProcess); callingProcess = debugger.GetProcess(pProcess);
process.IsProcessRunning = false; callingProcess.IsRunning = false;
debugger.CurrentProcess = process;
foreach(Thread t in process.Threads) {
t.CurrentFunction = null;
}
} }
// Sets CurrentProcess // Sets CurrentProcess
@ -58,12 +57,9 @@ namespace DebuggerLibrary
ICorDebugProcess pProcess; ICorDebugProcess pProcess;
pAppDomain.GetProcess(out pProcess); pAppDomain.GetProcess(out pProcess);
Process process = debugger.GetProcess(pProcess);
process.IsProcessRunning = false; callingProcess = debugger.GetProcess(pProcess);
debugger.CurrentProcess = process; callingProcess.IsRunning = false;
foreach(Thread t in process.Threads) {
t.CurrentFunction = null;
}
} }
// Sets CurrentProcess, CurrentThread and CurrentFunction // Sets CurrentProcess, CurrentThread and CurrentFunction
@ -72,15 +68,10 @@ namespace DebuggerLibrary
{ {
EnterCallback(name); EnterCallback(name);
Thread thread = debugger.GetThread(pThread); callingThread = debugger.GetThread(pThread);
Process process = thread.Process;
process.IsProcessRunning = false; callingProcess = callingThread.Process;
debugger.CurrentProcess = process; callingProcess.IsRunning = false;
process.CurrentThread = thread;
foreach(Thread t in process.Threads) {
t.CurrentFunction = null;
}
thread.CurrentFunction = thread.LastFunctionWithLoadedSymbols;
} }
void EnterCallback(string name) void EnterCallback(string name)
@ -91,20 +82,25 @@ namespace DebuggerLibrary
void ExitCallback_Continue() void ExitCallback_Continue()
{ {
debugger.Continue(); callingProcess.ContinueCallback();
callingThread = null;
callingProcess = null;
handlingCallback = false; handlingCallback = false;
} }
void ExitCallback_Paused(PausedReason reason) void ExitCallback_Paused(PausedReason reason)
{ {
if (debugger.CurrentThread == null) { if (callingThread != null) {
throw new DebuggerException("You are not allowed to pause since CurrentThread is not set"); callingThread.DeactivateAllSteppers();
} }
debugger.CurrentThread.DeactivateAllSteppers();
handlingCallback = false; handlingCallback = false;
debugger.OnDebuggingPaused(reason); debugger.Pause(reason, callingProcess, callingThread);
callingThread = null;
callingProcess = null;
} }
@ -114,7 +110,7 @@ namespace DebuggerLibrary
{ {
EnterCallback("StepComplete (" + reason.ToString() + ")", pThread); EnterCallback("StepComplete (" + reason.ToString() + ")", pThread);
if (debugger.CurrentThread.LastFunction.Module.SymbolsLoaded == false) { if (callingThread.LastFunction.Module.SymbolsLoaded == false) {
debugger.TraceMessage(" - leaving code without symbols"); debugger.TraceMessage(" - leaving code without symbols");
ExitCallback_Continue(); ExitCallback_Continue();
@ -341,7 +337,7 @@ namespace DebuggerLibrary
debugger.RemoveThread(thread); debugger.RemoveThread(thread);
if (thread.Process.CurrentThread == thread) { if (thread.Process.CurrentThread == thread) {
thread.Process.CurrentThread = null; thread.Process.SetCurrentThread(null);
} }
ExitCallback_Continue(); ExitCallback_Continue();
@ -400,7 +396,7 @@ namespace DebuggerLibrary
{ {
EnterCallback("Exception2", pThread); EnterCallback("Exception2", pThread);
debugger.CurrentThread.CurrentExceptionType = (ExceptionType)dwEventType; callingThread.CurrentExceptionType = (ExceptionType)dwEventType;
if (ExceptionType.DEBUG_EXCEPTION_UNHANDLED != (ExceptionType)dwEventType) { if (ExceptionType.DEBUG_EXCEPTION_UNHANDLED != (ExceptionType)dwEventType) {
// Handled exception // Handled exception

236
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/NDebugger-StateControl.cs

@ -0,0 +1,236 @@
// <file>
// <copyright see="prj:///doc/copyright.txt">2002-2005 AlphaSierraPapa</copyright>
// <license see="prj:///doc/license.txt">GNU General Public License</license>
// <owner name="David Srbecký" email="dsrbecky@gmail.com"/>
// <version>$Revision: 257 $</version>
// </file>
using System;
using System.Collections;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using DebuggerInterop.Core;
using DebuggerInterop.MetaData;
using System.Collections.Generic;
namespace DebuggerLibrary
{
public partial class NDebugger
{
bool isPaused;
bool pauseOnHandledException = false;
public event EventHandler<DebuggingPausedEventArgs> DebuggingPaused;
public event EventHandler<DebuggerEventArgs> DebuggingResumed;
public bool PauseOnHandledException {
get {
return pauseOnHandledException;
}
set {
pauseOnHandledException = value;
}
}
protected virtual void OnDebuggingPaused(PausedReason reason)
{
TraceMessage ("Debugger event: OnDebuggingPaused(" + reason.ToString() + ")");
if (DebuggingPaused != null) {
DebuggingPausedEventArgs args = new DebuggingPausedEventArgs(this, reason);
DebuggingPaused(this, args);
if (args.ResumeDebugging) {
Continue();
}
}
}
protected virtual void OnDebuggingResumed()
{
TraceMessage ("Debugger event: OnDebuggingResumed()");
if (DebuggingResumed != null) {
DebuggingResumed(this, new DebuggerEventArgs(this));
}
}
public Process CurrentProcess {
get {
if (IsRunning) return null;
if (currentProcess == null) {
return null;
} else {
if (currentProcess.IsRunning) return null;
return currentProcess;
}
}
set {
currentProcess = value;
}
}
public Thread CurrentThread {
get {
if (IsRunning) return null;
if (CurrentProcess == null) return null;
return CurrentProcess.CurrentThread;
}
set {
if (CurrentProcess != null) {
CurrentProcess.CurrentThread = value;
}
}
}
public Function CurrentFunction {
get {
if (IsRunning) return null;
if (CurrentThread == null) {
return null;
} else {
return CurrentThread.CurrentFunction;
}
}
set {
if (CurrentThread != null) {
CurrentThread.CurrentFunction = value;
}
}
}
public void AssertPaused()
{
if (!IsPaused) {
throw new DebuggerException("Debugger is not paused.");
}
}
public void AssertRunning()
{
if (IsPaused) {
throw new DebuggerException("Debugger is not running.");
}
}
public bool IsPaused {
get {
return isPaused;
}
}
public bool IsRunning {
get {
return !isPaused;
}
}
internal void Pause(PausedReason reason, Process process, Thread thread)
{
if (IsPaused) {
throw new DebuggerException("Already paused");
}
isPaused = true;
SetUpEnvironment(process, thread);
OnDebuggingPaused(reason);
}
internal void FakePause(PausedReason reason)
{
Process process = CurrentProcess;
Thread thread = CurrentThread;
Resume();
Pause(reason, process, thread);
}
internal void Resume()
{
if (!IsPaused) {
throw new DebuggerException("Already resumed");
}
OnDebuggingResumed();
isPaused = false;
}
void SetUpEnvironment(Process process, Thread thread)
{
CleanEnvironment();
// Set the CurrentProcess
if (process == null) {
if (thread != null) {
process = thread.Process;
}
}
currentProcess = process;
// Set the CurrentThread
if (process != null) {
if (thread != null) {
process.SetCurrentThread(thread);
} else {
IList<Thread> threads = process.Threads;
if (threads.Count > 0) {
process.SetCurrentThread(threads[0]);
} else {
process.SetCurrentThread(null);
}
}
}
// CurrentFunctions in threads are fetched on request
}
void CleanEnvironment()
{
// Remove all stored functions,
// they are disponsed between callbacks and
// they need to be regenerated
foreach(Thread t in Threads) {
t.ClearCurrentFunction();
}
// Clear current thread
if (currentProcess != null) {
currentProcess.SetCurrentThread(null);
}
// Clear current process
currentProcess = null;
}
public void Break()
{
foreach(Process p in Processes) {
if (p.IsRunning) {
p.Break();
}
}
}
public void StepInto()
{
CurrentFunction.StepInto();
}
public void StepOver()
{
CurrentFunction.StepOver();
}
public void StepOut()
{
CurrentFunction.StepOut();
}
public void Continue()
{
CurrentProcess.Continue();
}
public void Terminate()
{
foreach(Process p in Processes) {
p.Terminate();
}
}
}
}

110
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/NDebugger.cs

@ -26,8 +26,6 @@ namespace DebuggerLibrary
ApartmentState requiredApartmentState; ApartmentState requiredApartmentState;
EvalQueue evalQueue; EvalQueue evalQueue;
bool pauseOnHandledException = false;
internal EvalQueue EvalQueue { internal EvalQueue EvalQueue {
get { get {
@ -47,15 +45,6 @@ namespace DebuggerLibrary
} }
} }
public bool PauseOnHandledException {
get {
return pauseOnHandledException;
}
set {
pauseOnHandledException = value;
}
}
internal ManagedCallback ManagedCallback { internal ManagedCallback ManagedCallback {
get { get {
return managedCallback; return managedCallback;
@ -110,32 +99,6 @@ namespace DebuggerLibrary
TraceMessage("Reset done"); TraceMessage("Reset done");
} }
#region Public events
public event EventHandler<DebuggingPausedEventArgs> DebuggingPaused;
protected internal virtual void OnDebuggingPaused(PausedReason reason)
{
TraceMessage ("Debugger event: OnDebuggingPaused(" + reason.ToString() + ")");
if (DebuggingPaused != null) {
DebuggingPausedEventArgs args = new DebuggingPausedEventArgs(this, reason);
DebuggingPaused(this, args);
if (args.ResumeDebugging) {
Continue();
}
}
}
public event EventHandler<DebuggerEventArgs> DebuggingResumed;
protected internal virtual void OnDebuggingResumed()
{
TraceMessage ("Debugger event: OnDebuggingResumed()");
if (DebuggingResumed != null) {
DebuggingResumed(this, new DebuggerEventArgs(this));
}
}
/// <summary> /// <summary>
/// Fired when System.Diagnostics.Trace.WriteLine() is called in debuged process /// Fired when System.Diagnostics.Trace.WriteLine() is called in debuged process
@ -169,8 +132,6 @@ namespace DebuggerLibrary
} }
#endregion
public void StartWithoutDebugging(System.Diagnostics.ProcessStartInfo psi) public void StartWithoutDebugging(System.Diagnostics.ProcessStartInfo psi)
{ {
System.Diagnostics.Process process; System.Diagnostics.Process process;
@ -184,76 +145,25 @@ namespace DebuggerLibrary
Process process = Process.CreateProcess(this, filename, workingDirectory, arguments); Process process = Process.CreateProcess(this, filename, workingDirectory, arguments);
AddProcess(process); AddProcess(process);
} }
public Function CurrentFunction {
get {
if (IsCurrentThreadSafeForInspection) {
return CurrentThread.CurrentFunction;
} else {
return null;
}
}
set {
if (IsCurrentThreadSafeForInspection) {
CurrentThread.CurrentFunction = value;
}
}
}
public bool IsCurrentFunctionSafeForInspection {
get {
if (IsCurrentThreadSafeForInspection &&
CurrentThread.CurrentFunction != null &&
CurrentThread.CurrentFunction.HasSymbols) {
return true;
} else {
return false;
}
}
}
public SourcecodeSegment NextStatement { public SourcecodeSegment NextStatement {
get { get {
if (!IsCurrentFunctionSafeForInspection) return null; if (CurrentFunction == null) {
return CurrentProcess.CurrentThread.CurrentFunction.NextStatement; return null;
} else {
return CurrentFunction.NextStatement;
}
} }
} }
public VariableCollection LocalVariables { public VariableCollection LocalVariables {
get { get {
if (!IsCurrentFunctionSafeForInspection) return VariableCollection.Empty; if (CurrentFunction == null) {
return CurrentProcess.CurrentThread.CurrentFunction.GetVariables(); return VariableCollection.Empty;
} else {
return CurrentFunction.GetVariables();
}
} }
} }
public void Break()
{
CurrentProcess.Break();
}
public void StepInto()
{
CurrentProcess.CurrentThread.CurrentFunction.StepInto();
}
public void StepOver()
{
CurrentProcess.CurrentThread.CurrentFunction.StepOver();
}
public void StepOut()
{
CurrentProcess.CurrentThread.CurrentFunction.StepOut();
}
public void Continue()
{
CurrentProcess.Continue();
}
public void Terminate()
{
CurrentProcess.Terminate();
}
} }
} }

7
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Function.cs

@ -317,6 +317,8 @@ namespace DebuggerLibrary
SourcecodeSegment SetIP(bool simulate, string filename, int line, int column) SourcecodeSegment SetIP(bool simulate, string filename, int line, int column)
{ {
debugger.AssertPaused();
SourcecodeSegment suggestion = new SourcecodeSegment(filename, line, column, column); SourcecodeSegment suggestion = new SourcecodeSegment(filename, line, column, column);
ICorDebugFunction corFunction; ICorDebugFunction corFunction;
int ilOffset; int ilOffset;
@ -333,10 +335,7 @@ namespace DebuggerLibrary
corILFrame.CanSetIP((uint)ilOffset); corILFrame.CanSetIP((uint)ilOffset);
} else { } else {
corILFrame.SetIP((uint)ilOffset); corILFrame.SetIP((uint)ilOffset);
Thread thread = debugger.CurrentThread; debugger.FakePause(PausedReason.SetIP);
debugger.OnDebuggingResumed();
thread.CurrentFunction = thread.LastFunctionWithLoadedSymbols;
debugger.OnDebuggingPaused(PausedReason.SetIP);
} }
} catch { } catch {
return null; return null;

31
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/NDebugger-Processes.cs

@ -27,37 +27,6 @@ namespace DebuggerLibrary
} }
} }
public Process CurrentProcess {
get {
if (currentProcess == null && Processes.Count > 0) {
currentProcess = Processes[0];
}
return currentProcess;
}
set {
currentProcess = value;
}
}
public bool IsCurrentProcessSafeForInspection {
get {
if (CurrentProcess == null) {
return false;
} else {
return CurrentProcess.IsProcessSafeForInspection;
}
}
}
internal void CheckThatCurrentProcessIsSafeForInspection()
{
if (CurrentProcess == null) {
throw new DebuggerException("There is no process being debugged.");
} else {
CurrentProcess.CheckThatProcessIsSafeForInspection();
}
}
internal Process GetProcess(ICorDebugProcess corProcess) internal Process GetProcess(ICorDebugProcess corProcess)
{ {
foreach (Process process in Processes) { foreach (Process process in Processes) {

16
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/NDebugger-Threads.cs

@ -46,22 +46,6 @@ namespace DebuggerLibrary
return threadCollection.AsReadOnly(); return threadCollection.AsReadOnly();
} }
} }
public Thread CurrentThread {
get {
if (CurrentProcess == null) return null;
return CurrentProcess.CurrentThread;
}
set {
CurrentProcess.CurrentThread = value;
}
}
public bool IsCurrentThreadSafeForInspection {
get {
return IsCurrentProcessSafeForInspection;
}
}
internal Thread GetThread(ICorDebugThread corThread) internal Thread GetThread(ICorDebugThread corThread)
{ {

57
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Process.cs

@ -38,21 +38,18 @@ namespace DebuggerLibrary
public Thread CurrentThread { public Thread CurrentThread {
get { get {
if (currentThread != null) return currentThread; return currentThread;
IList<Thread> threads = Threads;
if (currentThread == null && threads.Count > 0) {
currentThread = threads[0];
return currentThread;
}
return null;
} }
set { set {
currentThread = value; currentThread = value;
if (debugger.ManagedCallback.HandlingCallback == false) { debugger.FakePause(PausedReason.CurrentThreadChanged);
debugger.OnDebuggingPaused(PausedReason.CurrentThreadChanged);
}
} }
} }
internal void SetCurrentThread(Thread thread)
{
currentThread = thread;
}
public IList<Thread> Threads { public IList<Thread> Threads {
get { get {
@ -117,7 +114,7 @@ namespace DebuggerLibrary
return new Process(debugger, outProcess); return new Process(debugger, outProcess);
} }
public void Break() internal void Break()
{ {
if (!isProcessRunning) { if (!isProcessRunning) {
throw new DebuggerException("Invalid operation"); throw new DebuggerException("Invalid operation");
@ -126,7 +123,7 @@ namespace DebuggerLibrary
corProcess.Stop(5000); // TODO: Hardcoded value corProcess.Stop(5000); // TODO: Hardcoded value
isProcessRunning = false; isProcessRunning = false;
debugger.OnDebuggingPaused(PausedReason.Break); debugger.Pause(PausedReason.Break, this, null);
} }
public void Continue() public void Continue()
@ -135,11 +132,18 @@ namespace DebuggerLibrary
throw new DebuggerException("Invalid operation"); throw new DebuggerException("Invalid operation");
} }
debugger.Resume();
isProcessRunning = true; isProcessRunning = true;
if (debugger.ManagedCallback.HandlingCallback == false) { corProcess.Continue(0);
debugger.OnDebuggingResumed(); }
internal void ContinueCallback()
{
if (isProcessRunning) {
throw new DebuggerException("Invalid operation");
} }
isProcessRunning = true;
corProcess.Continue(0); corProcess.Continue(0);
} }
@ -156,7 +160,7 @@ namespace DebuggerLibrary
corProcess.Terminate(0); corProcess.Terminate(0);
} }
public bool IsProcessRunning { public bool IsRunning {
get { get {
return isProcessRunning; return isProcessRunning;
} }
@ -164,26 +168,17 @@ namespace DebuggerLibrary
isProcessRunning = value; isProcessRunning = value;
} }
} }
public bool IsProcessSafeForInspection { public bool IsPaused {
get { get {
if (isProcessRunning) return false; return !isProcessRunning;
if (CurrentThread == null) return false;
return true;
} }
} }
internal void CheckThatProcessIsSafeForInspection() public void AssertPaused()
{ {
if (!IsProcessSafeForInspection) { if (!IsPaused) {
if (isProcessRunning) { throw new DebuggerException("Process is not paused.");
throw new DebuggerException("Process is not safe for inspection because it is running.");
} else if (CurrentThread == null){
throw new DebuggerException("Process is not safe for inspection because it has no thread.");
} else {
throw new DebuggerException("Process is not safe for inspection.");
}
} }
} }
} }

29
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Thread.cs

@ -84,7 +84,7 @@ namespace DebuggerLibrary
public bool Suspended { public bool Suspended {
get { get {
if (!process.IsProcessSafeForInspection) return lastSuspendedState; if (process.IsRunning) return lastSuspendedState;
CorDebugThreadState state; CorDebugThreadState state;
corThread.GetDebugState(out state); corThread.GetDebugState(out state);
@ -99,7 +99,7 @@ namespace DebuggerLibrary
public ThreadPriority Priority { public ThreadPriority Priority {
get { get {
if (!HasBeenLoaded) return lastPriority; if (!HasBeenLoaded) return lastPriority;
if (!process.IsProcessSafeForInspection) return lastPriority; if (process.IsRunning) return lastPriority;
Variable runTimeVar = RuntimeVariable; Variable runTimeVar = RuntimeVariable;
if (runTimeVar is NullRefVariable) return ThreadPriority.Normal; if (runTimeVar is NullRefVariable) return ThreadPriority.Normal;
@ -111,7 +111,7 @@ namespace DebuggerLibrary
public Variable RuntimeVariable { public Variable RuntimeVariable {
get { get {
if (!HasBeenLoaded) throw new DebuggerException("Thread has not started jet"); if (!HasBeenLoaded) throw new DebuggerException("Thread has not started jet");
process.CheckThatProcessIsSafeForInspection(); process.AssertPaused();
ICorDebugValue corValue; ICorDebugValue corValue;
corThread.GetObject(out corValue); corThread.GetObject(out corValue);
@ -122,7 +122,7 @@ namespace DebuggerLibrary
public string Name { public string Name {
get { get {
if (!HasBeenLoaded) return lastName; if (!HasBeenLoaded) return lastName;
if (!process.IsProcessSafeForInspection) return lastName; if (process.IsRunning) return lastName;
Variable runtimeVar = RuntimeVariable; Variable runtimeVar = RuntimeVariable;
if (runtimeVar is NullRefVariable) return lastName; if (runtimeVar is NullRefVariable) return lastName;
Variable runtimeName = runtimeVar.SubVariables["m_Name"]; Variable runtimeName = runtimeVar.SubVariables["m_Name"];
@ -187,7 +187,7 @@ namespace DebuggerLibrary
get { get {
List<Function> callstack = new List<Function>(); List<Function> callstack = new List<Function>();
if (!process.IsProcessSafeForInspection) return callstack; if (process.IsRunning) return callstack;
ICorDebugChainEnum corChainEnum; ICorDebugChainEnum corChainEnum;
corThread.EnumerateChains(out corChainEnum); corThread.EnumerateChains(out corChainEnum);
@ -227,13 +227,17 @@ namespace DebuggerLibrary
public Function CurrentFunction { public Function CurrentFunction {
get { get {
process.CheckThatProcessIsSafeForInspection(); process.AssertPaused();
if (currentFunction == null) { if (currentFunction == null) {
currentFunction = LastFunctionWithLoadedSymbols; currentFunction = LastFunctionWithLoadedSymbols;
} }
return currentFunction; if (currentFunction != null && currentFunction.HasSymbols) {
return currentFunction;
} else {
return null;
}
} }
set { set {
if (value != null && !value.HasSymbols) { if (value != null && !value.HasSymbols) {
@ -242,11 +246,14 @@ namespace DebuggerLibrary
currentFunction = value; currentFunction = value;
if (debugger.ManagedCallback.HandlingCallback == false) { debugger.FakePause(PausedReason.CurrentFunctionChanged);
debugger.OnDebuggingPaused(PausedReason.CurrentFunctionChanged);
}
} }
} }
internal void ClearCurrentFunction()
{
currentFunction = null;
}
public Function LastFunctionWithLoadedSymbols { public Function LastFunctionWithLoadedSymbols {
get { get {

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

@ -58,7 +58,7 @@ namespace DebuggerLibrary
/// </summary> /// </summary>
public void AsyncPerformEval() public void AsyncPerformEval()
{ {
debugger.CheckThatCurrentProcessIsSafeForInspection(); debugger.AssertPaused();
debugger.CurrentThread.CorThread.CreateEval(out corEval); debugger.CurrentThread.CorThread.CreateEval(out corEval);

Loading…
Cancel
Save