addr2line输出问号怎么办

48 篇文章 0 订阅
36 篇文章 0 订阅

前言

使用backtrace等工具将程序异常运行的堆栈打印出来,然后再结合使用addr2line将堆栈地址转为文件行,将对于定位故障非常有帮助,但有时使用addr2line却输出为??:0 !

从addr2line的man手册中看确实没有分C和C++语言的区别,而且还有特殊的选项-C针对于C++编译器的函数重命名,所以,输出??:0 ,应该是找不到对应行号了,特别是使用地址信息的不正确。

结合个人实践,将对backtrace输出的地址信息进行分类!

backtrace显示地址分类

/lib/x86_64-linux-gnu/libc.so.6(clone+0x43) [0x7faf347b3133]

  • **()**中携带的地址信息为模块内地址,分为+0x0ffsetsymbol+0x0ffset两种情况,其中+0x0ffset可以直接作为addr2line的地址参数;symbol+0x0ffset地址在多几步处理后,可以作为addr2line的地址参数,特别是结合objdump -D工具。
  • **[]**中携带的地址为函数运行时地址,所以,一般是不能直接用的

在没有**()内地址信息时,[]**的地址可以作为地址参数

如果您确定堆栈信息与运行程序和依赖库是一致的话,且程序携带-g的调试信息,那么可以深入使用objdump -D工具进行人工分析。

-rdynamic

-rdynamic编译选项,从个人实践来看,作用被夸大了。携带此参数后,显示出来的symbol+0ffset的地址信息,无法直接作为addr2line的地址参数,去掉选项后,反而得到了能够直接使用的(+0xOffset)的地址

对于动态库的适应

如果SO库本身携带有调试信息的话,同样可以用addr2line -e /path/to/so addr,定位到SO库某文件中的某行。

[]地址的特殊性

从一个很小的青蛙例子,可以backtrace打印出**类[]的地址,多运行几次发现类[]**地址存在动态变化,所以,不能直接作为addr2line进行使用。反而是(+0xOffset)(Symbol+0xOffset)的地址非常稳定,比较适合作为addr2line的参数进行使用!

(+0xOffset)中的0xOffset可以直接作为addr2line的地址参数来使用

symbol+0xffset地址结合objdump

纯手工计算

   # template
   objdump -D /path/to/relocatable_object | grep -A20 ‘symbol’

   # example 
   objdump -D a.out |grep -A20 'main'

   # output
   ...
    0000000000003920 <main>:
    3920:	f3 0f 1e fa          	endbr64 
    3924:	55                   	push   %rbp
    3925:	48 89 e5             	mov    %rsp,%rbp
    3928:	53                   	push   %rbx

# 对于解析不出来的symbol+0xOffset进行特殊处理,特别关注<symbol>的位置
# 对于无法识别的`addr2line -e a.out main+0x1fc`

addr2line -e a.out $(printf '%x' $((0x3920 + 0x1fc)))
  • objdump -D将程序或库进行汇编输出,可以看到符号在模块内的地址
  • grep -A选项打印匹配行后多少行;另外,-C为匹配行的上下多少行,-B为匹配行前多少行,在监控动态输出日志时非常有帮助

固化

#!/bin/bash
# file: queryRowNo.sh

addr="$2"

name=${addr%+*}
offset=${addr#*+}

base=$(objdump -D $1 | grep "<$name>" | awk '{print $1}')

if [ -z "$base" ]; then
  echo "can't get the base addr of $name"
  exit
fi

base="0x$base"

addr2line -e "$1" $(printf '%x' $((base + offset)))

# example using shell script file
./queryRowNo.sh /lib/libACE.so.6.5.19 _ZN15ACE_Sig_Handler8dispatchEiP9siginfo_tP10ucontext_t+0x55

参考

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值