c++函数的堆栈跟踪是否抛出异常?

发布于 2024-11-14 01:18:12 字数 576 浏览 7 评论 0原文

我可以利用 gcc 的回溯来获取程序任何给定点的堆栈跟踪,但我想从抛出异常时(即在堆栈展开之前)堆栈所在的任何帧获取跟踪。

例如,下面的块

func() {
  throw std::exception();
}

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

应该仍然能够以某种方式保留 func() 的框架。

之前已询问过,但它涉及一个未处理的异常,该异常会终止程序并且可能没有给调用堆栈一个放松的机会?

有没有办法做到这一点,同时仍然能够正常捕获和处理异常?

可能有一种方法,比如为所有异常设置一个处理程序,除了生成跟踪并重新抛出异常之外什么也不做。理想情况下,我应该能够在 Exception 类构造函数中生成跟踪,但在这里我不一定能够控制可能遇到的异常。

I can make use of gcc's backtrace to obtain a stack trace at any given point of a program, but I would like to obtain the trace from whatever frame the stack was in at the time an exception is thrown, ie prior to the stack unwinding.

For instance, the following block

func() {
  throw std::exception();
}

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

ought to still be able to retain a frame for func() somehow.

This has been asked before, but it involved an unhandled exception that would terminate the program and presumably didn't give the callstack a chance to unwind?

Is there a way to do this while still being able to catch and handle the exception normally?

There could be an approach like having a handler for all exceptions that do nothing but generate the trace and re-throw the exceptions. Ideally I should be able to generate traces within Exception class constructors, but here I do not necessarily have control over the exceptions that could be encountered.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

韶华倾负 2024-11-21 01:18:12

您可能对正在开发的 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

希望这有帮助!

You might be interested in a Boost library under development: Portable Backtrace. Example:

#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);
    }
}

Prints:

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

Hope this helps!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文