llvm-symbolizer命令的使用

作者 by adtxl / 2022-01-25 / 暂无评论 / 549 个足迹

1.概要

llvm-symbolizer - convert addresses into source code locations

llvm-symbolizer [options]

2.描述

llvm-symbolizer 从标准输入读取目标文件名和地址,并将相应的源代码位置打印到标准输出。如果在命令行中指定了目标文件,则llvm-symbolizer 仅处理来自标准输入的地址,其余部分将逐字输出。该程序在目标文件中使用调试信息部分和符号表。

3.示例

$ cat addr.txt
a.out 0x4004f4
/tmp/b.out 0x400528
/tmp/c.so 0x710
/tmp/mach_universal_binary:i386 0x1f84
/tmp/mach_universal_binary:x86_64 0x100000f24
$ llvm-symbolizer < addr.txt
main
/tmp/a.cc:4

f(int, int)
/tmp/b.cc:11

h_inlined_into_g
/tmp/header.h:2
g_inlined_into_f
/tmp/header.h:7
f_inlined_into_main
/tmp/source.cc:3
main
/tmp/source.cc:8

_main
/tmp/source_i386.cc:8

_main
/tmp/source_x86_64.cc:8
$ cat addr2.txt
0x4004f4
0x401000
$ llvm-symbolizer -obj=a.out < addr2.txt
main
/tmp/a.cc:4

foo(int)
/tmp/a.cc:12
$cat addr.txt
0x40054d
$llvm-symbolizer -inlining -print-address -pretty-print -obj=addr.exe < addr.txt
0x40054d: inc at /tmp/x.c:3:3
 (inlined by) main at /tmp/x.c:9:0
$llvm-symbolizer -inlining -pretty-print -obj=addr.exe < addr.txt
inc at /tmp/x.c:3:3
 (inlined by) main at /tmp/x.c:9:0

4.选项

-obj, -exe, -e :要符号化的目标文件的路径

-functions=[none|short|linkage], -f :指定打印功能名称的方式(分别省略功能名称,打印短功能名称或打印完整链接名称)。默认为linkage。

-use-symbol-table: 首先将存储在符号表中的函数名称替换为调试信息部分中的函数名称。默认为true。

-demagle, -C :打印解码的函数名称。默认为true

-no-demagle: 不要打印demangled函数名称

-inlining, -inlines, -i :如果源代码位置在内联函数中,则打印所有已处理的帧。默认为true

-defualt-arch: 如果二进制文件包含多个体系结构的目标文件(例如,它是Mach-O通用二进制文件),则表示给定体系结构的目标文件。您还可以通过binary_name:arch_name在输入中写入来指定体系结构(请参阅上面的示例)。如果未以任一方式指定体系结构,则不会对地址进行符号化。默认为空字符串。

dsym-hint=<path/to/file.sSYM>:(仅Darwin)如果二进制文件的调试信息不​​在默认位置,请在通过-dsym-hint标志提供的.dSYM路径中查找调试信息 。该标志可以多次使用。

-print-address,-addresses,-a:在源代码位置之前打印地址。默认为false。

-pretty-print,-p :打印人类可读输出。如果-inlining指定,则封闭范围以(内联方式)为前缀

-basenames, -s:打印文件路径时剥离目录

-adjust-vma=<offset>:执行查找时,将指定的偏移量添加到目标文件地址。这可以用于执行查找,就像对象通过偏移重新定位一样。

-output-style=[llvm|gnu]:指定首选输出样式。默认为LLVM。当输出样式设置为时GNU,该工具遵循GNU的addr2line样式
与LLVM风格的区别在于:

不打印源代码位置的列

报告后的地址不添加空行

当内联框架未显示且-use-symbol-table 处于打开状态时,不会将内联函数的名称替换为最顶层调用者的名称

$ llvm-symbolizer -p -e=addr.exe 0x40054d 0x400568
inc at /tmp/x.c:3:3
 (inlined by) main at /tmp/x.c:14:0

main at /tmp/x.c:14:3

$ llvm-symbolizer --output-style=LLVM -p -i=0 -e=addr.exe 0x40054d 0x400568
main at /tmp/x.c:3:3

main at /tmp/x.c:14:3

$ llvm-symbolizer --output-style=GNU -p -i=0 -e=addr.exe 0x40054d 0x400568
inc at /tmp/x.c:3
main at /tmp/x.c:14

5.退出

llvm-symbolizer返回0.其他退出代码表示内部程序错误。

6.在Android12中使用

如果已经执行过source,lunch命令,直接使用即可,如下所示

$ llvm-symbolizer -e=./out/target/product/tv_e2_isdb/./symbols/data/asan/system/lib/libbootanimation.so 0xfe42
android::FileMap::getDataPtr() const
system/core/libutils/include/utils/FileMap.h:79:43
android::BootAnimation::initTexture(android::FileMap*, int*, int*)
frameworks/base/cmds/bootanimation/BootAnimation.cpp:1107:37

如果是在未source,lunch的环境中,直接运行会有报错

$ llvm-symbolizer -e=./out/target/product/tv_e2_isdb/./symbols/data/asan/system/lib/libbootanimation.so 0xfe42

Command 'llvm-symbolizer' not found, but can be installed with:

apt install llvm
Please ask your administrator.

可以安装,但最好使用aoso自带的,即prebuilts/clang/host/linux-x86/clang-r416183b1目录里面的,

$ ./prebuilts/clang/host/linux-x86/clang-r416183b1/bin/llvm-symbolizer -e=./out/target/product/tv_e2_isdb/./symbols/data/asan/system/lib/libbootanimation.so 0xfe42
android::FileMap::getDataPtr() const
system/core/libutils/include/utils/FileMap.h:79:43
android::BootAnimation::initTexture(android::FileMap*, int*, int*)
frameworks/base/cmds/bootanimation/BootAnimation.cpp:1107:37

参考:
1.llvm-symbolizer commandline

独特见解