[PATCH 1/1] libtracecmd: fix memory leak on partial reverse iteration
Felix Moessbauer <[email protected]> Fri, 21 Nov 2025 14:47:49 +0100
| Newsgroups | org.kernel.vger.linux-trace-devel |
|---|---|
| Message-ID | <[email protected]> |
When calling tracecmd_iterate_events_reverse with a callback that does not always return 0, the trace is only partially iterated. By that, the non-iterated records are leaked, resulting in the error: 1 pages still allocated on cpu <cpu> We fix this by always iterating the remaining events on all selected CPUs. In the full iteration case, this stops on the first record as this is already zero. In the partial iteration case, all remaining records are freed, which is - by construction of the records list - at max a page size. Signed-off-by: Felix Moessbauer <[email protected]> --- Note, that this bug has been reported in [1]. [1] https://lore.kernel.org/linux-trace-devel/[email protected]/ Best regards, Felix Moessbauer Siemens AG lib/trace-cmd/trace-input.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/lib/trace-cmd/trace-input.c b/lib/trace-cmd/trace-input.c index f2471c92..afdbd2aa 100644 --- a/lib/trace-cmd/trace-input.c +++ b/lib/trace-cmd/trace-input.c @@ -2995,6 +2995,25 @@ static struct tep_record *next_last_event(struct tracecmd_input *handle, return record; } +static void free_last_events(struct tracecmd_input *handle, + struct tep_record **last_records, + cpu_set_t *cpu_set, int cpu_size, + int cpus) +{ + struct tep_record *record; + int cpu; + + for (cpu = 0; cpu < cpus; cpu++) { + if (cpus && !CPU_ISSET_S(cpu, cpu_size, cpu_set)) + continue; + + do { + record = next_last_event(handle, last_records, cpu); + tracecmd_free_record(record); + } while (record); + } +} + /** * tracecmd_iterate_events_reverse - iterate events over a given handle backwards * @handle: The handle to iterate over @@ -3057,6 +3076,7 @@ int tracecmd_iterate_events_reverse(struct tracecmd_input *handle, } } while (next_cpu >= 0 && ret == 0); + free_last_events(handle, records, cpus, cpu_size, max_cpus); free(records); return ret; -- 2.51.0