挂载kprobe时do_sys_open与__x86_sys_open的差异及相关问题咨询
问题解答
一、替换函数名后无法打印文件名的原因
两种写法对应的内核函数参数列表完全不同,和原有BPF逻辑的参数读取逻辑不匹配:
- 原有代码通过
b.get_syscall_prefix().decode() + 'open'获取的是架构对应的系统调用入口函数(比如x86平台下是__x86_sys_open),这类系统调用入口的参数顺序完全匹配用户态syscall的传参顺序,第二个参数就是用户态传入的文件名字符串指针,原有opensnoop的BPF代码就是按照这个偏移读取文件名的。 - 你替换的
do_sys_open是内核内部实现open逻辑的封装函数,参数顺序和系统调用入口完全不同:第一个参数是内核态的文件系统上下文指针,文件名参数的偏移位置发生了变化,部分内核版本中该函数的参数列表还存在额外封装,原有代码按照旧偏移读取到的不是正确的文件名指针,自然不会输出正常的文件名。
二、常见疑问解答
1. attach_kprobe(event=fn)的参数fn是系统调用还是事件?
- 该参数是你要探测的内核符号名称,没有严格限制类型:既可以是系统调用对应的内核函数名,也可以是任意内核导出的内部函数名。只要你传入的符号在内核中存在,kprobe就会在该函数执行时触发你的BPF逻辑。
2. 可用的系统调用列表是否可以从/proc/kallsyms获取?
- 可以。
/proc/kallsyms存储了当前运行内核所有导出的符号,包括所有系统调用对应的内核函数(通常带有sys_前缀或者架构相关的前缀如__x64_sys_),也包括do_sys_open这类内核内部函数,你可以直接从该文件中过滤得到所有可用于kprobe探测的系统调用符号。
内容的提问来源于stack exchange,提问作者phoxd
相关产品推荐
相关产品推荐

