addr2line/objdump/nm/readelf使用

来源:互联网 发布:java管理bug工具 编辑:程序博客网 时间:2024/05/12 17:06

原址

熟练掌握GNU tools 的使用后,在调试Native,kernel crash类异常时可发挥事半功倍的作用.

概要
    Android编译工具使用了gcc,因此了解和使用gnu toolchain可以在debug时更加方便。
    工具目录(这里只列了ARM平台相关的工具)
        ARM32位版本:prebuilts/linux-x86/gcc/arm/arm-linux-androideabi-$version/bin
        ARM64位版本:prebuilts/linux-x86/gcc/aarch64/aarch64-linux-android-$version/bin
    为了方便使用,可以将目录添加到环境变量中
        编辑$HOME/.bash_profile文件,在最后添加以下语句即可将$HOME/bin加入环境变量,$HOME/bin也可以改为你想添加的路径:
            PATH=$PATH:$HOME/bin
            export PATH
1. addr2line
    将地址转换为地址所在的文件及行数(显示所在函数)
    使用方法:arm-linux-androideabi-addr2line [option(s)] [addr(s)]
(1). 参数 (常用)
    -e --exe=<executable>: 设置要查询地址的文件(默认: a.out)
        一般是*.so/*.a和可执行程序
        此文件必须带有debug信息,在android codebase里是放在out/target/product/$project/symbols目录下
    -f –functions: 显示地址所在的函数名
    -C --demangle[=style]: 反重整函数名为可读方式
        自动识别格式,C++函数才需要此参数
(2). 例子
   
 arm-linux-androideabi-addr2line -e libc.so -f -C 0x23234
    wcscoll
    alps/bionic/libc/wchar/wcscoll.c:37
(3). 什么情况下需要用到?
    发 生NE后,会生成tombstones/tombstones_xx文件或aee_exp里的db解开之后的__exp_main.txt ,里面有backtrace信息,就可以通过addr2line分析出哪个文件哪行哪个函数(注意用-e 载入的文件必须和手机的bin档同一次编译生成,否则地址和符号可能不一致)
2. nm
    arm-linux-androideabi-nm [option(s)] [file(s)]
    列出该文件的符号(函数,变量,文件等),包含名字、地址、大小
(1). 参数 (常用)
    -C, --demangle[=STYLE]: 反重整符号为可读方式
        自动识别格式
    -e --exe=<executable>: 设置要查询地址的文件(默认: a.out)
        一般是*.so和可执行程序
    -D, --dynamic: 只显示动态符号
    -g, --extern-only: 只显示外部符号
    -l, --line-numbers:多显示符号所在文件和行数
    -S, --print-size: 多显示符号的大小
    -u, --undefined-only: 只显示未定义的符号
(2). 符号类型 (常用)
    小写表示是本地符号,大写表示全局符号(external)
    A: 符号值是绝对的。在进一步的连接中,不会被改变(absolute)
    B: 符号位于未初始化数据段(BSS section)
    C: 共用(common)符号. 共用符号是未初始化的数据。在连接时,多个共用符号可能采用一个同样的名字,如果这个符号在某个地方被定义,共用符号被认为是未定义的引用
    D: 已初始化数据段的符号(data section)
    F: 源文件名称符号
    R: 只读数据段符号.(定义为const的变量)
    T: 代码段的符号 (text section)
    U: 未定义符号
    ?: 未知符号类型,或者目标文件特有的符号类型
(3). 例子
    
arm-linux-androideabi-nm -g test
        00009018 D __CTOR_LIST__
        00009010 T __FINI_ARRAY__
        00009008 T __INIT_ARRAY__
                 U __aeabi_unwind_app_pr0
        ......
3. objdump
    arm-linux-androideabi-objdump <option(s)> <file(s)>
    查看对象文件(*.so/*.a或应用程序)的内容信息
(1). 参数 (常用)
    至少需要一个以下的参数
        -a, --archive-headers: 显示库(*.a)成员信息
        -f, --file-headers:显示obj中每个文件的整体头部摘要信息
        -h, --[section-]headers:显示目标文件各个section的头部摘要信息
        -x, --all-headers: 显示所有头部摘要信息
        -d, --disassemble:反汇编代码段
        -D, --disassemble-all: 反汇编所有段
        -S, --source:反汇编出源代码,额外有debug信息,隐含-d,如果编译时有-g,效果更明显
        -t, --syms: 显示符号表
        -r, --reloc: 显示重定位记录
    -C, --demangle[=STYLE]: 反重整符号为可读方式
        自动识别格式
(2). 例子
    
arm-linux-androideabi-objdump -S libstdc++.so > disas.txt
(3). 什么情况下需要用到?
    当发生NE后,拿到backtrace可以查看对应地址的汇编代码。
4. readelf
    arm-linux-androideabi-readelf <option(s)> elf-file(s)
    查看elf文件(*.so/*.a或应用程序)的内容信息
(1). 参数 (常用)
    -a, --all: 显示所有可显示的内容
    -h --file-header: 显示ELF文件头
    -l --segments: 显示程序头组
    -S --sections: 显示节头组
    -t: 显示节头细节
    -e --headers: 等效于-h -l -S
    -s --syms: 显示符号表
    -n --notes: 显示内核说明
    -r --relocs: 显示重定位信息
    -u --unwind: 显示解栈信息
    -d --dynamic: 显示动态节
    -p –string-dump=<num|name>: 以字符串的方式显示节
    -W --wide: 允许一行显示超过80个字符
(2). 例子
    
arm-linux-androideabi-readelf -a -W adb > 1.txt
(3). 什么情况下需要用到?
    学习/查看ELF结构。
5. c++filt
    arm-linux-androideabi-c++filt <function name>
    反重整C++符号为可读方式
(1). 例子
    
arm-linux-androideabi-c++filt _ZN20android_audio_legacy22AudioPolicyManagerBase17setSystemPropertyEPKcS2
    android_audio_legacy::AudioPolicyManagerBase::setSystemProperty(char const*, char const*)
(2). 什么情况下需要用到?
    通过GAT解开db后(输入symbols目录),如果是NE的话,可以查看解开的C++的对应的symbols是否和c++filt的一样,不一样则symbols目录和手机bin档不匹配。

阅读全文
0 0
原创粉丝点击