我尝试将backtrace()
与addr2line
结合使用,以获取调用堆栈的行号。
以下是我的main.cpp
的内容:
#include <execinfo.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void print_stack_trace() {
void *array[10];
size_t size;
char **strings;
size_t i;
// Get the current call stack
size = backtrace(array, 20);
// Convert it into an array of strings
strings = backtrace_symbols(array, size);
if (strings == NULL) {
perror("backtrace_symbols");
exit(EXIT_FAILURE);
}
// Print all the stack trace symbols
for (i = 0; i < size; i++) {
printf("%s\n", strings[i]);
}
free(strings);
}
void dummy_function() {
// Generate a stack trace
print_stack_trace();
}
int main(void) {
// Call a function and then print the stack trace within that function
dummy_function();
return 0;
}
字符串
我使用以下命令编译了代码:
g++ -rdynamic -g3 main.cpp -o main.out
型
运行可执行文件时:
./main.out
型
输出为:
./main.out(_Z17print_stack_tracev+0x2c) [0x556c59bed235]
./main.out(_Z14dummy_functionv+0xd) [0x556c59bed2da]
./main.out(main+0xd) [0x556c59bed2ea]
/lib/x86_64-linux-gnu/libc.so.6(+0x29d90) [0x7f9128c7bd90]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0x80) [0x7f9128c7be40]
./main.out(_start+0x25) [0x556c59bed145]
型
根据backtrace_symbols()
手册页,括号中的地址(例如,0x556c59bed2da
)是返回地址。我已经使用-g
选项进行编译,并使用addr2line
如下:
addr2line -f -e ./main.out 0x556c59bed2da
型
但输出是:
??
??:0
型
我用objdump
检查了函数地址:
objdump -S -l -d ./main.out
型
地址似乎以0000
开头,如下所示:
0000000000001209 <_Z17print_stack_tracev>:
00000000000012cd <_Z14dummy_functionv>:
型
这些与backtrace_symbols()
输出(0x556c59bed2da
)不匹配。
如何使用addr2line
来正确确定调用堆栈的行号?
1条答案
按热度按时间s4chpxco1#
当程序运行时,通过检查
/proc/<PID>/maps
来查找进程在内存中的基址。这是一行,包含程序名和权限r-xp
(可执行段)。假设基址是
0x556c59bec000
。那么.textMap表中_Z14dummy_functionv
内部的地址是0x556c59bed2da
减去0x556c59bec000
是12da
。将其传递给addr2line
。