Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751932AbdCCHKz (ORCPT ); Fri, 3 Mar 2017 02:10:55 -0500 Received: from mga14.intel.com ([192.55.52.115]:21232 "EHLO mga14.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751894AbdCCHKw (ORCPT ); Fri, 3 Mar 2017 02:10:52 -0500 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.35,234,1484035200"; d="scan'208";a="1104232194" From: Jin Yao To: acme@kernel.org, jolsa@kernel.org Cc: Linux-kernel@vger.kernel.org, ak@linux.intel.com, kan.liang@intel.com, milian.wolff@kdab.com, Jin Yao Subject: [PATCH v4 4/5] perf report: Show inline stack in stdio mode Date: Fri, 3 Mar 2017 18:43:04 +0800 Message-Id: <1488537785-10684-5-git-send-email-yao.jin@linux.intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1488537785-10684-1-git-send-email-yao.jin@linux.intel.com> References: <1488537785-10684-1-git-send-email-yao.jin@linux.intel.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3918 Lines: 145 If the address belongs to an inlined function, the source information back to the first non-inlined function will be printed. For example: perf report --stdio --inline 0.69% 0.00% inline ld-2.23.so [.] dl_main | ---dl_main | --0.56%--_dl_relocate_object | ---_dl_relocate_object (inline) elf_dynamic_do_Rela (inline) Signed-off-by: Jin Yao Tested-by: Milian Wolff --- tools/perf/ui/stdio/hist.c | 76 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-) diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c index 668f4ae..3356bfb 100644 --- a/tools/perf/ui/stdio/hist.c +++ b/tools/perf/ui/stdio/hist.c @@ -17,6 +17,57 @@ static size_t callchain__fprintf_left_margin(FILE *fp, int left_margin) return ret; } +static size_t inline__fprintf(struct map *map, u64 ip, + int left_margin, FILE *fp) +{ + struct dso *dso; + struct inline_node *node; + struct inline_list *ilist; + int ret = 0, i = 0; + + if (map == NULL) + return 0; + + dso = map->dso; + if (dso == NULL) + return 0; + + if (dso->kernel != DSO_TYPE_USER) + return 0; + + node = dso__parse_addr_inlines(dso, + map__rip_2objdump(map, ip)); + if (node == NULL) + return 0; + + ret += callchain__fprintf_left_margin(fp, left_margin); + ret += fprintf(fp, "|\n"); + ret += callchain__fprintf_left_margin(fp, left_margin); + ret += fprintf(fp, "---"); + left_margin += 3; + + list_for_each_entry(ilist, &node->val, list) { + if (ilist->filename != NULL) { + if (i++ > 0) + ret = callchain__fprintf_left_margin(fp, + left_margin); + + if (ilist->funcname) + ret += fprintf(fp, "%s (inline)", + ilist->funcname); + else + ret += fprintf(fp, "%s:%d (inline)", + ilist->filename, + ilist->line_nr); + + ret += fprintf(fp, "\n"); + } + } + + inline_node__delete(node); + return ret; +} + static size_t ipchain__fprintf_graph_line(FILE *fp, int depth, int depth_mask, int left_margin) { @@ -78,6 +129,10 @@ static size_t ipchain__fprintf_graph(FILE *fp, struct callchain_node *node, fputs(str, fp); fputc('\n', fp); free(alloc_str); + + if (symbol_conf.inline_name) + ret += inline__fprintf(chain->ms.map, chain->ip, + left_margin + 11, fp); return ret; } @@ -229,6 +284,7 @@ static size_t callchain__fprintf_graph(FILE *fp, struct rb_root *root, if (!i++ && field_order == NULL && sort_order && !prefixcmp(sort_order, "sym")) continue; + if (!printed) { ret += callchain__fprintf_left_margin(fp, left_margin); ret += fprintf(fp, "|\n"); @@ -251,6 +307,12 @@ static size_t callchain__fprintf_graph(FILE *fp, struct rb_root *root, if (++entries_printed == callchain_param.print_limit) break; + + if (symbol_conf.inline_name) + ret += inline__fprintf(chain->ms.map, + chain->ip, + left_margin, + fp); } root = &cnode->rb_root; } @@ -529,6 +591,8 @@ static int hist_entry__fprintf(struct hist_entry *he, size_t size, bool use_callchain) { int ret; + int callchain_ret = 0; + int inline_ret = 0; struct perf_hpp hpp = { .buf = bf, .size = size, @@ -547,7 +611,17 @@ static int hist_entry__fprintf(struct hist_entry *he, size_t size, ret = fprintf(fp, "%s\n", bf); if (use_callchain) - ret += hist_entry_callchain__fprintf(he, total_period, 0, fp); + callchain_ret = hist_entry_callchain__fprintf(he, total_period, + 0, fp); + + if ((callchain_ret == 0) && + (symbol_conf.inline_name)) { + inline_ret = inline__fprintf(he->ms.map, he->ip, 0, fp); + ret += inline_ret; + if (inline_ret > 0) + ret += fprintf(fp, "\n"); + } else + ret += callchain_ret; return ret; } -- 2.7.4