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. 例子

在程序运行过程中出现错误

../../_images/addr2line_error.jpg

可以根据给出的寄存器地址信息,在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行中出了错误

../../_images/addr2line_error_2.jpg

继续通过 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行中出了错误

../../_images/addr2line_error_3.jpg

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]

写入地址不合法