2.5. Addr2line 调试
2.5.1. 工具介绍
Linux调试工具(Addr2line)
addr2line
将地址转换为文件名和行号。给定可执行文件中的地址或可重定位对象部分中的偏移量,它会使用调试信息来确定与之相关的文件名和行数。
如果无法确定文件名或函数名, addr2line
将在它们的位置打印两个问号;如果无法确定行号, addr2line
将打印 0 或一个问号。
2.5.2. 用法
addr2line
用于得到程序指令地址所对应的函数,以及函数所在的源文件名和行号。如果没有在命令行中给出地址,就从标准输入中读取它们。
用法:
addr2line [选项] [地址]
选项 |
描述 |
描述(中文) |
---|---|---|
-a |
Show addresses |
在函数名、文件和行号信息之前,显示地址,以十六进制形式 |
-b |
Set the binary file format |
设置二进位文件格式 |
-e |
Set the input file name (default is a.out) |
指定需要转换地址的可执行文件名,默认为a.out |
-i |
Unwind inlined functions |
如果需要转换的地址是一个内联函数,则输出的信息包括其最近范围内的一个非内联函数的信息。 |
-j |
Read section-relative offsets instead of addresses |
读取相对于段的偏移而非地址 |
-p |
Make the output easier to read for humans |
使得该函数的输出信息更加人性化:每一个地址的信息占一行 |
-s |
Strip directory names |
仅仅显示每个文件名的基址(即不显示文件的具体路径,只显示文件名) |
-f |
Show function names |
在显示文件名、行号输出信息的同时显示函数名信息 |
-C |
Demangle function names |
解码函数名 |
-h |
Display this information |
帮助 |
2.5.3. 例子
在程序运行过程中出现错误
可以根据给出的寄存器地址信息,在Linux下通过 addr2line
快速定位程序死机的位置
通过 x1(ra):000000004007eff6 我们可以快速定位到程序死机的调用函数
addr2line [选项] [输出文件路径][地址][附加选项]
gec@ubuntu:~/zx-rtt-sdk$ addr2line -e ./output/ZXM47D0N_rtt/images/m4.elf 000000004007eff6
/home/gec/zx-rtt-sdk/packages/third-party/lvgl/lvgl-8.3.2/src/core/lv_obj_pos.c:857
从上面的例子我们可以知道,程序是在 /home/gec/zx-rtt-sdk/packages/third-party/lvgl/lvgl-8.3.2/src/core/lv_obj_pos.c 文件中的857行中出了错误
继续通过 mepc:0000000040079de4 地址可以快速定位到程序死机的具体位置
gec@ubuntu:~/zx-rtt-sdk$ addr2line -e ./output/ZXM47D0N_rtt/images/m4.elf 0000000040079de4
/home/gec/zx-rtt-sdk/packages/third-party/lvgl/lvgl-8.3.2/src/core/lv_obj_draw.c:393 (discriminator 1)
从上面的例子我们可以知道,程序是在 /home/gec/zx-rtt-sdk/packages/third-party/lvgl/lvgl-8.3.2/src/core/lv_obj_draw.c 文件中的393行中出了错误
2.5.4. 其它示例
gec@ubuntu:~/zx-rtt-sdk$ addr2line -e ./output/ZXM47D0N_rtt/images/m4.elf 0000000040079de4 -f -p
_lv_obj_get_ext_draw_size 于 /home/gec/zx-rtt-sdk/packages/third-party/lvgl/lvgl-8.3.2/src/core/lv_obj_draw.c:393 (discriminator 1)
也可以通过 mcause
寄存器初步排除死机原因
Mcause |
说明 |
---|---|
mcause:0x00[Instruction address misaligned] |
指令地址非对齐 |
mcause:0x01[Instruction access fault] |
指令获取不合法 |
mcause:0x02[Illegal instruction] |
非法指令 |
mcause:0x03[Breakpoint] |
零地址访问 |
mcause:0x04[Load address misaligned] |
读取地址非对齐 |
mcause:0x05[Load access fault] |
读取地址不合法 |
mcause:0x06[Store address misaligned] |
写入地址非对齐 |
mcause:0x07[Store access fault] |
写入地址不合法 |