From 0cbf33424a4034bc18c433cb6bf8fd72544a05b4 Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Wed, 19 Mar 2025 22:25:13 +0200 Subject: fix deadlock when exiting of ior doesn't work when there are no events --- internal/eventfilter.go | 1 - internal/eventloop.go | 70 ++++++++++++++++++++++++------------------- internal/flamegraph/worker.go | 1 - internal/ior.go | 7 +++-- 4 files changed, 43 insertions(+), 36 deletions(-) (limited to 'internal') diff --git a/internal/eventfilter.go b/internal/eventfilter.go index c249f20..74ce228 100644 --- a/internal/eventfilter.go +++ b/internal/eventfilter.go @@ -8,7 +8,6 @@ import ( "strings" ) -// TODO: Move to event package? type eventFilter struct { commFilterEnable bool commFilter string diff --git a/internal/eventloop.go b/internal/eventloop.go index ff00671..497522f 100644 --- a/internal/eventloop.go +++ b/internal/eventloop.go @@ -47,8 +47,8 @@ func newEventLoop(flags flags.Flags) *eventLoop { } } -// TODO: Could use the table from the gos project to display the stats here func (e *eventLoop) stats() string { + fmt.Println("Waiting for staps to be ready") <-e.done duration := time.Since(e.startTime) @@ -101,39 +101,17 @@ func (e *eventLoop) events(ctx context.Context, rawCh <-chan []byte) <-chan *eve go func() { defer close(ch) - for raw := range rawCh { + for { select { - case <-ctx.Done(): - return + case raw := <-rawCh: + e.processRawEvent(raw, ch) default: - } - - e.numTracepoints++ - switch EventType(raw[0]) { - case ENTER_OPEN_EVENT: - if ev, ok := e.filter.openEvent(NewOpenEvent(raw)); ok { - e.syscallEnter(ev) - } - case EXIT_OPEN_EVENT: - e.syscallExit(NewFdEvent(raw), ch) - case ENTER_FD_EVENT: - e.syscallEnter(NewFdEvent(raw)) - case EXIT_FD_EVENT: - e.syscallExit(NewFdEvent(raw), ch) - case EXIT_NULL_EVENT: - e.syscallExit(NewNullEvent(raw), ch) - case EXIT_RET_EVENT: - e.syscallExit(NewRetEvent(raw), ch) - case ENTER_NAME_EVENT: - if ev, ok := e.filter.nameEvent(NewNameEvent(raw)); ok { - e.syscallEnter(ev) + select { + case <-ctx.Done(): + return + default: + time.Sleep(time.Millisecond * 10) } - case ENTER_PATH_EVENT: - if ev, ok := e.filter.pathEvent(NewPathEvent(raw)); ok { - e.syscallEnter(ev) - } - default: - panic(fmt.Sprintf("unhandled event type %v: %v", EventType(raw[0]), raw)) } } }() @@ -141,6 +119,36 @@ func (e *eventLoop) events(ctx context.Context, rawCh <-chan []byte) <-chan *eve return ch } +func (e *eventLoop) processRawEvent(raw []byte, ch chan *event.Pair) { + e.numTracepoints++ + switch EventType(raw[0]) { + case ENTER_OPEN_EVENT: + if ev, ok := e.filter.openEvent(NewOpenEvent(raw)); ok { + e.syscallEnter(ev) + } + case EXIT_OPEN_EVENT: + e.syscallExit(NewFdEvent(raw), ch) + case ENTER_FD_EVENT: + e.syscallEnter(NewFdEvent(raw)) + case EXIT_FD_EVENT: + e.syscallExit(NewFdEvent(raw), ch) + case EXIT_NULL_EVENT: + e.syscallExit(NewNullEvent(raw), ch) + case EXIT_RET_EVENT: + e.syscallExit(NewRetEvent(raw), ch) + case ENTER_NAME_EVENT: + if ev, ok := e.filter.nameEvent(NewNameEvent(raw)); ok { + e.syscallEnter(ev) + } + case ENTER_PATH_EVENT: + if ev, ok := e.filter.pathEvent(NewPathEvent(raw)); ok { + e.syscallEnter(ev) + } + default: + panic(fmt.Sprintf("unhandled event type %v: %v", EventType(raw[0]), raw)) + } +} + func (e *eventLoop) syscallEnter(enterEv event.Event) { tid := enterEv.GetTid() if !e.filter.commFilterEnable { diff --git a/internal/flamegraph/worker.go b/internal/flamegraph/worker.go index e590163..09458fd 100644 --- a/internal/flamegraph/worker.go +++ b/internal/flamegraph/worker.go @@ -37,7 +37,6 @@ func (w worker) run(ctx context.Context, wg *sync.WaitGroup, ch <-chan *event.Pa pathMap[traceId] = cnt w.collapsed[filePath] = pathMap - // TODO: Enable Go race detector ev.Recycle() default: diff --git a/internal/ior.go b/internal/ior.go index 0de3636..0b52340 100644 --- a/internal/ior.go +++ b/internal/ior.go @@ -91,11 +91,12 @@ func Run(flags flags.Flags) { fmt.Println("Probing for", duration) ctx, cancel := context.WithTimeout(context.Background(), duration) - c := make(chan os.Signal, 1) - signal.Notify(c, os.Interrupt, syscall.SIGTERM) + signalCh := make(chan os.Signal, 1) + signal.Notify(signalCh, os.Interrupt, syscall.SIGTERM) go func() { - <-c + <-signalCh + fmt.Println("Received signal, shutting down...") cancel() }() -- cgit v1.2.3