保留回溯跟踪的重试异常 我需要捕获一些“致命”的C++ >代码>异常< /> >,然后刷新日志并用它自己的回溯来重写日志。
但是,我当前的解决方案(正确地)显示了错误的堆栈跟踪保留回溯跟踪的重试异常 我需要捕获一些“致命”的C++ >代码>异常< /> >,然后刷新日志并用它自己的回溯来重写日志。,c++,debugging,exception,gdb,C++,Debugging,Exception,Gdb,但是,我当前的解决方案(正确地)显示了错误的堆栈跟踪 #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 f
#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;
}
结果是
程序以信号SIGABRT终止,中止
来自/usr/lib/x86_64-linux-gnu/libstdc++.so.6的std::terminate()中的4 0x00007f496eb53701
5 0x00007f496eb53919,位于/usr/lib/x86\u 64-linux-gnu/libstdc++.so.6中的
6 0x0000000000400d71处于致命状态(标准::异常常量&)()
主管道中的7 0x0000000000400e5b()
我认为重新触发异常(通过const ref)是一种传递原始回溯的技术;我感兴趣的是回溯
foo()
(无参数),抛出E
将通过从现有对象复制构造一个新的异常实例来抛出它
不过,我不确定其中任何一项对堆栈跟踪有何帮助。“通过原始回溯”没有什么意义,因为C++中的异常没有携带任何回溯,并且在您的<代码> catch <代码>块被调用时,堆栈已经被清除。 这里,我不确定您要完成什么,但是要重新抛出一个异常,您需要写“代码>抛出;
(无参数),抛出E
将通过从现有对象复制构造一个新的异常实例来抛出它
不过,我不确定其中任何一项对堆栈跟踪有何帮助。“通过原始回溯”没有什么意义,因为C++中的异常没有携带任何回溯,并且在您的<代码> catch <代码>块被调用时,堆栈已经被清除。 脚本:
backtrace
quit
。。。只有当次文件即将退出时(或者当您使用核心文件时,如在您的示例中,当它已经退出时),您才会看到堆栈跟踪,因为您没有告诉gdb在任何地方停止
另一种方法是使用gdbcatch-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
这将在每次抛出时停止,并打印回溯。但是,您不希望打印来自fatal
帧的堆栈跟踪。为此,您可以使用gdb便利函数,并使catchpoint有条件:
(gdb) cond 1 $_any_caller_matches("fatal", 10)
(“10”只是猜测有多少帧可以从<处理抛出的C++库内脏中分离<代码>致命< /代码>)
用脚本:
backtrace
quit
。。。只有当次文件即将退出时(或者当您使用核心文件时,如在您的示例中,当它已经退出时),您才会看到堆栈跟踪,因为您没有告诉gdb在任何地方停止
另一种方法是使用gdbcatch-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
这将在每次抛出时停止,并打印回溯。但是,您不希望打印来自fatal
帧的堆栈跟踪。为此,您可以使用gdb便利函数,并使catchpoint有条件:
(gdb) cond 1 $_any_caller_matches("fatal", 10)
(10)只是猜测有多少帧可以从“处理投掷的C++库内脏”中分离出代码<致命代码>代码> < < /p> 这个问题已经得到回答,但是我想补充一点,可以在<强>标准C++ 11 <强> > < /p>中创建适当的回溯。
使用及
它在StackOverflow中进行了描述,并且介绍了如何在代码中获得异常的回溯,而无需调试器或繁琐的日志记录,只需编写一个适当的异常处理程序,它将重新显示嵌套的异常。
然而,这要求您将所有希望跟踪的函数包装到try/catch
块中,但它允许您对发生的事情和打印的信息进行大量定制。由于可以对任何派生的异常类执行此操作,因此可以向此类回溯添加大量信息
您还可以查看my或my,其中回溯看起来像这样:
Library API: Exception caught in function 'api_function'
Backtrace:
~/Git/mwe-cpp-exception/src/detail/Library.cpp:17 : library_function failed
~/Git/mwe-cpp-exception/src/detail/Library.cpp:13 : could not open file "nonexistent.txt"
这个问题已经得到了回答,但我想补充一点,可以在标准C++11中创建适当的回溯:
使用及
它在StackOverflow中进行了描述,并且介绍了如何在代码中获得异常的回溯,而无需调试器或繁琐的日志记录,只需编写一个适当的异常处理程序,它将重新显示嵌套的异常。
然而,这要求您将所有希望跟踪的函数包装到try/catch
块中,但它允许您对发生的事情和打印的信息进行大量定制。由于可以对任何派生的异常类执行此操作,因此可以向此类回溯添加大量信息
您还可以查看my或my,其中回溯看起来像这样:
Library API: Exception caught in function 'api_function'
Backtrace:
~/Git/mwe-cpp-exception/src/detail/Library.cpp:17 : library_function failed
~/Git/mwe-cpp-exception/src/detail/Library.cpp:13 : could not open file "nonexistent.txt"
很好,我在catch
块中抛出ed,放弃fatal()
scoping。。。回溯是意料之中的,标准C++中没有任何东西将异常与“回溯”关联起来。无论您在描述什么,它都是特定于一个实现的。您需要阅读该实现的文档。顺便说一句,要在异常处理程序中重新抛出异常,只需抛出throw代码>-无需显式重新显示已捕获的异常。请记住,如果没有要重试的活动异常,则调用terminate()
。很好,我在catch
块中抛出ed,放弃fatal()
作用域。。。回溯是预期的,在标准C++中没有关联EXC的东西。