Just-In-Time Debugging

[Previous] [Next]

The ability to connect a debugger to any process at any time is called just-in-time debugging. Here's a little more information about how this works: when you click on the Cancel button, you're telling the UnhandledExceptionFilter function that you want to debug the process.

Internally, UnhandledExceptionFilter invokes the debugger by looking into the following registry subkey:

 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug 

Inside this subkey, there is a data value named Debugger, which is typically set to the following value when you install Visual Studio:

 "C:\Program Files\Microsoft Visual Studio\Common\MSDev98\Bin\msdev.exe" -p %ld -e %ld 

Windows 98
In Windows 98, these values are not stored in the registry—they are stored in the Win.ini file.

This line tells the system which program (MSDev.exe) to run as the debugger. Of course, you can change this to the debugger of your choice. UnhandledExceptionFilter also passes two parameters on the command line to the debugger. The first parameter is the ID of the process that is to be debugged. The second parameter identifies an inheritable manual-reset event that was created in the nonsignaled state by the UnhandledExceptionFilter function. Vendors must implement their debuggers so that they recognize the -p and -e switches as identifying the process ID and the event handle.

After the process ID and event handle are merged into the string, UnhandledExceptionFilter executes the debugger by calling CreateProcess. At this point, the debugger process starts running and checks its command-line arguments. If the -p switch exists, the debugger grabs the process ID and attaches itself to the process by calling DebugActiveProcess:

 BOOL DebugActiveProcess(DWORD dwProcessID); 

Once the debugger attaches itself, the operating system informs the debugger of the debuggee's state. For example, the system will tell the debugger how many threads are in the debuggee and which DLLs are loaded in the debuggee's address space. It takes time for the debugger to accumulate all of this data as it prepares to debug the process. While all of this preparation is going on, the thread inside UnhandledExceptionFilter must wait. It does this by calling WaitForSingleObject, passing the handle of the manual-reset event that it had created. You'll recall that this event was created in the nonsignaled state, and therefore, the debuggee's thread is immediately suspended waiting for the event.

After the debugger has fully initialized, it again checks its command line looking for the -e switch. If this switch exists, the debugger gets the handle of the event and calls SetEvent. The debugger can use the event's handle value directly because the event's handle was created inheritable and because the debuggee's call to the UnhandledExceptionFilter function spawned the debugger process as a child process.

Setting the event causes the debuggee's thread to wake up. The thread communicates the information about the unhandled exception to the debugger. The debugger receives this notification and loads the proper source code file, positioning itself at the instruction that raised the exception. Wow, this is all very cool!

By the way, you don't have to wait for an exception before you can debug a process. You can always connect a debugger to any process at any time by running "MSDEV -p PID" where PID is the ID of the process you want to debug. In fact, the Windows 2000 Task Manager makes this easy for you. When viewing the Process tab, you can select a process, click the right mouse button, and choose the Debug menu option. This causes the Task Manager to look at the same registry subkey we just discussed and call CreateProcess, passing the ID of the selected process. In this case, the Task Manager passes 0 for the event handle.



Programming Applications for Microsoft Windows
Programming Applications for Microsoft Windows (Microsoft Programming Series)
ISBN: 1572319968
EAN: 2147483647
Year: 1999
Pages: 193

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net