c++ - 重新抛出异常保留回溯

标签 c++ debugging exception gdb

我需要捕获一些“致命的”C++ 异常,然后刷新日志并重新抛出前者,使用它自己的回溯

但是,我当前的解决方案(正确地)显示了错误的堆栈跟踪。

#include <exception>
#include <iostream>

void fatal(const std::exception & E)
{
    // do - something - extremely - important
    throw E;
}

int foo()
{
    throw std::runtime_error("yet another foo function");
}

int main()
{
    try
    {
        return foo();
    }
    catch (const std::exception & E)
    {
        fatal(E);
    }
    return -1;
}

程序被包装

  $ cat ./backtrace
  backtrace
  quit

  $ ulimit -c unlimited
  $ ./a.out
  $ gdb -q ./a.out core -x ./backtrace

结果是

Program terminated with signal SIGABRT, Aborted.

..................................................

4 0x00007f496eb53701 in std::terminate() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6

5 0x00007f496eb53919 in __cxa_throw () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6

6 0x0000000000400d71 in fatal(std::exception const&) ()

7 0x0000000000400e5b in main ()

我认为重新抛出异常(通过 const ref)是一种传递原始回溯的技术;我感兴趣的是回溯 foo(),而不是 fatal()

最佳答案

用你的脚本:

backtrace
quit

... 你只会在下级程序即将退出时看到堆栈跟踪(或者当你使用核心文件时,就像你的示例中那样,当它已经退出时),因为你没有告诉 gdb 在任何地方停止.

另一种方法是使用 gdb catch throw 命令,加上一些脚本。这样您就可以在每次 throw 时捕获堆栈跟踪。你可以这样做:

(gdb) catch throw
Catchpoint 1 (throw)
(gdb) commands
Type commands for breakpoint(s) 1, one per line.
End with a line saying just "end".
> silent
> backtrace
> continue
> end

这将在每次 throw 时停止并打印回溯。但是,您不想打印来自 fatal 帧的堆栈跟踪。为此,您可以使用 gdb 便利函数并使捕获点有条件:

(gdb) cond 1 $_any_caller_matches("fatal", 10)

(“10”只是猜测有多少帧可以将 fatal 与处理抛出的 C++ 库内部分开。)

关于c++ - 重新抛出异常保留回溯,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52381731/

相关文章:

C++ Qt QString 用一个替换双反斜杠

c++ - 如何使用 CAtlComModule 实现 COM 事件接收器?

javascript - 在 Visual Studio 2010 中调试 Javascript 代码

C++ 断点被忽略/遗漏

c# - 锁定未处理的异常处理程序是否安全?

java - 无法加载: InvalidPluginException

c++ - Mavericks 的 g++ 编译问题

java - 将 C++ 校验和函数转换为 Java

c++ - 使用 qt creator 进行 jit 调试 (Windows)

java - 在带有 Spring Rest 的全局异常处理程序中使用通用异常类处理程序是一个好习惯吗?