繁体   English   中英

为什么某些本机线程在我的代码中没有源的堆栈跟踪?

[英]Why do some native threads have a stack trace without an origin in my code?

我有一个大量使用Task Parallel Library的C#.NET 4.5应用程序,经过几天的操作,最终最终该线程被饿死了。

当我从AdPlus抓取HANG转储并通过Visual Studio查看线程时,在代码中看到43个线程没有明显的起源:

ntdll.dll!_NtWaitForSingleObject@12()  + 0x15 bytes 
ntdll.dll!_NtWaitForSingleObject@12()  + 0x15 bytes 
kernel32.dll!@BaseThreadInitThunk@12()  + 0x12 bytes    
ntdll.dll!___RtlUserThreadStart@8()  + 0x27 bytes   
ntdll.dll!__RtlUserThreadStart@8()  + 0x1b bytes    

为什么这些线程在其堆栈跟踪中没有显示托管来源?

给定进程中的所有线程,甚至TPL线程都具有此启动过程。 当您启动运行线程时,最终CLR会调用操作系统来启动线程。 您正在查看的是线程在启动时执行的功能。 如果暂停任何托管进程,您会看到在堆栈底部有非托管调用。 您看不到托管启动过程的原因是,每个线程都有自己的堆栈,由操作系统在创建线程时创建。

例如,运行以下命令:

for (int i = 0; i < 10; i++)
{
    Thread t = new Thread(new ThreadStart(()=>Thread.Sleep(100000)));
    t.Start();
}
Console.ReadKey();

然后使用WinDbg进入该过程,并查看其中一个睡眠线程,给出一个如下所示的调用堆栈(所有线程的底部都具有相同的两个功能,在此练习中我只是转储一个。) :

0:012> !dumpstack
OS Thread Id: 0x3694 (12)
Current frame: ntdll!ZwDelayExecution+0xa
Child-SP         RetAddr          Caller, Callee
000000001dc8ea70 000007fefd1c1203 KERNELBASE!SleepEx+0xab, calling ntdll!NtDelayExecution
000000001dc8eae0 000007fefd1c38fb KERNELBASE!SleepEx+0x12d, calling ntdll!RtlActivateActivationContextUnsafeFast
000000001dc8eb10 000007fed860a888 clr!CExecutionEngine::ClrSleepEx+0x29, calling KERNEL32!SleepExStub
000000001dc8eb40 000007fed874d483 clr!Thread::UserSleep+0x7c, calling clr!ClrSleepEx
000000001dc8eba0 000007fed874d597 clr!ThreadNative::Sleep+0xb7, calling clr!Thread::UserSleep
[... removed some frames for clarity ...]
000000001dc8f6f0 000007fed874fcb6 clr!Thread::intermediateThreadProc+0x7d
000000001dc8faf0 000007fed874fc9f clr!Thread::intermediateThreadProc+0x66, calling clr!alloca_probe
000000001dc8fb30 0000000077195a4d KERNEL32!BaseThreadInitThunk+0xd
000000001dc8fb60 00000000773cb831 ntdll!RtlUserThreadStart+0x1d

作为参考,这是Thread对象,其中包装了我们转储了以下堆栈的线程:

0:012> !do 2a23e08
Name:        System.Threading.Thread
MethodTable: 000007fed76522f8
EEClass:     000007fed7038200
Size:        96(0x60) bytes
File:        C:\Windows\Microsoft.Net\assembly\GAC_64\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll
Fields:
              MT    Field   Offset                 Type VT     Attr            Value Name
000007fed763eca8  4000765        8 ....Contexts.Context  0 instance 0000000000000000 m_Context
000007fed765a958  4000766       10 ....ExecutionContext  0 instance 0000000000000000 m_ExecutionContext
000007fed7650e08  4000767       18        System.String  0 instance 0000000000000000 m_Name
000007fed76534a8  4000768       20      System.Delegate  0 instance 0000000000000000 m_Delegate
000007fed7655390  4000769       28 ...ation.CultureInfo  0 instance 0000000000000000 m_CurrentCulture
000007fed7655390  400076a       30 ...ation.CultureInfo  0 instance 0000000000000000 m_CurrentUICulture
000007fed76513e8  400076b       38        System.Object  0 instance 0000000000000000 m_ThreadStartArg
000007fed7654a00  400076c       40        System.IntPtr  1 instance          24a5ed0 DONT_USE_InternalThread
000007fed7653980  400076d       48         System.Int32  1 instance                2 m_Priority
000007fed7653980  400076e       4c         System.Int32  1 instance               12 m_ManagedThreadId
000007fed7658c48  400076f       50       System.Boolean  1 instance                1 m_ExecutionContextBelongsToOuterScope
000007fed7672e70  4000770      378 ...LocalDataStoreMgr  0   shared           static s_LocalDataStoreMgr
                                 >> Domain:Value  00000000005f40b0:NotInit  <<
000007fed7672df0  4000771        8 ...alDataStoreHolder  0   shared         TLstatic s_LocalDataStore
                                  >> Thread:Value <<

System.IntPtr brillantly命名DONT_USE_InternalThread持有的指针OS线程。 (我的猜测是它可能是CreateThread的句柄,但我没有对此进行过多调查。)


(编者注: brillant的拼写是故意拼写的。请不要“修复”它)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM