Quick tips: How to easily identify a thread in a thread object

Hello,

It´s been a while since my last post.

I´ve decided to start a new topic regarding debugging posts. It´s called quick tips debugging code and here is my first post on the series.

Sometimes while debugging an issue I have to related different threads. (E.g: on a thread there is a reference to another thread object).

So the question is: how to easily identify a thread in a thread object ?

Below is the result of issuing !do on a thread object ( my sample is based on clr2.0)

0:777> !do 00000000c0559e38

Name: System.Threading.Thread

MethodTable: 00000642788c2360

EEClass: 00000642788c21c0

Size: 104(0x68) bytes

GC Generation: 2

(C:\WINDOWS\assembly\GAC_64\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll)

Fields:

              MT Field Offset Type VT Attr Value Name

00000642788e1428 4000685 8 ....Contexts.Context 0 instance 00000000cfff6a68 m_Context

00000642788cfa38 4000686 10 ....ExecutionContext 0 instance 0000000000000000 m_ExecutionContext

00000642788c1ad0 4000687 18 System.String 0 instance 0000000000000000 m_Name

00000642788c35f0 4000688 20 System.Delegate 0 instance 0000000000000000 m_Delegate

0000064278915788 4000689 28 System.Object[][] 0 instance 000000015001a888 m_ThreadStaticsBuckets

0000064278909f18 400068a 30 System.Int32[] 0 instance 000000015001a9d0 m_ThreadStaticsBits

00000642788cb5f0 400068b 38 ...ation.CultureInfo 0 instance 0000000000000000 m_CurrentCulture

00000642788cb5f0 400068c 40 ...ation.CultureInfo 0 instance 0000000000000000 m_CurrentUICulture

00000642788c0cd8 400068d 48 System.Object 0 instance 0000000000000000 m_ThreadStartArg

00000642788c9618 400068e 50 System.IntPtr 1 instance 793781312 DONT_USE_InternalThread

00000642788ca770 400068f 58 System.Int32 1 instance 2 m_Priority

00000642788ca770 4000690 5c System.Int32 1 instance 741 m_ManagedThreadId

00000642788e1708 4000691 2d0 ...LocalDataStoreMgr 0 shared static s_LocalDataStoreMgr

                                 >> Domain:Value 000000000018d100:0000000140003108 000000003cb6dd50:0000000160039a18 000000003d34c6d0:00000001502d7a60 <<

00000642788c0cd8 4000692 2d8 System.Object 0 shared static s_SyncObject

                                 >> Domain:Value 000000000018d100:00000000cfff2d40 000000003cb6dd50:00000000900eefb0 000000003d34c6d0:00000001402e0e50 <<

You can see there is a System.IntPtr by the name DON’T_USE_InternalThread.

Lets convert its value to hex

0:777> ?0n793781312

Evaluate expression: 793781312 = 00000000`2f502440

Now it´s only necessary to do a match between this hex value and the object from !threads output.

752 ea 3a60 000000002efeda40 220 Enabled 0000000000000000:0000000000000000 000000000018d100 0 Ukn

753 2e3 2618 000000002ef3bcd0 220 Enabled 0000000000000000:0000000000000000 000000000018d100 0 Ukn

XXXX 2e4 0 000000006912de70 9820 Enabled 0000000000000000:0000000000000000 000000000018d100 0 Ukn

XXXX 2e5 0 000000002f502440 9820 Enabled 0000000000000000:0000000000000000 000000000018d100 0 Ukn

XXXX 2e6 0 000000002ea9a080 9820 Enabled 0000000000000000:0000000000000000 000000000018d100 0 Ukn

In my case, it was a thread that had already died. Otherwise you would then proceed to look at thread number (first column)

Till next time

Bruno