快乐虾
http://blog.csdn.net/lights_joy/
1.1加载调试引擎
由于我们无法干预VC的调试引擎加载,但可以侦听VC的调试引擎加载事件,在此事件处理中可以调用自己的调试引擎:
publicvoidLaunchDebugTarget(stringfilePath, stringenv)
{
varserver= (IDebugCoreServer3)GetService(typeof(IDebugCoreServer3));
vardebugger= (IVsDebugger3)GetService(typeof(IVsDebugger));
VsDebugTargetInfo3[] debugTargets=newVsDebugTargetInfo3[1];
debugTargets[0].dlo= (uint)DEBUG_LAUNCH_OPERATION.DLO_CreateProcess;
debugTargets[0].bstrExe=filePath;
debugTargets[0].bstrEnv=env;
debugTargets[0].guidLaunchDebugEngine=newGuid(lights.EmbedLinux.Debugger.Engine.EngineConstants.EngineId);
VsDebugTargetProcessInfo[] processInfo=newVsDebugTargetProcessInfo[debugTargets.Length];
try
{
debugger.LaunchDebugTargets3(1, debugTargets, processInfo);
}
catch(Exceptione)
{
Debug.WriteLine("Exception when Launch debugger: "+e.Message);
}
}
在此使用了IVsDebugger.LaunchDebugTarget3,在此调用中,SDM将根据EngineId查找此Engine所在的文件并进行引擎的创建。
1.2LaunchSuspended
在SDM创建引擎后调用的第一个函数是LauchSuspended:
// Launches a process by means of the debug engine.
// Normally, Visual Studio launches a program using theIDebugPortEx2::LaunchSuspended method and then attaches the debugger
// to the suspended program. However, there arecircumstances in which the debug engine may need to launch a program
// (for example, if the debug engine is part of aninterpreter and the program being debugged is an interpreted language),
// in which case Visual Studio uses theIDebugEngineLaunch2::LaunchSuspended method
// The IDebugEngineLaunch2::ResumeProcess method iscalled to start the process after the process has been successfully launched ina suspended state.
intIDebugEngineLaunch2.LaunchSuspended(stringpszServer, IDebugPort2port, stringexe, stringargs, stringdir, stringenv, stringoptions, enum_LAUNCH_FLAGSlaunchFlags, uinthStdInput, uinthStdOutput, uinthStdError, IDebugEventCallback2ad7Callback, outIDebugProcess2process)
在此函数中,我们可以让python通过某个连接加载虚拟机里的gdb,再将python进程的ID号返回给SDM:
AD_PROCESS_IDadProcessId=newAD_PROCESS_ID();
adProcessId.ProcessIdType= (uint)enum_AD_PROCESS_ID.AD_PROCESS_ID_SYSTEM;
adProcessId.dwProcessId= (uint)_process.Id;
EngineUtils.RequireOk(port.GetProcess(adProcessId,outprocess));
1.3ResumeProcess
SDM调用的第二个关键函数是ResumeProcess:
// Resume a process launched byIDebugEngineLaunch2.LaunchSuspended
intIDebugEngineLaunch2.ResumeProcess(IDebugProcess2process)
这个函数感觉有点歧义,似乎应该在这里让gdb里加载的应用运行起来,但实际上,在这个函数里应该做的是创建ProgramNode:
// Send a program node to the SDM. This will cause theSDM to turn around and call IDebugEngine2.Attach
// which will complete the hookup with AD7
IDebugPort2port;
EngineUtils.RequireOk(process.GetPort(outport));
IDebugDefaultPort2defaultPort= (IDebugDefaultPort2)port;
IDebugPortNotify2portNotify;
EngineUtils.RequireOk(defaultPort.GetPortNotify(outportNotify));
EngineUtils.RequireOk(portNotify.AddProgramNode(newAD7ProgramNode(_process.Id)));
1.4Attach
下一个关键函数:
// Attach the debug engine to a program.
intIDebugEngine2.Attach(IDebugProgram2[] rgpPrograms, IDebugProgramNode2[] rgpProgramNodes, uintceltPrograms, IDebugEventCallback2ad7Callback, enum_ATTACH_REASONdwReason)
在这个函数中,我们需要发送两个事件给SDM:
AD7EngineCreateEvent.Send(this);
AD7ProgramCreateEvent.Send(this);
1.5LoadComplete
当gdb成功加载应用程序后,我们需要发送LoadComplete通知SDM:
Send(newAD7LoadCompleteEvent(), AD7LoadCompleteEvent.IID, thread);
1.6设置断点
设置断点的工作后面单独说,在此先跳过。
1.7Continue
在断点设置完成后,SDM将调用Continue:
// Continue is called from the SDM when it wantsexecution to continue in the debugee
// but have stepping state remain. An example is when atracepoint is executed,
// and the debugger does not want to actually enter breakmode.
publicintContinue(IDebugThread2pThread)
在这个函数中就可以让gdb执行run命令了。
至此,SDM成功加载gdb及要调试的应用。
??每一件事都要用多方面的角度来看它