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

Libunwind获取的PC值无法配合addr2line使用的问题咨询

解决libunwind回溯addr2line无法解析PC的问题

我之前也碰到过这个坑!问题出在libunwind输出的function_name+0xoffset里的偏移值,和addr2line需要的地址格式不匹配——前者是相对于函数起始地址的偏移,而addr2line要的是程序内存中的绝对虚拟地址,或者是可执行文件的相对地址(如果是PIE程序的话还要额外处理)。

下面给你一步步拆解解决方案:

1. 先让libunwind输出绝对PC地址

修改你的代码,用unw_get_ip()拿到当前指令的绝对地址,这才是addr2line能识别的关键信息。示例代码如下:

#include <libunwind.h>
#include <stdio.h>

void print_backtrace() {
    unw_cursor_t cursor;
    unw_context_t context;

    unw_getcontext(&context);
    unw_init_local(&cursor, &context);

    printf("Backtrace (absolute PC):\n");
    while (unw_step(&cursor) > 0) {
        unw_word_t ip;
        unw_get_reg(&cursor, UNW_REG_IP, &ip);

        char func_name[256];
        unw_word_t func_offset;
        int ret = unw_get_proc_name(&cursor, func_name, sizeof(func_name), &func_offset);
        
        if (ret == 0) {
            printf("0x%lx (%s+0x%lx)\n", ip, func_name, func_offset);
        } else {
            printf("0x%lx (unknown function)\n", ip);
        }
    }
}

// 测试用函数
void nested_func() {
    print_backtrace();
}

void middle_func() {
    nested_func();
}

int main() {
    middle_func();
    return 0;
}

编译时记得加调试符号和链接libunwind:

g++ -g -o test test.cpp -lunwind

2. 处理PIE位置无关可执行文件的情况

现在大多数系统默认编译PIE程序,程序加载地址是随机的,直接用绝对PC传给addr2line会无效。这时候需要:

  • 先获取程序的加载基址:运行程序后,查看/proc/<你的进程PID>/maps,找到主程序的第一行(比如55f87a6a2000-55f87a6a4000 r-xp ... /home/you/test),前面的0x55f87a6a2000就是加载基址。
  • 用绝对PC减去加载基址,得到可执行文件内的相对地址,再传给addr2line。

比如你运行程序得到的绝对PC是0x55f87a6a369d,减去基址0x55f87a6a2000得到0x169d,然后执行:

addr2line -e test 0x169d

就能看到对应的文件名和行号了。

嫌手动计算麻烦的话,也可以用addr2line的--adjust-vma参数直接指定加载基址:

addr2line -e test --adjust-vma=0x55f87a6a2000 0x55f87a6a369d

3. 避坑提醒

  • 编译时必须加-g:没有调试符号的话,addr2line只能输出??:0,啥有用信息都没有。
  • 注意PC的指令偏移:部分架构(比如x86-64)中,unw_get_ip()返回的是下一条要执行的指令地址,这时候需要给PC减1,才能让addr2line对应到当前代码行。
  • 动态链接库的函数:如果回溯里有.so中的函数,要给addr2line的-e参数指定对应的动态库文件,而不是主程序。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 07:06:51