본문 바로가기

3.구현/HTML5&Javascript

MSND에 있는 디버깅 기본에 대한 내용

About Basic Debugging

The debugging functions can be used to create a basic, event-driven debugger. Event-driven means that the debugger is notified every time certain events occur in the process being debugged. Notification enables the debugger to take appropriate action in response to the events.

Debug Support from Process, Thread, and Exception Functions describes the debugging-specific features of certain process, thread, and exception-handling functions.

Creating a Basic Debugger describes using the basic debugging functions to create a simple debugger. These functions enable an application to wait for debugging events, cause breakpoint exceptions, transfer execution control to the debugger, and so on.

Debugging Events describes the debug event mechanism. Debugging events cause the system to notify the debugger.

Debugging Functions

The following functions are used with debugging.

Function

Description

CheckRemoteDebuggerPresent

Determines whether the specified process is being debugged.

ContinueDebugEvent

Enables a debugger to continue a thread that previously reported a debugging event.

DebugActiveProcess

Enables a debugger to attach to an active process and debug it.

DebugActiveProcessStop

Stops the debugger from debugging the specified process.

DebugBreak

Causes a breakpoint exception to occur in the current process.

DebugBreakProcess

Causes a breakpoint exception to occur in the specified process.

DebugSetProcessKillOnExit

Sets the action to be performed when the debugging thread exits.

FatalExit

Transfers execution control to the debugger.

FlushInstructionCache

Flushes the instruction cache for the specified process.

GetThreadContext

Retrieves the context of the specified thread.

GetThreadSelectorEntry

Retrieves a descriptor table entry for the specified selector and thread.

IsDebuggerPresent

Determines whether the calling process is being debugged.

OutputDebugString

Sends a string to the debugger for display.

ReadProcessMemory

Reads data from an area of memory in a specified process.

SetThreadContext

Sets the context for the specified thread.

WaitForDebugEvent

Waits for a debugging event to occur in a process being debugged.

WriteProcessMemory

Writes data to an area of memory in a specified process.

Debug Support from Process, Thread, and Exception Functions

Some functions essential to debugging are actually classified as process, thread, or exception-handling functions. For a description of how to start a process that is going to be debugged, see Process Functions. For information on how to examine and manipulate the context and execution of a thread, see Thread Functions. For a description of how a debugger should handle exceptions, see Exception Handling Functions.

Creating a Basic Debugger

Debugging a Running Process describes attaching the debugger to a running process. Writing the Debugger's Main Loop describes the functions used in the debugger's main loop of execution.

Although most of the debugging functions are used to create a debugger, several functions are designed for use in the process being debugged. For more information, see Communicating with the Debugger.

Debugging a Running Process

To debug a process that is already running, the debugger should use DebugActiveProcess with the process identifier. To retrieve a list of process identifiers, use either the EnumProcesses or Process32First function.

DebugActiveProcess attaches the debugger to the active process. In this case, only the active process can be debugged; its child processes cannot. The debugger must have appropriate access to the executing process to use DebugActiveProcess. For more information about access rights, see Access Control.

After the debugger has either created or attached itself to the process it intends to debug, the system notifies the debugger of all debugging events that occur in the process, and, if specified, in any child processes. For more information about debugging events, see Debugging Events.

To detach from the process being debugged, the debugger should use the DebugActiveProcessStop function.

Writing the Debugger's Main Loop

The debugger uses the WaitForDebugEvent function at the beginning of its main loop. This function blocks the debugger until a debugging event occurs. When the debugging event occurs, the system suspends all threads in the process being debugged and notifies the debugger of the event.

The debugger can interact with the user, or manipulate the state of the process being debugged, by using the GetThreadContext, GetThreadSelectorEntry, ReadProcessMemory, SetThreadContext, and WriteProcessMemory functions. GetThreadSelectorEntry returns the descriptor table entry for a specified selector and thread. Debuggers use the descriptor table entry to convert a segment-relative address to a linear virtual address. The ReadProcessMemory and WriteProcessMemory functions require linear virtual addresses.

Debuggers frequently read the memory of the process being debugged and write the memory that contains instructions to the instruction cache. After the instructions are written, the debugger calls the FlushInstructionCache function to execute the cached instructions.

The debugger uses the ContinueDebugEvent function at the end of its main loop. This function allows the process being debugged to continue executing.

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 system. 
                // Last chance: Display an appropriate error. 
                    break;
 
                case EXCEPTION_BREAKPOINT: 
                // First chance: Display the current 
                // instruction and register values. 
                    break;
 
                case EXCEPTION_DATATYPE_MISALIGNMENT: 
                // First chance: Pass this on to the system. 
                // Last chance: Display an appropriate error. 
                    break;
 
                case EXCEPTION_SINGLE_STEP: 
                // First chance: Update the display of the 
                // current instruction and register values. 
                    break;
 
                case DBG_CONTROL_C: 
                // First chance: Pass this on to the system. 
                // Last chance: Display an appropriate error. 
                    break;
 
                default;
                // Handle other exceptions. 
                    break;
            } 
 
        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. 
            break;
 
        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. Be sure to close the handle to the process image 
        // file with CloseHandle.
            break;
 
        case EXIT_THREAD_DEBUG_EVENT: 
        // Display the thread's exit code. 
            break;
 
        case EXIT_PROCESS_DEBUG_EVENT: 
        // Display the process's exit code. 
            break;
 
        case LOAD_DLL_DEBUG_EVENT: 
        // Read the debugging information included in the newly 
        // loaded DLL. Be sure to close the handle to the loaded DLL 
        // with CloseHandle.
            break;
 
        case UNLOAD_DLL_DEBUG_EVENT: 
        // Display a message that the DLL has been unloaded. 
            break;
 
        case OUTPUT_DEBUG_STRING_EVENT: 
        // Display the output debugging string. 
            break;
 
    } 
 
// Resume executing the thread that reported the debugging event. 
 
ContinueDebugEvent(DebugEv.dwProcessId, DebugEv.dwThreadId, dwContinueStatus); 
 
}

Communicating with the Debugger

The OutputDebugString function sends a string from the process being debugged to the debugger by generating an OUTPUT_DEBUG_STRING_EVENT debugging event. A process can detect whether it is being debugged by calling the IsDebuggerPresent function.

The DebugBreak function causes a breakpoint exception in the current process. A breakpoint is a location in a program where execution is stopped to allow the developer to examine the program's code, variables, and register values and, as necessary, to make changes, continue execution, or terminate execution.

The FatalExit function terminates the current process and gives execution control to the debugger, but unlike DebugBreak, it does not generate an exception. This function should only be used as a last resort, because it does not always free the process's memory or close its files.

Debugging Structures

The following structures are used with debugging.

CONTEXT
CREATE_PROCESS_DEBUG_INFO
CREATE_THREAD_DEBUG_INFO
DEBUG_EVENT
EXCEPTION_DEBUG_INFO
EXIT_PROCESS_DEBUG_INFO
EXIT_THREAD_DEBUG_INFO
LDT_ENTRY
LOAD_DLL_DEBUG_INFO
OUTPUT_DEBUG_STRING_INFO
RIP_INFO
UNLOAD_DLL_DEBUG_INFO

반응형