Browse Source

Created classes to keep debugger state. State changes to paused for whole callback

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/2.0@1250 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
David Srbecký 20 years ago
parent
commit
610f738f4c
  1. 2
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Debugger.Core.csproj
  2. 20
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/DebugeeState.cs
  3. 6
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/DebuggerEvents/PausedReason.cs
  4. 171
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/Internal/ManagedCallback.cs
  5. 71
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/NDebugger-StateControl.cs
  6. 2
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/NDebugger.cs
  7. 33
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/PauseSession.cs
  8. 12
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Function.cs
  9. 28
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Process.cs
  10. 2
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Thread.cs
  11. 5
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/Eval.cs
  12. 6
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Value.cs
  13. 12
      src/AddIns/Misc/Debugger/Debugger.Tests/Project/Src/DebuggerTests.cs

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

@ -368,6 +368,8 @@ @@ -368,6 +368,8 @@
<Compile Include="Src\Wrappers\CorDebug\ICorDebugGenericValue.cs" />
<Compile Include="Src\Interop\CorSym\ISymUnmanagedDispose.cs" />
<Compile Include="Src\Wrappers\CorSym\Autogenerated\ISymUnmanagedDispose.cs" />
<Compile Include="Src\Debugger\DebugeeState.cs" />
<Compile Include="Src\Debugger\PauseSession.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="README.TXT" />

20
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/DebugeeState.cs

@ -0,0 +1,20 @@ @@ -0,0 +1,20 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="David Srbecký" email="dsrbecky@gmail.com"/>
// <version>$Revision$</version>
// </file>
using System;
namespace Debugger
{
/// <summary>
/// Unique identifier of the state of the debugee.
/// Changes when debuggee is stepped, but not when properity is evaluated.
/// </summary>
public class DebugeeState
{
}
}

6
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/DebuggerEvents/PausedReason.cs

@ -9,17 +9,17 @@ namespace Debugger @@ -9,17 +9,17 @@ namespace Debugger
{
public enum PausedReason:int
{
AllEvalsComplete,
EvalComplete,
StepComplete,
Breakpoint,
Break,
ControlCTrap,
Exception,
DebuggerError,
EvalComplete,
CurrentThreadChanged,
CurrentFunctionChanged,
ExceptionIntercepted,
SetIP
SetIP,
Other
}
}

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

