locked
Threads and Tasks hierarchy RRS feed

  • Question

  • Hey guys,

    I am trying to find a way of getting the thread hierarchy from thread's information (or any other information) inside a debugger.

    Let's say I have the main thread and then I create a new thread, start it and join it in the main thread. Where should I look in order to see the parent-child relation between the main and the second thread? Callstack may be a place... but I don't think there's enough information on there to get this kind of relationship between threads.

    Is there any info on that? - Same questions for tasks (TPL)

    Thanks


    Eusebiu
    Saturday, November 20, 2010 9:51 PM

All replies

  • Hey, I've been looking into debugging interfaces and I noticed the ICorDebugChain interface which has some interesting methods like GetCaller and GetReason. In my example I provided (a main thread creates, starts and joins with a second thread), the caller for each ICorDebugChain is NULL and the CorDebugChainReason is CHAIN_NONE. I'd expect that the caller for the second thread stack not to be null and the reason should be CHAIN_THREAD_START. Am I missing something? Thanks
    Eusebiu
    Sunday, November 21, 2010 11:42 AM
  • Hey,

    I've played a little with WinDbg and see how the stack trace looks in this scenario...

    public static void Main(string[] args)
    {
    	Console.WriteLine("Hello World!");
    	Thread t = new Thread(new ThreadStart(MyMethod));
    	t.Start();
    	t.Join();
    	Console.Write("Press any key to continue . . . ");
    	Console.ReadKey(true);
    }
    		
    public static void MyMethod()
    {
    	Console.WriteLine("enter");
    	Console.ReadLine();
    	Console.WriteLine("exit");
    }

    The child thread stack:

     

    ChildEBP RetAddr Caller, Callee
    0315f514 7c90daea ntdll!ZwRequestWaitReplyPort+0xc
    ...
    
    0315f830 7a0ac292 (MethodDesc 799084ec +0x12 System.Console.ReadLine())
    0315f838 03030143 (MethodDesc 009c37fc +0x23 testc.Program.MyMethod()), calling (MethodDesc 799084ec +0 System.Console.ReadLine())
    0315f840 79b2ae5b (MethodDesc 7996e4d4 +0x63 System.Threading.ThreadHelper.ThreadStart_Context(System.Object))
    0315f850 79ab7ff4 (MethodDesc 798f75e8 +0xb0 System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean))
    0315f86c 79ab7f34 (MethodDesc 798f75dc +0x2c System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)), calling (MethodDesc 798f75e8 +0 System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean))
    0315f88c 79b2ade8 (MethodDesc 798e86c0 +0x44 System.Threading.ThreadHelper.ThreadStart()), calling (MethodDesc 798f75dc +0 System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object))
    0315f8a4 791421db clr!CallDescrWorker+0x33
    ...
    0315fe94 791f5a08 clr!Thread::intermediateThreadProc+0x4b
    0315ffa0 791f59f6 clr!Thread::intermediateThreadProc+0x39, calling clr!_alloca_probe_16
    <strong>0315ffb4 7c80b729 KERNEL32!BaseThreadStart+0x37</strong>
    
    The parent thread:

     

     

    0:000> !dumpstack
    OS Thread Id: 0x16e0 (0)
    Current frame: ntdll!KiFastSystemCallRet
    ChildEBP RetAddr Caller, Callee
    <strong>0012f06c 7c90df4a ntdll!ZwWaitForMultipleObjects+0xc</strong>
    0012f070 7c809590 KERNEL32!WaitForMultipleObjectsEx+0x12c, calling ntdll!NtWaitForMultipleObjects
    ...
    
    0012f3b0 79161f8e clr!PreStubWorker+0x165, calling clr!_EH_epilog3
    0012f3ec 7a053eb5 (MethodDesc 79885160 +0x5 System.Threading.Thread.Join()), calling clr!ThreadNative::Join
    0012f3f0 030300ee (MethodDesc 009c37f0 +0x7e testc.Program.Main(System.String[])), calling (MethodDesc 79885160 +0 System.Threading.Thread.Join())
    0012f414 791421db clr!CallDescrWorker+0x33
    ...
    0012fec4 7922d199 clr!ExecuteEXE+0x58, calling clr!SystemDomain::ExecuteMainMethod
    0012ff18 7922d09a clr!_CorExeMainInternal+0x19f, calling clr!ExecuteEXE
    ...
    0012ffb8 79004de3 mscoree!_CorExeMain_Exported+0x8, calling mscoree!ShellShim__CorExeMain
    0012ffc0 7c817077 KERNEL32!BaseProcessStart+0x23
    

    What's the connection between the first frame in the child stack (0315ffb4 7c80b729 KERNEL32!BaseThreadStart+0x37) and the last element of the parent stack (0012f06c 7c90df4a ntdll!ZwWaitForMultipleObjects+0xc)?

    How can I connect the addresses?

    Thanks

     


    Eusebiu
    Monday, November 22, 2010 10:11 AM