Using Debugging Support

The following example uses the WaitForDebugEvent and ContinueDebugEvent functions to illustrate how a simple debugger might be organized.

DEBUG_EVENT DebugEv;                   // debugging event information 
DWORD dwContinueStatus = DBG_CONTINUE; // exception continuation 
 
for(;;) 
{ 
 
// Wait for a debugging event to occur. The second parameter indicates 
// that the function does not return until a debugging event occurs. 
 
    WaitForDebugEvent(&DebugEv, INFINITE); 
 
// Process the debugging event code. 
 
    switch (DebugEv.dwDebugEventCode) 
    { 
        case EXCEPTION_DEBUG_EVENT: 
        // Process the exception code. When handling 
        // exceptions, remember to set the continuation 
        // status parameter (dwContinueStatus). This value 
        // is used by the ContinueDebugEvent function. 
 
            switch (DebugEv.u.Exception.ExceptionRecord.ExceptionCode) 
            { 
                case EXCEPTION_ACCESS_VIOLATION: 
                // First chance: Pass this on to the kernel. 
                // Last chance: Display an appropriate error. 
 
                case EXCEPTION_BREAKPOINT: 
                // First chance: Display the current 
                // instruction and register values. 
 
                case EXCEPTION_DATATYPE_MISALIGNMENT: 
                // First chance: Pass this on to the kernel. 
                // Last chance: Display an appropriate error. 
 
                case EXCEPTION_SINGLE_STEP: 
                // First chance: Update the display of the 
                // current instruction and register values. 
 
                case DBG_CONTROL_C: 
                // First chance: Pass this on to the kernel. 
                // Last chance: Display an appropriate error. 
 
                // Handle other exceptions. 
            } 
 
        case CREATE_THREAD_DEBUG_EVENT: 
        // As needed, examine or change the thread's registers 
        // with the GetThreadContext and SetThreadContext functions; 
        // and suspend and resume thread execution with the 
        // SuspendThread and ResumeThread functions. 
 
        case CREATE_PROCESS_DEBUG_EVENT: 
        // As needed, examine or change the registers of the 
        // process's initial thread with the GetThreadContext and 
        // SetThreadContext functions; read from and write to the 
        // process's virtual memory with the ReadProcessMemory and 
        // WriteProcessMemory functions; and suspend and resume 
        // thread execution with the SuspendThread and ResumeThread 
        // functions. 
 
        case EXIT_THREAD_DEBUG_EVENT: 
        // Display the thread's exit code. 
 
        case EXIT_PROCESS_DEBUG_EVENT: 
        // Display the process's exit code. 
 
        case LOAD_DLL_DEBUG_EVENT: 
        // Read the debugging information included in the newly 
        // loaded DLL. 
 
        case UNLOAD_DLL_DEBUG_EVENT: 
        // Display a message that the DLL has been unloaded. 
 
        case OUTPUT_DEBUG_STRING_EVENT: 
        // Display the output debugging string. 
 
    } 
 
// Resume executing the thread that reported the debugging event. 
 
ContinueDebugEvent(DebugEv.dwProcessId, 
    DebugEv.dwThreadId, dwContinueStatus); 
 
}