You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何结合backtrace()与addr2line获取调用栈的行号?

解决backtrace与addr2line匹配行号的问题

问题根源

你的问题是**地址空间随机化(ASLR)**导致的:

  • objdump显示的是程序文件中的链接时偏移地址(以0000开头)
  • 程序运行时,ASLR会随机分配加载基地址,所以backtrace输出的是虚拟内存地址,和链接时偏移不匹配,直接传给addr2line自然查不到有效信息。

两种解决方法

方法1:临时关闭ASLR(调试用)

关闭ASLR后,程序每次运行的加载地址都会和链接时偏移一致,无需手动计算:

  1. 执行命令关闭ASLR:
    echo 0 | sudo tee /proc/sys/kernel/randomize_va_space
    
  2. 重新运行你的程序,此时backtrace输出的地址会和objdump显示的地址一致,直接用addr2line即可:
    addr2line -f -e ./main.out 0x12da
    
  3. 调试完成后,记得恢复ASLR(系统默认开启,提升安全性):
    echo 2 | sudo tee /proc/sys/kernel/randomize_va_space
    

方法2:不关闭ASLR,手动计算偏移地址

如果不想关闭ASLR,需要将运行时虚拟地址转换为链接时偏移:

  1. 获取程序的加载基地址:
    • 先运行程序,找到它的PID(比如用ps aux | grep main.out)
    • 查看进程的内存映射,找到main.out的可执行段(权限为r-xp),起始地址就是基地址:
      cat /proc/[你的PID]/maps | grep main.out
      
      示例输出:
      556c59bec000-556c59bed000 r-xp 00000000 08:01 123456 ./main.out
      
      这里的0x556c59bec000就是加载基地址。
  2. 计算偏移地址:用backtrace输出的虚拟地址减去基地址
    0x556c59bed2da - 0x556c59bec000 = 0x12da
    
  3. 将偏移地址传给addr2line:
    addr2line -f -e ./main.out 0x12da
    
    此时就能正确输出函数名和对应行号了。

可选:代码层面自动处理偏移

如果想让程序自动输出可直接用的偏移地址,可以在print_stack_trace中添加逻辑,读取自身的加载基地址,然后将array中的地址减去基地址后输出。示例(需要链接-ldl):

#include <dlfcn.h>

void print_stack_trace() {
  void *array[10];
  size_t size;
  char **strings;
  size_t i;

  // 获取加载基地址
  Dl_info info;
  dladdr((void*)print_stack_trace, &info);
  uintptr_t base_addr = (uintptr_t)info.dli_fbase;

  size = backtrace(array, 20);
  strings = backtrace_symbols(array, size);

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

  // 输出时同时显示偏移地址
  for (i = 0; i < size; i++) {
    uintptr_t addr = (uintptr_t)array[i];
    uintptr_t offset = addr - base_addr;
    printf("%s | 偏移地址: 0x%lx\n", strings[i], offset);
  }

  free(strings);
}

编译时添加-ldl:

g++ -rdynamic -g3 -ldl main.cpp -o main.out

运行后直接用输出的偏移地址传给addr2line即可。

内容的提问来源于stack exchange,提问作者Tokubara

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 10:20:01