The following code fragment uses the WaitForDebugEvent and ContinueDebugEvent functions to illustrate how a simple debugger might be organized.
DEBUG_EVENT debug_ev; /* debug event info */
DWORD continue_status = DBG_CONTINUE; /* exception continuation */
for(;;)
/*
* Wait for a debug event to occur. The second parameter
* (-1) indicates that the function will not return until
* a debug event occurs.
*/
WaitForDebugEvent(&debug_ev, -1);
/* Switch on the debug event code. */
switch (debug_ev.dwDebugEventCode) {
case EXCEPTION_DEBUG_EVENT:
/*
* Switch on the exception code. When handling
* exceptions, remember to set the continuation
* status (continue_status). This value is used
* by ContinueDebugEvent.
*/
switch (debug_ev.u.Exception.ExceptionRecord.ExceptionCode) {
case EXCEPTION_ACCESS_VIOLATION:
.
. /* Handle the exception. */
.
case EXCEPTION_BREAKPOINT:
.
. /* Handle the exception. */
.
case EXCEPTION_DATATYPE_MISALIGNMENT:
.
. /* Handle the exception. */
.
case EXCEPTION_SINGLE_STEP:
.
. /* Handle the exception. */
.
case DBG_CONTROL_C:
.
. /* Handle the exception. */
.
/* Handle other exceptions. */
;
}
case CREATE_THREAD_DEBUG_EVENT:
.
. /* Respond to the debug event. */
.
case CREATE_PROCESS_DEBUG_EVENT:
.
. /* Respond to the debug event. */
.
case EXIT_THREAD_DEBUG_EVENT:
.
. /* Respond to the debug event. */
.
case EXIT_PROCESS_DEBUG_EVENT:
.
. /* Respond to the debug event. */
.
case LOAD_DLL_DEBUG_EVENT:
.
. /* Respond to the debug event. */
.
case UNLOAD_DLL_DEBUG_EVENT:
.
. /* Respond to the debug event. */
.
case OUTPUT_DEBUG_STRING_EVENT:
.
. /* Respond to the debug event. */
.
;
}
/* Resume executing the thread that reported the debug event. */
ContinueDebugEvent(debug_ev.dwProcessId,
debug_ev.dwThreadId, continue_status);