问题
I have a large, complex C# GUI application which is crashing in a completely reproducible way, but I cannot easily diagnose the cause of the crash because rather than breaking the debugger with a call stack in the usual way, the debugging session completely exits.
The only hint is that there's a message at the end of the output window: STATUS_STACK_BUFFER_OVERRUN.
I am painstakingly trying to put breakpoints in at random places before the crash happens, trying to gradually get my breakpoints closer to where the problem happens, but this approach is not getting me anywhere quickly.
I'm wondering if there are any existing tools which work sort of like an instrumenting profiler, basically observing and logging all of the function enters and exits, so that when the program crashes with a corrupted stack, it's still possible to examine this external data to determine where execution was last happening?
I don't expect that this is a feature that most performance-oriented profilers have, since they are more concerned with how many times a function was called and for how long, but perhaps there's a tool which will tell me exactly what the last known running piece of code was?
I'm open to other suggestions if there's a way to solve/diagnose this within Visual Studio or using other techniques.
回答1:
You can use a conditional breakpoint to trigger when the stack depth exceeds a certain value:
(new StackTrace()).GetFrames().Length > 60
The trick here is knowing where to put the breakpoint, as it has to be set somewhere in the recursive cycle. But if you know what triggers the error you might have enough intuition to choose some strategic places to put the check. You can also use a process of elimination: if the breakpoint isn't triggered, you know that code is not involved in the cycle.
Also note that the conditional breakpoint is costly and will significantly slow down the application being debugged. If you're not opposed to littering your code with debugging statements, you can call Debugger.Break() instead of setting breakpoints:
if (Debugger.IsAttached && (new StackTrace()).GetFrames().Length > 60)
Debugger.Break();
回答2:
STATUS_STACK_BUFFER_OVERRUN means that someone blew passed the end or beginning of their stack variables, most likely in unmanaged or interop code.
If you attach the debugger in native mode or mixed mode, go to the Exceptions window and add a Win32 exception with the code 0xc0000409 (stack overflow). If you trigger the error, it should break in the debugger.
回答3:
You can use my Runtime Flow tool to log all function calls in your application. After a crash you can see what was the last function enter.
来源:https://stackoverflow.com/questions/48428147/tools-for-tracing-a-c-sharp-crash-when-debugger-exits-with-no-call-stack