none
Native vs Managed Threads

    Question

  • Hi,

     

    what is the difference between managed and native thread? Aren't they both threads in terms of OS object?

     

    When I run ~ I get this:

     

    0:000> ~
    .  0  Id: 540.e9c Suspend: -1 Teb: 7ffae000 Unfrozen

    When I run !Threads I get this:

     

    0:000> !Threads
    ThreadCount: 5
    UnstartedThread: 0
    BackgroundThread: 5
    PendingThread: 0
    DeadThread: 0
    Hosted Runtime: yes
                                          PreEmptive   GC Alloc           Lock
           ID OSID ThreadOBJ    State     GC       Context       Domain   Count APT Exception
    XXXX    1  184 000dcad0   1808220 Disabled 00000000:00000000 00102b68     1 Ukn (Threadpool Worker) System.StackOverflowException (0260106c)
    XXXX    2  bf4 000e8918      b220 Enabled  00000000:00000000 000d9ec8     0 Ukn (Finalizer)
    XXXX    3  c3c 000ed090      1220 Enabled  00000000:00000000 000d9ec8     0 Ukn
    XXXX    4  180 000ff450    80a220 Enabled  00000000:00000000 000d9ec8     0 Ukn (Threadpool Completion Port)
    XXXX    5  cac 00159998   880a220 Enabled  00000000:00000000 000d9ec8     0 Ukn (Threadpool Completion Port)

     

    When I run !ClrStack it says that I it is not a managed thread, although I have 5 managed threads listed above:

     

    0:000> !ClrStack
    OS Thread Id: 0xe9c (0)
    Unable to walk the managed stack. The current thread is likely not a
    managed thread. You can run !threads to get a list of managed threads in
    the process

     

    I want to change the current thread, but the ~n command does not work for me. It only sees the native thread I guess. How can I switch to the context of one of the managed threads and dump their stack?

     

    Thanks,

    Martin Kulov

    www.kulov.net

    Monday, November 26, 2007 10:42 PM

Answers

  • In .NET a managed thread is assumed to be a logical thread running within the parent process.  Today a managed thread maps to a native thread (in the default host) but MS has warned that this is an implementation detail that can be changed in the future.  In fact I believe the host actually determines how they are implemented.  I've heard, but can't confirm, that SQL uses fibers for managed threads.  Therefore you should not make the assumption that a managed thread is backed by a native thread as it might not be the case in the future. 

     

    I'm not a WinDbg expert but I believe ~N works for managed threads as well.  I believe your problem with ClrStack is the fact that you're not sitting on a managed thread right now.  Use ~N to switch to the managed thread of choice and then use ClrStack to get the stack.  In your case ~1 would switch to the first thread and then ClrStack would give you what remains of the stack.  Of course since you have an exception you can also just use !printexception to dump the exception information rather than trolling through the stack.  It might prove to be more useful.

     

    Michael Taylor - 11/27/07

    http://p3net.mvps.org

     

     

    Tuesday, November 27, 2007 1:59 PM
    Moderator

All replies

  • In .NET a managed thread is assumed to be a logical thread running within the parent process.  Today a managed thread maps to a native thread (in the default host) but MS has warned that this is an implementation detail that can be changed in the future.  In fact I believe the host actually determines how they are implemented.  I've heard, but can't confirm, that SQL uses fibers for managed threads.  Therefore you should not make the assumption that a managed thread is backed by a native thread as it might not be the case in the future. 

     

    I'm not a WinDbg expert but I believe ~N works for managed threads as well.  I believe your problem with ClrStack is the fact that you're not sitting on a managed thread right now.  Use ~N to switch to the managed thread of choice and then use ClrStack to get the stack.  In your case ~1 would switch to the first thread and then ClrStack would give you what remains of the stack.  Of course since you have an exception you can also just use !printexception to dump the exception information rather than trolling through the stack.  It might prove to be more useful.

     

    Michael Taylor - 11/27/07

    http://p3net.mvps.org

     

     

    Tuesday, November 27, 2007 1:59 PM
    Moderator
  • Hi Martin,
    Believe it or not I face the very same problem.
    our problem is that at that point all managed threads are killed.  (The threads with an ID of XXXX have ended and are waiting to be recycled - full article: http://blogs.msdn.com/johan/archive/2007/11/13/getting-started-with-windbg-part-i.aspx).

    Actually you are performing the "!clrstack" in the current thread of WinDbg, which is not the managed thread you need.
    To get actual results you need to go into the Managed thred with the ~[Numb]s command where [Numb] is the ID of the managed thread, but all managed threads have ended, so ... dead end ;-/

    Sorry, we both need some other approach to the provlem. The StackOverFlow is very ungly ;(

    cheers,
    Anton
    Tuesday, November 27, 2007 2:26 PM