summaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-02-23 09:55:29 +0200
committerPaul Buetow <paul@buetow.org>2026-02-23 09:55:29 +0200
commit9e7b820cfacb50299720b9d391de907d6f3fbdec (patch)
tree9c61cfffa44e407003d369ff1ba5ab99eb64c3f9 /internal
parent55f33883838336c70d483779b0435c6e781b615e (diff)
Fix integration trace expectations and fd/open event handling
Diffstat (limited to 'internal')
-rw-r--r--internal/c/generated_tracepoints.c2
-rw-r--r--internal/eventloop.go5
-rw-r--r--internal/eventloop_test.go31
-rw-r--r--internal/generate/bpfhandler.go4
-rw-r--r--internal/generate/codegen_test.go10
-rw-r--r--internal/generate/testdata.go33
6 files changed, 83 insertions, 2 deletions
diff --git a/internal/c/generated_tracepoints.c b/internal/c/generated_tracepoints.c
index 9f62fd8..ae38cbb 100644
--- a/internal/c/generated_tracepoints.c
+++ b/internal/c/generated_tracepoints.c
@@ -5696,7 +5696,7 @@ int handle_sys_enter_mmap(struct trace_event_raw_sys_enter *ctx) {
ev->pid = pid;
ev->tid = tid;
ev->time = bpf_ktime_get_boot_ns();
- ev->fd = (__s32)ctx->args[0];
+ ev->fd = (__s32)ctx->args[4];
bpf_ringbuf_submit(ev, 0);
return 0;
diff --git a/internal/eventloop.go b/internal/eventloop.go
index 654d0fc..c9151d6 100644
--- a/internal/eventloop.go
+++ b/internal/eventloop.go
@@ -242,11 +242,14 @@ func (e *eventLoop) tracepointExited(exitEv event.Event, ch chan<- *event.Pair)
case *OpenEvent:
openEv := ep.EnterEv.(*OpenEvent)
comm := types.StringValue(openEv.Comm[:])
+ ep.Comm = comm
if fd := int32(ep.ExitEv.(*RetEvent).Ret); fd >= 0 {
file := file.NewFd(fd, types.StringValue(openEv.Filename[:]), v.Flags)
e.files[fd] = file
ep.File = file
- ep.Comm = comm
+ } else {
+ // Keep path information for failed opens so error scenarios remain observable.
+ ep.File = file.NewPathname(openEv.Filename[:])
}
e.comms[openEv.Tid] = comm
diff --git a/internal/eventloop_test.go b/internal/eventloop_test.go
index 319e6c7..09d84ea 100644
--- a/internal/eventloop_test.go
+++ b/internal/eventloop_test.go
@@ -29,6 +29,7 @@ func TestEventloop(t *testing.T) {
"OpenEventTest1": makeOpenEventTestData1(t),
"OpenEventTest2": makeOpenEventTestData2(t),
"OpenEventTest3": makeOpenEventTestData3(t),
+ "OpenEventFailureTest": makeOpenEventFailureTestData(t),
// FdEvent tests
"ReadEventTest": makeReadEventTestData(t),
"WriteEventTest": makeWriteEventTestData(t),
@@ -211,6 +212,36 @@ func makeOpenEventTestData3(t *testing.T) (td testData) {
return td
}
+func makeOpenEventFailureTestData(t *testing.T) (td testData) {
+ enterEv, enterEvBytes := makeEnterOpenEvent(t, defaulTime, defaultPid, defaultTid)
+ td.rawTracepoints = append(td.rawTracepoints, enterEvBytes)
+
+ exitEv, exitEvBytes := makeExitOpenEvent(t, defaulTime+100, defaultPid, defaultTid)
+ exitEv.Ret = -2
+ exitEvBytes, _ = exitEv.Bytes()
+ td.rawTracepoints = append(td.rawTracepoints, exitEvBytes)
+
+ td.validates = append(td.validates, func(t *testing.T, _ *eventLoop, ep *event.Pair) {
+ if !enterEv.Equals(ep.EnterEv) {
+ t.Errorf("Expected '%v' but got '%v'", enterEv, ep.EnterEv)
+ }
+ if !exitEv.Equals(ep.ExitEv) {
+ t.Errorf("Expected '%v' but got '%v'", exitEv, ep.ExitEv)
+ }
+ if ep.File == nil {
+ t.Fatalf("Expected file to be set for failed open")
+ }
+ if got, want := ep.FileName(), types.StringValue(enterEv.Filename[:]); got != want {
+ t.Errorf("Expected file name '%v' but got '%v'", want, got)
+ }
+ if got, want := ep.Comm, types.StringValue(enterEv.Comm[:]); got != want {
+ t.Errorf("Expected comm '%v' but got '%v'", want, got)
+ }
+ })
+
+ return td
+}
+
func makeEnterOpenEvent(t *testing.T, time uint64, pid, tid uint32) (types.OpenEvent, []byte) {
ev := types.OpenEvent{
EventType: types.ENTER_OPEN_EVENT,
diff --git a/internal/generate/bpfhandler.go b/internal/generate/bpfhandler.go
index 1ce6d3e..eb9c4c4 100644
--- a/internal/generate/bpfhandler.go
+++ b/internal/generate/bpfhandler.go
@@ -59,6 +59,10 @@ func generateExtra(tp GeneratedTracepoint, isEnter bool) string {
switch tp.Classification.Kind {
case KindFd:
+ fdIdx := f.FieldNumber("fd")
+ if fdIdx >= 0 {
+ return fmt.Sprintf(" ev->fd = (__s32)ctx->args[%d];\n", fdIdx)
+ }
return " ev->fd = (__s32)ctx->args[0];\n"
case KindDup3:
diff --git a/internal/generate/codegen_test.go b/internal/generate/codegen_test.go
index 6402214..3e48c79 100644
--- a/internal/generate/codegen_test.go
+++ b/internal/generate/codegen_test.go
@@ -149,6 +149,16 @@ func TestGenerateIoUringRegisterHandler(t *testing.T) {
requireContains(t, output, "ev->fd = (__s32)ctx->args[0];")
}
+func TestGenerateMmapHandlerUsesFdArgumentIndex(t *testing.T) {
+ output := generateFromPair(t, FormatMmap, FormatExitMmap)
+
+ requireContains(t, output, `SEC("tracepoint/syscalls/sys_enter_mmap")`)
+ requireContains(t, output, "struct fd_event *ev")
+ requireContains(t, output, "ev->event_type = ENTER_FD_EVENT;")
+ requireContains(t, output, "ev->trace_id = SYS_ENTER_MMAP;")
+ requireContains(t, output, "ev->fd = (__s32)ctx->args[4];")
+}
+
func TestGenerateDup3Handler(t *testing.T) {
output := generateFromPair(t, FormatDup3, FormatExitDup3)
diff --git a/internal/generate/testdata.go b/internal/generate/testdata.go
index 76228a3..fb68dfb 100644
--- a/internal/generate/testdata.go
+++ b/internal/generate/testdata.go
@@ -168,6 +168,39 @@ format:
print fmt: "start: 0x%08lx, len: 0x%08lx, flags: 0x%08lx", ((unsigned long)(REC->start)), ((unsigned long)(REC->len)), ((unsigned long)(REC->flags))
`
+const FormatMmap = `name: sys_enter_mmap
+ID: 100
+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:unsigned long addr; offset:16; size:8; signed:0;
+ field:unsigned long len; offset:24; size:8; signed:0;
+ field:unsigned long prot; offset:32; size:8; signed:0;
+ field:unsigned long flags; offset:40; size:8; signed:0;
+ field:unsigned long fd; offset:48; size:8; signed:0;
+ field:unsigned long off; offset:56; size:8; signed:0;
+
+print fmt: "addr: 0x%08lx, len: 0x%08lx, prot: 0x%08lx, flags: 0x%08lx, fd: 0x%08lx, off: 0x%08lx", ((unsigned long)(REC->addr)), ((unsigned long)(REC->len)), ((unsigned long)(REC->prot)), ((unsigned long)(REC->flags)), ((unsigned long)(REC->fd)), ((unsigned long)(REC->off))
+`
+
+const FormatExitMmap = `name: sys_exit_mmap
+ID: 99
+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
+`
+
const FormatExitMsync = `name: sys_exit_msync
ID: 1028
format: