当我的KDE程序崩溃时(通常是:()),我可以生成事后回溯(我想它实际上不是事后,只是错误被捕获并保存)并使用它来提交错误报告如果我安装了调试符号。它是如何工作的,如何将该功能添加到我自己的程序中?
我现在遇到一个问题,我编写的程序(在C ++中)间歇性崩溃,显然是由于内存管理不善造成的。在gdb
下运行程序是非常不切实际的,因为它是一个需要几个小时才能运行的大规模模拟,只有当系统的大小非常高时才会出现崩溃。能够自动将回溯转储到文件中可以节省很多时间。
我认为它涉及将所有内容包装在某种try{}catch(){}
例程中但是如何从中获得有用的回溯呢?有没有更好的办法?我的所有编程都在Linux上,如果这会影响答案。
答案 0 :(得分:3)
您无法使用try
/ catch
,因为那些需要正确的程序,而您遇到的崩溃是因为您的程序格式错误/不正确/破碎。您通常不能使用确定性编程来解决非确定性的破坏代码。首先避免编写损坏的代码(使用像Clang的asan / tsan / ubsan和Valgrind这样的工具,并编写测试),或者在编程错误时使用一种不会形成错误的语言(如Java或Python)
通常情况下,当操作系统由于某些非法操作(例如非法指令或非法内存访问)而导致您的进程终止时,它会在从系统中删除之前创建进程的核心转储。核心转储包含整个内存内容(或多或少),它包含所有正在运行的线程的堆栈跟踪。
一些当代操作系统将coredump传送到处理它的程序,例如将其上传到软件供应商进行分析。您可以执行类似的操作,但您必须使用操作系统进行安排。但是,仅仅发送正在运行的线程的堆栈跟踪而不是整个内存就足够了。
您还可以通过使用库(libunwind?)或附加调试器来创建正在运行的程序的堆栈跟踪,这会中断程序,但通常没有太多用处 - 唯一有趣的堆栈跟踪是非法行动发生的地方,因为你想知道那次行动是什么。
答案 1 :(得分:0)
根据您遇到的崩溃类型,您还可以在程序终止处理程序中执行某种日志记录操作。
此时可用的调试信息在很大程度上取决于您的编译器及其设置,当然不能保证这将在每种情况下都能正常工作,例如,内存不足。
答案 2 :(得分:0)
您可以整合google breakpad。或者你至少可以看看消息来源。 AFAIK它通过提供各种信号处理程序来创建转储。