11

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

在 Linux 上,我会使用 GNUbacktrace()功能 - Windows 是否有等效功能?

有没有办法在程序崩溃后提取有用的调试信息?还是仅来自流程内部?

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

4

9 回答 9

7

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

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

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

于 2009-05-12T00:24:05.903 回答
3

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

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

于 2009-05-12T00:30:09.420 回答
2

该网站提供了在 C++ 异常后在 Win32 上进行堆栈检索的非常详细的概述:

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

当然,这只会在进程内部起作用,所以如果进程终止或崩溃到它在代码运行之前终止的地步,它将无法工作。

于 2009-05-12T00:21:30.837 回答
2

生成一个小型转储文件。然后,您可以将其加载到windbgVisual Studio 中并检查发生崩溃的整个堆栈。

这是开始阅读的好地方。

于 2009-05-12T00:25:47.867 回答
2

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

几年前我发表了一篇关于这个的文章。

http://www.ddj.com/architect/185300443

于 2009-05-12T08:14:02.267 回答
2

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

首先,在主函数中,我调用_set_se_translator,并传入一个将抛出 C++ 异常而不是使用结构化 Windows 异常的函数。此函数获取一个错误代码,您可以通过FormatMessage获取一个 Windows 错误消息,以及一个 PEXCEPTION_POINTERS 参数,您可以使用它来编写一个小型转储(代码here)。您还可以检查某些“崩溃”错误的异常代码,例如 EXCEPTION_NONCONTINUABLE_EXCEPTION 或 EXCEPTION_STACK_OVERFLOW :)

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

于 2009-05-13T14:00:58.323 回答
1

如果您想获取运行时崩溃的调用堆栈(以及其他有用的信息),甚至在现场发布版本,那么您需要设置Dr Watson(运行 DrWtsn32.exe)。如果您选中“生成故障转储”选项,当应用程序崩溃时,它会将一个小型转储文件写入指定的路径(称为 user.dmp)。

您可以使用它,将它与您在构建服务器时创建的符号结合起来(在编译器/链接器中设置它以生成 pdb 文件 - 将这些安全地放在家里,您可以使用它们来匹配转储,以便他们可以计算出源代码发生事故的地方)

获取自己的 windbg,打开它并使用菜单选项“加载故障转储”。加载完所有内容后,您可以键入“~#kp”以获取每个线程的调用堆栈(或单击当前线程顶部的按钮)。

网上有很多关于如何做到这一点的好文章,是我最喜欢的一篇,你会想阅读这篇文章以了解如何帮助自己真正轻松地管理符号。

于 2009-05-12T08:24:26.603 回答
1

您必须在应用程序中设置转储生成框架,您可以这样做。

然后,您可以将转储文件上传到服务器,以便使用 windbg 等转储分析器进行进一步分析。

于 2009-05-13T11:47:27.417 回答
0

您可能想使用 adplus 来捕获崩溃调用堆栈。

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

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

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

于 2010-05-27T10:30:31.077 回答