Now that you know which thread you want to examine, you can load the dump file in Windows Debugger (WinDbg). Go to the desired thread by typing
~<threadnumber>s
(e.g., ~7s). Then, type
kb
to get the stack trace for that thread. You should see a dump similar to the one at the bottom of Figure 5. (Note that an overlying window shows source code for the section of code being executed in the thread. The code showed up because I copied debug.pdbi.e., the debug symbolsto the same directory as debug.dll. You might not see such a window.) At the top of the stack, you can see a call to debug.dll, so you can conclude that this DLL is using all the CPU time. If debug.dll were a real application running on your system, you could now ask the developer to review the code for problems.
Troubleshooting Without a Log
If you don't have a Performance Monitor log, you can simply look at what all the threads in the inetinfo.exe dump file are doing (the command to dump the stacks for all threads is ~*kb) to determine which thread is the culprit. Remember that most threads will be waiting for another process or for data; you can eliminate those threads immediately. One of the following synchronization calls on the top frame of a thread's stack indicates a thread that you can ignore:
- NtRemoveIoCompletion
- Sleep
- SleepEx
- WaitForCriticalSection
- WaitForMultipleObjects
- WaitForSingleObject
- ZwRplyWaitReceivePort
- ZwUserGetMessage
(This list isn't all-inclusive; other calls also can indicate no CPU utilization.) Another thing to remember is that the top frame of the stack for thread 0 in inetinfo.exe always reports the Zw-ReadFile state. However, thread 0 (and this statement applies only to thread 0) in the ZwReadFile state isn't really doing any work. You can assume that it isn't using any CPU cycles.
When you examine dump files that you've captured during a time of high CPU utilization, you can fairly easily see which process or processes are using all the processor time. Eliminate all the threads that are in one of the states listed above, then look at the threads that are left. If you don't have the Performance Monitor log to accompany the dump, you must do some guesswork, but you can almost always narrow the list of threads until you find the ones that are actually utilizing the CPU.