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

发布于 2024-07-20 16:45:08 字数 229 浏览 11 评论 0 原文

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

在 Linux 上,我会使用 GNU backtrace() 函数 - Windows 上有等效的函数吗?

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

(“测试你的应用程序,使其不会崩溃”这样的建议没有帮助!-所有重要的程序都会有错误)

If my C++ app crashes on Windows I want to send useful debugging information to our server.

On Linux I would use the GNU backtrace() function - is there an equivalent for Windows?

Is there a way to extract useful debugging information after a program has crashed? Or only from within the process?

(Advice along the lines of "test you app so it doesn't crash" is not helpful! - all non-trivial programs will have bugs)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

雨后咖啡店 2024-07-27 16:45:08

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

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

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

The function Stackwalk64 can be used to snap a stack trace on Windows.

If you intend to use this function, you should be sure to compile your code with FPO disabled - without symbols, StackWalk64 won't be able to properly walk FPO'd frames.

You can get some code running in process at the time of the crash via a top-level __try/__except block by calling SetUnhandledExceptionFilter. This is a bit unreliable since it requires you to have code running inside a crashed process.
Alternatively, you can just the built-in Windows Error Reporting to collect crash data. This is more reliable, since it doesn't require you to add code running inside the compromised, crashed process. The only cost is to get a code-signing certificate, since you must submit a signed binary to the service. https://sysdev.microsoft.com/en-US/Hardware/signup/ has more details.

焚却相思 2024-07-27 16:45:08

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

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

You can use the Windows API call MiniDumpWriteDump if you wish to roll your own code. Both Windows XP and Vist automate this process and you can sign up at https://winqual.microsoft.com to gain access to the error reports.

Also check out http://kb.mozillazine.org/Breakpad and http://www.codeproject.com/KB/debug/crash_report.aspx for other solutions.

厌倦 2024-07-27 16:45:08

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

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

当然,这只能在进程内起作用,因此如果进程在该代码运行之前终止或崩溃到终止的程度,这是行不通的。

This website provides quite a detailed overview of stack retrieval on Win32 after a C++ exception:

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

Of course, this will only work from within the process, so if the process gets terminated or crashes to the point where it terminates before that code is run, it won't work.

你另情深 2024-07-27 16:45:08

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

这里是开始阅读的好地方。

Generate a minidump file. You can then load it up in windbg or Visual Studio and inspect the entire stack where the crash occurred.

Here's a good place to start reading.

幻想少年梦 2024-07-27 16:45:08

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

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

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

Its quite simple to dump the current stackframe addresses into a log file. All you have to do is get such a function called on program faults (i.e. a interrupt handler in Windows) or asserts. This can be done at released versions as well. The log file then can be matched with a map file resulting in a call stack with function names.

I published a article about this some years ago.

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

你穿错了嫁妆 2024-07-27 16:45:08

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

首先,在主函数中,我调用 _set_se_translator,并传入一个将抛出 C++ 异常的函数,而不是使用结构化 Windows 异常。 此函数获取一个错误代码,您可以通过 FormatMessage 获取该错误代码的 Windows 错误消息 和 PEXCEPTION_POINTERS 参数,您可以使用它来编写小型转储 (此处代码)。 您还可以检查异常代码以查找某些应该避免的“崩溃”错误,例如 EXCEPTION_NONCONTINUABLE_EXCEPTION 或 EXCEPTION_STACK_OVERFLOW :)(如果可以恢复,我会提示用户通过电子邮件向我发送此小型转储文件。)

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

Let me describe how I handle crashes in my C++/WTL application.

First, in the main function, I call _set_se_translator, and pass in a function that will throw a C++ exception instead of using structured windows exceptions. This function gets an error code, for which you can get a Windows error message via FormatMessage, and a PEXCEPTION_POINTERS argument, which you can use to write a minidump (code here). You can also check the exception code for certain "meltdown" errors that you should just bail from, like EXCEPTION_NONCONTINUABLE_EXCEPTION or EXCEPTION_STACK_OVERFLOW :) (If it's recoverable, I prompt the user to email me this minidump file.)

The minidump file itself can be opened in Visual Studio like a normal project, and providing you've created a .pdb file for your executable, you can run the project and it'll jump to the exact location of the crash, together with the call stack and registers, which can be examined from the debugger.

初雪 2024-07-27 16:45:08

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

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

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

网上有很多关于如何执行此操作的好文章,这篇是我的最喜欢的,您需要阅读本文来了解如何帮助自己轻松管理符号。

If you want to grab a callstack (plus other good info) for a runtime crash, on a release build even on site, then you need to set up Dr Watson (run DrWtsn32.exe). If you check the 'generate crash dumps' option, when an app crashes, it'll write a mini dump file to the path specified (called user.dmp).

You can take this, combine it with the symbols you created when you built your server (set this in your compiler/linker to generate pdb files - keep these safe at home, you use them to match the dump so they can work out the source where the crash occurred)

Get yourself windbg, open it and use the menu option to 'load crash dump'. Once it's loaded everything you can type '~#kp' to get a callstack for every thread (or click the button at the top for the current thread).

There's good articles to know how to do this all over the web, This one is my favourite, and you'll want to read this to get an understanding of how to helpyourself manage the symbols really easily.

烙印 2024-07-27 16:45:08

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

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

You will have to set up a dump generation framework in your application, here is how you may do it.

You may then upload the dump file to the server for further analysis using dump analyzers like windbg.

眼角的笑意。 2024-07-27 16:45:08

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

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

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

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

You may want to use adplus to capture the crash callstack.

You can download and install Debugging tools for Windows.

Usage of adplus is mentioned here:
Adplus usage

This creates the complete crash or hang dump. Once you have the dump, Windbg comes to the rescue. Map the correct pdbs and symbols and you are all set to analyze the dump. To start with use the command "!analyze -v"

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文