Correlating between .NET and native thread in Windbg

I recently saw a stackoverflow question where  someone wanted to know how they could correlate between  managed and native threads within Windbg.

Here is the managed thread object within the debugger

0:004> !do 02a1d6c4
Name:        System.Threading.Thread
MethodTable: 672e001c
EEClass:     67018ed8
Size:        48(0x30) bytes
File:        C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll
MT    Field   Offset                 Type VT     Attr    Value Name
672c8a78  4000720        4 ….Contexts.Context  0 instance 00000000 m_Context
672db4b8  4000721        8 ….ExecutionContext  0 instance 00000000 m_ExecutionContext
672df9fc  4000722        c        System.String  0 instance 02a1a220 m_Name
672dfed0  4000723       10      System.Delegate  0 instance 00000000 m_Delegate
672e63f4  4000724       14 …ation.CultureInfo  0 instance 00000000 m_CurrentCulture
672e63f4  4000725       18 …ation.CultureInfo  0 instance 00000000 m_CurrentUICulture
672df638  4000726       1c        System.Object  0 instance 00000000 m_ThreadStartArg
672daa7c  4000727       20        System.IntPtr  1 instance   542560 DONT_USE_InternalThread
672e29c8  4000728       24         System.Int32  1 instance        2 m_Priority
672e29c8  4000729       28         System.Int32  1 instance        3 m_ManagedThreadId
672cb76c  400072a      18c …LocalDataStoreMgr  0   shared   static s_LocalDataStoreMgr
>> Domain:Value  0049f148:NotInit  <<
672ce328  400072b        c …alDataStoreHolder  0   shared TLstatic s_LocalDataStore
>> Thread:Value <<

The present thread’s @$teb (Thread Environment Block) is 7efac000

0:004> ? @$teb Evaluate expression: 2130374656 = 7efac000

The DONT_USE_InternalThread is pointer to the native thread. Dumping the raw memory of the pointer should give us more information we are looking for.

0:004> dd poi(02a1d6c4+20)
00542560  67e9ee88 0000b220 00000000 056ef42c
00542570  00000000 00000000 00000000 00000003
00542580  00000000 00542588 00542588 00542588
00542590  00000000 00000000 baad0000 004a4f30
005425a0  7efac000 baadf00d 00000000 00000000
005425b0  00024dac 00000000 00000000 00000000
005425c0  00000000 baadf00d 00541ba0 00544290
005425d0  00544298 00000200 00544290 00544580

The pointer to teb is in the 40th offset of the  DONT_USE_InternalThread and here is the script that would get teb for each managed thread.

.foreach ($thread {!dumpheap -mt 672e001c -short}) { .if ( poi(${$thread}+20) != 0) {.printf "%p \n",dwo(poi(${$thread}+20)+40)}}

0:004> .foreach ($thread {!dumpheap -mt 672e001c -short}) { .if ( poi(${$thread}+20) != 0) {.printf “%p \n”,dwo(poi(${$thread}+20)+40) }}

So with the above we could dump the teb structure using dt ntdll!_TEB command. In the next post I will demonstrate how this can be used to debug some cool stuff :)

3 thoughts on “Correlating between .NET and native thread in Windbg

  1. You can do even more things with DONT_USE_InternalThread. I did write a (very fast) tracing library that is able to trace the exception object when a method is left with an exception without any try/catch blocks.

    Only a using block is required:
    void DoMethod(…)
    using(Tracer t = new Tracer(myType,”DoMethod”)

    t.Info(“Got there”);
    throw new Exception(…)

    When you set the environment variable to
    set _Trace=file c:\temp\exceptions.txt; * Exception

    You enable first time exception tracing for all methods that are instrumented like this and write the exceptions into the configured file.

    Alois Kraus

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s