mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 17:47:41 +02:00
perf libdw: Fix callchain parent update in ORDER_CALLER mode
Fix the parent srcline lookup in `libdw_a2l_cb()` to target the correct parent node depending on the callchain order (ORDER_CALLER/ORDER_CALLEE). This ensures inline callchains are not corrupted when nest depth > 2. Signed-off-by: Ian Rogers <irogers@google.com> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: James Clark <james.clark@linaro.org> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Masami Hiramatsu <mhiramat@kernel.org> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Zecheng Li <zli94@ncsu.edu> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
674dea094e
commit
0e18b5bb7c
|
|
@ -4,6 +4,7 @@
|
|||
#include "srcline.h"
|
||||
#include "symbol.h"
|
||||
#include "dwarf-aux.h"
|
||||
#include "callchain.h"
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <elfutils/libdwfl.h>
|
||||
|
|
@ -80,7 +81,6 @@ static int libdw_a2l_cb(Dwarf_Die *die, void *_args)
|
|||
struct symbol *inline_sym = new_inline_sym(args->dso, args->sym, dwarf_diename(die));
|
||||
const char *call_fname = die_get_call_file(die);
|
||||
char *call_srcline = srcline__unknown;
|
||||
struct inline_list *ilist;
|
||||
|
||||
if (!inline_sym)
|
||||
return -ENOMEM;
|
||||
|
|
@ -89,14 +89,20 @@ static int libdw_a2l_cb(Dwarf_Die *die, void *_args)
|
|||
if (call_fname)
|
||||
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)
|
||||
if (!list_empty(&args->node->val)) {
|
||||
struct inline_list *parent;
|
||||
|
||||
if (callchain_param.order == ORDER_CALLEE)
|
||||
parent = list_first_entry(&args->node->val, struct inline_list, list);
|
||||
else
|
||||
parent = list_last_entry(&args->node->val, struct inline_list, list);
|
||||
|
||||
if (args->leaf_srcline == parent->srcline)
|
||||
args->leaf_srcline_used = false;
|
||||
else if (ilist->srcline != srcline__unknown)
|
||||
free(ilist->srcline);
|
||||
ilist->srcline = call_srcline;
|
||||
else if (parent->srcline != srcline__unknown)
|
||||
free(parent->srcline);
|
||||
parent->srcline = call_srcline;
|
||||
call_srcline = NULL;
|
||||
break;
|
||||
}
|
||||
if (call_srcline && call_srcline != srcline__unknown)
|
||||
free(call_srcline);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user