什么是 LogHelp_TerminateOnAssert?

What is LogHelp_TerminateOnAssert?

十年前有一个类似的 question,但没有好的答案 - 希望从那以后情况有所改变。

我有一个基于 .NET 4.72 的相当多线程的 Winforms 应用程序。我正在使用 Process Explorer Threads 视图查看它,它有很多 clr.dll!LogHelp_TerminateOnAssert+0x6835 类型调用。我已经设置了 Symbols 路径,但它并没有真正为我清除任何东西。

我通过 DebugDiag 和 WinDbg 转储了该应用程序并 运行 它,没有发现任何明显的可疑之处。

所以我的问题:

我的代码中唯一的条目是 !get_FrameReceived,该线程的堆栈如下:

循环次数最多的线程栈是这样的:

在发布版本中,所有这些断言都被编译成一个简单的 ret,类似于

ifdef ( debug ) { function body here } elseif { ret } endif

所以偏移量这么大的符号是假的

因此您可能需要加载该地址的实际符号以获得合理的调用堆栈

你可以看到clr 4.0.30319中函数的大小clr.dll只有1个字节

0:000> x /v /t clr!LogHelp_TerminateOnAssert
pub func   100115a0             0 <NoType> clr!LogHelp_TerminateOnAssert (<no parameter info>)
0:000> .fnent clr!LogHelp_TerminateOnAssert
Debugger function entry 01bad5e0 for:
(100115a0)   clr!RtlUnwindCallback   |  (100115a1)   clr!memset
Exact matches:
    clr!RtlUnwindCallback (void)
    clr!_TlgDefineProvider_annotation__Tlgg_hClrProviderProv (void)

OffStart:  000115a0
ProcSize:  0x1
Prologue:  0x0
Params:    0n0 (0x0 bytes)
Locals:    0n0 (0x0 bytes)
Registers: 0n0
0:000> u clr!LogHelp_TerminateOnAssert l1
clr!RtlUnwindCallback:
100115a0 c3              ret

大偏移量

clr.dll!LogHelp_TerminateOnAssert+0x6835

表示该方法中的实际执行距其开头 0x6835 = 26661 字节。一个方法不太可能那么大。 (正如@blabb 指出的那样,这是一个 1 字节的方法)。

通常你会看到当你没有正确设置符号时(就像在链接的原始问题中),但你已经修复了。

微软很可能只发布了 clr.dll 的 public 符号,而不是私有符号。在这种情况下,您只会看到最后一个已知的 public 方法。

起始地址

请注意该列名为“起始地址”。 Process Explorer 将显示堆栈中的第一个条目。

所以这就是一切的开始。你似乎担心这就是一切的终结。

注意:一些已知的内部方法如RtlUserThreadStartBaseThreadInitThunk在显示起始地址时将被跳过。否则他们可能看起来都一样。

线程真正做的事情在列表的顶部,即ZwRemoveIoCompletion,所以它似乎在做一些IO操作。

您的问题

Should I be concerned with the large number of LogHelp_TerminateOnAssert calls?

没有。这些只是美好事物的起点。 GetQueuedCompletionStatus() 看起来有一些 IO 正在进行,.NET 为您使用 IO 完成端口 (IOCP)。

Is the application leaking memory?

您无法通过查看调用堆栈来判断这一点。随着时间的推移,你可以通过查看内存来判断。

如果你有太多的网络 IO 正在进行并且网络跟不上它,.NET 可能在队列中有越来越多的项目,所以它可能看起来像 内存泄漏。

Does it have an excessive number of exceptions that don't filter down when I am running the app in Visual Studio?

您也不会从调用堆栈中看出这一点。如果您不信任 Visual Studio.

,您将附加一个调试器(例如 WinDbg)并检查异常(例如 sxe clr