保留回溯跟踪的重试异常 我需要捕获一些“致命”的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在任何地方停止

另一种方法是使用gdb
catch-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在任何地方停止

另一种方法是使用gdb
catch-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的东西。