@ -10,7 +10,7 @@ @@ -10,7 +10,7 @@
// Output: \1 - intention \2 - declaration \3 - function name \4-9 parameters
// Replace with:
// \1\2\n\1{\n\1\tEnterCallback("\3");\n\1\t\n\1\tExitCallback_Continue();\n\1}
// \1\2\n\1{\n\1\tEnterCallback(PausedReason.Other, "\3");\n\1\t\n\1\tExitCallback_Continue();\n\1}
using System;
using System.Runtime.InteropServices;
@ -22,88 +22,55 @@ namespace Debugger @@ -22,88 +22,55 @@ namespace Debugger
class ManagedCallback
{
NDebugger debugger;
bool handlingCallback = false;
Process callingProcess;
Thread callingThread;
public NDebugger Debugger {
get {
return debugger;
}
}
public ManagedCallback(NDebugger debugger)
{
this.debugger = debugger;
}
public bool HandlingCallback {
get {
return handlingCallback;
}
}
// Sets CurrentProcess
void EnterCallback(string name, ICorDebugProcess pProcess)
{
EnterCallback(name);
callingProcess = debugger.GetProcess(pProcess);
callingProcess.IsRunning = false;
}
// Sets CurrentProcess
void EnterCallback(string name, ICorDebugAppDomain pAppDomain)
void EnterCallback(PausedReason pausedReason, string name, ICorDebugProcess pProcess)
{
EnterCallback(name);
callingProcess = debugger.GetProcess(pAppDomain.Process);
callingProcess.IsRunning = false;
debugger.TraceMessage("Callback: " + name);
debugger.AssertRunning();
debugger.PauseSession = new PauseSession(pausedReason);
debugger.CurrentProcess = debugger.GetProcess(pProcess);
debugger.CurrentProcess.IsRunning = false;
}
void EnterCallback(string name, ICorDebugThread pThread)
void EnterCallback(PausedReason pausedReason, string name, ICorDebugAppDomain pAppDomain)
{
EnterCallback(name);
callingThread = debugger.GetThread(pThread);
callingProcess = callingThread.Process;
callingProcess.IsRunning = false;
EnterCallback(pausedReason, name, pAppDomain.Process);
}
void EnterCallback(string name)
void EnterCallback(PausedReason pausedReason, string name, ICorDebugThread pThread)
{
handlingCallback = true;
debugger.TraceMessage("Callback: " + name);
// ExitProcess may be called at any time when debuggee is killed
if (name != "ExitProcess") {
debugger.AssertRunning();
}
if (name != "ExitProcess") debugger.AssertRunning();
Thread thread = debugger.GetThread(pThread);
debugger.PauseSession = new PauseSession(pausedReason);
debugger.CurrentProcess = thread.Process;
debugger.CurrentProcess.IsRunning = false;
debugger.CurrentProcess.CurrentThread = thread;
}
void ExitCallback_Continue()
{
callingProcess.ContinueCallback();
callingThread = null;
callingProcess = null;
handlingCallback = false;
debugger.CurrentProcess.Continue();
}
void ExitCallback_Paused(PausedReason reason)
void ExitCallback_Paused()
{
if (callingThread != null) {
callingThread.DeactivateAllSteppers();
if (debugger.CurrentThread != null) {
debugger.CurrentThread.DeactivateAllSteppers();
}
handlingCallback = false;
debugger.Pause(reason, callingProcess, callingThread, null);
callingThread = null;
callingProcess = null;
debugger.Pause();
}
@ -111,7 +78,7 @@ namespace Debugger @@ -111,7 +78,7 @@ namespace Debugger
public void StepComplete(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugStepper pStepper, CorDebugStepReason reason)
{
EnterCallback("StepComplete (" + reason.ToString() + ")", pThread);
EnterCallback(PausedReason.StepComplete, "StepComplete (" + reason.ToString() + ")", pThread);
Stepper stepper = debugger.GetThread(pThread).GetStepper(pStepper);
if (stepper != null) {
@ -122,23 +89,23 @@ namespace Debugger @@ -122,23 +89,23 @@ namespace Debugger
}
}
if (!callingThread.LastFunction.HasSymbols) {
if (!debugger.CurrentThread.LastFunction.HasSymbols) {
// This should not happen with JMC enabled
debugger.TraceMessage(" - leaving code without symbols");
ExitCallback_Continue();
} else {
ExitCallback_Paused(PausedReason.StepComplete);
ExitCallback_Paused();
}
}
// Do not pass the pBreakpoint parameter as ICorDebugBreakpoint - marshaling of it fails in .NET 1.1
public void Breakpoint(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, IntPtr pBreakpoint)
{
EnterCallback("Breakpoint", pThread);
EnterCallback(PausedReason.Breakpoint, "Breakpoint", pThread);
ExitCallback_Paused(PausedReason.Breakpoint);
ExitCallback_Paused();
// foreach (Breakpoint b in debugger.Breakpoints) {
// if (b.Equals(pBreakpoint)) {
@ -150,23 +117,23 @@ namespace Debugger @@ -150,23 +117,23 @@ namespace Debugger
public void BreakpointSetError(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugBreakpoint pBreakpoint, uint dwError)
{
EnterCallback("BreakpointSetError", pThread);
EnterCallback(PausedReason.Other, "BreakpointSetError", pThread);
ExitCallback_Continue();
}
public unsafe void Break(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread)
{
EnterCallback("Break", pThread);
EnterCallback(PausedReason.Break, "Break", pThread);
ExitCallback_Paused(PausedReason.Break);
ExitCallback_Paused();
}
public void ControlCTrap(ICorDebugProcess pProcess)
{
EnterCallback("ControlCTrap", pProcess);
EnterCallback(PausedReason.ControlCTrap, "ControlCTrap", pProcess);
ExitCallback_Paused(PausedReason.ControlCTrap);
ExitCallback_Paused();
}
public unsafe void Exception(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, int unhandled)
@ -179,7 +146,7 @@ namespace Debugger @@ -179,7 +146,7 @@ namespace Debugger
Exception2(pAppDomain, pThread, null, 0, (CorDebugExceptionCallbackType)exceptionType, 0);
} else {
// This callback should be ignored in v2 applications
EnterCallback("Exception", pThread);
EnterCallback(PausedReason.Other, "Exception", pThread);
ExitCallback_Continue();
}
@ -191,14 +158,14 @@ namespace Debugger @@ -191,14 +158,14 @@ namespace Debugger
public void LogSwitch(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, int lLevel, uint ulReason, string pLogSwitchName, string pParentName)
{
EnterCallback("LogSwitch", pThread);
EnterCallback(PausedReason.Other, "LogSwitch", pThread);
ExitCallback_Continue();
}
public void LogMessage(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, int lLevel, string pLogSwitchName, string pMessage)
{
EnterCallback("LogMessage", pThread);
EnterCallback(PausedReason.Other, "LogMessage", pThread);
debugger.OnLogMessage(pMessage);
@ -207,21 +174,21 @@ namespace Debugger @@ -207,21 +174,21 @@ namespace Debugger
public void EditAndContinueRemap(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugFunction pFunction, int fAccurate)
{
EnterCallback("EditAndContinueRemap", pThread);
EnterCallback(PausedReason.Other, "EditAndContinueRemap", pThread);
ExitCallback_Continue();
}
public void EvalException(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugEval corEval)
{
EnterCallback("EvalException", pThread);
EnterCallback(PausedReason.EvalComplete, "EvalException", pThread);
HandleEvalComplete(pAppDomain, pThread, corEval, true);
}
public void EvalComplete(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugEval corEval)
{
EnterCallback("EvalComplete", pThread);
EnterCallback(PausedReason.EvalComplete, "EvalComplete", pThread);
HandleEvalComplete(pAppDomain, pThread, corEval, false);
}
@ -239,23 +206,23 @@ namespace Debugger @@ -239,23 +206,23 @@ namespace Debugger
debugger.SetupNextEvaluation(debugger.GetThread(pThread));
ExitCallback_Continue();
} else {
ExitCallback_Paused(PausedReason.AllEvalsComplete);
ExitCallback_Paused();
}
}
public void DebuggerError(ICorDebugProcess pProcess, int errorHR, uint errorCode)
{
EnterCallback("DebuggerError", pProcess);
EnterCallback(PausedReason.DebuggerError, "DebuggerError", pProcess);
string errorText = String.Format("Debugger error: \nHR = 0x{0:X} \nCode = 0x{1:X}", errorHR, errorCode);
System.Windows.Forms.MessageBox.Show(errorText);
ExitCallback_Paused(PausedReason.DebuggerError);
ExitCallback_Paused();
}
public void UpdateModuleSymbols(ICorDebugAppDomain pAppDomain, ICorDebugModule pModule, IStream pSymbolStream)
{
EnterCallback("UpdateModuleSymbols", pAppDomain);
EnterCallback(PausedReason.Other, "UpdateModuleSymbols", pAppDomain);
ExitCallback_Continue();
}
@ -266,7 +233,7 @@ namespace Debugger @@ -266,7 +233,7 @@ namespace Debugger
public void CreateProcess(ICorDebugProcess pProcess)
{
EnterCallback("CreateProcess", pProcess);
EnterCallback(PausedReason.Other, "CreateProcess", pProcess);
// Process is added in NDebugger.Start
@ -275,7 +242,7 @@ namespace Debugger @@ -275,7 +242,7 @@ namespace Debugger
public void CreateAppDomain(ICorDebugProcess pProcess, ICorDebugAppDomain pAppDomain)
{
EnterCallback("CreateAppDomain", pAppDomain);
EnterCallback(PausedReason.Other, "CreateAppDomain", pAppDomain);
pAppDomain.Attach();
@ -284,14 +251,14 @@ namespace Debugger @@ -284,14 +251,14 @@ namespace Debugger
public void LoadAssembly(ICorDebugAppDomain pAppDomain, ICorDebugAssembly pAssembly)
{
EnterCallback("LoadAssembly", pAppDomain);
EnterCallback(PausedReason.Other, "LoadAssembly", pAppDomain);
ExitCallback_Continue();
}
public unsafe void LoadModule(ICorDebugAppDomain pAppDomain, ICorDebugModule pModule)
{
EnterCallback("LoadModule", pAppDomain);
EnterCallback(PausedReason.Other, "LoadModule", pAppDomain);
debugger.AddModule(pModule);
@ -302,14 +269,14 @@ namespace Debugger @@ -302,14 +269,14 @@ namespace Debugger
{
if (pAppDomain != null) {
EnterCallback("NameChange: pAppDomain", pAppDomain);
EnterCallback(PausedReason.Other, "NameChange: pAppDomain", pAppDomain);
ExitCallback_Continue();
}
if (pThread != null) {
EnterCallback("NameChange: pThread", pThread);
EnterCallback(PausedReason.Other, "NameChange: pThread", pThread);
Thread thread = debugger.GetThread(pThread);
thread.HasBeenLoaded = true;
@ -323,7 +290,7 @@ namespace Debugger @@ -323,7 +290,7 @@ namespace Debugger
{
// We can not use pThread since it has not been added yet
// and we continue from this callback anyway
EnterCallback("CreateThread", pAppDomain);
EnterCallback(PausedReason.Other, "CreateThread", pAppDomain);
debugger.AddThread(pThread);
@ -332,7 +299,7 @@ namespace Debugger @@ -332,7 +299,7 @@ namespace Debugger
public void LoadClass(ICorDebugAppDomain pAppDomain, ICorDebugClass c)
{
EnterCallback("LoadClass", pAppDomain);
EnterCallback(PausedReason.Other, "LoadClass", pAppDomain);
ExitCallback_Continue();
}
@ -343,14 +310,14 @@ namespace Debugger @@ -343,14 +310,14 @@ namespace Debugger
public void UnloadClass(ICorDebugAppDomain pAppDomain, ICorDebugClass c)
{
EnterCallback("UnloadClass", pAppDomain);
EnterCallback(PausedReason.Other, "UnloadClass", pAppDomain);
ExitCallback_Continue();
}
public void UnloadModule(ICorDebugAppDomain pAppDomain, ICorDebugModule pModule)
{
EnterCallback("UnloadModule", pAppDomain);
EnterCallback(PausedReason.Other, "UnloadModule", pAppDomain);
debugger.RemoveModule(pModule);
@ -359,14 +326,14 @@ namespace Debugger @@ -359,14 +326,14 @@ namespace Debugger
public void UnloadAssembly(ICorDebugAppDomain pAppDomain, ICorDebugAssembly pAssembly)
{
EnterCallback("UnloadAssembly", pAppDomain);
EnterCallback(PausedReason.Other, "UnloadAssembly", pAppDomain);
ExitCallback_Continue();
}
public void ExitThread(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread)
{
EnterCallback("ExitThread", pThread);
EnterCallback(PausedReason.Other, "ExitThread", pThread);
Thread thread = debugger.GetThread(pThread);
@ -381,14 +348,14 @@ namespace Debugger @@ -381,14 +348,14 @@ namespace Debugger
public void ExitAppDomain(ICorDebugProcess pProcess, ICorDebugAppDomain pAppDomain)
{
EnterCallback("ExitAppDomain", pAppDomain);
EnterCallback(PausedReason.Other, "ExitAppDomain", pAppDomain);
ExitCallback_Continue();
}
public void ExitProcess(ICorDebugProcess pProcess)
{
EnterCallback("ExitProcess", pProcess);
EnterCallback(PausedReason.Other, "ExitProcess", pProcess);
Process process = debugger.GetProcess(pProcess);
@ -406,54 +373,54 @@ namespace Debugger @@ -406,54 +373,54 @@ namespace Debugger
public void ChangeConnection(ICorDebugProcess pProcess, uint dwConnectionId)
{
EnterCallback("ChangeConnection", pProcess);
EnterCallback(PausedReason.Other, "ChangeConnection", pProcess);
ExitCallback_Continue();
}
public void CreateConnection(ICorDebugProcess pProcess, uint dwConnectionId, IntPtr pConnName)
{
EnterCallback("CreateConnection", pProcess);
EnterCallback(PausedReason.Other, "CreateConnection", pProcess);
ExitCallback_Continue();
}
public void DestroyConnection(ICorDebugProcess pProcess, uint dwConnectionId)
{
EnterCallback("DestroyConnection", pProcess);
EnterCallback(PausedReason.Other, "DestroyConnection", pProcess);
ExitCallback_Continue();
}
public void Exception2(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugFrame pFrame, uint nOffset, CorDebugExceptionCallbackType exceptionType, uint dwFlags)
{
EnterCallback("Exception2", pThread);
EnterCallback(PausedReason.Exception, "Exception2", pThread);
// This callback is also called from Exception(...)!!!! (the .NET 1.1 version)
// Whatch out for the zeros and null!
// Exception -> Exception2(pAppDomain, pThread, null, 0, exceptionType, 0);
callingThread.CurrentExceptionType = (ExceptionType)exceptionType;
debugger.CurrentThread.CurrentExceptionType = (ExceptionType)exceptionType;
if (ExceptionType.DEBUG_EXCEPTION_UNHANDLED != (ExceptionType)exceptionType) {
// Handled exception
if (debugger.PauseOnHandledException) {
ExitCallback_Paused(PausedReason.Exception);
ExitCallback_Paused();
} else {
ExitCallback_Continue();
}
} else {
// Unhandled exception
ExitCallback_Paused(PausedReason.Exception);
ExitCallback_Paused();
}
}
public void ExceptionUnwind(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, CorDebugExceptionUnwindCallbackType dwEventType, uint dwFlags)
{
EnterCallback("ExceptionUnwind", pThread);
EnterCallback(PausedReason.ExceptionIntercepted, "ExceptionUnwind", pThread);
if (dwEventType == CorDebugExceptionUnwindCallbackType.DEBUG_EXCEPTION_INTERCEPTED) {
ExitCallback_Paused(PausedReason.ExceptionIntercepted);
ExitCallback_Paused();
} else {
ExitCallback_Continue();
}
@ -461,14 +428,14 @@ namespace Debugger @@ -461,14 +428,14 @@ namespace Debugger
public void FunctionRemapComplete(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugFunction pFunction)
{
EnterCallback("FunctionRemapComplete", pThread);
EnterCallback(PausedReason.Other, "FunctionRemapComplete", pThread);
ExitCallback_Continue();
}
public void FunctionRemapOpportunity(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugFunction pOldFunction, ICorDebugFunction pNewFunction, uint oldILOffset)
{
EnterCallback("FunctionRemapOpportunity", pThread);
EnterCallback(PausedReason.Other, "FunctionRemapOpportunity", pThread);
ExitCallback_Continue();
}
@ -476,9 +443,9 @@ namespace Debugger @@ -476,9 +443,9 @@ namespace Debugger
public void MDANotification(ICorDebugController c, ICorDebugThread t, ICorDebugMDA mda)
{
if (c.Is<ICorDebugAppDomain>()) {
EnterCallback("MDANotification", c.CastTo<ICorDebugAppDomain>());
EnterCallback(PausedReason.Other, "MDANotification", c.CastTo<ICorDebugAppDomain>());
} else if (c.Is<ICorDebugProcess>()){
EnterCallback("MDANotification", c.CastTo<ICorDebugProcess>());
EnterCallback(PausedReason.Other, "MDANotification", c.CastTo<ICorDebugProcess>());
} else {
throw new System.Exception("Unknown callback argument");
}

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

@ -18,12 +18,11 @@ namespace Debugger @@ -18,12 +18,11 @@ namespace Debugger
{
public partial class NDebugger
{
PausedReason? pausedReason = null;
bool pauseOnHandledException = false;
ManualResetEvent pausedHandle = new ManualResetEvent(false);
object sessionID = new object();
object debugeeStateID = new object();
PauseSession pauseSession;
DebugeeState debugeeState;
Process currentProcess;
@ -74,10 +73,12 @@ namespace Debugger @@ -74,10 +73,12 @@ namespace Debugger
if (currentProcess == null) {
return null;
} else {
if (currentProcess.IsRunning) return null;
return currentProcess;
}
}
set {
currentProcess = value;
}
}
public Thread CurrentThread {
@ -102,21 +103,21 @@ namespace Debugger @@ -102,21 +103,21 @@ namespace Debugger
/// <summary>
/// Indentification of the current debugger session. This value changes whenever debugger is continued
/// </summary>
public object SessionID {
public PauseSession PauseSession {
get {
return sessionID;
return pauseSession;
}
internal set {
sessionID = value;
pauseSession = value;
}
}
/// <summary>
/// Indentification of the state of the debugee. This value changes whenever the state of the debugee significatntly changes
/// </summary>
public object DebugeeStateID {
public DebugeeState DebugeeState {
get {
return debugeeStateID;
return debugeeState;
}
}
@ -136,13 +137,13 @@ namespace Debugger @@ -136,13 +137,13 @@ namespace Debugger
public bool IsPaused {
get {
return (pausedReason != null);
return (pauseSession != null);
}
}
public bool IsRunning {
get {
return (pausedReason == null);
return (pauseSession == null);
}
}
@ -153,60 +154,28 @@ namespace Debugger @@ -153,60 +154,28 @@ namespace Debugger
public PausedReason PausedReason {
get {
AssertPaused();
return (PausedReason)pausedReason;
return pauseSession.PausedReason;
}
}
internal void Pause(PausedReason reason, Process process, Thread thread, Function function)
internal void Pause()
{
if (IsPaused) {
throw new DebuggerException("Already paused");
}
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();
// Debugger state is unknown after calling OnDebuggingPaused (it may be resumed)
if (IsPaused) {
if (reason != PausedReason.AllEvalsComplete) {
debugeeStateID = new object();
if (PausedReason != PausedReason.EvalComplete) {
debugeeState = new DebugeeState();
OnDebuggeeStateChanged();
}
}
// This is a good point to autmaticaly evaluate evals from update of variables (if there are any)
if (IsPaused) {
this.StartEvaluation();
}
if (IsPaused) {
pausedHandle.Set();
}
}
internal void FakePause(PausedReason reason, bool keepCurrentFunction)
{
Process process = CurrentProcess;
Thread thread = CurrentThread;
Function function = CurrentFunction;
Resume();
Pause(reason, process, thread, keepCurrentFunction ? function : null);
}
internal void Resume()
{
if (IsRunning) {
@ -217,14 +186,8 @@ namespace Debugger @@ -217,14 +186,8 @@ namespace Debugger
pausedHandle.Reset();
pausedReason = null;
// Remove all stored functions, they are disponsed between callbacks and they need to be regenerated
foreach(Thread t in Threads) {
t.CurrentFunction = null;
}
pauseSession = null;
// Clear current process
currentProcess = null;
}

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

@ -132,7 +132,7 @@ namespace Debugger @@ -132,7 +132,7 @@ namespace Debugger
currentProcess = null;
pausedHandle.Reset();
pausedReason = null;
pauseSession = null;
pendingEvalsCollection.Clear();

33
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/PauseSession.cs

@ -0,0 +1,33 @@ @@ -0,0 +1,33 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="David Srbecký" email="dsrbecky@gmail.com"/>
// <version>$Revision$</version>
// </file>
using System;
using Debugger.Wrappers.CorDebug;
namespace Debugger
{
/// <summary>
/// Holds information about the state of paused debugger.
/// Expires when when Continue is called on debugger.
/// </summary>
public class PauseSession
{
PausedReason pausedReason;
public PausedReason PausedReason {
get {
return pausedReason;
}
}
public PauseSession(PausedReason pausedReason)
{
this.pausedReason = pausedReason;
}
}
}

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

@ -23,7 +23,7 @@ namespace Debugger @@ -23,7 +23,7 @@ namespace Debugger
Module module;
ICorDebugFunction corFunction;
ICorDebugILFrame corILFrame;
object corILFrameDebuggerSessionID;
object corILFramePauseSession;
bool steppedOut;
Thread thread;
@ -110,7 +110,7 @@ namespace Debugger @@ -110,7 +110,7 @@ namespace Debugger
this.chainIndex = chainIndex;
this.frameIndex = frameIndex;
this.corILFrame = corILFrame;
this.corILFrameDebuggerSessionID = debugger.SessionID;
this.corILFramePauseSession = debugger.PauseSession;
corFunction = corILFrame.Function;
module = debugger.GetModule(corFunction.Module);
@ -129,9 +129,9 @@ namespace Debugger @@ -129,9 +129,9 @@ namespace Debugger
internal ICorDebugILFrame CorILFrame {
get {
if (HasExpired) throw new DebuggerException("Function has expired");
if (corILFrameDebuggerSessionID != debugger.SessionID) {
if (corILFramePauseSession != debugger.PauseSession) {
corILFrame = thread.GetFunctionAt(chainIndex, frameIndex).CorILFrame;
corILFrameDebuggerSessionID = debugger.SessionID;
corILFramePauseSession = debugger.PauseSession;
}
return corILFrame;
}
@ -361,8 +361,10 @@ namespace Debugger @@ -361,8 +361,10 @@ namespace Debugger
if (simulate) {
CorILFrame.CanSetIP((uint)ilOffset);
} else {
// invalidates all frames and chains for the current thread
CorILFrame.SetIP((uint)ilOffset);
debugger.FakePause(PausedReason.SetIP, false);
debugger.PauseSession = new PauseSession(PausedReason.SetIP);
debugger.Pause();
}
} catch {
return null;

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

@ -60,7 +60,7 @@ namespace Debugger @@ -60,7 +60,7 @@ namespace Debugger
{
CurrentThread = thread;
debugger.FakePause(PausedReason.CurrentThreadChanged, false);
debugger.Pause();
}
public IList<Thread> Threads {
@ -122,36 +122,26 @@ namespace Debugger @@ -122,36 +122,26 @@ namespace Debugger
if (!isProcessRunning) {
throw new DebuggerException("Invalid operation");
}
corProcess.Stop(5000); // TODO: Hardcoded value
corProcess.Stop(5000); // TODO: Hardcoded value
isProcessRunning = false;
debugger.Pause(PausedReason.Break, this, null, null);
debugger.PauseSession = new PauseSession(PausedReason.Break);
debugger.CurrentProcess = this;
debugger.Pause();
}
public void Continue()
{
if (isProcessRunning) {
throw new DebuggerException("Invalid operation");
}
debugger.Resume();
isProcessRunning = true;
debugger.SessionID = new object();
corProcess.Continue(0);
}
internal void ContinueCallback()
{
if (isProcessRunning) {
throw new DebuggerException("Invalid operation");
}
isProcessRunning = true;
debugger.SessionID = new object();
corProcess.Continue(0);
}
public void Terminate()
{
// Resume stoped tread

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

@ -317,7 +317,7 @@ namespace Debugger @@ -317,7 +317,7 @@ namespace Debugger
{
CurrentFunction = function;
debugger.FakePause(PausedReason.CurrentFunctionChanged, true);
debugger.Pause();
}
public Function LastFunctionWithLoadedSymbols {

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

@ -24,8 +24,6 @@ namespace Debugger @@ -24,8 +24,6 @@ namespace Debugger
{
NDebugger debugger;
object debugeeStateIDatCreation;
ICorDebugEval corEval;
ICorDebugFunction corFunction;
CorValuesGetter getArgs;
@ -101,7 +99,6 @@ namespace Debugger @@ -101,7 +99,6 @@ namespace Debugger
this.debugger = debugger;
this.corFunction = corFunction;
this.getArgs = getArgs;
this.debugeeStateIDatCreation = debugger.DebugeeStateID;
// Schedule the eval for evaluation
debugger.AddEval(this);
@ -115,7 +112,7 @@ namespace Debugger @@ -115,7 +112,7 @@ namespace Debugger
/// <returns>True is setup was successful</returns>
internal bool SetupEvaluation(Thread targetThread)
{
if (!debugger.ManagedCallback.HandlingCallback) debugger.AssertPaused();
debugger.AssertPaused();
ICorDebugValue[] args = getArgs();

6
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Value.cs

@ -17,7 +17,7 @@ namespace Debugger @@ -17,7 +17,7 @@ namespace Debugger
{
protected NDebugger debugger;
protected ICorDebugValue corValue;
object debuggerSessionIDatCreation;
object pauseSessionAtCreation;
public event EventHandler<ValueEventArgs> ValueChanged;
@ -38,7 +38,7 @@ namespace Debugger @@ -38,7 +38,7 @@ namespace Debugger
/// </summary>
public bool IsExpired {
get {
return debuggerSessionIDatCreation != debugger.SessionID;
return pauseSessionAtCreation != debugger.PauseSession;
}
}
@ -106,7 +106,7 @@ namespace Debugger @@ -106,7 +106,7 @@ namespace Debugger
if (corValue != null) {
this.corValue = DereferenceUnbox(corValue);
}
this.debuggerSessionIDatCreation = debugger.SessionID;
this.pauseSessionAtCreation = debugger.PauseSession;
}
public override string ToString()

12
src/AddIns/Misc/Debugger/Debugger.Tests/Project/Src/DebuggerTests.cs

@ -527,22 +527,22 @@ namespace Debugger.Tests @@ -527,22 +527,22 @@ namespace Debugger.Tests
Assert.AreEqual(typeof(UnavailableValue), subVars[1].Value.GetType());
debugger.StartEvaluation();
WaitForPause(PausedReason.AllEvalsComplete, null);
WaitForPause(PausedReason.EvalComplete, null);
Assert.AreEqual("private", subVars[1].Value.AsString);
Assert.AreEqual(typeof(UnavailableValue), subVars[2].Value.GetType());
debugger.StartEvaluation();
WaitForPause(PausedReason.AllEvalsComplete, null);
WaitForPause(PausedReason.EvalComplete, null);
Assert.AreEqual("public", subVars[2].Value.AsString);
Assert.AreEqual(typeof(UnavailableValue), subVars[3].Value.GetType());
debugger.StartEvaluation();
WaitForPause(PausedReason.AllEvalsComplete, null);
WaitForPause(PausedReason.EvalComplete, null);
Assert.AreEqual(typeof(UnavailableValue), subVars[3].Value.GetType());
Assert.AreEqual(typeof(UnavailableValue), subVars[4].Value.GetType());
debugger.StartEvaluation();
WaitForPause(PausedReason.AllEvalsComplete, null);
WaitForPause(PausedReason.EvalComplete, null);
Assert.AreEqual("static", subVars[4].Value.AsString);
debugger.Continue();
@ -569,7 +569,7 @@ namespace Debugger.Tests @@ -569,7 +569,7 @@ namespace Debugger.Tests
if (var is PropertyVariable) {
Assert.AreEqual(typeof(UnavailableValue), var.Value.GetType(), "Variable name: " + var.Name);
debugger.StartEvaluation();
WaitForPause(PausedReason.AllEvalsComplete, null);
WaitForPause(PausedReason.EvalComplete, null);
Assert.AreEqual(false, var.Value.IsExpired, "Variable name: " + var.Name);
Assert.AreNotEqual(null, var.Value.AsString, "Variable name: " + var.Name);
}
@ -584,7 +584,7 @@ namespace Debugger.Tests @@ -584,7 +584,7 @@ namespace Debugger.Tests
}
}
debugger.StartEvaluation();
WaitForPause(PausedReason.AllEvalsComplete, null);
WaitForPause(PausedReason.EvalComplete, null);
debugger.Continue();
debugger.WaitForPrecessExit();

Loading…
Cancel
Save