summaryrefslogtreecommitdiff
path: root/internal/generate
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-05-23 20:10:43 +0300
committerPaul Buetow <paul@buetow.org>2026-05-23 20:10:43 +0300
commit4e67c348ef1dc2c0d08f3e90c2affb555b205d0e (patch)
tree5006f1f9c0e27040a2143d63f5cc0dd472f6ce63 /internal/generate
parenta2151af07c58efa3bf541e0273702ae991eda799 (diff)
2c fix epoll_create and pidfd_open flags in BPF codegen
epoll_create(size) was recording size (args[0]) as flags — hardcode to 0 since the syscall has no flags argument. pidfd_open(pid, flags) was recording pid (args[0]) as flags — use args[1] instead. Add test fixtures and codegen tests that verify the correct argument indexes and reject the old wrong ones. Regenerate generated_tracepoints.c. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Diffstat (limited to 'internal/generate')
-rw-r--r--internal/generate/bpfhandler.go4
-rw-r--r--internal/generate/codegen_test.go35
-rw-r--r--internal/generate/testdata.go59
3 files changed, 96 insertions, 2 deletions
diff --git a/internal/generate/bpfhandler.go b/internal/generate/bpfhandler.go
index 95a14b0..3d3db4a 100644
--- a/internal/generate/bpfhandler.go
+++ b/internal/generate/bpfhandler.go
@@ -281,7 +281,7 @@ func generateExtraPipe(f *Format, isEnter bool) string {
// that captures the flags argument. Syscalls not listed here default to "0".
// To add a new eventfd-like syscall, register its flags expression below.
var eventfdFlagsExpr = map[string]string{
- "sys_enter_epoll_create": "(__s32)ctx->args[0]",
+ "sys_enter_epoll_create": "0", // epoll_create(size) has no flags argument
"sys_enter_epoll_create1": "(__s32)ctx->args[0]",
"sys_enter_inotify_init1": "(__s32)ctx->args[0]",
"sys_enter_fanotify_init": "(__s32)ctx->args[0]",
@@ -292,7 +292,7 @@ var eventfdFlagsExpr = map[string]string{
"sys_enter_userfaultfd": "(__s32)ctx->args[0]",
"sys_enter_signalfd4": "(__s32)ctx->args[3]",
"sys_enter_timerfd_create": "(__s32)ctx->args[1]",
- "sys_enter_pidfd_open": "(__s32)ctx->args[0]",
+ "sys_enter_pidfd_open": "(__s32)ctx->args[1]", // pidfd_open(pid, flags): flags at args[1]
"sys_enter_fsmount": "(__s32)ctx->args[1]",
"sys_enter_fsopen": "(__s32)ctx->args[1]",
}
diff --git a/internal/generate/codegen_test.go b/internal/generate/codegen_test.go
index 276a832..d74939b 100644
--- a/internal/generate/codegen_test.go
+++ b/internal/generate/codegen_test.go
@@ -379,6 +379,41 @@ func TestGenerateEventfdHandler(t *testing.T) {
requireContains(t, output, "ev->ret = ctx->ret;")
}
+func TestGenerateEpollCreateHandlerUsesZeroFlags(t *testing.T) {
+ output := generateFromPair(t, FormatEpollCreate, FormatExitEpollCreate)
+
+ requireContains(t, output, "struct eventfd_event *ev")
+ requireContains(t, output, "ev->event_type = ENTER_EVENTFD_EVENT;")
+ requireContains(t, output, "ev->trace_id = SYS_ENTER_EPOLL_CREATE;")
+ // epoll_create(size) has no flags argument; the generated code must
+ // hardcode flags to 0 instead of reading ctx->args[0] (which is size).
+ requireContains(t, output, "__s32 flags = 0;")
+ if strings.Contains(output, "flags = (__s32)ctx->args[0]") {
+ t.Error("epoll_create handler must not use ctx->args[0] (size) as flags")
+ }
+ requireContains(t, output, "ev->ret = -1;")
+ requireContains(t, output, "SEC(\"tracepoint/syscalls/sys_exit_epoll_create\")")
+ requireContains(t, output, "ev->event_type = EXIT_EVENTFD_EVENT;")
+ requireContains(t, output, "ev->ret = ctx->ret;")
+}
+
+func TestGeneratePidfdOpenHandlerUsesArg1Flags(t *testing.T) {
+ output := generateFromPair(t, FormatPidfdOpen, FormatExitPidfdOpen)
+
+ requireContains(t, output, "struct eventfd_event *ev")
+ requireContains(t, output, "ev->event_type = ENTER_EVENTFD_EVENT;")
+ requireContains(t, output, "ev->trace_id = SYS_ENTER_PIDFD_OPEN;")
+ // pidfd_open(pid, flags): flags is at args[1], not args[0] (which is pid).
+ requireContains(t, output, "__s32 flags = (__s32)ctx->args[1];")
+ if strings.Contains(output, "flags = (__s32)ctx->args[0]") {
+ t.Error("pidfd_open handler must not use ctx->args[0] (pid) as flags")
+ }
+ requireContains(t, output, "ev->ret = -1;")
+ requireContains(t, output, "SEC(\"tracepoint/syscalls/sys_exit_pidfd_open\")")
+ requireContains(t, output, "ev->event_type = EXIT_EVENTFD_EVENT;")
+ requireContains(t, output, "ev->ret = ctx->ret;")
+}
+
func TestGenerateEpollCtlHandler(t *testing.T) {
output := generateFromPair(t, FormatEpollCtl, FormatExitEpollCtl)
diff --git a/internal/generate/testdata.go b/internal/generate/testdata.go
index d94c141..9b57983 100644
--- a/internal/generate/testdata.go
+++ b/internal/generate/testdata.go
@@ -1775,3 +1775,62 @@ format:
field:int __syscall_nr; offset:8; size:4; signed:1;
field:long ret; offset:16; size:8; signed:1;
`
+
+// epoll_create(int size) — single argument, no flags.
+const FormatEpollCreate = `name: sys_enter_epoll_create
+ID: 1451
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int __syscall_nr; offset:8; size:4; signed:1;
+ field:int size; offset:16; size:8; signed:0;
+
+print fmt: "size: 0x%08lx", ((unsigned long)(REC->size))
+`
+
+const FormatExitEpollCreate = `name: sys_exit_epoll_create
+ID: 1450
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int __syscall_nr; offset:8; size:4; signed:1;
+ field:long ret; offset:16; size:8; signed:1;
+
+print fmt: "0x%lx", REC->ret
+`
+
+// pidfd_open(pid_t pid, unsigned int flags) — flags at args[1], not args[0].
+const FormatPidfdOpen = `name: sys_enter_pidfd_open
+ID: 1461
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int __syscall_nr; offset:8; size:4; signed:1;
+ field:pid_t pid; offset:16; size:8; signed:0;
+ field:unsigned int flags; offset:24; size:8; signed:0;
+
+print fmt: "pid: 0x%08lx, flags: 0x%08lx", ((unsigned long)(REC->pid)), ((unsigned long)(REC->flags))
+`
+
+const FormatExitPidfdOpen = `name: sys_exit_pidfd_open
+ID: 1460
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int __syscall_nr; offset:8; size:4; signed:1;
+ field:long ret; offset:16; size:8; signed:1;
+
+print fmt: "0x%lx", REC->ret
+`