如何在C ++程序的stacktrace中查看有用信息(文件名,行号)

问题描述 投票:5回答:1

这是一个复杂的,因为依赖于Boost版本和平台。

我正在使用boost stacktrace打印回溯,其中一些断言失败。根据您使用的模式(链接文档~5种模式),有一些外部编译时和运行时deps。我更喜欢基于调试信息和导出信息的东西(后者我认为后者也适用于生产版本)。但我可以使用默认模式或BOOST_STACKTRACE_USE_ADDR2LINEBOOST_STACKTRACE_USE_BACKTRACE - 所有3只显示我的实际程序代码的调用堆栈中的地址 - 请参阅下面的谷歌测试测试中的堆栈跟踪:

 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,没有任何东西可以显示函数名称。

相关:thisthis

我正在使用:gcc 8.2,boost 1.69(stracktrace lib的仅限标题模式),Arch Linux(在这个系统上我必须手动安装未包装的libbacktrace,所以我更喜欢采用ADDR2LINE方法)


编辑:更新链接到最新的boost.stacktrace。


Edit2:我注意到boost.stacktrace doc包含这个提示

由于地址空间布局随机化,共享库中的函数名称可能无法解码。总比没有好。

...这听起来很有帮助,但对我来说却是另一种方式,我没有在我自己的可执行文件中获取符号,但我是以libgtest.so为例。所以就好像调试信息设置有问题一样。任何想法都赞赏。

c++ boost stack-trace debug-symbols
1个回答
0
投票

第1部分

我把以下文件放在一起(改编自here)。由于Windows中没有execinfo.h(我知道),这只适用于Linux。它不使用boost,但它无论如何都可能有用。

backtrace_util.h:

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

back trace_UT IL.曹操:

#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);
}

back trace_test.曹操:

#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]


Part 2

当试图取消获得的名字时,我遇到了thisthis。我没有跟进整个事情。

© www.soinside.com 2019 - 2024. All rights reserved.