gpt4 book ai didi

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

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:49:57 25 4
gpt4 key购买 nike

这是一个复杂的问题,因为它也取决于 Boost 版本和平台。

我正在使用 boost stacktrace在某些断言失败的地方打印回溯。有一些外部编译时和运行时依赖,具体取决于您使用的模式(链接文档~5 种模式)。我更喜欢基于调试信息和导出信息的东西(我认为后者也适用于生产构建)。但是我无法使用默认模式或 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,nothing 使函数名称成为出现。

相关:this , this .

我在:gcc 8.2,boost 1.69(stracktrace lib 的仅 header 模式),Arch Linux(在这个系统上我必须手动安装没有打包的 libbacktrace,所以我更愿意去ADDR2LINE 方法)


编辑:更新了指向最新 boost.stacktrace 的链接。


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

Function names from shared libraries may not be decoded due to address space layout randomization. Still better than nothing.

... 这听起来很有用,但对我来说恰恰相反,我没有在我自己的可执行文件中获取符号,但我是 libgtest.so 的例子。所以好像调试信息设置有问题。任何想法表示赞赏。

最佳答案

第 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

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

回溯测试.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 , 和 this .我没有跟进将整个事情放在一起。

关于c++ - 如何在C++程序的stacktrace中查看有用的信息(文件名,行号),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54755838/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com