如何用ftrace追踪可加载内核模块的静态函数?以zram_init为例
追踪可加载内核模块中的静态函数
核心问题分析
你遇到的echo zram_init > set_graph_function失败,本质是静态函数未导出内核符号,导致ftrace无法通过函数名定位到它;模块未加载的问题只需先执行modprobe zram就能解决,这里重点讲静态函数的追踪方案。
方案1:修改模块源码导出符号(适合可重新编译场景)
如果能拿到模块源码并重新编译,这是最直接的方式:
- 找到目标静态函数(比如
zram_init或zram的writepage实现),去掉static修饰符,或者添加EXPORT_SYMBOL_GPL()宏导出符号:// 以zram_init为例 int zram_init(...) { // 原函数逻辑 } EXPORT_SYMBOL_GPL(zram_init); - 重新编译模块(
make -C /lib/modules/$(uname -r)/build M=$(pwd) modules),加载新模块后,就能直接用ftrace的set_graph_function或set_ftrace_filter追踪该函数。
注意:静态函数设计为内部私有,导出仅适合调试场景,不要用于生产环境。
方案2:用kprobe动态追踪(无需修改源码,通用方案)
kprobe可以直接追踪内核任意地址,不受符号导出限制,步骤如下:
步骤1:获取静态函数的实际地址
- 先加载模块:
modprobe zram - 查看模块加载基址:
cat /sys/module/zram/sections/.text # 输出类似:0xffffffffc0a20000 - 用
nm查看模块文件中的静态函数偏移:nm zram.ko | grep zram_init # 输出类似:0000000000001234 t zram_init - 计算实际地址:基址 + 偏移(比如
0xffffffffc0a20000 + 0x1234 = 0xffffffffc0a21234)
步骤2:注册kprobe并开启追踪
- 注册探测点(替换为实际地址):
echo 'p:my_zram_probe 0xffffffffc0a21234' > /sys/kernel/debug/kprobes/events - 开启追踪:
echo 1 > /sys/kernel/debug/tracing/tracing_on - 查看trace输出:
cat /sys/kernel/debug/tracing/trace
针对zram writepage的追踪
zram的writepage函数会注册到文件系统的address_space_operations中,你可以:
- 先追踪通用的
filemap_writepage函数,在trace中查看调用的具体函数地址,再将该地址对应到zram的静态writepage函数,用kprobe追踪; - 或者直接通过
nm zram.ko找到zram writepage函数的偏移,计算实际地址后注册kprobe。
方案3:利用内核静态tracepoint(如果模块自带)
部分内核模块会内置调试用的静态tracepoint,查看是否有zram相关事件:
ls /sys/kernel/debug/tracing/events/zram/
如果存在zram_writepage等事件,直接启用即可:
echo 1 > /sys/kernel/debug/tracing/events/zram/zram_writepage/enable
这种方式无需关心函数是否静态,直接捕获业务逻辑事件。
追踪模块初始化函数(如zram_init)
如果要追踪未加载模块的初始化函数,可以结合模块加载事件+ kprobe:
- 先开启模块加载事件追踪:
echo 1 > /sys/kernel/debug/tracing/events/module/module_load/enable - 加载模块:
modprobe zram,从trace中提取zram的加载基址; - 用
nm zram.ko得到zram_init的偏移,计算实际地址后注册kprobe; - 重新加载模块(
rmmod zram && modprobe zram),就能捕获初始化函数的调用。
必要的内核配置
确保内核开启了以下配置(可通过zcat /proc/config.gz | grep <CONFIG>验证):
CONFIG_KPROBES=y:启用kprobeCONFIG_FTRACE=y:启用ftrace框架CONFIG_KALLSYMS_ALL=y:显示所有符号(包括静态函数)CONFIG_DEBUG_FS=y:挂载debugfs(默认已挂载到/sys/kernel/debug)
内容的提问来源于stack exchange,提问作者HardcoreHenry
相关产品推荐
相关产品推荐

