分析windbg中的!threadpool和!threads的输出

Joh*_*hnW 13 multithreading windbg threadpool

我在四台服务器上生成了转储,并正在分析!threadpool和!threads的输出.我注意到大致一致的输出:

0:024> !threadpool
CPU utilization 0%
Worker Thread: Total: 2 Running: 0 Idle: 2 MaxLimit: 200 MinLimit: 2
Work Request in Queue: 0
Number of Timers: 27
Completion Port Thread:Total: 2 Free: 0 MaxFree: 4 CurrentLimit: 2 MaxLimit: 200 MinLimit: 2

!threads -special ThreadCount: 32 UnstartedThread: 0 BackgroundThread: 19 PendingThread: 0 DeadThread: 13 Hosted Runtime: no

我的问题是:
1)我怎样才能确定这27个计时器的来源是什么?
2)13个死线是什么意思?
3)我的一个线程被标记为有锁.如果我切换到该线程并运行!clrstack,我会看到以下内容 - 它与我的计时器有关吗?


0:027> !clrstack
OS Thread Id: 0x14cc (27)
*** WARNING: Unable to verify checksum for System.ni.dll
Child-SP         RetAddr          Call Site
000000000ca6e1a0 000007fef5c06477 System.Threading.WaitHandle.WaitAny(System.Threading.WaitHandle[], Int32, Boolean)
000000000ca6e200 000007fef673175b System.Net.TimerThread.ThreadProc()
000000000ca6e2d0 000007fef67c95fd System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
000000000ca6e320 000007fef84d1552 System.Threading.ThreadHelper.ThreadStart()

Ric*_*lay 16

1)如何确定这27个定时器的来源是什么?

尝试查找TimerCallback(for Threading.Timer)的实例:

!dumpheap -type TimerCallback
Run Code Online (Sandbox Code Playgroud)

然后转储回调属性(其中回调地址是dumpheap输出中的"Address"):

!do <callback address>
Run Code Online (Sandbox Code Playgroud)

然后转储属性的Value地址_target:

!do <_target address>
Run Code Online (Sandbox Code Playgroud)

那应该吐出一个持有TimerCallback引用的对象,它应该引导你到创建定时器的地方.

如果您还没有,我建议您查看Tess Ferrandez的调试实验室.

2)13个死线是什么意思?

我的理解是死线程指的是一个C++线程,它不再具有活动的OS线程,但仍然具有引用,因此无法销毁(C++线程使用引用计数).

AC#thread保存对C++线程的引用,如果您的托管代码保留对C#线程的引用,那么这可能是您的问题.

关于Yun Jin博客的这篇文章可能对你有些兴趣.

3)我的一个线程被标记为有锁.如果我切换到该线程并运行!clrstack,我会看到以下内容 - 它与我的计时器有关吗?

这看起来像一个(System.Threading)计时器线程等待其间隔过去.