Re: [PATCH v1 23/58] perf python: Add LiveSession helper

sashiko-bot
2026-04-20T02:14:23Z

Sashiko AI review found 3 potential issue(s):
- [Medium] File descriptors are leaked if `self.evlist.mmap()` raises an exception.
- [Medium] Events are not configured for sampling, preventing the generation of `PERF_RECORD_SAMPLE` events.
- [Medium] Unhandled `InterruptedError` during `evlist.poll()` causes the session to crash.
--

commit 124f0d8a2c7d1fd2c50503c9af92fd9cf4a5c8b5
Author: Ian Rogers <irogers@google.com>

perf python: Add LiveSession helper

This commit introduces the LiveSession class in tools/perf/python/perf_live.py.
It allows running callbacks for live events using perf.evlist and
perf.parse_events, avoiding the need to fork a perf record process or use a
perf.data file.

> diff --git a/tools/perf/python/perf_live.py b/tools/perf/python/perf_live.py
> new file mode 100755
> index 0000000000000..81d92f720b586
> --- /dev/null
> +++ b/tools/perf/python/perf_live.py
[ ... ]
> + def run(self):
> + """Run the live session."""
> + self.evlist.open()
> + self.evlist.mmap()
> +
> + try:

If self.evlist.mmap() raises an exception, will the file descriptors acquired
by self.evlist.open() be leaked?

Since the try block begins after these calls, an exception in mmap() would
cause the function to exit without reaching the finally clause that calls
self.evlist.close().

Could the try block be expanded to include self.evlist.mmap() to ensure
cleanup occurs on all exit paths?

> + while True:
> + # Poll for events with 100ms timeout
> + self.evlist.poll(100)

Can this poll call raise an InterruptedError?

The Python extension wraps the system poll() call. If it is interrupted by a
non-fatal signal like SIGWINCH, it returns -1 with EINTR, which translates
to an InterruptedError in Python.

Since the except block below only catches KeyboardInterrupt, would this cause
the live session to crash on normal signals instead of safely retrying?

> + for cpu in self.cpus:
> + event = self.evlist.read_on_cpu(cpu)
> + while event:
> + if event.type == perf.RECORD_SAMPLE:

Will event.type ever equal perf.RECORD_SAMPLE with this setup?

The LiveSession constructor initializes the event list using
perf.parse_events(), which configures standard events as counting events
(attr.sample_period = 0) by default.

Because self.evlist.config() is never called to enable sampling or set up
PERF_SAMPLE_* fields, it seems the kernel will not generate
PERF_RECORD_SAMPLE events. Could this cause the poll loop to time out
indefinitely instead of invoking the callback?

> + self.sample_callback(event)
> + event = self.evlist.read_on_cpu(cpu)
> + except KeyboardInterrupt:
> + pass
> + finally:
> + self.evlist.close()

--
Sashiko AI review · https://sashiko.dev/#/patchset/20260419235911.2186050-1-irogers@google.com?part=23