Как распечатать полный backtrace из программы?

Я сколько не рыл - не нашел нормального решения. Предположим, у меня есть некий закопанный метод. И мне нужно из этого метода распечатать всю цепочку, которая к этому методу привела.
То есть какой-нить std::cout с выводом наподобие
0) файл1.cpp:10 main() блаблабла
1) файл2.cpp:55 Объект1::метод1(аргумент1 = "блабла", аргумент2 = "блабла...)
2) файл3.cpp:66 Объект2::метод123(аргумент1 = 0xabbababa, аргумент2 = "блабла..., this=0x0)
...
NNN) файлNNN.cpp:NN ЗакопанныйОбъектN::метод(аргумент1...

Как это сделать?
  • Вопрос задан
  • 282 просмотра
Пригласить эксперта
Ответы на вопрос 3
@kitzu Автор вопроса
вот одно из решений - используется libunwind - но не выводит переданные значения
#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);
  }
}


пример вывода
#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
Ответ написан
Комментировать
@ins52
Для Windows SEH использую StackWalker.
При исключении полный стек выводит, правда надо pdb-файл положить рядом exe-шником чтобы стек вывелся с нормальными именами функций.
Ответ написан
Комментировать
AxisPod
@AxisPod
Вывести проблемы нет, проблема собрать стек вызовов. Это от платформы зависит знатно и от компилятора.

Если не хочется тащить сторонние библиотеки.
Глядите на backtrace, backtrace_symbols и деманглинг (зависит от компилятора, у gcc к примеру есть готовая функция abi::__cxa_demangle).
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы