【问题标题】:How to print stacktrace once an exception is thrown before the catch block (stack unwinding)在 catch 块之前抛出异常后如何打印堆栈跟踪(堆栈展开)
【发布时间】:2021-11-04 07:47:39
【问题描述】:

假设我们有以下代码:

#include <exception>


void funcA() {
    funcB();
}

void funcB() {
    funcC();
}

void funcC() {
    funcD();
}

void funcD() {
    throw std::runtime_error("Exception!!"); //3
}

void funcE() {
    int * p;
    delete p; //4
}

int main (int argc, char **argv) {
    
    try {
        funcA(); //1
    } catch (std::exception exc) {
        std::cerr << exc.what() << endl; //2
        return EXIT_FAILURE;
    }
    
    return EXIT_SUCCESS;
}

我想以多线程高效的方式打印堆栈跟踪以及引发异常的行号。

过去几天我一直在检查人们正在采取的解决方案和方法,但不幸的是,在我的情况下没有任何用处。例如,我可以使用 //2 中的 boost 库 boost::stacktrace::stacktrace() 或任何其他库,但这里的问题是我必须捕获异常才能执行此操作,如果您的代码有数百个嵌套函数,这种方法效率不高。您不能只检查所有这些并用try-catch 包装每个并单独处理它们。

所以基本上我需要做的是,如果在//3 处引发异常,我应该能够在 `//2

中打印异常的堆栈跟踪

我知道堆栈展开以及它是如何工作的,但据我了解,每当您的代码到达 catch 块时,这意味着异常堆栈已展开并且您无法获取它。 如果我错了,请纠正我!

有没有办法在展开异常堆栈之前至少添加类似于中间件的东西?还是我必须手动完成?

编辑:

另外,当我可以funcE() 时会发生什么是内存访问异常,但这个异常永远不会被捕获。有没有办法捕获此类异常或至少在崩溃前打印其堆栈跟踪?

注意:

我在 Linux 和 macOS、C++11 和 Silicon Web 框架上运行我的代码。 这是一个很大的系统,所以我正在尝试实现一些可以在整个系统中使用的日志记录机制。

【问题讨论】:

  • 与其抛出像runtime_error 这样的通用异常,不如添加您自己的类层次结构,其中包含更多语义上重要的异常,这有助于缩小可能引发每个异常的位置。然后为每个异常添加一些重要的描述,以便每个文本都是唯一的,并且可以用于定位引发异常的确切位置。
  • 另一种可能的方式(可以与上面结合)是使用一个特殊的函数甚至预处理宏来抛出异常,这个函数或宏可以添加诸如回溯或源位置,可以是日志,也可以是异常本身的一部分。
  • 我添加了runtime_error作为示例,代码可能会抛出任何类型的异常,我无法将try-catch块添加到系统中的所有函数中,即使我有一个自定义异常类@Someprogrammerdude
  • 我可以搜索关于宏的任何示例或概念吗? @Someprogrammerdude 提前谢谢老兄:)
  • 你不应该在任何地方添加try catch,只有在某些高处才有意义并且可以实际处理异常。另请注意,某些异常可能无法处理,您应该让它们继续运行以终止程序。还要记住,应该为真正的异常问题保留异常。如果您有一个可以恢复的错误(例如无法打开 可选 文件),那么通常不需要为此抛出异常。

标签: c++11 exception stack-trace stack-unwinding


【解决方案1】:

我发布这个以防有人遇到同样的问题并想要一个快速有用的答案。

我最终使用 gist 覆盖了主要的 C++ 抛出异常行为

我更改了 __cxa_throw 函数中的一些内容来解决我自己的问题,并使用 boost::stacktrace 来获得更易于阅读的堆栈跟踪。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-04
    • 2014-08-06
    • 1970-01-01
    • 2011-01-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多