]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
perf libdw_addr2line: Fixes to srcline memory allocation
authorIan Rogers <irogers@google.com>
Sat, 17 Jan 2026 05:28:31 +0000 (21:28 -0800)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Tue, 20 Jan 2026 16:03:24 +0000 (13:03 -0300)
Some irregular stack traces are causing double frees and memory
leaks. Make the code robust by proactively freeing and being more
careful with the memory management of the leaf_srcline.

Fixes: 88c51002d06f9a68 ("perf addr2line: Add a libdw implementation")
Signed-off-by: Ian Rogers <irogers@google.com>
Cc: Aditya Bodkhe <aditya.b1@linux.ibm.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Albert Ou <aou@eecs.berkeley.edu>
Cc: Alexandre Ghiti <alex@ghiti.fr>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Athira Rajeev <atrajeev@linux.ibm.com>
Cc: Chun-Tse Shao <ctshao@google.com>
Cc: Dmitriy Vyukov <dvyukov@google.com>
Cc: Dr. David Alan Gilbert <linux@treblig.org>
Cc: Guo Ren <guoren@kernel.org>
Cc: Haibo Xu <haibo1.xu@intel.com>
Cc: Howard Chu <howardchu95@gmail.com>
Cc: Ian Rogers <irogers@google.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@linaro.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: John Garry <john.g.garry@oracle.com>
Cc: Krzysztof Ɓopatowski <krzysztof.m.lopatowski@gmail.com>
Cc: Leo Yan <leo.yan@linux.dev>
Cc: Mark Wielaard <mark@klomp.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Palmer Dabbelt <palmer@dabbelt.com>
Cc: Paul Walmsley <pjw@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Sergei Trofimovich <slyich@gmail.com>
Cc: Shimin Guo <shimin.guo@skydio.com>
Cc: Stephen Brennan <stephen.s.brennan@oracle.com>
Cc: Thomas Falcon <thomas.falcon@intel.com>
Cc: Will Deacon <will@kernel.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/util/libdw.c

index e4bfd52bd17263bff0b69dbfe5e47016acd436ab..b96c4e0d728fb0b7beda2aa0dfa5286cb66e0902 100644 (file)
@@ -42,16 +42,24 @@ static int libdw_a2l_cb(Dwarf_Die *die, void *_args)
                call_srcline = srcline_from_fileline(call_fname, die_get_call_lineno(die));
 
        list_for_each_entry(ilist, &args->node->val, list) {
+               if (args->leaf_srcline == ilist->srcline)
+                       args->leaf_srcline_used = false;
+               else if (ilist->srcline != srcline__unknown)
+                       free(ilist->srcline);
                ilist->srcline =  call_srcline;
                call_srcline = NULL;
                break;
        }
-       if (call_srcline && call_fname)
+       if (call_srcline && call_srcline != srcline__unknown)
                free(call_srcline);
 
        /* Add this symbol to the chain as the leaf. */
-       inline_list__append_tail(inline_sym, args->leaf_srcline, args->node);
-       args->leaf_srcline_used = true;
+       if (!args->leaf_srcline_used) {
+               inline_list__append_tail(inline_sym, args->leaf_srcline, args->node);
+               args->leaf_srcline_used = true;
+       } else {
+               inline_list__append_tail(inline_sym, strdup(args->leaf_srcline), args->node);
+       }
        return 0;
 }