Skip to content

Advanced Usage

Floweynt edited this page May 1, 2024 · 11 revisions

Although stacktrace::dump_stacktrace is typically sufficient for most applications, you can also use some of the more "complex" features.

Exceptions

Use/extend the stacktrace_exception class

#include "stacktrace.h"
#include "stacktrace_exception.h"

void some_buggy_function()
{
  throw stacktrace::stacktrace_exception("something is wrong!");
}

int main()
{
  try 
  {
    some_buggy_function();
  }
  catch(stacktrace::stacktrace_exception& e)
  {
    // use stream manipulators to set how to print exception
    // stacktrace::shortexcept: prints e.what()
    // stacktrace::longexcept: prints e.what()
    // stacktrace::stacktrace: prints e.what() and a stacktrace
    // some stacktrace elements from the constructor + stacktrace-generating functions will be printed
    std::cout << stacktrace::stacktrace << e;
  }
}

This example will output:

what: something is wrong!
stacktrace:
AT: [000055fca4f1d530] /home/runner/work/stacktrace/stacktrace/examples/../include/detail/stacktrace_execinfo_impl.h:11 (stacktrace::stacktrace(unsigned long))
AT: [000055fca4f21aef] /home/runner/work/stacktrace/stacktrace/source/stacktrace.cpp:42 (stacktrace::stack_aware_exception::stack_aware_exception(char const*, int, char const*, char const*, char const*))
AT: [000055fca4f1cb3a] /home/runner/work/stacktrace/stacktrace/examples/main.cpp:67 (some_buggy_function())
AT: [000055fca4f1cd2f] /home/runner/work/stacktrace/stacktrace/examples/main.cpp:119 (main)
AT: [00007fb9cb8780b3] UNK:0 (UNK)
AT: [000055fca4f1c90e] UNK:0 (_start)

Custom printing

All you need to do is to implement a printer function (that takes a stacktrace::entry and a std::ostream). Be sure to not add a newline when printing, as that is already done for you.

#include "stacktrace.h"

int main()
{
  // make use of the short type for a print function (optional, you can just stick the lambda in the call)
  stacktrace::stack_printer printer = [](const stacktrace::entry& e, std::ostream& os) 
  { 
    os << "AT: [" << e.address << "] " << e.file << ':' << e.line << " (" << e.function << ')';
  };

  stacktrace::dump_stacktrace(10, printer, std::cout);
}

This example will print:

MESSAGE: something is wrong!
AT FUNC: void some_buggy_function()
AT FILE: /home/runner/work/stacktrace/stacktrace/examples/main.cpp:67 (some_buggy_function)

STACKTRACE:
AT: [00005606b07fe50c] /home/runner/work/stacktrace/stacktrace/examples/../include/detail/stacktrace_execinfo_impl.h:11 (stacktrace::stacktrace(unsigned long))
AT: [00005606b0802acb] /home/runner/work/stacktrace/stacktrace/source/stacktrace.cpp:42 (stacktrace::stack_aware_exception::stack_aware_exception(char const*, int, char const*, char const*, char const*))
AT: [00005606b07fdb3a] /home/runner/work/stacktrace/stacktrace/examples/main.cpp:67 (some_buggy_function())
AT: [00005606b07fdd0b] /home/runner/work/stacktrace/stacktrace/examples/main.cpp:119 (main)
AT: [00007f155bda50b3] UNK:0 (UNK)
AT: [00005606b07fd90e] UNK:0 (_start)

Finer control

You can also get finer control over what happens to the stacktrace

#include "stacktrace.h"

int main()
{
  stacktrace::pointer_stacktrace pointers = stacktrace::stacktrace(10); // capture the raw addresses of the stacktrace
  stacktrace::symbol_stacktrace symbols = stacktrace::get_symbols(pointers); // use symbols to make the stacktrace more readable
                                                                            // dont call this if you are in release and have no symbols
  stacktrace::dump_stacktrace(symbols, std::cout); // dump_stacktrace works with a pre-existing symbol stacktrace
}

Signal-safe stacktrace

This allows for stacktrace dumps in a signal handler.

#include <stacktrace.h>
#include <csignal>

int main()
{
    std::cout << "Waiting for signal...\n";
    signal(SIGINT, +[](int) {
        stacktrace::signal_safe_stacktrace([](uintptr_t ptr) {
            std::cout << ptr << '\n'; // cout is NOT signal safe. It is only used as a "proof of concept"
        });       
    });
    while(1){}
}
Clone this wiki locally