📄 process.cs
字号:
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="David Srbecký" email="dsrbecky@gmail.com"/>
// <version>$Revision: 1294 $</version>
// </file>
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Threading;
using Debugger.Wrappers.CorDebug;
namespace Debugger
{
public class Process: RemotingObjectBase
{
NDebugger debugger;
ICorDebugProcess corProcess;
Thread selectedThread;
bool isProcessRunning = true;
public NDebugger Debugger {
get {
return debugger;
}
}
internal Process(NDebugger debugger, ICorDebugProcess corProcess)
{
this.debugger = debugger;
this.corProcess = corProcess;
}
internal ICorDebugProcess CorProcess {
get {
return corProcess;
}
}
public Thread SelectedThread {
get {
return selectedThread;
}
set {
selectedThread = value;
}
}
public IList<Thread> Threads {
get {
List<Thread> threads = new List<Thread>();
foreach(Thread thread in debugger.Threads) {
if (thread.Process == this) {
threads.Add(thread);
}
}
return threads;
}
}
static public Process CreateProcess(NDebugger debugger, string filename, string workingDirectory, string arguments)
{
return debugger.MTA2STA.Call<Process>(delegate{
return StartInternal(debugger, filename, workingDirectory, arguments);
});
}
static unsafe Process StartInternal(NDebugger debugger, string filename, string workingDirectory, string arguments)
{
debugger.TraceMessage("Executing " + filename);
uint[] processStartupInfo = new uint[17];
processStartupInfo[0] = sizeof(uint) * 17;
uint[] processInfo = new uint[4];
ICorDebugProcess outProcess;
if (workingDirectory == null || workingDirectory == "") {
workingDirectory = System.IO.Path.GetDirectoryName(filename);
}
fixed (uint* pprocessStartupInfo = processStartupInfo)
fixed (uint* pprocessInfo = processInfo)
outProcess =
debugger.CorDebug.CreateProcess(
filename, // lpApplicationName
// If we do not prepend " ", the first argument migh just get lost
" " + arguments, // lpCommandLine
ref _SECURITY_ATTRIBUTES.Default, // lpProcessAttributes
ref _SECURITY_ATTRIBUTES.Default, // lpThreadAttributes
1,//TRUE // bInheritHandles
0x00000010 /*CREATE_NEW_CONSOLE*/, // dwCreationFlags
IntPtr.Zero, // lpEnvironment
workingDirectory, // lpCurrentDirectory
(uint)pprocessStartupInfo, // lpStartupInfo
(uint)pprocessInfo, // lpProcessInformation,
CorDebugCreateProcessFlags.DEBUG_NO_SPECIAL_OPTIONS // debuggingFlags
);
return new Process(debugger, outProcess);
}
internal void Break()
{
if (!isProcessRunning) {
throw new DebuggerException("Invalid operation");
}
corProcess.Stop(5000); // TODO: Hardcoded value
isProcessRunning = false;
debugger.PauseSession = new PauseSession(PausedReason.Break);
debugger.SelectedProcess = this;
if (this.SelectedThread == null && this.Threads.Count > 0) {
this.SelectedThread = this.Threads[0];
}
if (debugger.SelectedThread != null) {
// Disable all steppers - do not Deactivate since function tracking still needs them
foreach(Stepper s in debugger.SelectedThread.Steppers) {
s.PauseWhenComplete = false;
}
debugger.SelectedThread.SelectedFunction = debugger.SelectedThread.LastFunctionWithLoadedSymbols;
}
debugger.Pause();
}
public void Continue()
{
if (isProcessRunning) {
throw new DebuggerException("Invalid operation");
}
debugger.Resume();
isProcessRunning = true;
corProcess.Continue(0);
}
public void Terminate()
{
// Resume stoped tread
if (corProcess.IsRunning == 0) {
corProcess.Continue(0); // TODO: Remove this...
}
// Stop&terminate - both must be called
corProcess.Stop(5000); // TODO: ...and this
corProcess.Terminate(0);
}
public bool IsRunning {
get {
return isProcessRunning;
}
internal set {
isProcessRunning = value;
}
}
public bool IsPaused {
get {
return !isProcessRunning;
}
}
public void AssertPaused()
{
if (!IsPaused) {
throw new DebuggerException("Process is not paused.");
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -