diff options
| author | Paul Buetow <paul@buetow.org> | 2026-02-23 10:45:21 +0200 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-02-23 10:45:21 +0200 |
| commit | 59df9d8c4562ee46a37256e1330bd5e65781eba7 (patch) | |
| tree | 73bf9f16226b6868a5bd2a05ef2d62383075a22c /internal | |
| parent | faeb28d0e0e8ad6b1ec1bbd7aa4d0db1f07013e5 (diff) | |
Track pidfd_getfd returned fds in eventloop
Diffstat (limited to 'internal')
| -rw-r--r-- | internal/eventloop.go | 11 | ||||
| -rw-r--r-- | internal/eventloop_test.go | 64 |
2 files changed, 75 insertions, 0 deletions
diff --git a/internal/eventloop.go b/internal/eventloop.go index f4f7a7c..345150c 100644 --- a/internal/eventloop.go +++ b/internal/eventloop.go @@ -323,6 +323,17 @@ func (e *eventLoop) tracepointExited(exitEv event.Event, ch chan<- *event.Pair) e.files[newFd] = fdFile.Dup(newFd) } } + if ep.Is(SYS_ENTER_PIDFD_GETFD) { + retEv, ok := ep.ExitEv.(*RetEvent) + if !ok { + panic("expected *types.RetEvent") + } + if newFd := int32(retEv.Ret); newFd >= 0 { + transferredFile := file.NewFdWithPid(newFd, v.Pid) + e.files[newFd] = transferredFile + ep.File = transferredFile + } + } if retEv, ok := ep.ExitEv.(*RetEvent); ok { ep.Bytes = bytesFromRet(retEv) diff --git a/internal/eventloop_test.go b/internal/eventloop_test.go index f147f41..9c26372 100644 --- a/internal/eventloop_test.go +++ b/internal/eventloop_test.go @@ -3,6 +3,7 @@ package internal import ( "context" "os" + "path/filepath" "syscall" "testing" "time" @@ -40,6 +41,8 @@ func TestEventloop(t *testing.T) { "FsyncEventTest": makeFsyncEventTestData(t), "SyncFileRangeEventTest": makeSyncFileRangeEventTestData(t), "CopyFileRangeEventTest": makeCopyFileRangeEventTestData(t), + "PidfdGetfdEventTest": makePidfdGetfdEventTestData(t), + "PidfdGetfdFailureTest": makePidfdGetfdFailureTestData(t), "MmapEventTest": makeMmapEventTestData(t), "MsyncEventTest": makeMsyncEventTestData(t), "FtruncateEventTest": makeFtruncateEventTestData(t), @@ -679,6 +682,67 @@ func makeSyncFileRangeEventTestData(t *testing.T) (td testData) { return td } +func makePidfdGetfdEventTestData(t *testing.T) (td testData) { + pid := uint32(os.Getpid()) + tid := uint32(os.Getpid()) + + dir := t.TempDir() + path := filepath.Join(dir, "pidfd-getfd-source.txt") + fd, err := syscall.Open(path, syscall.O_RDWR|syscall.O_CREAT|syscall.O_TRUNC, 0o644) + if err != nil { + t.Fatalf("open source file: %v", err) + } + t.Cleanup(func() { syscall.Close(fd) }) + + enterEv, enterEvBytes := makeEnterFdEvent(t, defaulTime, pid, tid, 9999, types.SYS_ENTER_PIDFD_GETFD) + td.rawTracepoints = append(td.rawTracepoints, enterEvBytes) + + exitEv, exitEvBytes := makeExitRetEvent(t, defaulTime+100, pid, tid, types.SYS_EXIT_PIDFD_GETFD, int64(fd)) + td.rawTracepoints = append(td.rawTracepoints, exitEvBytes) + + td.validates = append(td.validates, func(t *testing.T, el *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 pidfd_getfd to attach returned file") + } + if got, want := ep.File.Name(), path; got != want { + t.Errorf("Expected transferred file '%v' but got '%v'", want, got) + } + if _, ok := el.files[int32(fd)]; !ok { + t.Errorf("Expected transferred fd %d to be tracked", fd) + } + }) + + return td +} + +func makePidfdGetfdFailureTestData(t *testing.T) (td testData) { + enterEv, enterEvBytes := makeEnterFdEvent(t, defaulTime, defaultPid, defaultTid, 9999, types.SYS_ENTER_PIDFD_GETFD) + td.rawTracepoints = append(td.rawTracepoints, enterEvBytes) + + exitEv, exitEvBytes := makeExitRetEvent(t, defaulTime+100, defaultPid, defaultTid, types.SYS_EXIT_PIDFD_GETFD, -1) + td.rawTracepoints = append(td.rawTracepoints, exitEvBytes) + + td.validates = append(td.validates, func(t *testing.T, el *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 _, ok := el.files[9999]; ok { + t.Errorf("Expected no tracked fd for failed pidfd_getfd") + } + }) + + return td +} + func makeCopyFileRangeEventTestData(t *testing.T) (td testData) { srcFd := int32(49) dstFd := int32(50) |
