Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c++ stacktrace from the function an exception is thrown?

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.

like image 891
maldoz Avatar asked Jun 07 '11 20:06

maldoz


1 Answers

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!

like image 119
BЈовић Avatar answered Sep 28 '22 06:09

BЈовић