One can simply use the defaults provided by the library. In the example below, the two steps (getting the stack and resolving its symbols) are collapsed into one line:
#include <iostream> #include <boost/call_stack/call_stack.hpp> int main() { std::cout << "I am here: \n" << boost::call_stack::default_call_stack_info(boost::call_stack::default_stack(true)) // true: capture the call stack << std::endl; return 0; }
On a Windows platform, the output could look like:
I am here: [181eea] boost::call_stack::detail::get_stack<boost::call_stack::call_frame,40>+0x4a At c:\work\boost\callstack\call_stack\boost\call_stack\detail\win\stack.hpp:43 In C:\work\boost\callstack\call_stack\bin.v2\libs\call_stack\example\msvc-11.0\debug\link-static\threading-multi\deflt.exe [187160] boost::call_stack::detail::call_stack_impl<boost::call_stack::call_frame,40>::get_stack+0x10 At c:\work\boost\callstack\call_stack\boost\call_stack\detail\call_stack_impl.hpp:122 In C:\work\boost\callstack\call_stack\bin.v2\libs\call_stack\example\msvc-11.0\debug\link-static\threading-multi\deflt.exe [182b2c] boost::call_stack::detail::call_stack_impl<boost::call_stack::call_frame,40>::call_stack_impl<boost::call_stack::call_frame,40>+0x2c At c:\work\boost\callstack\call_stack\boost\call_stack\detail\call_stack_impl.hpp:59 In C:\work\boost\callstack\call_stack\bin.v2\libs\call_stack\example\msvc-11.0\debug\link-static\threading-multi\deflt.exe [182ac4] boost::call_stack::call_stack<40>::call_stack<40>+0x14 At c:\work\boost\callstack\call_stack\boost\call_stack\stack.hpp:61 In C:\work\boost\callstack\call_stack\bin.v2\libs\call_stack\example\msvc-11.0\debug\link-static\threading-multi\deflt.exe [181086] main+0x26 At c:\work\boost\callstack\call_stack\libs\call_stack\example\default.cpp:9 In C:\work\boost\callstack\call_stack\bin.v2\libs\call_stack\example\msvc-11.0\debug\link-static\threading-multi\deflt.exe [189b89] __tmainCRTStartup+0x199 At f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c:536 In C:\work\boost\callstack\call_stack\bin.v2\libs\call_stack\example\msvc-11.0\debug\link-static\threading-multi\deflt.exe [189ccd] mainCRTStartup+0xd At f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c:377 In C:\work\boost\callstack\call_stack\bin.v2\libs\call_stack\example\msvc-11.0\debug\link-static\threading-multi\deflt.exe [765433aa] ??+0x0 At ??:0 In ?? [779d9ef2] ??+0x0 At ??:0 In ?? [779d9ec5] ??+0x0 At ??:0 In ??
If the defaults offered by the library are not adequate, choose a symbol resolver,
a frame formatter and a stack depth to create the appropriate boost::call_stack::call_stack_info
:
// Maximum depth of the stack to collect. static const std::size_t max_stack_size = 20; typedef boost::call_stack::call_stack<max_stack_size> stack_type; stack_type here(true); // Just get the stack. Resolve symbols later. typedef boost::call_stack::call_stack_info< stack_type , boost::call_stack::extended_symbol_resolver, boost::call_stack::fancy_call_frame_formatter
> extended_call_stack_info_type; // Resolve symbols and display the information std::cout << "Stack is " << here.depth() << " frames depth:\n" << extended_call_stack_info_type(here) << std::endl;
To trace an exception back to the place in code where it was thrown, embed a call_stack in the exception. This might not be feasible nor desireable for all types of exceptions.
For instance, a symbol resolver will usually allocate heap memory for the symbol information and this might not be a good thing for in a bad_alloc context. In such difficult situations, the null_resolver might be of help.
#include <iostream> #include <exception> #include <boost/call_stack/call_stack.hpp> class traced_exception : public std::exception { public: static const std::size_t max_stack_size = 20; typedef boost::call_stack::call_stack<max_stack_size> stack_type; typedef boost::call_stack::call_stack_info< stack_type , boost::call_stack::extended_symbol_resolver // extended_symbol_resolver, basic_symbol_resolver or null_symbol_resolver , boost::call_stack::fancy_call_frame_formatter // fancy_call_frame_formatter or terse_call_frame_formatter > call_stack_info_type; traced_exception() : std::exception() , _where(true) // Capture stack {} const stack_type& where() const throw() { return _where; } const char * what() const throw() { return "traced_exception"; } private: stack_type _where; }; void func2() { throw traced_exception(); } void func1() { func2(); } int main() { try { func1(); } catch (const traced_exception& ex) { std::cout << "Exception: " << ex.what() << "\n" << "Stack is " << ex.where().depth() << " frames depth:\n" << traced_exception::call_stack_info_type(ex.where()) << std::endl; } return 0; }
Possible output on a Linux platform:
Exception: traced_exception Stack is 10 frames depth: [0x41ae02] unsigned long boost::call_stack::detail::get_stack<boost::call_stack::call_frame, 20ul>(boost::array<boost::call_stack::call_frame, 20ul>&)+0x40 At /home/amelinte/work/boost/call_stack/call_stack/libs/call_stack/example/../../../boost/call_stack/detail/gnu/stack.hpp:41 In ../../../bin.v2/libs/call_stack/example/gcc-4.7/debug/link-static/threading-multi/exception [0x41a4d4] boost::call_stack::detail::call_stack_impl<boost::call_stack::call_frame, 20ul>::get_stack()+0x18 At /home/amelinte/work/boost/call_stack/call_stack/libs/call_stack/example/../../../boost/call_stack/detail/call_stack_impl.hpp:119 In ../../../bin.v2/libs/call_stack/example/gcc-4.7/debug/link-static/threading-multi/exception [0x4195e4] boost::call_stack::detail::call_stack_impl<boost::call_stack::call_frame, 20ul>::call_stack_impl(bool)+0x3e At /home/amelinte/work/boost/call_stack/call_stack/libs/call_stack/example/../../../boost/call_stack/detail/call_stack_impl.hpp:59 In ../../../bin.v2/libs/call_stack/example/gcc-4.7/debug/link-static/threading-multi/exception [0x41858d] boost::call_stack::call_stack<20ul>::call_stack(bool)+0x23 At /home/amelinte/work/boost/call_stack/call_stack/libs/call_stack/example/../../../boost/call_stack/stack.hpp:75 In ../../../bin.v2/libs/call_stack/example/gcc-4.7/debug/link-static/threading-multi/exception [0x416ec0] traced_exception::traced_exception()+0x38 At /home/amelinte/work/boost/call_stack/call_stack/libs/call_stack/example/exception.cpp:20 In ../../../bin.v2/libs/call_stack/example/gcc-4.7/debug/link-static/threading-multi/exception [0x4146fc] func2()+0x1e At /home/amelinte/work/boost/call_stack/call_stack/libs/call_stack/example/exception.cpp:39 In ../../../bin.v2/libs/call_stack/example/gcc-4.7/debug/link-static/threading-multi/exception [0x414717] func1()+0x9 At /home/amelinte/work/boost/call_stack/call_stack/libs/call_stack/example/exception.cpp:45 In ../../../bin.v2/libs/call_stack/example/gcc-4.7/debug/link-static/threading-multi/exception [0x41472c] main+0x13 At /home/amelinte/work/boost/call_stack/call_stack/libs/call_stack/example/exception.cpp:61 In ../../../bin.v2/libs/call_stack/example/gcc-4.7/debug/link-static/threading-multi/exception [0x7f94667cfea5] __libc_start_main+0xf5 At ??:0 In /lib/x86_64-linux-gnu/libc.so.6 [0x4145c9] _start+0x4145c9 At ??:0 In ../../../bin.v2/libs/call_stack/example/gcc-4.7/debug/link-static/threading-multi/exception