以下示例使用WaitForDebugEvent和ContinueDebugEvent函数来说明如何组织简单的调试器。
DEBUG_EVENT DebugEv; //调试事件信息
DWORD dwContinueStatus = DBG_CONTINUE; //异常继续en
for(;;)
{
//等待调试事件发生。第二个参数表示
//该函数在调试事件发生之前不会返回。
WaitForDebugEvent(&DebugEv, INFINITE);
//处理调试事件代码。
switch(DebugEv.dwDebugEventCode)
{
case EXCEPTION_DEBUG_EVENT:
//处理异常代码。处理时
//异常,记得设置继续
// status参数(dwContinueStatus)。这个值
//由ContinueDebugEvent函数使用。
switch(DebugEv.u.Exception.ExceptionRecord.ExceptionCode)
{
case EXCEPTION_ACCESS_VIOLATION:
//第一次机会:将其传递给内核。
//最后机会:显示适当的错误。
case EXCEPTION_BREAKPOINT:
//第一次机会:显示当前的
//指令和寄存器值。
case EXCEPTION_DATATYPE_MISALIGNMENT:
//第一次机会:将其传递给内核。
//最后机会:显示适当的错误。
case EXCEPTION_SINGLE_STEP:
//第一次机会:更新显示
//当前指令和寄存器值。
case DBG_CONTROL_C:
//第一次机会:将其传递给内核。
//最后机会:显示适当的错误。
//处理其他异常。
}
case CREATE_THREAD_DEBUG_EVENT:
//根据需要,检查或更改线程的寄存器
//使用GetThreadContext和SetThreadContext函数;
//并挂起并恢复线程执行
// SuspendThread和ResumeThread函数。
case CREATE_PROCESS_DEBUG_EVENT:
//根据需要,检查或更改寄存器
//进程的初始线程与GetThreadContext和
// SetThreadContext函数;阅读和写入
//进程的虚拟内存与ReadProcessMemory和
// WriteProcessMemory函数;并暂停和恢复
//使用SuspendThread和ResumeThread执行线程
// 功能。
case EXIT_THREAD_DEBUG_EVENT:
//显示线程的退出代码。
case EXIT_PROCESS_DEBUG_EVENT:
//显示进程的退出代码。
case LOAD_DLL_DEBUG_EVENT:
//读取新添加的调试信息
//加载DLL。
case UNLOAD_DLL_DEBUG_EVENT:
//显示DLL已卸载的消息。
case OUTPUT_DEBUG_STRING_EVENT:
//显示输出调试字符串。
}
//恢复执行报告调试事件的线程。
ContinueDebugEvent(DebugEv.dwProcessId,
DebugEv.dwThreadId, dwContinueStatus);
}