Search code examples
c#.netclrwindbgdebugdiag

What is LogHelp_TerminateOnAssert?


There is a similar question from a decade ago, but there was no good answer - hopefully things have changed since then.

I have a fairly multithreaded Winforms app based on .NET 4.72. I am looking at it with Process Explorer Threads view and it has a lot of clr.dll!LogHelp_TerminateOnAssert+0x6835 type calls. I've setup the Symbols path but it didn't really clear anything up for me.

I took a dump of the application and ran it through DebugDiag and WinDbg and didn't see anything suspicious that stood out.

So my questions:

  • Should I be concerned with the large number of LogHelp_TerminateOnAssert calls?
  • Is the application leaking memory?
  • Does it have an excessive number of exceptions that don't filter down when I am running the app in Visual Studio?

enter image description here

The only entry from my code here is !get_FrameReceived and the stack for that thread is as follows:

enter image description here

The stack for the thread with the most cycles is like this:

enter image description here


Solution

  • Large offsets

    clr.dll!LogHelp_TerminateOnAssert+0x6835
    

    means that the actual execution in that method is 0x6835 = 26661 bytes away from its beginning. It's unlikely that a method is that big. (As @blabb points out, it's a 1 byte method).

    Usually you see that when you have not set up the symbols correctly (like in the linked original question), but you have that fixed.

    Chances are that Microsoft has only release the public symbols of clr.dll and not the private ones. In that case, you'll only see the last known public method.

    Start address

    Please note that the column is named "Start address". Process Explorer will show the first entry on the stack.

    So this is where everything starts. You seem to be concerned that this is where everything ends.

    Note: some known internal methods like RtlUserThreadStart and BaseThreadInitThunk will be skipped when displaying the start address. Otherwise they'd probably all look the same.

    What the thread is really doing is on the top of the list, i.e. ZwRemoveIoCompletion, so it seems to do some IO operation.

    Your questions

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

    No. These are just the starting point for something good. The GetQueuedCompletionStatus() looks like there's some IO going on and .NET uses IO Completion Ports (IOCP) for you.

    Is the application leaking memory?

    You don't tell that from a look at call stacks. You tell that by looking at the memory over time.

    If you have too much network IO going on and the network can't keep up with it, .NET may have more and more items in the queue, so it may look like a memory leak.

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

    You would also not tell that from the call stack. You would attach a debugger (e.g. WinDbg) and check for exceptions (like sxe clr), if you don't trust Visual Studio.