Как просмотреть полезную информацию (имя файла, номер строки) в трассировке стека программы C ++ - PullRequest
0 голосов
/ 19 февраля 2019

Это сложный вопрос, поскольку он зависит от версии Boost и платформы.

Я использую boost stacktrace , чтобы напечатать backtrace, где некоторые утверждения не выполняются.Существуют некоторые внешние задержки времени компиляции и выполнения, в зависимости от того, какой режим вы используете (ссылка документы ~ 5 режимов).Я бы предпочел что-то, основанное как на отладочной информации, так и на информации об экспорте (последняя из которых, как я предполагаю, будет работать и в производственных сборках).Но я не могу заставить работать ни режим по умолчанию, ни BOOST_STACKTRACE_USE_ADDR2LINE, ни BOOST_STACKTRACE_USE_BACKTRACE - все 3 показывают только адреса в стеке вызовов для моего действительного программного кода - см. Ниже трассировку стека из теста google-test:

 0# 0x000055E47D43BDC2 in Debug/myprog
 1# 0x000055E47D489055 in Debug/myprog
 2# 0x000055E47D567FDF in Debug/myprog
 3# 0x000055E47D560CDE in Debug/myprog
 4# void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) in /usr/lib/libgtest.so.1.8.1
 5# testing::Test::Run() in /usr/lib/libgtest.so.1.8.1
 6# testing::TestInfo::Run() in /usr/lib/libgtest.so.1.8.1
 7# testing::TestCase::Run() in /usr/lib/libgtest.so.1.8.1
 8# testing::internal::UnitTestImpl::RunAllTests() in /usr/lib/libgtest.so.1.8.1

Что я пробовал: -rdynamic, -fno-pie и -fPIC, (я уже на -O0), -ggdb3 вместо значения по умолчанию -g3, Ничего делает имена функций такими, чтобыпоказать вверх.

Похожие: это , это .

Я нахожусь: gcc 8.2, boost 1.69 (режим только заголовка дляstracktrace lib), Arch Linux (в этой системе мне пришлось бы вручную устанавливать libbacktrace, который не упакован, поэтому я бы предпочел использовать подход ADDR2LINE)


Edit: обновленная ссылка на последнюю версию.stacktrace.


Edit2: я заметил, что документ boost.stacktrace содержит эту подсказку

Имена функций из общих библиотек могут не декодироваться из-за рандомизации расположения адресного пространства.Все же лучше, чем ничего.

... звучит полезно, но для меня все наоборот, я не получаю символы в своем собственном исполняемом файле, но я, например, для libgtest.so.Так что как будто что-то не так с настройкой отладочной информации.Любые идеи приветствуются.

1 Ответ

0 голосов
/ 22 февраля 2019

Часть 1

Я собрал следующие файлы (адаптировано из здесь ).Поскольку в Windows нет execinfo.h (о котором я знаю), это работает только в Linux.Он не использует повышение, но в любом случае может быть полезным.

backtrace_util.h:

#ifndef BACKTRACE_UTIL_H
#define BACKTRACE_UTIL_H
void backtrace_print(void);
#endif // BACKTRACE_UTIL_H

backtrace_util.cc:

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

void backtrace_print(void) {
    int j, nptrs;
#define SIZE 100
    void *buffer[100];
    char **strings;

    nptrs = backtrace(buffer, SIZE);
    printf("backtrace() returned %d addresses\n", nptrs);

    /* The call backtrace_symbols_fd(buffer, nptrs, STDOUT_FILENO)
     would produce similar output to the following: */

    strings = backtrace_symbols(buffer, nptrs);
    if (strings == NULL) {
        perror("backtrace_symbols");
        exit(EXIT_FAILURE);
    }

    for (j = 0; j < nptrs; j++)
        printf("%s\n", strings[j]);

    free(strings);
}

backtrace_test.cc:

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

#include "backtrace_util.h"

void myfunc(int ncalls) {
    if (ncalls > 1)
        myfunc(ncalls - 1);
    else {
        backtrace_print();
    }
}

int main(int argc, char *argv[]) {
    if (argc != 2) {
        fprintf(stderr, "%s num-calls\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    myfunc(atoi(argv[1]));
    exit(EXIT_SUCCESS);
}

Скомпилировано / связано с -std=c++17 -g, связано с -rdynamic.Вывод:

$ ./backtrace_test 2
backtrace() returned 6 addresses
./backtrace_test(_Z15backtrace_printv+0x2e) [0x55c51759bc51]
./backtrace_test(_Z6myfunci+0x25) [0x55c51759bbbb]
./backtrace_test(_Z6myfunci+0x1e) [0x55c51759bbb4]
./backtrace_test(main+0x5b) [0x55c51759bc19]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xe7) [0x7f3c2c2f5b97]
./backtrace_test(_start+0x2a) [0x55c51759baaa]


Часть 2

При попытке разобрать полученные имена, я наткнулся на this , и это .Я не стал собирать все это вместе.

...