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: 88c51002d06f ("perf addr2line: Add a libdw implementation")
Signed-off-by: Ian Rogers <[email protected]>
---
 tools/perf/util/libdw.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/tools/perf/util/libdw.c b/tools/perf/util/libdw.c
index e4bfd52bd172..b96c4e0d728f 100644
--- a/tools/perf/util/libdw.c
+++ b/tools/perf/util/libdw.c
@@ -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;
 }
 
-- 
2.52.0.457.g6b5491de43-goog


Reply via email to