Browse Source
git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@71 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61shortcuts
4 changed files with 306 additions and 214 deletions
@ -0,0 +1,212 @@
@@ -0,0 +1,212 @@
|
||||
// <file>
|
||||
// <owner name="David Srbecký" email="dsrbecky@post.cz"/>
|
||||
// </file>
|
||||
|
||||
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; |
||||
} |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue