summaryrefslogtreecommitdiff
path: root/internal/eventloop.go
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-03-01 23:33:46 +0200
committerPaul Buetow <paul@buetow.org>2026-03-01 23:33:46 +0200
commit3690b89082215ff5c1fc84110074cf08b1b8909c (patch)
treee89f32688b64a467cb804e9df615a32cc6c2522c /internal/eventloop.go
parent3a438f0381a21c0055db3cce3164ff0ef5970cc0 (diff)
Route non-fatal event-loop warnings to TUI
Diffstat (limited to 'internal/eventloop.go')
-rw-r--r--internal/eventloop.go79
1 files changed, 64 insertions, 15 deletions
diff --git a/internal/eventloop.go b/internal/eventloop.go
index 6d4b065..f303f65 100644
--- a/internal/eventloop.go
+++ b/internal/eventloop.go
@@ -43,6 +43,7 @@ type eventLoop struct {
flamegraph flamegraph.IorDataCollector // Storing all paths in a map structure for analysis
liveTrie *flamegraph.LiveTrie
printCb func(ep *event.Pair) // Callback to print the event
+ warningCb func(message string) // Optional callback for non-fatal event processing warnings
cfg eventLoopConfig
// Statistics
@@ -144,7 +145,12 @@ func (e *eventLoop) run(ctx context.Context, rawCh <-chan []byte) {
if e.cfg.flamegraphEnable {
fmt.Println("Waiting for flamegraph")
- <-e.flamegraph.Done
+ if err := <-e.flamegraph.Done; err != nil {
+ e.notifyWarning(fmt.Sprintf("Flamegraph generation failed: %v", err))
+ if e.warningCb == nil {
+ fmt.Println("Flamegraph generation failed:", err)
+ }
+ }
}
}
@@ -182,7 +188,8 @@ func (e *eventLoop) processRawEvent(raw []byte, ch chan<- *event.Pair) {
evType := EventType(raw[0])
handler, ok := e.rawHandlers[evType]
if !ok {
- panic(fmt.Sprintf("unhandled event type %v: %v", evType, raw))
+ e.notifyWarning(fmt.Sprintf("Dropped unhandled raw event type %d", evType))
+ return
}
handler(raw, ch)
}
@@ -279,6 +286,7 @@ func (e *eventLoop) tracepointExited(exitEv event.Event, ch chan<- *event.Pair)
// enterEv:SYS_ENTER_OPEN => exitEv:SYS_EXIT_OPEN
if ep.EnterEv.GetTraceId()-1 != ep.ExitEv.GetTraceId() {
e.numTracepointMismatches++
+ e.notifyWarning("Dropped tracepoint pair with mismatched enter/exit IDs")
ep.Recycle()
return
}
@@ -286,9 +294,14 @@ func (e *eventLoop) tracepointExited(exitEv event.Event, ch chan<- *event.Pair)
switch v := ep.EnterEv.(type) {
case *OpenEvent:
openEv := ep.EnterEv.(*OpenEvent)
+ retEvent, ok := ep.ExitEv.(*RetEvent)
+ if !ok {
+ e.recyclePair(ep, "Dropped malformed open exit event")
+ return
+ }
comm := types.StringValue(openEv.Comm[:])
ep.Comm = comm
- if fd := int32(ep.ExitEv.(*RetEvent).Ret); fd >= 0 {
+ if fd := int32(retEvent.Ret); fd >= 0 {
file := file.NewFd(fd, types.StringValue(openEv.Filename[:]), v.Flags)
e.files[fd] = file
ep.File = file
@@ -319,7 +332,12 @@ func (e *eventLoop) tracepointExited(exitEv event.Event, ch chan<- *event.Pair)
nameEvent := ep.EnterEv.(*PathEvent)
if ep.Is(SYS_ENTER_CREAT) {
- if fd := int32(ep.ExitEv.(*RetEvent).Ret); fd >= 0 {
+ retEvent, ok := ep.ExitEv.(*RetEvent)
+ if !ok {
+ e.recyclePair(ep, "Dropped malformed creat exit event")
+ return
+ }
+ if fd := int32(retEvent.Ret); fd >= 0 {
file := file.NewFd(fd, types.StringValue(nameEvent.Pathname[:]),
syscall.O_CREAT|syscall.O_WRONLY|syscall.O_TRUNC)
e.files[fd] = file
@@ -360,10 +378,16 @@ func (e *eventLoop) tracepointExited(exitEv event.Event, ch chan<- *event.Pair)
if ep.Is(SYS_ENTER_DUP) || ep.Is(SYS_ENTER_DUP2) {
fdFile, ok := ep.File.(file.FdFile)
if !ok {
- panic("expected a file.FdFile")
+ e.recyclePair(ep, "Dropped malformed dup source event")
+ return
+ }
+ retEvent, ok := ep.ExitEv.(*RetEvent)
+ if !ok {
+ e.recyclePair(ep, "Dropped malformed dup exit event")
+ return
}
// Duplicating fd
- newFd := int32(ep.ExitEv.(*RetEvent).Ret)
+ newFd := int32(retEvent.Ret)
if newFd != -1 {
e.files[newFd] = fdFile.Dup(newFd)
}
@@ -371,7 +395,8 @@ func (e *eventLoop) tracepointExited(exitEv event.Event, ch chan<- *event.Pair)
if ep.Is(SYS_ENTER_PIDFD_GETFD) {
retEv, ok := ep.ExitEv.(*RetEvent)
if !ok {
- panic("expected *types.RetEvent")
+ e.recyclePair(ep, "Dropped malformed pidfd_getfd exit event")
+ return
}
if newFd := int32(retEv.Ret); newFd >= 0 {
transferredFile := file.NewFdWithPid(newFd, v.Pid)
@@ -400,9 +425,15 @@ func (e *eventLoop) tracepointExited(exitEv event.Event, ch chan<- *event.Pair)
// Duplicating fd
fdFile, ok := ep.File.(file.FdFile)
if !ok {
- panic("expected a file.FdFile")
+ e.recyclePair(ep, "Dropped malformed dup3 source event")
+ return
+ }
+ retEvent, ok := ep.ExitEv.(*RetEvent)
+ if !ok {
+ e.recyclePair(ep, "Dropped malformed dup3 exit event")
+ return
}
- newFd := int32(ep.ExitEv.(*RetEvent).Ret)
+ newFd := int32(retEvent.Ret)
if newFd != -1 {
duppedFdFile := fdFile.Dup(newFd)
duppedFdFile.AddFlags(dup3Event.Flags & syscall.O_CLOEXEC)
@@ -413,7 +444,8 @@ func (e *eventLoop) tracepointExited(exitEv event.Event, ch chan<- *event.Pair)
tid := ep.EnterEv.GetTid()
retEvent, ok := ep.ExitEv.(*RetEvent)
if !ok {
- panic("expected *types.RetEvent for open_by_handle_at exit")
+ e.recyclePair(ep, "Dropped malformed open_by_handle_at exit event")
+ return
}
if fd := int32(retEvent.Ret); fd >= 0 {
@@ -441,7 +473,8 @@ func (e *eventLoop) tracepointExited(exitEv event.Event, ch chan<- *event.Pair)
if ep.Is(SYS_ENTER_IO_URING_SETUP) {
retEvent, ok := exitEv.(*types.RetEvent)
if !ok {
- panic("expected *types.RetEvent")
+ e.recyclePair(ep, "Dropped malformed io_uring_setup exit event")
+ return
}
if fd := int32(retEvent.Ret); fd >= 0 {
fdFile := file.NewFdWithPid(fd, v.Pid)
@@ -452,7 +485,8 @@ func (e *eventLoop) tracepointExited(exitEv event.Event, ch chan<- *event.Pair)
if ep.Is(SYS_ENTER_GETCWD) {
retEvent, ok := ep.ExitEv.(*types.RetEvent)
if !ok {
- panic("expected *types.RetEvent")
+ e.recyclePair(ep, "Dropped malformed getcwd exit event")
+ return
}
if retEvent.Ret > 0 {
if cwd, err := os.Readlink(fmt.Sprintf("/proc/%d/cwd", ep.EnterEv.GetTid())); err == nil {
@@ -481,7 +515,8 @@ func (e *eventLoop) tracepointExited(exitEv event.Event, ch chan<- *event.Pair)
retEvent, ok := exitEv.(*types.RetEvent)
if !ok {
- panic("expected *types.RetEvent")
+ e.recyclePair(ep, "Dropped malformed fcntl exit event")
+ return
}
// Syscall returned -1, nothing was changed with the fd
if retEvent.Ret == -1 {
@@ -490,7 +525,8 @@ func (e *eventLoop) tracepointExited(exitEv event.Event, ch chan<- *event.Pair)
fdFile, ok := ep.File.(file.FdFile)
if !ok {
- panic("expected a file.FdFile")
+ e.recyclePair(ep, "Dropped malformed fcntl file event")
+ return
}
// See fcntl(2) for implementation details
@@ -511,7 +547,8 @@ func (e *eventLoop) tracepointExited(exitEv event.Event, ch chan<- *event.Pair)
}
default:
- panic(fmt.Sprintf("unknown type: %v", v))
+ e.recyclePair(ep, "Dropped malformed enter event")
+ return
}
prevPairTime, _ := e.prevPairTimes[ep.EnterEv.GetTid()]
ep.CalculateDurations(prevPairTime)
@@ -519,6 +556,18 @@ func (e *eventLoop) tracepointExited(exitEv event.Event, ch chan<- *event.Pair)
ch <- ep
}
+func (e *eventLoop) recyclePair(ep *event.Pair, warning string) {
+ e.notifyWarning(warning)
+ ep.Recycle()
+}
+
+func (e *eventLoop) notifyWarning(message string) {
+ if e.warningCb == nil || message == "" {
+ return
+ }
+ e.warningCb(message)
+}
+
func (e *eventLoop) comm(tid uint32) string {
if comm, ok := e.comms[tid]; ok {
return comm