支持作者新书,点击京东购买《Yocto项目实战教程:高效定制嵌入式Linux系统》
视频教程请关注 B 站:“嵌入式 Jerry”
/proc/kallsyms 全面解析和实战应用指南
作为 Linux 内核调试中的基础技术之一,
/proc/kallsyms
是很多内核工具和调试技术的基石。本文将给出一篇绝对全面的指南,包括不同类型的内核符号,配合 ftrace、perf、kprobe等调试工具的实战应用,并介绍为什么它是 Linux 内核开发者必备技能之一。
一、kallsyms 是什么?
/proc/kallsyms
是 Linux 内核开启 CONFIG_KALLSYMS
选项时由内核自动创建的一个虚拟文件,用于列出内核已编译进去的 全部函数和变量等符号信息。
简单理解:
它就是一份「内核函数和变量名 → 内存地址」的映射表。
二、文件格式解读
指令:
cat /proc/kallsyms
每行输出格式:
<地址> <类型> <符号名>
实例:
ffff8000087b38a0 t pca9450_i2c_probe
ffff80000913ba90 d pca9450_volatile_regs
常见类型符号意义:
类型 | 意义 |
---|---|
T | 全局函数(non-static公共函数) |
t | 本地函数(static 静态函数) |
D | 全局变量,初始化的 data |
d | 本地变量(static 静态变量) |
B/b | BSS 段,未初始化的全局变量 |
R/r | 只读数据(const 或 .rodata段的数据) |
U | 未解析的外部符号(用于用户端) |
三、kallsyms 与各类调试工具的关系
1. 与 ftrace
ftrace 需要用 set_ftrace_filter
指定函数名,函数名必须是存在于 /proc/kallsyms
中的符号,否则无法 trace
实例:
echo pca9450_i2c_probe > /sys/kernel/debug/tracing/set_ftrace_filter
2. 与 perf
perf 抓到地址时,会配合 kallsyms 用来解析函数名:
perf report
# [.] 0xffff8000087b38a0 -> 该地址在 kallsyms 里就是 pca9450_i2c_probe
3. 与 kprobe
如果想用动态方式定位给一个函数扩展方法,需要确认目标函数存在,也来自 kallsyms
echo 'p:p1 pca9450_i2c_probe' > /sys/kernel/debug/tracing/kprobe_events
4. 与 crash / gdb 分析 vmcore
用于分析给定地址是否对应于函数/变量
crash> sym ffff8000087b38a0
ffff8000087b38a0 (t) pca9450_i2c_probe
四、实战场景分析
实战1: ftrace 无法跟踪 probe 函数?
现象:
echo pca9450_probe > set_ftrace_filter
cat trace_pipe # 一直不出现
解决:
- 用 kallsyms 确认函数名
- 发现真正的函数名是
pca9450_i2c_probe
cat /proc/kallsyms | grep pca9450
实战2: perf 拦到地址,不知是什么函数?
# perf report 中显示
0xffff8000087b38a0
# 用 kallsyms 查看
cat /proc/kallsyms | grep 87b38a0
# 输出: pca9450_i2c_probe
实战3:实时性调试查看 symbol 是否被注册
# 尝试 insmod 定制模块
insmod mymod.ko
# 确认模块里定义的 symbol 是否已出现
cat /proc/kallsyms | grep my_driver_probe
五、安全性与进阶
地址隐藏:
如果看到 kallsyms 里是这样的:
00000000 T panic
00000000 T printk
说明启用了 KASLR 隐藏地址,或者 /proc/kallsyms
只对 root 可见
配置项
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y # 包括 static 函数等
CONFIG_KALLSYMS_BASE_RELATIVE=y
六、实用工具补充
配合 addr2line 转换地址为源码行
# 需要 vmlinux 有调试信息
addr2line -e vmlinux 0x87b38a0
配合 nm 查看 symbol
nm vmlinux | grep pca9450
七、总结
/proc/kallsyms
是 Linux 内核很根基的一个 symbol 管理模块- 它不是调试工具,但是几乎所有内核调试工具都依赖于它(ftrace, perf, crash, eBPF, kprobe)
- 对于写内核模块,调试 probe/不规则对象,跟踪 symbol 时都依赖它
- 配合
/proc/kallsyms
的完备体系: vmlinux 、nm 、addr2line 、dwarves (如 pahole)
如果你在做调试、实施性分析、核心无控 bug 跟踪,不熟悉
/proc/kallsyms
的用法和本质,都是一个分数不过兴的调试环境。
支持作者新书,点击京东购买《Yocto项目实战教程:高效定制嵌入式Linux系统》
视频教程请关注 B 站:“嵌入式 Jerry”