调试器在没有调用堆栈的情况下退出时跟踪C#崩溃的工具?

时间:2018-01-24 17:15:20

标签: c# visual-studio crash profiler

我有一个庞大,复杂的C#GUI应用程序,它以完全可重现的方式崩溃,但我不能轻易诊断崩溃的原因,因为不是通过调试堆栈以通常的方式打破调试器,完全调试会话退出。

唯一的提示是输出窗口末尾有一条消息:STATUS_STACK_BUFFER_OVERRUN。

我煞费苦心地试图在崩溃发生之前将断点放在随机位置,试图逐渐让我的断点更接近问题发生的地方,但这种做法并没有让我快速到达任何地方。

我想知道是否有任何现有的工具有点像仪器分析器,基本上观察和记录所有进入和退出的功能,这样当程序崩溃时,它会损坏堆栈,它就会出现问题。 ; s仍然可以检查这些外部数据以确定最后一次执行的位置吗?

我不希望这是大多数以性能为导向的分析器所具有的功能,因为他们更关心函数调用的次数和持续时间,但也许有一个工具,会告诉我最后一个已知的运行代码是什么?

如果能够在Visual Studio中使用其他技术解决/诊断此问题,我可以接受其他建议。

3 个答案:

答案 0 :(得分:1)

您可以使用conditional breakpoint来触发when the stack depth exceeds a certain value

(new StackTrace()).GetFrames().Length > 60

这里的技巧是知道断点的位置,因为它必须在递归周期的某处设置。但是如果你知道是什么引发了错误,那么你可能有足够的直觉来选择一些战略性的地方来进行检查。您还可以使用消除过程:如果没有触发断点,您就知道代码不参与循环。

另请注意,条件断点的成本很高,并且会显着降低正在调试的应用程序的速度。如果您不反对使用调试语句乱丢代码,则可以call Debugger.Break()而不是设置断点:

if (Debugger.IsAttached && (new StackTrace()).GetFrames().Length > 60)
    Debugger.Break();

答案 1 :(得分:0)

STATUS_STACK_BUFFER_OVERRUN表示有人吹过堆栈变量的结束或开始,很可能是非托管或互操作代码。

如果以纯模式或混合模式附加调试器,请转到Exceptions窗口并添加代码为0xc0000409的Win32异常(堆栈溢出)。如果触发错误,它应该在调试器中中断。

答案 2 :(得分:0)

您可以使用我的Runtime Flow工具记录应用程序中的所有函数调用。崩溃后,您可以看到最后一个函数输入的内容。