从抛出异常的函数获取C++堆栈跟踪?

5
我可以利用gcc的回溯功能,在程序的任何给定点获取堆栈跟踪,但我希望在抛出异常时从堆栈所在的任何框架中获取跟踪,即在堆栈展开之前获取跟踪。

例如,以下代码块:
func() {
  throw std::exception();
}

try {
  func();
}
catch ( std::exception ) {
  std::cout << print_trace();
  //do stuff
}

需要想办法保留func()的框架。

这个问题之前已经有人问过了,但是那个问题涉及到未处理的异常,会终止程序并且可能没有机会展开调用栈?

是否有一种方法可以在正常捕获和处理异常的情况下实现这一点?

可以采用一种方法,即为所有异常设置一个处理程序,该处理程序除了生成跟踪信息并重新抛出异常外不执行任何操作。理想情况下,我应该能够在Exception类构造函数中生成跟踪信息,但在这里,我不一定能够控制可能遇到的异常。


5
如果您想知道异常抛出的位置,最好的方法是将该信息存储在异常中。 - user2100815
1个回答

5

您可能会对正在开发中的Boost库感兴趣:Portable Backtrace。例如:

#include <boost/backtrace.hpp>
#include <iostream>

int foo()
{
    throw boost::runtime_error("My Error");
    return 10;
}

int bar()
{
    return foo()+20;
}


int main()
{
    try {
        std::cout << bar() << std::endl;
    }
    catch(std::exception const &e)
    {
        std::cerr << e.what() << std::endl;
        std::cerr << boost::trace(e);
    }
}

输出:

My Error
0x403fe1: boost::stack_trace::trace(void**, int) + 0x1b in ./test_backtrace
0x405451: boost::backtrace::backtrace(unsigned long) + 0x65 in ./test_backtrace
0x4054d2: boost::runtime_error::runtime_error(std::string const&) + 0x32 in ./test_backtrace
0x40417e: foo() + 0x44 in ./test_backtrace
0x40425c: bar() + 0x9 in ./test_backtrace
0x404271: main + 0x10 in ./test_backtrace
0x7fd612ecd1a6: __libc_start_main + 0xe6 in /lib/libc.so.6
0x403b39: __gxx_personality_v0 + 0x99 in ./test_backtrace

希望这能帮到您!

差不多了,但還不夠……我只能依靠從boost異常中獲取跟踪信息,對於其他異常如std::bad_alloc等一概無能為力。太遺憾了,在Java中,跟踪信息不像標準異常類那樣內置! - maldoz
@maldoz 并不是每个人都需要回溯。但我同意它可能会有用。 - BЈовић

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接