summaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-02-21 13:13:14 +0200
committerPaul Buetow <paul@buetow.org>2026-02-21 13:13:14 +0200
commitb766efdd3547b4f8a0d0374dafb83b6832d6e43e (patch)
tree4b797d3e26a551007b07c334759545afb9d240bb /internal
parent6d53aeb16bee34eeee14b457cd0e7b0811bee873 (diff)
Track io_uring setup fds in event loop
Amp-Thread-ID: https://ampcode.com/threads/T-019c7fd9-5870-77b7-9909-3eb7550d17bb Co-authored-by: Amp <amp@ampcode.com>
Diffstat (limited to 'internal')
-rw-r--r--internal/eventloop.go13
-rw-r--r--internal/eventloop_test.go33
2 files changed, 45 insertions, 1 deletions
diff --git a/internal/eventloop.go b/internal/eventloop.go
index 91af7c9..c5467ec 100644
--- a/internal/eventloop.go
+++ b/internal/eventloop.go
@@ -345,6 +345,17 @@ func (e *eventLoop) tracepointExited(exitEv event.Event, ch chan<- *event.Pair)
}
case *NullEvent:
+ if ep.Is(SYS_ENTER_IO_URING_SETUP) {
+ retEvent, ok := exitEv.(*types.RetEvent)
+ if !ok {
+ panic("expected *types.RetEvent")
+ }
+ if fd := int32(retEvent.Ret); fd >= 0 {
+ fdFile := file.NewFdWithPid(fd, v.Pid)
+ e.files[fd] = fdFile
+ ep.File = fdFile
+ }
+ }
ep.Comm = e.comm(ep.EnterEv.GetTid())
if !e.filter.eventPair(ep) {
ep.Recycle()
@@ -404,7 +415,7 @@ func (e *eventLoop) tracepointExited(exitEv event.Event, ch chan<- *event.Pair)
// TODO: mmap, msync...
// TODO: getcwd?
// TODO: sync_file_range
- // TODO: https://man7.org/linux/man-pages/man2/io_uring_enter.2.html (already captured but without FDs)
+ // TODO: io_uring_enter/io_uring_register are captured without fd arguments.
prevPairTime, _ := e.prevPairTimes[ep.EnterEv.GetTid()]
ep.CalculateDurations(prevPairTime)
diff --git a/internal/eventloop_test.go b/internal/eventloop_test.go
index f608eab..f53e6f3 100644
--- a/internal/eventloop_test.go
+++ b/internal/eventloop_test.go
@@ -50,6 +50,7 @@ func TestEventloop(t *testing.T) {
// NullEvent tests
"SyncEventTest": makeSyncEventTestData(t),
"IoUringSetupEventTest": makeIoUringSetupEventTestData(t),
+ "IoUringSetupFailureTest": makeIoUringSetupFailureTestData(t),
// Dup3Event tests
"Dup3EventTest": makeDup3EventTestData(t),
"Dup3WithCloexecTest": makeDup3WithCloexecTestData(t),
@@ -901,6 +902,38 @@ func makeIoUringSetupEventTestData(t *testing.T) (td testData) {
if !exitEv.Equals(ep.ExitEv) {
t.Errorf("Expected '%v' but got '%v'", exitEv, ep.ExitEv)
}
+ if ep.File == nil {
+ t.Errorf("Expected io_uring fd to be tracked")
+ }
+ if _, ok := el.files[48]; !ok {
+ t.Errorf("Expected io_uring fd 48 to be tracked")
+ }
+ })
+
+ return td
+}
+
+func makeIoUringSetupFailureTestData(t *testing.T) (td testData) {
+ enterEv, enterEvBytes := makeEnterNullEvent(t, defaulTime, defaultPid, defaultTid, types.SYS_ENTER_IO_URING_SETUP)
+ td.rawTracepoints = append(td.rawTracepoints, enterEvBytes)
+
+ // io_uring_setup returns -1 on failure
+ exitEv, exitEvBytes := makeExitRetEvent(t, defaulTime+100, defaultPid, defaultTid, types.SYS_EXIT_IO_URING_SETUP, -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 ep.File != nil {
+ t.Errorf("Expected io_uring_setup failure to have no file tracked")
+ }
+ if len(el.files) != 0 {
+ t.Errorf("Expected no fds to be tracked after io_uring_setup failure")
+ }
})
return td