【问题标题】:Getting the backtrace from the catch block从 catch 块中获取回溯
【发布时间】:2011-05-16 02:21:57
【问题描述】:

我正在使用backtrace 来获取引发异常的位置的信息。在我的异常的构造函数中,我将回溯存储在 std::string 中,在这种类型的异常的 catch 块中,我正在打印这个回溯。

但我想知道,是否有可能以某种方式在 catch 块中为其他异常类型获得相同的回溯?

【问题讨论】:

  • 你可能想看看this post。它可能会让你到达你想去的地方。
  • std::set_terminate 的问题是调用回调时程序还是会终止。

标签: c++ linux exception-handling backtrace


【解决方案1】:

所讨论的类是否具有您可以编辑的共同基础?

否则,我在How can some code be run each time an exception is thrown in a Visual C++ program? 提供了一个很棒但被严重低估的答案;-P 其他一些人也发表了意见。

【讨论】:

  • 但我不是 linux,因此这里没有 Visual Studio ;)
  • 是的,我抛出的异常类有一个共同的基础,我可以获得那些的回溯。问题是如何从其他异常类型中获取回溯?例如 std::out_of_range
  • @VJo:我的肮脏黑客不是 Visual C++ 特定的(事实上,我只在 GCC 中测试过)——但它也不适合严肃的生产使用。对于 std::out_of_range,这很麻烦 - 猜测这取决于它对您的价值,但您可以使用调试器技术探索更改 std::exception 本身。您是在处理从 3rd 方库抛出的 std::out_of_range 等(如果是,您甚至有源代码),还是仅在您自己的代码中处理?是否有太多资源可以更改 throw 语句?
  • 我不能使用它,因为它只有在从同一个编译单元(cpp 文件)抛出异常时才有效。一旦抛出异常的函数在另一个文件中,它将无法工作。
【解决方案2】:

您可能对正在开发的 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 版本中,目前我被锁定到 boost 1.34.1 :(
  • 或许您可以单独下载并单独使用。然后,当/如果它成为官方 Boost 时,您可能可以切换/升级。祝你好运!
  • 对不起,但我意识到这并不能回答我的问题。为此,您必须抛出 boost 异常,但如果捕获到另一种异常类型,则不会打印回溯。
  • 没问题。希望你能找到你要找的东西。
【解决方案3】:

我不这么认为。当执行在 catch 块中停止时,堆栈被展开,之前发生的所有事情都不再在堆栈中了。

【讨论】:

  • 是的,完全正确。这使我们想到“抛出异常时我该怎么做” - stackoverflow.com/q/4223390/57428
  • Len Holgate 提到 Debug API 可以在异常被抛出时准确地捕获它。看起来很复杂,但可行。
猜你喜欢
  • 1970-01-01
  • 2011-09-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-28
相关资源
最近更新 更多