【发布时间】:2021-12-14 07:06:57
【问题描述】:
在使用 libbpf-bootstrap 时,我得到了 kprobe 系统调用的意外(和奇怪)函数参数。例如,对于带有int close(inf fd) 签名的close 系统调用上的kprobe,我得到了像fd=15761240 这样的巨大fd 值,而预期像fd=4 这样的小整数。在Debian 11 x64 (kernel 5.10.0-7-amd64) 和Ubuntu 21.10 x64 (kernel ~5.13) 上转载此内容。
调试代码:
#include "vmlinux.h"
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>
#include <bpf/bpf_core_read.h>
char LICENSE[] SEC("license") = "Dual BSD/GPL";
// accept4 syscall
// int accept4(int sockfd, struct sockaddr *restrict addr, socklen_t *restrict addrlen);
SEC("kretprobe/__x64_sys_accept4")
int BPF_KRETPROBE(accept, int ret) {
u64 id = bpf_get_current_pid_tgid();
u32 pid = id >> 32;
// filter specific pid for simplicity
if (pid != 31114 || ret < 0) {
return 0;
}
// debug returned file descriptor
bpf_printk("opened pid=%d fd=%d", pid, ret);
return 0;
}
// close syscall
// int close(int fd);
SEC("kprobe/__x64_sys_close")
int BPF_KPROBE(close, int fd) {
u64 id = bpf_get_current_pid_tgid();
u32 pid = id >> 32;
// filter specific pid for simplicity
if (pid != 31114) {
return 0;
}
// debug fd arg (expected to be equal to fd returned on accept4)
bpf_printk("closed pid=%d fd=%d", pid, fd);
return 0;
}
结果(见意外的fd=4 与fd=15761240 的差异):
$ cat /sys/kernel/debug/tracing/trace_pipe
main-31114 [001] d... 9069.254408: bpf_trace_printk: opened pid=31114 fd=4
main-31114 [001] d... 9069.321946: bpf_trace_printk: closed pid=31114 fd=15761240
我尝试更改 vmlinux.h:首先使用 libbbpf-bootstrap 提供的 vmlinux.h,然后使用来自实例操作系统内核的“本机”vmlinux.h,在这两种方式上我都遇到了上述问题。
还尝试以 BCC 方式运行相同的 bpf 程序(在运行时使用 bcc 编译),其中 kprobes 声明时没有 BPF_KPROBE 宏,如下所示:
int syscall__probe_close_entry(struct pt_regs *ctx, int fd) { ... }
它按预期工作:fd=4 在所有调试点。
是 BPF_KPROBE 宏错误/与内核不兼容还是我遗漏了什么?
【问题讨论】:
-
这很奇怪!即使没有
BPF_KPROBE,直接使用PT_REGS_PARM1_CORE(ctx)也会产生相同的fd值。 gist.github.com/nyrahul/5cb87f8c9a8e29046b3aa763b0b9633f 另外,使用密件抄送也对我有用! -
你检查过
bpftool prog dump对应的BPF字节码了吗?也许比较 bcc 和 libbpf-bootstrap 的字节码会有所帮助?