A
A
Andrew2016-08-15 01:49:51
C++ / C#
Andrew, 2016-08-15 01:49:51

How to print full backtrace from program?

No matter how much I dug, I did not find a normal solution. Suppose I have some buried method. And I need to print out the entire chain from this method, which led to this method.
That is, some std::cout thread with output like
0) file1.cpp:10 main() blablabla
1) file2.cpp:55 Object1::method1(argument1 = "blabla", argument2 = "blabla...)
2 ) file3.cpp:66 Object2::method123(argument1 = 0xabbababa, argument2 = "blabla..., this=0x0)
...
NNN) fileNNN.cpp:NN BuriedObjectN::method(argument1...
How to do it?

Answer the question

In order to leave comments, you need to log in

3 answer(s)
A
Andrew, 2016-08-15
@kitzu

here is one solution - using libunwind - but not outputting passed values

#define __STDC_FORMAT_MACROS
#include <inttypes.h>

#define UNW_LOCAL_ONLY
#include <libunwind.h>

#include <cxxabi.h>

#include <stdio.h>
#include <stdlib.h>

void backtrace()
{
  unw_cursor_t cursor;
  unw_context_t context;

  unw_getcontext(&context);
  unw_init_local(&cursor, &context);

  int n=0;
  while ( unw_step(&cursor) ) {
    unw_word_t ip, sp, off;

    unw_get_reg(&cursor, UNW_REG_IP, &ip);
    unw_get_reg(&cursor, UNW_REG_SP, &sp);

    char symbol[256] = {"<unknown>"};
    char *name = symbol;

    if ( !unw_get_proc_name(&cursor, symbol, sizeof(symbol), &off) ) {
      int status;
      if ( (name = abi::__cxa_demangle(symbol, NULL, NULL, &status)) == 0 )
        name = symbol;
    }

    printf("#%-2d 0x%016" PRIxPTR " sp=0x%016" PRIxPTR " %s + 0x%" PRIxPTR "\n",
        ++n,
        static_cast<uintptr_t>(ip),
        static_cast<uintptr_t>(sp),
        name,
        static_cast<uintptr_t>(off));

    if ( name != symbol )
      free(name);
  }
}

output example
#1  0x00000000003f909c sp=0x00000000afdfd348 OtherObjectName::OtherObjectName(long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) + 0xcb8
#2  0x00000000001f6974 sp=0x00000000afdfd8c0 ObjectName::dothat(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) + 0xa98
#3  0x00000000001e7c94 sp=0x00000000afdfe218 ObjectName::doit(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool) + 0x63f8
#4  0x00000000001d52f4 sp=0x00000000afdfeb08 ObjectName::justdo(ObjectNameTable_entry_s&, unsigned short) + 0xd524
#5  0x00000000001c7bc8 sp=0x00000000afdfec98 ObjectName::run() + 0x9f8

I
ins52, 2016-08-18
@ins52

For Windows SEH I use StackWalker .
With an exception, the full stack displays, though you need to put the pdb file next to the exe file so that the stack is displayed with normal function names.

A
AxisPod, 2016-08-17
@AxisPod

There is no problem to output, the problem is to collect the call stack. It depends a lot on the platform and the compiler.
If you do not want to drag third-party libraries.
Look at backtrace, backtrace_symbols and demangle (depends on the compiler, gcc has a ready function abi::__cxa_demangle for example).

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question