Hello, On Fri, Feb 22, 2019 at 1:07 AM Jonas Rabenstein <jonas.rabenst...@studium.uni-erlangen.de> wrote: > > Use map__inlines to resolve inlined functions for every entry with > an symbol that should be added to a callchain. > > Signed-off-by: Jonas Rabenstein <jonas.rabenst...@studium.uni-erlangen.de> > --- > tools/perf/util/machine.c | 115 ++++++++++++++++++++++++++++---------- > 1 file changed, 87 insertions(+), 28 deletions(-) > > diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c > index dce29c21e4ea..070d074482b4 100644 > --- a/tools/perf/util/machine.c > +++ b/tools/perf/util/machine.c > @@ -1908,6 +1908,91 @@ struct iterations { > u64 cycles; > }; > > +static int __add_callchain_location(struct callchain_cursor *cursor, > + struct symbol **parent, > + struct addr_location *root_al, > + u64 addr, struct addr_location *al, > + bool branch, struct branch_flags *flags, > + u64 branch_from, struct iterations *iter) > +{ > + int nr_loop_iter = 0; > + u64 iter_cycles = 0; > + > + if (symbol_conf.hide_unresolved && al->sym == NULL) > + return 0; > + > + if (al->sym) { > + if (perf_hpp_list.parent && !*parent && > + symbol__match_regex(al->sym, &parent_regex)) > + *parent = al->sym; > + else if (have_ignore_callees && root_al && > + symbol__match_regex(al->sym, &ignore_callees_regex)) { > + /* Treat this symbol as the root, > + forgetting its callees. */ > + *root_al = *al; > + callchain_cursor_reset(cursor); > + } > + } > + > + if (iter) { > + nr_loop_iter = iter->nr_loop_iter; > + iter_cycles = iter->cycles; > + } > + return callchain_cursor_append(cursor, addr, al->map, al->sym, branch, > + flags, nr_loop_iter, iter_cycles, > + branch_from, al->srcline); > +} > + > +static int __add_callchain_ip(struct callchain_cursor *cursor, u64 ip, > + struct addr_location *al, bool branch, > + struct branch_flags *flags, u64 branch_from, > + struct iterations *iter, struct symbol **parent, > + struct addr_location *root_al) > +{ > + struct inline_node *inline_node; > + struct inline_list *inline_list; > + const char *srcline; > + struct symbol *symbol; > + int err = 0; > + > + al->srcline = callchain_srcline(al->map, al->sym, al->addr); > + if (callchain_param.order == ORDER_CALLER) > + err = __add_callchain_location(cursor, parent, root_al, ip, > al, > + branch, flags, branch_from, > iter); > + if (err || !al->map || !al->sym) > + goto no_inline; > + > + inline_node = map__inlines(al->map, ip, al->sym); > + if (!inline_node || list_empty(&inline_node->val)) > + goto no_inline; > + > + symbol = al->sym; > + srcline = al->srcline; > + list_for_each_entry(inline_list, &inline_node->val, list) { > + if (inline_list->symbol == symbol) > + continue; > + al->sym = inline_list->symbol; > + al->srcline = inline_list->srcline; > + err = __add_callchain_location(cursor, parent, root_al, ip, > + al, branch, flags, > + branch_from, iter); > + if (err) > + break; > + }
Does this loop do the job both for ORDER_CALLER and ORDER_CALLEE? Thanks, Namhyung > + > + if (callchain_param.order == ORDER_CALLEE) { > + al->srcline = srcline; > + al->sym = symbol; > + } > + > +no_inline: > + if (!err && callchain_param.order == ORDER_CALLEE) > + err = __add_callchain_location(cursor, parent, root_al, ip, > al, > + branch, flags, branch_from, > iter); > + return err; > +} > + > + > static int add_callchain_ip(struct thread *thread, > struct callchain_cursor *cursor, > struct symbol **parent, > @@ -1920,9 +2005,6 @@ static int add_callchain_ip(struct thread *thread, > u64 branch_from) > { > struct addr_location al; > - int nr_loop_iter = 0; > - u64 iter_cycles = 0; > - const char *srcline = NULL; > > al.filtered = 0; > al.sym = NULL; > @@ -1955,31 +2037,8 @@ static int add_callchain_ip(struct thread *thread, > thread__find_symbol(thread, *cpumode, ip, &al); > } > > - if (al.sym != NULL) { > - if (perf_hpp_list.parent && !*parent && > - symbol__match_regex(al.sym, &parent_regex)) > - *parent = al.sym; > - else if (have_ignore_callees && root_al && > - symbol__match_regex(al.sym, &ignore_callees_regex)) { > - /* Treat this symbol as the root, > - forgetting its callees. */ > - *root_al = al; > - callchain_cursor_reset(cursor); > - } > - } > - > - if (symbol_conf.hide_unresolved && al.sym == NULL) > - return 0; > - > - if (iter) { > - nr_loop_iter = iter->nr_loop_iter; > - iter_cycles = iter->cycles; > - } > - > - srcline = callchain_srcline(al.map, al.sym, al.addr); > - return callchain_cursor_append(cursor, ip, al.map, al.sym, > - branch, flags, nr_loop_iter, > - iter_cycles, branch_from, srcline); > + return __add_callchain_ip(cursor, ip, &al, branch, flags, branch_from, > + iter, parent, root_al); > } > > struct branch_info *sample__resolve_bstack(struct perf_sample *sample, > -- > 2.19.2 >