如果我的C ++应用程序在Windows上崩溃,我想发送有用的debugging信息到我们的服务器。
在Linux上,我会使用GNU的backtrace()
函数 – 是否有相当于Windows?
程序崩溃后,有没有办法提取有用的debugging信息? 还是只从内部过程?
(build议“testing你的应用程序,所以它不会崩溃”没有帮助! – 所有不平凡的程序都会有错误)
Stackwalk64功能可用于在Windows上捕捉堆栈跟踪。
如果你打算使用这个函数,你应该确保在FPO禁用的情况下编译你的代码 – 没有符号,StackWalk64将不能正确地走FPO的帧。
通过调用SetUnhandledExceptionFilter,可以在崩溃时通过顶级__try/__except
块获取正在运行的一些代码。 这是有点不可靠的,因为它要求你在崩溃的进程中运行代码。 或者,您可以只使用内置的Windows错误报告来收集崩溃数据。 这是更可靠的,因为它不需要你添加运行在受损的,崩溃的进程中的代码。 唯一的代价是获得代码签名证书,因为您必须向服务提交签名的二进制文件。 https://sysdev.microsoft.com/en-US/Hardware/signup/有更多的细节。
如果您希望推出自己的代码,则可以使用Windows API调用MiniDumpWriteDump 。 Windows XP和Vist都可以自动执行此过程,您可以通过https://winqual.microsoft.com注册以访问错误报告。
在C ++异常之后,本网站提供了Win32上堆栈检索的详细概述:
http://www.eptacom.net/pubblicazioni/pub_eng/except.html
当然,这只会在进程内部工作,所以如果进程终止或崩溃到在代码运行之前终止的地步,它将无法工作。
生成一个小型转储文件。 然后,您可以将它加载到windbg
或Visual Studio中,并检查发生崩溃的整个堆栈。
这是一个开始阅读的好地方。
将当前堆栈帧地址转储到日志文件非常简单。 所有你需要做的就是获得这样的函数调用程序错误(即在Windows中的中断处理程序)或断言。 这也可以在发布的版本中完成。 日志文件然后可以匹配一个映射文件导致一个调用堆栈与函数名称。
几年前我发表了一篇关于这个的文章。
让我来描述一下如何在我的C ++ / WTL应用程序中处理崩溃。
首先,在主函数中,调用_set_se_translator ,并传递一个函数,该函数将抛出一个C ++异常,而不是使用结构化窗口异常。 这个函数得到一个错误代码,你可以通过FormatMessage得到一个Windows错误信息,还有一个PEXCEPTION_POINTERS参数,你可以使用它来写一个minidump( 代码在这里 )。 你也可以检查你应该保释的某些“崩溃”错误的异常代码,例如EXCEPTION_NONCONTINUABLE_EXCEPTION或EXCEPTION_STACK_OVERFLOW :)(如果它是可恢复的,我提示用户给我发这个小型转储文件。)
小型转储文件本身可以在Visual Studio中像普通项目一样打开,并且为您的可执行文件创建了一个.pdb文件,您可以运行该项目,并跳转到崩溃的确切位置,调用堆栈和寄存器,可以从调试器中检查。
如果你想抓取一个调用堆栈(加上其他更好的信息)的运行时崩溃,甚至在现场发布,那么你需要设置Dr Watson (运行DrWtsn32.exe)。 如果您选中“生成崩溃转储”选项,则当应用程序崩溃时,它将向指定的路径(称为user.dmp)写入一个小型转储文件。
你可以把它与你在建立你的服务器时创建的符号结合起来(在你的编译器/链接器中设置这个符号来生成pdb文件 – 在家里保持这些文件的安全,你用它们来匹配转储,以便他们可以找出源发生事故的地方)
让自己windbg ,打开它,并使用菜单选项“加载崩溃转储”。 一旦它被加载,你可以输入'〜#kp'来获得每个线程的调用堆栈(或者点击当前线程顶部的按钮)。
有很好的文章知道如何做到这一点, 这是我最喜欢的,你会想要阅读这个了解如何帮助你自己管理符号很容易。
您将不得不在应用程序中设置转储生成框架,以下是您可以执行的操作。
然后,您可以将转储文件上传到服务器,以便使用windbg等转储分析器进一步分析。
您可能需要使用adplus捕获崩溃callstack。
您可以下载并安装Windows的调试工具。
在这里提到adplus的用法: Adplus用法
这将创建完整的崩溃或挂起转储。 一旦你有转储,Windbg来救援。 映射正确的pdbs和符号,并且您将全部设置为分析转储。 要开始使用命令“!analyze -v”