linux 内核 addr2line,介绍addr2line调试命令

用addr2line可以将函数地址解析为函数名,在抓取调堆栈时Java层的堆栈本身就是显示函数名与行数,这个不需要转换,但对于native和kernel层的则是函数地址,需要借助addr2line来进行转换。 接下来分析介绍一下这个地址转换方法

一、Native地址转换

首先获取symbols表,要找到对应的版本的symbols,以及对应版本的addr2line,这样才能确保完全匹配。 然后执行如下命令,即可转换函数名:

64位:cd prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin

./aarch64-linux-android-addr2line -f -C -e libxxx.so ...

32位:cd /prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9/bin

./arm-linux-androideabi-addr2line -f -C -e libxxx.so ...

二、Kernel地址转换

(1)首先,获取符号地址,比如获取epoll_wait的符号地址:prebuilts/gcc/linux-x86/arm/arm-eabi-4.8/bin/arm-eabi-nm out/target/product/cancro/obj/KERNEL_OBJ/vmlinux |grep epoll_wait

该命令执行后,可获取sys_epoll_wait命令的符号地址,如下c02b2f28 T sys_epoll_wait

(2)然后,计算地址

例如 [<0000000000000000>] SyS_epoll_wait+0x2a0/0x324

则计算后的地址c02b2f28 + 2a0 = 目标地址。而对于kernel来说都是通过vmlinux来获取的,这时再执行命令可转换函数名./aarch64-linux-android-addr2line -Cfe /out/target/product/cancro/obj/KERNEL_OBJ/vmlinux [目标地址]

(3)实例aarch64-linux-android-nm out/target/product/gemini/obj/KERNEL_OBJ/vmlinux | grep binder_thread_read

aarch64-linux-android-addr2line -f -C -e out/target/product/gemini/obj/KERNEL_OBJ/vmlinux ffffffc000aa8cb4

<think>嗯,用户现在问的是关于addr2line -e vmlinux的用途、功能、作用和使用方法。之前他们问过vmlinux是什么,所以我得先回忆一下之前是怎么解释的。vmlinuxLinux内核编译后的未压缩ELF文件,包含符号表和调试信息,对吧?现在用户提到的addr2line应该和调试相关,结合vmlinux使用。 首先,用户提供的引用里提到了使用aarch64-linux-android-addr2line命令,参数有-e指向vmlinux文件,后面跟着地址。这可能是在将内存地址转换为源代码位置。需要确认addr2line的基本功能,以及-e参数的作用。addr2line通常用于将地址转换为文件名和行号,这需要调试信息,而vmlinux正好包含这些信息。 接下来,用户想知道addr2line -e vmlinux的具体用途。可能需要解释这个命令内核调试中的作用,比如当系统崩溃或出现问题时,通过内核日志中的地址,用这个命令找到对应的代码位置。另外,用户可能在实际开发中遇到需要分析崩溃日志的情况,这时候addr2line就派上用场了。 还要考虑用户可能的深层需求。他们可能正在调试内核问题,遇到了地址无法解析的情况,需要工具帮助定位。或者他们是在学习内核调试的方法,想了解常用工具的使用。需要详细说明使用步骤,比如如何获取崩溃地址,如何运行命令,以及参数的具体含义。 另外,用户引用的内容里有不同的工具路径,比如aarch64-linux-android-addr2line,可能需要指出交叉编译工具链的使用,因为内核可能是在不同架构上运行的,比如ARM架构,所以需要使用对应的addr2line版本。这点在之前的回答里提到过vmlinux用于不同架构的调试,可能需要在这里强调工具链的选择。 还要注意命令中的参数,比如-f显示函数名,-C用于demangle C++符号,-e指定ELF文件。用户示例中用了这些参数,所以在解释时要覆盖这些选项的作用,以及为什么在调试内核时需要它们。 可能需要举例说明,比如给出一个addr2line命令的具体例子,解析一个地址,并展示输出结果,这样用户更容易理解。同时,提醒常见问题,比如地址无效、调试信息缺失等情况,帮助用户避免常见陷阱。 最后,用户之前的问题涉及到vmlinux与压缩镜像的区别,这里可以再次强调vmlinux包含完整的符号和调试信息,而压缩后的镜像可能没有,所以addr2line必须使用vmlinux文件才能正确解析地址。这样连接之前的回答,让信息更连贯。</think>### addr2line -e vmlinux 功能详解 #### 一、核心作用 `addr2line -e vmlinux` 是 Linux 内核调试的核心工具链组件,其核心功能是**将内存地址映射到源代码位置**,通过解析 $vmlinux$ 文件中的调试信息,实现: $$ \text{机器地址} \xrightarrow{\text{ELF符号表+调试信息}} \text{源代码文件:行号} $$ 该命令特别适用于内核崩溃日志分析(如 Oops 信息)、性能剖析数据解析等场景[^1][^2]。 --- #### 二、参数详解(以典型命令为例) ```bash aarch64-linux-android-addr2line -f -C -e vmlinux ffffffc000aa8cb4 ``` | 参数 | 功能说明 | |------|--------------------------------------------------------------------------| | `-e` | 指定 ELF 文件路径(必须与崩溃时运行的内核匹配) | | `-f` | 显示函数名称 | | `-C` | 解码 C++ 符号(demangle,对内核调试通常非必需) | | 地址 | 待解析的 16 进制地址(如 `ffffffc000aa8cb4` 来自内核崩溃日志的 PC 寄存器) | --- #### 三、典型应用场景 1. **内核崩溃分析** 解析 Oops 信息中的指令指针(PC)和堆栈地址: ```bash # 示例崩溃信息片段 PC is at nft_do_chain+0x4c/0x5a8 LR is at nft_do_chain+0x30/0x5a8 # 使用命令 aarch64-linux-android-addr2line -e vmlinux ffffffc000aa8cb4 ``` 输出结果示例: ``` nft_do_chain net/netfilter/nf_tables_core.c:287 ``` 2. **性能剖析定位** 解析 `perf report` 输出的热点地址: ```bash # 解析 perf 记录的地址 addr2line -e vmlinux -f 0xffffff8008084560 ``` 3. **动态追踪工具配合** 与 ftrace/kprobe 等工具结合使用: ```bash # 解析函数入口地址 echo 'p:myprobe nft_do_chain' > /sys/kernel/debug/tracing/kprobe_events cat /sys/kernel/debug/tracing/trace | grep myprobe | awk '{print $3}' | xargs addr2line -e vmlinux ``` --- #### 四、使用前提与验证 | 必要条件 | 验证方法 | |-------------------------------|------------------------------------| | 1. 使用与运行内核匹配的vmlinux | `uname -r` 与编译版本一致[^1] | | 2. 保留内核符号表 | `nm vmlinux | grep __start___ex_table` | | 3. 确保调试信息未剥离 | `file vmlinux` 显示 "with debug_info" | --- #### 五、常见问题排查 1. **地址无效** ```bash addr2line: DWARF error: could not find variable specification at offset 0x0 ``` **解决方案**:确认地址是否来自内核空间(通常以 `0xffffff` 开头) 2. **符号未匹配** ```bash ??:0 # 输出异常 ``` **原因**: - 使用的 vmlinux 与运行内核版本不一致 - 内核编译时未启用 `CONFIG_DEBUG_INFO` 选项[^3] 3. **交叉编译环境问题** ```bash Format not recognized ``` **处理**:必须使用与目标架构匹配的 addr2line 工具(如示例中的 `aarch64-linux-android-addr2line`) ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值