Linux ftrace无法捕获已加载内核模块的函数调用该如何解决
问题原因及解决步骤
1. 外部模块编译缺失ftrace所需的编译参数
内核自带的模块编译时会自动注入ftrace要求的编译标记,而你自行编译外部模块hello.ko时默认没有这些参数,导致函数入口没有预留ftrace的hook点位,哪怕符号出现在available_filter_functions列表中也无法被跟踪。
aarch64平台下需要在模块Makefile中添加如下编译参数:
ccflags-y += -fpatchable-function-entry=2
重新编译模块后再加载测试。
2. CPU绑定与跟踪掩码不匹配
- 你代码中将线程绑定到了CPU2,但未检查
kthread_bind的返回值,若你启动QEMU时分配的vCPU数量小于3,CPU2不存在,绑定操作会直接失败。可以先注释掉kthread_bind(mythread,2);这行代码,简化测试场景。 - 检查ftrace的跟踪CPU掩码,默认可能未开启对应CPU的跟踪:
# 查看当前跟踪的CPU掩码 cat /sys/kernel/debug/tracing/tracing_cpumask # 开启所有CPU的跟踪 echo 0xf > /sys/kernel/debug/tracing/tracing_cpumask
3. 目标函数被编译器内联
编译器可能会将简单的hello_log函数内联到调用处,导致函数没有独立的入口点,ftrace无法捕获。修改函数定义添加__noinline标记强制不内联:
__noinline void hello_log(void) { printk(KERN_INFO "should I stop\n"); }
4. 测试流程优化
- 加载更新后的模块后,先确认目标函数已进入可过滤列表:
cat /sys/kernel/debug/tracing/available_filter_functions | grep hello_log - 先用更简单的function tracer测试,排除function_graph的额外影响:
确认function tracer能正常捕获后,再切换到function_graph tracer测试。cd /sys/kernel/debug/tracing echo 0 > tracing_on echo > trace # 清空历史trace buffer echo function > current_tracer echo hello_log > set_ftrace_filter echo 1 > tracing_on sleep 10 # 等待至少2个调用周期(你的函数每5秒调用一次) cat trace
内容的提问来源于stack exchange,提问作者InsaneCoder
相关产品推荐
相关产品推荐

