如何使用bpftrace探测内核函数中的局部变量var1
使用bpftrace探测内核函数局部变量的方法
要获取内核函数fun1中局部变量var1的值,核心难点在于局部变量不像函数参数那样有固定的调用约定偏移,需要借助调试信息或手动计算栈偏移来实现,具体方法如下:
方法一:利用内核DWARF调试信息(推荐)
如果你的系统内核编译时包含了DWARF调试信息(通常需要安装对应内核版本的调试包,比如RedHat系的kernel-devel、Debian系的linux-image-$(uname -r)-dbg),或者自定义编译内核时开启了CONFIG_DEBUG_INFO选项,bpftrace可以直接通过变量名访问局部变量。
示例bpftrace命令:
bpftrace -e 'kprobe:fun1 { printf("var1的值: %d\n", var1); }'
直接在kprobe探针中引用var1即可,bpftrace会通过调试信息自动解析变量的栈位置。
方法二:手动计算栈偏移(无调试信息时使用)
如果没有调试信息,需要先反汇编内核函数,找到var1相对于栈基指针(如x86架构的rbp、ARM架构的fp)的偏移:
- 反汇编目标内核函数,以x86架构为例:
objdump -d /usr/lib/debug/lib/modules/$(uname -r)/vmlinux | grep -A 30 fun1 - 从反汇编结果中定位
var1的栈偏移,比如发现var1存储在rbp-0x8的位置。 - 在bpftrace中通过栈指针偏移访问变量:
bpftrace -e 'kprobe:fun1 { printf("var1的值: %d\n", *(int*)(reg("rbp") - 0x8)); }'
注意事项
- 内核编译优化(如
-O2及以上)可能会将局部变量优化到寄存器中,甚至直接消除变量,这种情况下无论哪种方法都无法探测到var1。 - 如果目标函数被编译器内联,原函数的栈结构会被合并到调用函数中,也无法直接探测到原函数的局部变量。
- 运行bpftrace需要root权限或具备
CAP_BPF等相关权限。
内容的提问来源于stack exchange,提问作者boycechen
相关产品推荐
相关产品推荐

