【发布时间】:2015-06-03 21:26:16
【问题描述】:
我有一个使用 UCMA(统一通信托管 API)4.0 SDK 的托管应用程序。我正在尝试调试应用程序使用 100% 的 CPU 并且系统挂起的问题。我已经使用 SOS 扩展来尝试调试根本原因。我目前被卡住了。我设法找到了占用 CPU 时间的线程 ID,但它们大多是非托管线程。我真的需要这方面的帮助。
线程 15、18、16、17、19、20 都是非托管线程,具有相同的调用堆栈。线程 9、10、11、12、13、14 都是非托管线程,并且也具有相同的调用堆栈。另一个问题是线程 21 和 22 似乎正在等待一个事件,那么为什么它们被认为是消耗 CPU 时间的失控线程?
有人知道 ZwRemoveIoCompletionEx 在做什么吗?这是像 NtWaitForMultipleObjects 一样处于休眠状态的东西,还是会占用 CPU 时间?在此应用程序的情况下,一旦达到 100%,它就永远不会下降,直到应用程序重新启动。
0:000> !loadby sos clr
0:009> .time
Debug session time: Wed May 27 15:47:52.000 2015 (UTC - 4:00)
System Uptime: 31 days 1:05:59.329
Process Uptime: 31 days 1:01:27.000
Kernel time: 0 days 21:44:58.000
User time: 1 days 16:51:40.000
0:000> !runaway
User Mode Time
Thread Time
15:113c 0 days 3:46:30.510
18:1418 0 days 3:18:07.135
16:1404 0 days 3:08:01.009
17:140c 0 days 3:07:19.310
19:1428 0 days 3:04:56.943
20:1434 0 days 2:52:51.664
22:1450 0 days 0:47:50.153
9:11dc 0 days 0:45:02.904
21:1440 0 days 0:43:34.623
12:13cc 0 days 0:33:35.298
11:1250 0 days 0:32:50.386
14:fbc 0 days 0:31:57.018
10:1178 0 days 0:29:12.920
13:13c4 0 days 0:28:42.048
2:fa8 0 days 0:03:11.678
4:1164 0 days 0:02:45.080
0:015> kb
RetAddr : Args to Child : Call Site
000007fe`fd36546f : 00000000`272946f0 000007fe`e5394b29 00000000`27295b18 00000000`27295b18 : ntdll!ZwRemoveIoCompletionEx+0xa
00000000`7700c089 : 00000000`1c4981e0 00000000`00000001 00000000`00000001 00000000`00000000 : KERNELBASE!GetQueuedCompletionStatusEx+0xdf
000007fe`e51b634b : 00000000`000009b0 00000000`00000000 00000000`00000000 00000000`00000000 : kernel32!GetQueuedCompletionStatusExStub+0x19
000007fe`e538fc0b : 00000000`1c4981e0 00000000`1c4981e0 000007fe`e5905340 00000000`00000000 : rtmpal!RtcPalTaskQueueDequeue+0x17
000007fe`e538f960 : 00000000`1f55fcf0 00000000`00000000 00000000`1db59eb0 00000000`1f55fcf0 : Microsoft_Rtc_Internal_Media!CStreamingEngineImpl::EngineWorkerThread+0x267
000007fe`e51b33c8 : 00000000`00000000 00000000`1c40a6a0 00000000`1c4a4f80 00000000`00000000 : Microsoft_Rtc_Internal_Media!CStreamingEngineImpl::EngineWorkerThreadProc+0xf0
000007fe`f22a3d67 : 00000000`00000000 00000000`1c40a6a0 00000000`00000000 00000000`00000000 : rtmpal!RtcPalSetSchedulerPolicy+0x194
000007fe`f22a3f0e : 000007fe`f233cdb0 00000000`00000000 00000000`00000000 00000000`00000000 : msvcr110!beginthreadex+0x107
00000000`76fd652d : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : msvcr110!endthreadex+0x192
00000000`7720c541 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : kernel32!BaseThreadInitThunk+0xd
00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!RtlUserThreadStart+0x1d
0:022> !clrstack
OS Thread Id: 0x1450 (22)
Child SP IP Call Site
000000001fdcda68 000000007723186a [HelperMethodFrame_1OBJ: 000000001fdcda68] System.Threading.WaitHandle.WaitMultiple(System.Threading.WaitHandle[], Int32, Boolean, Boolean)
000000001fdcdba0 000007fee968c64c System.Threading.WaitHandle.WaitAny(System.Threading.WaitHandle[], Int32, Boolean)
000000001fdcdc00 000007fe8e097a70 Microsoft.Rtc.Internal.Media.RtpEventHandlerThread.EventHandlerThreadProc()
000000001fdce8d0 000007fee973d0b5 System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
000000001fdcea30 000007fee973ce19 System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
000000001fdcea60 000007fee973cdd7 System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
000000001fdceab0 000007fee96b0301 System.Threading.ThreadHelper.ThreadStart()
000000001fdcedc8 000007feed44ffe3 [GCFrame: 000000001fdcedc8]
000000001fdcf0f8 000007feed44ffe3 [DebuggerU2MCatchHandlerFrame: 000000001fdcf0f8]
0:021> kb
RetAddr : Args to Child : Call Site
000007fe`fd331430 : 00000000`00190398 00000000`771f3a92 00000000`c0000008 00000000`00000110 : ntdll!NtWaitForMultipleObjects+0xa
00000000`76fd1220 : 00000000`1edefc18 00000000`1edefc00 00000000`00000000 00000000`00da7a64 : KERNELBASE!WaitForMultipleObjectsEx+0xe8
000007fe`e53bc322 : 00000000`0000cae8 00816179`f67cb320 00000000`1c497eb0 00000000`1edefce0 : kernel32!WaitForMultipleObjects+0xb0
000007fe`e51b33c8 : 00000000`00000000 00000000`00000000 00000000`1dad4630 00000000`1c4a5160 : Microsoft_Rtc_Internal_Media!CStreamingEngineImpl::TimerThreadProc+0x37e
000007fe`f22a3d67 : 00000000`00000000 00000000`1dad4630 00000000`00000000 00000000`00000000 : rtmpal!RtcPalSetSchedulerPolicy+0x194
000007fe`f22a3f0e : 000007fe`f233cdb0 00000000`00000000 00000000`00000000 00000000`00000000 : msvcr110!beginthreadex+0x107
00000000`76fd652d : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : msvcr110!endthreadex+0x192
00000000`7720c541 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : kernel32!BaseThreadInitThunk+0xd
00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!RtlUserThreadStart+0x1d
0:013> kb
RetAddr : Args to Child : Call Site
000007fe`fd36546f : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!ZwRemoveIoCompletionEx+0xa
00000000`7700c089 : 00000000`00000000 00000000`000000b7 00000000`00000001 00000000`1c4a4a40 : KERNELBASE!GetQueuedCompletionStatusEx+0xdf
000007fe`e51c0fef : 000007fe`e5905340 000007fe`e53eb764 00000000`00000000 00000000`1dac2ab0 : kernel32!GetQueuedCompletionStatusExStub+0x19
000007fe`e53eaf4b : 000007fe`e5905340 00000000`35bdd608 00000000`00000001 00000000`1f17fc20 : rtmpal!RtcPalIOCP::GetQueuedCompletionStatus+0x18f
000007fe`e53eac6d : 00000000`00000510 00000000`0000dddd 00000000`1dad9fe0 00000000`1f17fc80 : Microsoft_Rtc_Internal_Media!CTransportManagerImpl::TransportWorkerThread+0xe7
000007fe`e51b33c8 : 00000000`00000000 00000000`1c409460 00000000`1c4a4e40 00000000`00000000 : Microsoft_Rtc_Internal_Media!CTransportManagerImpl::TransportWorkerThreadProc+0x13d
000007fe`f22a3d67 : 00000000`00000000 00000000`1c409460 00000000`00000000 00000000`00000000 : rtmpal!RtcPalSetSchedulerPolicy+0x194
000007fe`f22a3f0e : 000007fe`f233cdb0 00000000`00000000 00000000`00000000 00000000`00000000 : msvcr110!beginthreadex+0x107
00000000`76fd652d : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : msvcr110!endthreadex+0x192
00000000`7720c541 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : kernel32!BaseThreadInitThunk+0xd
00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!RtlUserThreadStart+0x1d
【问题讨论】:
-
那么...您的线程实际上在做什么?你的代码是做什么的?
-
使用 Windbg 是确定正在发生的事情的最佳方式。唯一的问题是它需要天才才能弄清楚,这是因为 MSFT 从来没有真正以记录良好或易于理解的方式公开内部数据结构。那里有一些很好的教程,但是,在互联网上查找 WINDBG 教程和 WINDBG 失控线程。祝你好运,我从来没有发现 WINDBG 很容易破译,而且在 50 次左右我只有大约 5 次能够弄清楚。
-
@EdS。这就是我似乎无法追踪执行的地方,因为这些是非托管线程,似乎是由 Microsoft UCMA 库分离出来的。如果我可以将它映射回我的应用程序在 Microsoft UCMA SDK 上调用的托管线程 ID,那将会很有帮助。
-
"为什么它们被认为是失控线程?"他们不是。所有活动线程都按 CPU 时间排序,由您决定“失控”的阈值是多少。请注意,(现在)等待线程的 CPU 使用率大约是主要违规者的 1/4。
-
如果你有 100% cpu,你可以考虑使用性能分析器。这会让你到达你想去的地方......
标签: c# performance debugging cpu-usage ucma