【问题标题】:How to generate a post facto backtrace?如何生成事后回溯?
【发布时间】:2013-08-29 08:35:20
【问题描述】:

当我的 KDE 程序崩溃时(这很常见:(如果我安装了调试符号,则会报告错误。它是如何工作的以及如何将该功能添加到我自己的程序中?

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

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

【问题讨论】:

  • 您是否尝试过围绕单元测试构建您的开发周期? :-)
  • 确保在 main 中有一个大的外部 try 块。 “内存管理”是什么意思? accu.org/index.php/journals/1586

标签: c++ error-handling backtrace debug-backtrace


【解决方案1】:

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

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

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

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-03
        • 2023-03-29
        • 1970-01-01
        • 1970-01-01
        • 2014-08-26
        相关资源
        最近更新 更多