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

已剥离PIE编译程序:能否从boost stacktrace地址结合未剥离二进制提取函数名?

问题背景与疑问

我使用boost stacktrace在应用程序崩溃时转储堆栈跟踪,最终发布的程序会被剥离(stripped),这意味着不包含函数名信息。崩溃时的转储写入逻辑如下:

static void segmentationFaultHandler(int signo) {
    std::signal(signo, SIG_DFL);
    boost::stacktrace::safe_dump_to("./backtrace.dump");
    std::raise(SIGABRT);
}

程序下次启动时会将转储转换为包含地址的可读堆栈跟踪文本文件,但由于最终二进制文件已被剥离,无法提取函数名。该程序采用*PIE(位置独立可执行文件)*选项编译,请问:当我拥有堆栈跟踪中的地址和未剥离的二进制文件时,是否可以获取函数名信息?

可以还原函数名,具体步骤如下
  • 计算偏移地址:因为开启了PIE,程序运行时的加载地址是随机的,堆栈跟踪里的地址是加载地址,需要减去程序崩溃时的实际加载基地址,得到二进制文件内部的偏移地址。加载基地址可以通过系统日志(如dmesg)获取,部分转储工具也会直接记录。
  • 使用addr2line工具解析:借助未剥离的二进制文件,用addr2line直接还原函数名和行号:
    # 用偏移地址查询
    addr2line -e 未剥离的二进制文件名 偏移地址
    # 直接用加载地址,添加--pie参数自动处理基地址偏移
    addr2line -e 未剥离的二进制文件名 --pie 加载地址
    
  • 通过gdb验证:也可以用gdb加载未剥离的二进制文件,查询地址对应的函数:
    gdb 未剥离的二进制文件名
    # 查询偏移地址对应的函数
    (gdb) info symbol 偏移地址
    # 如果用加载地址,先设置基地址再查询
    (gdb) set baseaddress 加载基地址
    (gdb) info symbol 加载地址
    

核心逻辑是:未剥离的二进制文件保留了完整的调试符号(函数名、行号等),只要将堆栈中的加载地址转换为二进制内部的偏移地址,就能通过调试工具还原出函数名信息。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 10:35:19