diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Debugger.Core.csproj b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Debugger.Core.csproj
index 4b2a265cb6..386a0c912d 100644
--- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Debugger.Core.csproj
+++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Debugger.Core.csproj
@@ -66,6 +66,7 @@
+
@@ -87,4 +88,4 @@
-
+
\ No newline at end of file
diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/Internal/MTA2STA.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/Internal/MTA2STA.cs
index 50f083a9ef..c508467a5c 100644
--- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/Internal/MTA2STA.cs
+++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/Internal/MTA2STA.cs
@@ -25,6 +25,7 @@ namespace DebuggerInterop.Core
static object OnlyOneAtTimeLock = new Object();
static object DataLock = new Object();
+ object returnValue;
public MTA2STA()
{
@@ -37,7 +38,7 @@ namespace DebuggerInterop.Core
System.Console.WriteLine("MTA2STA: " + msg);
}
- public void CallInSTA (object targetObject, string functionName, object[] functionParameters)
+ public object CallInSTA (object targetObject, string functionName, object[] functionParameters)
{
lock (OnlyOneAtTimeLock) {
TraceMsg("call to process: " + functionName + " {");
@@ -63,6 +64,7 @@ namespace DebuggerInterop.Core
TraceMsg("} // MTA2STA: call processed: " + functionName);
}
+ return returnValue;
}
void PerformCall(object sender, EventArgs e)
@@ -105,11 +107,12 @@ namespace DebuggerInterop.Core
}
}
TraceMsg ("Invoke " + functionName + "{");
+ returnValue = null;
try {
if (targetObject is Type) {
- method.Invoke(null, outputParams);
+ returnValue = method.Invoke(null, outputParams);
} else {
- method.Invoke(targetObject, outputParams);
+ returnValue = method.Invoke(targetObject, outputParams);
}
} catch (System.Exception exception) {
System.Diagnostics.Debug.Fail("Invoke of " + functionName + " failed.", exception.ToString());
diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/NDebugger.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/NDebugger.cs
index f2aa0dde58..ad13d2a3bc 100644
--- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/NDebugger.cs
+++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/NDebugger.cs
@@ -40,48 +40,21 @@ namespace DebuggerLibrary
}
}
-
static ICorDebug corDebug;
static ManagedCallback managedCallback;
static ManagedCallbackProxy managedCallbackProxy;
- static bool isProcessRunning;
- static ICorDebugProcess mainProcess;
- static Thread mainThread;
- static Thread currentThread;
+ static Process mainProcess;
public static bool CatchHandledExceptions = false;
- #region Public propeties
-
- static public SourcecodeSegment NextStatement {
- get{
- try {
- return CurrentThread.NextStatement;
- } catch (CurrentThreadNotAviableException) {
- System.Diagnostics.Debug.Fail("Unable to get NextStatement. CurrentThreadNotAviableException");
- throw new NextStatementNotAviableException();
- }
- }
- }
-
- static public VariableCollection LocalVariables {
- get{
- Thread thread;
- try {
- thread = CurrentThread;
- }
- catch (CurrentThreadNotAviableException) {
- //System.Diagnostics.Debug.Fail("Unable to get LocalVariables. CurrentThreadNotAviableException");
- return new VariableCollection ();
- }
- return thread.LocalVariables;
- }
+ static internal ICorDebug CorDebug {
+ get {
+ return corDebug;
+ }
}
- #endregion
-
- static internal ICorDebugProcess MainProcess {
+ static internal Process CurrentProcess {
get {
return mainProcess;
}
@@ -101,41 +74,6 @@ namespace DebuggerLibrary
}
}
}
-
- public static Thread MainThread {
- get {
- return mainThread;
- }
- set {
- mainThread = value;
- }
- }
-
- static public Thread CurrentThread {
- get {
- if (!IsDebugging) throw new CurrentThreadNotAviableException();
- if (IsProcessRunning) throw new CurrentThreadNotAviableException();
- if (currentThread != null) return currentThread;
- if (mainThread != null) return mainThread;
- throw new CurrentThreadNotAviableException();
- }
- set {
- currentThread = value;
- if (mainThread == null) {
- mainThread = value;
- }
- if (managedCallback.HandlingCallback == false) {
- OnDebuggingPaused(PausedReason.CurrentThreadChanged);
- }
- }
- }
-
- static internal ICorDebugProcess corProcess {
- get {
- if (MainProcess != null) return MainProcess;
- throw new UnableToGetPropertyException(null, "corProcess", "Make sure debuger is attached to process");
- }
- }
internal static ManagedCallback ManagedCallback {
get {
@@ -184,10 +122,7 @@ namespace DebuggerLibrary
ClearThreads();
- MainProcess = null;
- mainThread = null;
- currentThread = null;
- isProcessRunning = false;
+ CurrentProcess = null;
GC.Collect(GC.MaxGeneration);
GC.WaitForPendingFinalizers();
@@ -303,6 +238,13 @@ namespace DebuggerLibrary
#region Execution control
+ static internal void Continue(ICorDebugAppDomain pAppDomain)
+ {
+ ICorDebugProcess outProcess;
+ pAppDomain.GetProcess(out outProcess);
+ outProcess.Continue(0);
+ }
+
static public void StartWithoutDebugging(System.Diagnostics.ProcessStartInfo psi)
{
System.Diagnostics.Process process;
@@ -310,184 +252,118 @@ namespace DebuggerLibrary
process.StartInfo = psi;
process.Start();
}
-
- static MTA2STA m2s = new MTA2STA();
static public void Start(string filename, string workingDirectory, string arguments)
{
- if (IsDebugging) {
- System.Diagnostics.Debug.Fail("Invalid operation");
- return;
- }
- m2s.CallInSTA(typeof(NDebugger), "StartInternal", new Object[] {filename, workingDirectory, arguments});
- return;
+ CurrentProcess = Process.CreateProcess(filename, workingDirectory, arguments);
}
- static public unsafe void StartInternal(string filename, string workingDirectory, string arguments)
- {
- TraceMessage("Executing " + filename);
-
- _SECURITY_ATTRIBUTES secAttr = new _SECURITY_ATTRIBUTES();
- secAttr.bInheritHandle = 0;
- secAttr.lpSecurityDescriptor = IntPtr.Zero;
- secAttr.nLength = (uint)sizeof(_SECURITY_ATTRIBUTES); //=12?
-
- uint[] processStartupInfo = new uint[17];
- processStartupInfo[0] = sizeof(uint) * 17;
- uint[] processInfo = new uint[4];
- ICorDebugProcess outProcess;
- fixed (uint* pprocessStartupInfo = processStartupInfo)
- fixed (uint* pprocessInfo = processInfo)
- corDebug.CreateProcess(
- filename, // lpApplicationName
- null, // lpCommandLine
- ref secAttr, // lpProcessAttributes
- ref secAttr, // lpThreadAttributes
- 1,//TRUE // bInheritHandles
- 0, // dwCreationFlags
- IntPtr.Zero, // lpEnvironment
- null, // lpCurrentDirectory
- (uint)pprocessStartupInfo, // lpStartupInfo
- (uint)pprocessInfo, // lpProcessInformation,
- CorDebugCreateProcessFlags.DEBUG_NO_SPECIAL_OPTIONS, // debuggingFlags
- out outProcess // ppProcess
- );
-
- isProcessRunning = true;
- MainProcess = outProcess;
- }
+ #endregion
- static public void Break()
+ public void ToggleBreakpointAt(string fileName, int line, int column)
{
- if (!IsDebugging || !IsProcessRunning) {
- System.Diagnostics.Debug.Fail("Invalid operation");
- return;
+ // Check if there is breakpoint on that line
+ foreach (Breakpoint breakpoint in Breakpoints) {
+ // TODO check filename too
+ if (breakpoint.SourcecodeSegment.StartLine == line) {
+ RemoveBreakpoint(breakpoint);
+ return;
+ }
}
- corProcess.Stop(5000); // TODO: Hardcoded value
-
- isProcessRunning = false;
- OnDebuggingPaused(PausedReason.Break);
- OnIsProcessRunningChanged();
- }
+ // Add the breakpoint
+ Breakpoint addedBreakpoint = AddBreakpoint(fileName, line, column);
- static public void StepInto()
- {
- try {
- CurrentThread.StepInto();
- } catch (CurrentThreadNotAviableException) {
- System.Diagnostics.Debug.Fail("Unable to prerform step. CurrentThreadNotAviableException");
+ // Check if it wasn't forced to move to different line with breakpoint
+ foreach (Breakpoint breakpoint in Breakpoints) {
+ if (breakpoint != addedBreakpoint) { // Only the old ones
+ if (breakpoint.SourcecodeSegment.StartLine == addedBreakpoint.SourcecodeSegment.StartLine) {
+ // Whops! We have two breakpoint on signle line, delete one
+ RemoveBreakpoint(addedBreakpoint);
+ return;
+ }
+ }
}
}
- static public void StepOver()
- {
- try {
- CurrentThread.StepOver();
- } catch (CurrentThreadNotAviableException) {
- System.Diagnostics.Debug.Fail("Unable to prerform step. CurrentThreadNotAviableException");
+
+ static public bool IsProcessRunning {
+ get {
+ if (!IsDebugging) return false;
+ return CurrentProcess.IsProcessRunning;
+ }
+ set {
+ if (CurrentProcess == null) return;
+ CurrentProcess.IsProcessRunning = value;
}
}
- static public void StepOut()
- {
- try {
- CurrentThread.StepOut();
- } catch (CurrentThreadNotAviableException) {
- System.Diagnostics.Debug.Fail("Unable to prerform step. CurrentThreadNotAviableException");
+ static public bool IsDebugging {
+ get {
+ return (CurrentProcess != null);
}
}
- static internal void Continue(ICorDebugAppDomain pAppDomain)
- {
- ICorDebugProcess outProcess;
- pAppDomain.GetProcess(out outProcess);
- if (MainProcess != outProcess) throw new DebuggerException("Request to continue AppDomain that does not belog to current process");
- Continue();
+ static public Thread CurrentThread {
+ get {
+ return CurrentProcess.CurrentThread;
+ }
+ set {
+ CurrentProcess.CurrentThread = value;
+ }
}
- static public void Continue()
- {
- if (!IsDebugging || IsProcessRunning) {
- System.Diagnostics.Debug.Fail("Invalid operation");
- return;
+ static public Thread MainThread {
+ get {
+ return CurrentProcess.MainThread;
}
-
- bool abort = false;
- OnDebuggingIsResuming(ref abort);
- if (abort == true) return;
-
- isProcessRunning = true;
- if (managedCallback.HandlingCallback == false) {
- OnDebuggingResumed();
- OnIsProcessRunningChanged();
+ set {
+ CurrentProcess.MainThread = value;
}
-
- corProcess.Continue(0);
}
- static public void Terminate()
- {
- if (!IsDebugging) {
- System.Diagnostics.Debug.Fail("Invalid operation");
- return;
+ static public SourcecodeSegment NextStatement {
+ get{
+ return CurrentProcess.NextStatement;
}
+ }
- int running;
- corProcess.IsRunning(out running);
- // Resume stoped tread
- if (running == 0) {
- Continue(); // TODO: Remove this...
+ static public VariableCollection LocalVariables {
+ get{
+ return CurrentProcess.LocalVariables;
}
- // Stop&terminate - both must be called
- corProcess.Stop(5000); // TODO: ...and this
- corProcess.Terminate(0);
}
- static public bool IsProcessRunning {
- get {
- if (!IsDebugging) return false;
- return isProcessRunning;
- }
- set {
- isProcessRunning = value;
- }
+ static public void Break()
+ {
+ CurrentProcess.Break();
}
- static public bool IsDebugging {
- get {
- return (MainProcess != null);
- }
+ static public void StepInto()
+ {
+ CurrentProcess.StepInto();
}
- #endregion
+ static public void StepOver()
+ {
+ CurrentProcess.StepOver();
+ }
- public void ToggleBreakpointAt(string fileName, int line, int column)
+ static public void StepOut()
{
- // Check if there is breakpoint on that line
- foreach (Breakpoint breakpoint in Breakpoints) {
- // TODO check filename too
- if (breakpoint.SourcecodeSegment.StartLine == line) {
- RemoveBreakpoint(breakpoint);
- return;
- }
- }
+ CurrentProcess.StepOut();
+ }
- // Add the breakpoint
- Breakpoint addedBreakpoint = AddBreakpoint(fileName, line, column);
+ static public void Continue()
+ {
+ CurrentProcess.Continue();
+ }
- // Check if it wasn't forced to move to different line with breakpoint
- foreach (Breakpoint breakpoint in Breakpoints) {
- if (breakpoint != addedBreakpoint) { // Only the old ones
- if (breakpoint.SourcecodeSegment.StartLine == addedBreakpoint.SourcecodeSegment.StartLine) {
- // Whops! We have two breakpoint on signle line, delete one
- RemoveBreakpoint(addedBreakpoint);
- return;
- }
- }
- }
+ static public void Terminate()
+ {
+ CurrentProcess.Terminate();
}
}
}
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
new file mode 100644
index 0000000000..e634525a2f
--- /dev/null
+++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Process.cs
@@ -0,0 +1,212 @@
+//
+//
+//
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Threading;
+
+using DebuggerInterop.Core;
+using DebuggerInterop.MetaData;
+
+namespace DebuggerLibrary
+{
+ public class Process
+ {
+ ICorDebugProcess corProcess;
+
+ Thread mainThread;
+ Thread currentThread;
+ bool isProcessRunning;
+
+ internal Process(ICorDebugProcess corProcess)
+ {
+ this.corProcess = corProcess;
+ }
+
+ internal ICorDebugProcess CorProcess {
+ get {
+ return corProcess;
+ }
+ }
+
+ public Thread CurrentThread {
+ get {
+ if (IsProcessRunning) throw new CurrentThreadNotAviableException();
+ if (currentThread != null) return currentThread;
+ if (mainThread != null) return mainThread;
+ throw new CurrentThreadNotAviableException();
+ }
+ set {
+ currentThread = value;
+ if (mainThread == null) {
+ mainThread = value;
+ }
+ if (NDebugger.ManagedCallback.HandlingCallback == false) {
+ NDebugger.OnDebuggingPaused(PausedReason.CurrentThreadChanged);
+ }
+ }
+ }
+
+ public Thread MainThread {
+ get {
+ return mainThread;
+ }
+ set {
+ mainThread = value;
+ }
+ }
+
+ public SourcecodeSegment NextStatement {
+ get{
+ try {
+ return CurrentThread.NextStatement;
+ } catch (CurrentThreadNotAviableException) {
+ System.Diagnostics.Debug.Fail("Unable to get NextStatement. CurrentThreadNotAviableException");
+ throw new NextStatementNotAviableException();
+ }
+ }
+ }
+
+ public VariableCollection LocalVariables {
+ get{
+ Thread thread;
+ try {
+ thread = CurrentThread;
+ }
+ catch (CurrentThreadNotAviableException) {
+ //System.Diagnostics.Debug.Fail("Unable to get LocalVariables. CurrentThreadNotAviableException");
+ return new VariableCollection ();
+ }
+ return thread.LocalVariables;
+ }
+ }
+
+ static public Process CreateProcess(string filename, string workingDirectory, string arguments)
+ {
+ MTA2STA m2s = new MTA2STA();
+ Process createdProcess = null;
+ createdProcess = (Process)m2s.CallInSTA(typeof(Process), "StartInternal", new Object[] {filename, workingDirectory, arguments});
+ return createdProcess;
+ }
+
+ static public unsafe Process StartInternal(string filename, string workingDirectory, string arguments)
+ {
+ NDebugger.TraceMessage("Executing " + filename);
+
+ _SECURITY_ATTRIBUTES secAttr = new _SECURITY_ATTRIBUTES();
+ secAttr.bInheritHandle = 0;
+ secAttr.lpSecurityDescriptor = IntPtr.Zero;
+ secAttr.nLength = (uint)sizeof(_SECURITY_ATTRIBUTES); //=12?
+
+ uint[] processStartupInfo = new uint[17];
+ processStartupInfo[0] = sizeof(uint) * 17;
+ uint[] processInfo = new uint[4];
+
+ ICorDebugProcess outProcess;
+
+ fixed (uint* pprocessStartupInfo = processStartupInfo)
+ fixed (uint* pprocessInfo = processInfo)
+ NDebugger.CorDebug.CreateProcess(
+ filename, // lpApplicationName
+ null, // lpCommandLine
+ ref secAttr, // lpProcessAttributes
+ ref secAttr, // lpThreadAttributes
+ 1,//TRUE // bInheritHandles
+ 0, // dwCreationFlags
+ IntPtr.Zero, // lpEnvironment
+ null, // lpCurrentDirectory
+ (uint)pprocessStartupInfo, // lpStartupInfo
+ (uint)pprocessInfo, // lpProcessInformation,
+ CorDebugCreateProcessFlags.DEBUG_NO_SPECIAL_OPTIONS, // debuggingFlags
+ out outProcess // ppProcess
+ );
+
+ return new Process(outProcess);
+ }
+
+ public void Break()
+ {
+ if (!IsProcessRunning) {
+ System.Diagnostics.Debug.Fail("Invalid operation");
+ return;
+ }
+
+ corProcess.Stop(5000); // TODO: Hardcoded value
+
+ isProcessRunning = false;
+ NDebugger.OnDebuggingPaused(PausedReason.Break);
+ NDebugger.OnIsProcessRunningChanged();
+ }
+
+ public void StepInto()
+ {
+ try {
+ CurrentThread.StepInto();
+ } catch (CurrentThreadNotAviableException) {
+ System.Diagnostics.Debug.Fail("Unable to prerform step. CurrentThreadNotAviableException");
+ }
+ }
+
+ public void StepOver()
+ {
+ try {
+ CurrentThread.StepOver();
+ } catch (CurrentThreadNotAviableException) {
+ System.Diagnostics.Debug.Fail("Unable to prerform step. CurrentThreadNotAviableException");
+ }
+ }
+
+ public void StepOut()
+ {
+ try {
+ CurrentThread.StepOut();
+ } catch (CurrentThreadNotAviableException) {
+ System.Diagnostics.Debug.Fail("Unable to prerform step. CurrentThreadNotAviableException");
+ }
+ }
+
+ public void Continue()
+ {
+ if (IsProcessRunning) {
+ System.Diagnostics.Debug.Fail("Invalid operation");
+ return;
+ }
+
+ bool abort = false;
+ NDebugger.OnDebuggingIsResuming(ref abort);
+ if (abort == true) return;
+
+ isProcessRunning = true;
+ if (NDebugger.ManagedCallback.HandlingCallback == false) {
+ NDebugger.OnDebuggingResumed();
+ NDebugger.OnIsProcessRunningChanged();
+ }
+
+ corProcess.Continue(0);
+ }
+
+ public void Terminate()
+ {
+ int running;
+ corProcess.IsRunning(out running);
+ // Resume stoped tread
+ if (running == 0) {
+ Continue(); // TODO: Remove this...
+ }
+ // Stop&terminate - both must be called
+ corProcess.Stop(5000); // TODO: ...and this
+ corProcess.Terminate(0);
+ }
+
+ public bool IsProcessRunning {
+ get {
+ return isProcessRunning;
+ }
+ set {
+ isProcessRunning = value;
+ }
+ }
+ }
+}