oops问题定位记录

文章目录

  • 一、前置条件:编译开启调试符号(-g)
    • [1.1 核心编译配置](#1.1 核心编译配置)
    • [1.2 编译产物要求](#1.2 编译产物要求)
  • [二、崩溃现场:提取 Oops 关键信息](#二、崩溃现场:提取 Oops 关键信息)
  • [三、核心工具 1:addr2line 地址转源码行](#三、核心工具 1:addr2line 地址转源码行)
    • [3.1 命令格式](#3.1 命令格式)
    • [3.2 实操示例](#3.2 实操示例)
    • [3.3 输出结果](#3.3 输出结果)
  • [四、兜底工具 2:objdump 反汇编验证](#四、兜底工具 2:objdump 反汇编验证)
    • [4.1 反汇编命令](#4.1 反汇编命令)
    • [4.2 查找崩溃位置](#4.2 查找崩溃位置)
  • 五、完整标准化流程(总结)
  • 六、常用命令速查表
  • 七、注意事项

一、前置条件:编译开启调试符号(-g)

1.1 核心编译配置

编译内核或内核模块时,必须添加 GCC 调试参数,生成符号表和行号信息:

makefile 复制代码
# Makefile 中添加编译参数
CFLAGS += -g    # 生成调试信息(必备)
CFLAGS += -O0   # 关闭编译器优化(推荐,避免行号错位)

1.2 编译产物要求

必须保留带调试符号的文件:

  • 内核:vmlinux(不可压缩的内核镜像,非bzImage)
  • 驱动模块:xxx.ko(未 strip 的原始模块)

二、崩溃现场:提取 Oops 关键信息

系统触发 Oops 后,从 dmesg / 串口日志中获取崩溃地址,核心关注 RIP 字段:

示例 Oops 日志

log 复制代码
RIP: 0010:test_func+0x28/0x80 [my_drv]

关键信息提取

字段 含义
test_func 崩溃函数名
0x28 函数内偏移量(核心)
0x80 函数总大小
my_drv 崩溃所在模块

三、核心工具 1:addr2line 地址转源码行

addr2line 是最快捷的定位工具,直接将偏移量转换为源码文件 + 行号。

3.1 命令格式

bash 复制代码
# 内核崩溃:使用 vmlinux
addr2line -e vmlinux [偏移地址]

# 模块崩溃:使用 xxx.ko
addr2line -e 模块名.ko [偏移地址]

3.2 实操示例

bash 复制代码
# 定位 my_drv.ko 中 相对 test_func(可以看objdump或者编译出的map文件)假如为 0xfffffe80 偏移 0x28 的代码
addr2line -e my_drv.ko 0xfffffe80 + 0x28

3.3 输出结果

plaintext 复制代码
/home/test/drv/my_drv.c:125

✅ 直接定位:my_drv.c 文件 第 125 行 为崩溃代码。

四、兜底工具 2:objdump 反汇编验证

当 addr2line 定位不准时,通过 objdump 反汇编,结合汇编 + 源码交叉验证。

4.1 反汇编命令

bash 复制代码
# 反汇编(带源码混合显示),输出到文件
objdump -dS my_drv.ko > drv_dump.txt
  • -d:反汇编代码段
  • -S:混合显示源码(依赖-g调试符号)

4.2 查找崩溃位置

  1. 打开 drv_dump.txt
  2. 搜索崩溃函数名(test_func)
  3. 找到偏移 0x28 对应的汇编 / 源码行
  4. 直接锁定崩溃逻辑

五、完整标准化流程(总结)

  1. 编译:内核 / 模块添加 -g -O0,保留调试符号;
  2. 抓日志:获取 Oops 日志,提取 函数+偏移量;
  3. 快速定位:使用 addr2line 直接映射源码行;
  4. 深度验证:使用 objdump 反汇编,确认汇编与源码对应关系;
  5. 修复问题:根据定位的代码行分析空指针、内存越界等崩溃根因。

六、常用命令速查表

操作场景 命令示例
模块地址转行号 addr2line -e test.ko 0x28
内核地址转行号 addr2line -e vmlinux 0xffffffff86123456
模块反汇编(带源码) objdump -dS test.ko > dump.log
查看 Oops 日志 `dmesg -T

七、注意事项

  • 必须使用未 strip 的 vmlinux/.ko 文件,strip 会删除调试符号;
  • 编译优化(-O1/-O2)会导致行号错乱,调试时建议用 -O0;
  • 偏移量直接使用 Oops 日志中的数值,无需额外计算
相关推荐
水饺编程1 小时前
第2章:Linux 基础,切换到超级用户
linux·c语言·汇编
便利店10241 小时前
系统活动一抓留存!深入 Linux C/C++ 调试工具之 sysdig
linux·运维·服务器·sysdig
qetfw2 小时前
Bash 变量:export、位置参数与默认值展开验证
linux·开发语言·chrome·bash
其实防守也摸鱼3 小时前
Cylab在线靶场——CTF中的通用技能
linux·数据库·学习·算法·靶场·ctf·学习网络安全
toooooop83 小时前
CentOS 7 内核 3.10.0-1160.119.1 升级指南
linux·运维·centos
码少女3 小时前
Linux——UDP协议和TCP协议
linux·网络·udp·tcp
GeW4 小时前
新质生产力发展路线图Linux、数据库、AI 一个都不能少
linux
kkkkkkkkkk_Z4 小时前
新手自学嵌入式 | 学习日记:Linux驱动复习之系统移植(U-Boot篇)
linux·运维·学习
Rabitebla4 小时前
【系统性学习笔记】Linux 权限篇(二):文件属性、权限修改与目录权限的底层逻辑
linux·c++·笔记·学习·算法
Lsetea5 小时前
curl下载HTTPS文件报23:证书验证成功与本地写入失败分层排查
linux·https·shell·ssl证书·curl