Wait Chain Traversal Debugging Extension for WinDbg

October 24, 2009

no comments

Wait Chain Traversal is a set of APIs introduced in Windows Vista that can be used to display diagnostic information about the wait chains of application threads.

A wait chain is an alternating sequence of THREAD, RESOURCE nodes where a THREAD element describes a thread that holds an instance of a resource and a RESOURCE element describes a resource that a thread waits for.

For example, the sequence T1 –> M1 –> T2 –> M2 –> T1 (where T1, T2 are threads and M1, M2 are mutex objects) describes a classic deadlock because effectively T1 is waiting for itself.

Unfortunately, there is no direct way to display this diagnostic information within the debugger. Therefore, I set forth to write a debugger extension for WinDbg, called wct.dll, that exposes wait chain information about threads and processes on the system. (Writing a debugger extension is a great deal of fun, and I strongly recommend it! :-))

Its syntax is very simple:

Wait Chain Traversal (WCT) debugging extension.
    By Sasha Goldshtein, tinyurl.com/sasha.
This debugging extension displays WCT information.
Syntax:
!wct                       Displays WCT information for the entire system.
!wct_proc [<ProcessID>]    Displays WCT information for the specified
                           process ID or for the current process.
!wct_thread [<ThreadID>]   Displays WCT information for the specified thread
                           ID or for the current thread.

Here’s some sample output from a test application that deadlocks on two mutex objects:

0:001> .load D:\Development\DebuggingExtensions\Release\wct.dll
0:001> !wct_thread
>>> Begin wait chain for thread 4784:6016 with 5 nodes
    Thread [4784:6016:blocked WT=7287568] ==>
    Mutex [\Sessions\1\BaseNamedObjects\SecondMutex] ==>
    Thread [4784:5924:blocked WT=7286947] ==>
    Mutex [\Sessions\1\BaseNamedObjects\FirstMutex] ==>
    Thread [4784:6016:blocked WT=7287568] ==>
DEADLOCK FOUND
>>> End wait chain for thread 4784:6016

In the above output, you see a wait chain for thread 6016 in process 4784. The chain begins with the thread itself which is blocked (WT stands for waiting time and indicates for how long the thread has been blocked). Next, you see the mutex (called “SecondMutex”) that the thread is trying to acquire, which is in turn owned by thread 5924 (of the same process). However, that very thread waits for another mutex (called “FirstMutex”) that is owned by thread 6016, which is right where we started—therefore, we have a deadlock.

You can download this extension from my Debugging Extensions project on CodePlex, where it is available with the source code. (Direct link to the release: x86, x64, updated to require Visual C++ 2008 runtime, see below.)

[Update 10/25: The original download links pointed to the DLL versions that might require the Visual C++ 2010 runtime. I added a Visual Studio 2008 solution to the source control and added download links to DLLs that certainly require only the Visual C++ 2008 runtime (x86, x64). Here is the full set of links: VS2010_x86, VS2010_x64, VS2008_x86, VS2008_x64. If you need a version that works with the Visual C++ 2005 runtime, feel free to compile one directly from the source.]

Add comment
facebook linkedin twitter email

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*