我有一个大型的、复杂的C#图形用户界面应用程序,它以一种完全可重复的方式崩溃,但我不能轻松地诊断出崩溃的原因,因为调试会话完全退出,而不是以通常的方式使用调用堆栈中断调试器。
唯一的提示是在输出窗口的末尾有一条消息: STATUS_STACK_BUFFER_OVERRUN。
我正在努力地在崩溃发生之前将断点放在随机的位置,试图逐渐使断点更接近问题发生的位置,但这种方法并不能让我很快到达任何地方。
我想知道是否有任何现有的工具,其工作方式类似于探测分析器,基本上观察和记录所有函数的进入和退出,以便当程序崩溃时,与损坏的堆栈,它仍然可以检查这些外部数据,以确定最后一次执行发生在哪里?
我不期望这是大多数面向性能的分析器所具有的功能,因为他们更关心函数被调用了多少次以及调用了多长时间,但也许有一种工具可以准确地告诉我最后一段已知的运行代码是什么?
如果有办法在Visual Studio中或使用其他技术解决/诊断此问题,我对其他建议持开放态度。
发布于 2018-01-25 01:33:18
您可以使用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();发布于 2018-01-25 04:03:39
STATUS_STACK_BUFFER_OVERRUN意味着有人忽略了堆栈变量的结尾或开头,很可能是在非托管或互操作代码中。
如果以本机模式或混合模式附加调试器,请转到“异常”窗口并添加代码为0xc0000409 (堆栈溢出)的Win32异常。如果触发了该错误,它将在调试器中中断。
发布于 2018-01-25 12:45:57
您可以使用我的Runtime Flow工具来记录应用程序中的所有函数调用。崩溃后,您可以看到最后输入的函数是什么。
https://stackoverflow.com/questions/48428147
复制相似问题