一旦在 catch 块之前抛出异常(堆栈展开),如何打印堆栈跟踪

How to print stacktrace once an exception is thrown before the catch block (stack unwinding)

假设我们有以下代码:

#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 框架。 这是一个大系统,所以我正在尝试实现一些可以在整个系统中使用的日志记录机制。

我发布这篇文章是为了防止有人遇到同样的问题并想要一个快速有用的答案。

我最终使用此 gist

覆盖了主要的 C++ 抛出异常行为

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