我需要捕获一些“致命的”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/