aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorMasami Hiramatsu <masami.hiramatsu.pt@hitachi.com>2015-08-11 21:24:07 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2015-08-12 12:20:27 -0400
commit75186a9b09e47072f442f43e292cd47180b67b5c (patch)
tree6e2dd157afabc61379468d0e8b8ad378c6a34069 /tools
parent63ab1749f39aeec27b0dcf71cd7996d862c5ad63 (diff)
perf probe: Fix to show lines of sys_ functions correctly
"perf probe --lines sys_poll" shows only the first line of sys_poll, because the SYSCALL_DEFINE macro: ---- SYSCALL_DEFINE*(foo,...) { body; } ---- is expanded as below (on debuginfo) ---- static inline int SYSC_foo(...) { body; } int SyS_foo(...) <- is an alias of sys_foo. { return SYSC_foo(...); } ---- So, "perf probe --lines sys_foo" decodes SyS_foo function and it also skips inlined functions(SYSC_foo) inside the target function because those functions are usually defined somewhere else. To fix this issue, this fix checks whether the inlined function is defined at the same point of the target function, and if so, it doesn't skip the inline function. Reported-by: Arnaldo Carvalho de Melo <acme@kernel.org> Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Namhyung Kim <namhyung@kernel.org> Link: http://lkml.kernel.org/r/20150812012406.11811.94691.stgit@localhost.localdomain Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/util/dwarf-aux.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/tools/perf/util/dwarf-aux.c b/tools/perf/util/dwarf-aux.c
index 57f3ef41c2bc..445f455dd377 100644
--- a/tools/perf/util/dwarf-aux.c
+++ b/tools/perf/util/dwarf-aux.c
@@ -734,15 +734,18 @@ int die_walk_lines(Dwarf_Die *rt_die, line_walk_callback_t callback, void *data)
734 Dwarf_Lines *lines; 734 Dwarf_Lines *lines;
735 Dwarf_Line *line; 735 Dwarf_Line *line;
736 Dwarf_Addr addr; 736 Dwarf_Addr addr;
737 const char *fname; 737 const char *fname, *decf = NULL;
738 int lineno, ret = 0; 738 int lineno, ret = 0;
739 int decl = 0, inl;
739 Dwarf_Die die_mem, *cu_die; 740 Dwarf_Die die_mem, *cu_die;
740 size_t nlines, i; 741 size_t nlines, i;
741 742
742 /* Get the CU die */ 743 /* Get the CU die */
743 if (dwarf_tag(rt_die) != DW_TAG_compile_unit) 744 if (dwarf_tag(rt_die) != DW_TAG_compile_unit) {
744 cu_die = dwarf_diecu(rt_die, &die_mem, NULL, NULL); 745 cu_die = dwarf_diecu(rt_die, &die_mem, NULL, NULL);
745 else 746 dwarf_decl_line(rt_die, &decl);
747 decf = dwarf_decl_file(rt_die);
748 } else
746 cu_die = rt_die; 749 cu_die = rt_die;
747 if (!cu_die) { 750 if (!cu_die) {
748 pr_debug2("Failed to get CU from given DIE.\n"); 751 pr_debug2("Failed to get CU from given DIE.\n");
@@ -773,9 +776,14 @@ int die_walk_lines(Dwarf_Die *rt_die, line_walk_callback_t callback, void *data)
773 * The line is included in given function, and 776 * The line is included in given function, and
774 * no inline block includes it. 777 * no inline block includes it.
775 */ 778 */
776 if (!dwarf_haspc(rt_die, addr) || 779 if (!dwarf_haspc(rt_die, addr))
777 die_find_inlinefunc(rt_die, addr, &die_mem))
778 continue; 780 continue;
781 if (die_find_inlinefunc(rt_die, addr, &die_mem)) {
782 dwarf_decl_line(&die_mem, &inl);
783 if (inl != decl ||
784 decf != dwarf_decl_file(&die_mem))
785 continue;
786 }
779 /* Get source line */ 787 /* Get source line */
780 fname = dwarf_linesrc(line, NULL, NULL); 788 fname = dwarf_linesrc(line, NULL, NULL);
781 789