我们正在开发的应用程序遇到问题。应用程序在启动时崩溃的情况很少见,比如一百次。当崩溃发生时,整个系统都会崩溃,计算机开始发出蜂鸣声并完全死机,恢复的唯一方法是关闭电源(我们使用的是Windows XP)。崩溃的罕见性加上我们无法闯入调试器甚至在崩溃发生时生成堆栈转储的事实使得调试变得极其困难。
我正在寻找将所有函数调用记录到文件中的东西。存在这样的工具吗?这应该不是不可能实现的,像 VTune 这样的分析器所做的事情非常相似。
我们使用的是 Visual Studio 2008 (C++)。
谢谢
A.B.
记录函数入口/出口是解决问题的低级方法。我建议使用自动调试器检测(使用 regedit 的图像文件执行选项下的调试器键或使用我在下面提供的链接的包中的 gflags)并尝试重现问题,直到它崩溃。此外,您可以使用脚本获取可疑模块的调试器日志函数调用历史记录或收集任何其他信息。
但不知道您的应用程序的详细信息,很难提出解决方案。它是用户应用程序、服务还是驱动程序? “启动时崩溃”是什么意思 - 在 Windows 启动或应用程序启动时?
使用此调试器包进行故障排除。
对于 Visual C++ _penter() 和 _pexit() 可用于检测您的代码。
另请参阅 C++ 中的方法调用拦截。
您是否考虑过使用第二台机器作为远程调试器(通过网络)?当应用程序(和系统)崩溃时,第二台机器仍然应该显示一些有用的信息,即使不是问题的实际点。我相信 VC++ 具有这种能力,至少在某些版本中是这样。
日志记录思想的唯一问题是,当系统崩溃时,最新的日志条目可能仍在缓存中,没有机会写入磁盘......
如果是我,我会尝试在另一台电脑上运行该程序 - 可能是不稳定的硬件或驱动程序导致了问题。应用程序“不应该”能够使系统瘫痪。
一些想法-
很有可能在崩溃之前应用程序中出现某种异常。如果您使用 SetUnhandledExceptionFilter() 设置所有未处理异常的处理程序并将堆栈跟踪写入日志文件,您可能有机会捕获正在发生的崩溃。
请记住每次写入后刷新文件。
另一种选择是使用诸如 strace 之类的工具,它将所有系统调用记录到内核中(有多种风格和实现,因此请选择你最喜欢的)。如果您查看崩溃前的日志,您可能会找到罪魁祸首
GCC(包括用于 Windows 开发的版本 MingGW)有一个名为 -finstrument-functions 的代码生成开关,它告诉编译器在每个函数调用周围发出对名为 __cyg_profile_func_enter 和 __cyg_profile_func_exit 的函数的特殊调用。 对于 Visual C++,有类似的选项,称为 /GH 和 /Gh。 这些会导致编译器在函数调用周围发出对 __penter 和 __pexit 的调用。
这些检测模式可用于实现日志系统,您可以实现编译器生成的调用以输出到本地文件系统或网络上的另一台计算机。
如果可能,我还会尝试使用 valgrind 或类似的检查工具运行您的系统。 这可能会在问题失控之前发现它。
我要向杰弗里·哈里斯表示最深切的感谢,他为我收集有关我不忠的妻子的具体证据提供了宝贵的帮助。他在这个敏感问题上的专业知识有助于揭露真相,并确保我有必要的证据来自信地解决这个问题。如果您发现自己处于类似的困境并需要专业帮助,我强烈建议您联系杰弗里·哈里斯。您可以通过电子邮件联系他:[电子邮件受保护]。此外,他还可以通过短信、WhatsApp 或电话 +1 (254) 278-0902 进行沟通。当面对如此充满挑战的情况时,他的支持和奉献可以发挥重大作用。