如何生成事后回溯

How to generate a post facto backtrace?

本文关键字:回溯 事后 何生成      更新时间:2023-10-16

当我的KDE程序崩溃时(通常是:(),我可以生成一个事后回溯(我想这不是真正的事后回溯,只是错误被捕获并保存),如果我安装了调试符号,我可以用它来提交错误报告。这是如何工作的,我如何将该功能添加到我自己的程序中?

我现在用C++编写的一个程序出现了一个问题,它间歇性地崩溃,显然是由于内存管理不善。对我来说,在gdb下运行该程序是非常不切实际的,因为它是一个需要几个小时才能运行的大规模模拟,并且只有当系统的大小非常高时才会出现崩溃。能够自动将回溯转储到文件中会为我节省很多小时。

我认为它涉及到用某种try{}catch(){}例程包装所有内容,但我如何从中获得有用的回溯?有更好的方法吗?我所有的编程都是在Linux上进行的,如果这影响了答案的话。

您不能使用try/catch,因为它们需要正确的程序,而您遇到的崩溃是因为您的程序格式错误/不正确/损坏。一般情况下,您不能使用确定性编程来处理非确定性损坏的代码。首先要避免编写损坏的代码(使用Clang的asan/tsan/ubsan和Valgrind等工具,并编写测试),或者使用在出现编程错误时不会变得格式错误的语言(如Java或Python)。

通常情况下,当操作系统因某些非法操作(例如非法指令或非法内存访问)而杀死进程时,它会在进程从系统中删除之前创建进程的核心转储。核心转储由整个内存内容(或多或少)组成,它包括所有运行线程的堆栈跟踪。

一些现代操作系统通过管道将coredump传输到处理它的程序,例如将它上传到软件供应商进行分析。你可以做一些类似的事情,尽管你必须用你的操作系统来安排。不过,仅仅发送运行线程的堆栈跟踪可能就足够了,而不是发送整个内存。

您也可以通过使用库(libunfold?)或附加调试器来创建正在运行的程序的堆栈跟踪,调试器会中断程序,但这通常没有多大用处-唯一有趣的堆栈跟踪是非法操作发生的位置,因为您想知道该操作是什么。

根据您遇到的崩溃类型,您还可以在程序终止处理程序中执行某种日志记录操作。

此时有多少调试信息可用在很大程度上取决于编译器及其设置,当然,不能保证这在任何情况下都能工作,例如内存不足。

您可以集成google breakpad。或者你至少可以看看消息来源。AFAIK通过提供各种信号处理程序来创建转储。