如何从崩溃中提取调试信息

时间:2009-05-12 00:12:52

标签: c++ windows crash stack-trace backtrace

如果我的C ++应用程序在Windows上崩溃,我想向我们的服务器发送有用的调试信息。

在Linux上我会使用GNU backtrace()函数 - 是否有Windows的等价物?

有没有办法在程序崩溃后提取有用的调试信息?或者只是在流程内?

(“测试你的应用程序,因此它不会崩溃”的建议没有帮助! - 所有非平凡的程序都会有错误)

9 个答案:

答案 0 :(得分:7)

函数Stackwalk64可用于在Windows上捕捉堆栈跟踪。

如果您打算使用此功能,您应该确保在禁用FPO的情况下编译代码 - 没有符号,StackWalk64将无法正确地执行FPO的帧。

通过调用SetUnhandledExceptionFilter,您可以通过顶级__try/__except块在崩溃时运行正在运行的代码。这有点不可靠,因为它要求您在崩溃的进程中运行代码。 或者,您可以只使用内置的Windows错误报告来收集崩溃数据。这样更可靠,因为它不需要您添加在受损,崩溃的进程中运行的代码。唯一的成本是获得代码签名证书,因为您必须向服务提交签名的二进制文件。 https://sysdev.microsoft.com/en-US/Hardware/signup/有更多详情。

答案 1 :(得分:3)

如果您希望推送自己的代码,可以使用Windows API调用MiniDumpWriteDump。 Windows XP和Vist都会自动执行此过程,您可以在https://winqual.microsoft.com注册以访问错误报告。

另请查看http://kb.mozillazine.org/Breakpadhttp://www.codeproject.com/KB/debug/crash_report.aspx以获取其他解决方案。

答案 2 :(得分:2)

本网站提供了一个关于C ++异常后Win32上的堆栈检索的详细概述:

http://www.eptacom.net/pubblicazioni/pub_eng/except.html

当然,这只能在流程中起作用,因此如果流程在运行代码之前终止或崩溃到终止点,它将无法工作。

答案 3 :(得分:2)

生成minidump文件。然后,您可以在windbg或Visual Studio中加载它,并检查崩溃发生的整个堆栈。

Here's一个开始阅读的好地方。

答案 4 :(得分:2)

将当前堆栈帧地址转储到日志文件中非常简单。您所要做的就是获得一个调用程序错误(即Windows中的中断处理程序)或断言的函数。这也可以在已发布的版本中完成。然后,日志文件可以与映射文件匹配,从而生成具有函数名称的调用堆栈。

几年前我发表了一篇关于此事的文章。

请参阅http://www.ddj.com/architect/185300443

答案 5 :(得分:2)

让我描述一下我如何在C ++ / WTL应用程序中处理崩溃。

首先,在main函数中,我调用_set_se_translator,并传入一个抛出C ++异常而不是使用结构化Windows异常的函数。此函数获取一个错误代码,您可以通过FormatMessage获取Windows错误消息,以及PEXCEPTION_POINTERS参数,您可以使用该参数编写一个小型转储(code here)。您还可以检查异常代码,查看您应该保释的某些“熔毁”错误,例如EXCEPTION_NONCONTINUABLE_EXCEPTION或EXCEPTION_STACK_OVERFLOW:)(如果可以恢复,我会提示用户给我发送这个minidump文件。)

minidump文件本身可以像普通项目一样在Visual Studio中打开,如果你为可执行文件创建了一个.pdb文件,你可以运行该项目,它会跳转到崩溃的确切位置,与调用堆栈和寄存器一起使用,可以从调试器中检查。

答案 6 :(得分:1)

如果你想为运行时崩溃获取一个callstack(以及其他好的信息),甚至在站点上的发布版本中,那么你需要设置Dr Watson(运行DrWtsn32.exe)。如果选中'generate crash dumps'选项,当应用程序崩溃时,它会将一个小型转储文件写入指定的路径(称为user.dmp)。

你可以把它与你在构建服务器时创建的符号结合起来(在编译器/链接器中设置它来生成pdb文件 - 在家里保持这些安全,你用它们来匹配转储,这样它们就可以工作了发生崩溃的来源)

获取自己windbg,打开它并使用菜单选项“加载崩溃转储”。一旦加载了所有内容,你可以输入'〜#kp'来获取每个线程的callstack(或点击当前线程顶部的按钮)。

有很好的文章知道如何在网络上做到这一点,This one是我最喜欢的,你需要read this来了解如何帮助自己轻松地管理符号

答案 7 :(得分:1)

您必须在应用程序中设置转储生成框架,here就是这样做的。

然后,您可以使用诸如windbg之类的转储分析器将转储文件上载到服务器以进行进一步分析。

答案 8 :(得分:0)

您可能希望使用adplus来捕获崩溃调用堆。

您可以下载并安装适用于Windows的调试工具。

这里提到了adplus的用法: Adplus usage

这会创建完整的崩溃或挂起转储。一旦你有转储,Windbg就会来救援。映射正确的pdbs和符号,您就可以分析转储了。首先使用命令“!analyze -v”