aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/probe-event.c
diff options
context:
space:
mode:
authorMasami Hiramatsu <masami.hiramatsu.pt@hitachi.com>2015-03-06 02:31:22 -0500
committerArnaldo Carvalho de Melo <acme@redhat.com>2015-03-12 11:39:53 -0400
commit811dd2ae7cd670fefbb3b220b529bb9876edde70 (patch)
treeb9baecbe353e4f7e91aea1021e106fffce52f1c6 /tools/perf/util/probe-event.c
parent9b118acae310f57baee770b5db402500d8695e50 (diff)
perf probe: Fix --line to handle aliased symbols in glibc
Fix perf probe --line to handle aliased symbols correctly in glibc. This makes line_range search failing back to address-based alternative search as same as --add and --vars. Without this patch; ----- # ./perf probe -x /usr/lib64/libc-2.17.so -L malloc Specified source line is not found. Error: Failed to show lines. ----- With this patch; ----- # ./perf probe -x /usr/lib64/libc-2.17.so -L malloc <__libc_malloc@/usr/src/debug/glibc-2.17-c758a686/malloc/malloc.c:0> 0 __libc_malloc(size_t bytes) 1 { mstate ar_ptr; void *victim; __malloc_ptr_t (*hook) (size_t, const __malloc_ptr_t) 6 = force_reg (__malloc_hook); 7 if (__builtin_expect (hook != NULL, 0)) 8 return (*hook)(bytes, RETURN_ADDRESS (0)); 10 arena_lookup(ar_ptr); 12 arena_lock(ar_ptr, bytes); ----- Note that this actually shows __libc_malloc, since it is the real instance of malloc. User can use both __libc_malloc and malloc for --line. 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> Cc: Naohiro Aota <naota@elisp.net> Cc: Peter Zijlstra <peterz@infradead.org> Link: http://lkml.kernel.org/r/20150306073122.6904.18540.stgit@localhost.localdomain Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/probe-event.c')
-rw-r--r--tools/perf/util/probe-event.c35
1 files changed, 33 insertions, 2 deletions
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index b8f45782126a..4cfd1211a2ae 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -353,6 +353,31 @@ static int get_alternative_probe_event(struct debuginfo *dinfo,
353 return ret; 353 return ret;
354} 354}
355 355
356static int get_alternative_line_range(struct debuginfo *dinfo,
357 struct line_range *lr,
358 const char *target, bool user)
359{
360 struct perf_probe_point pp = { 0 }, result = { 0 };
361 int ret, len = 0;
362
363 pp.function = lr->function;
364 pp.file = lr->file;
365 pp.line = lr->start;
366 if (lr->end != INT_MAX)
367 len = lr->end - lr->start;
368 ret = find_alternative_probe_point(dinfo, &pp, &result,
369 target, user);
370 if (!ret) {
371 lr->function = result.function;
372 lr->file = result.file;
373 lr->start = result.line;
374 if (lr->end != INT_MAX)
375 lr->end = lr->start + len;
376 clear_perf_probe_point(&pp);
377 }
378 return ret;
379}
380
356/* Open new debuginfo of given module */ 381/* Open new debuginfo of given module */
357static struct debuginfo *open_debuginfo(const char *module, bool silent) 382static struct debuginfo *open_debuginfo(const char *module, bool silent)
358{ 383{
@@ -734,7 +759,8 @@ static int _show_one_line(FILE *fp, int l, bool skip, bool show_num)
734 * Show line-range always requires debuginfo to find source file and 759 * Show line-range always requires debuginfo to find source file and
735 * line number. 760 * line number.
736 */ 761 */
737static int __show_line_range(struct line_range *lr, const char *module) 762static int __show_line_range(struct line_range *lr, const char *module,
763 bool user)
738{ 764{
739 int l = 1; 765 int l = 1;
740 struct int_node *ln; 766 struct int_node *ln;
@@ -750,6 +776,11 @@ static int __show_line_range(struct line_range *lr, const char *module)
750 return -ENOENT; 776 return -ENOENT;
751 777
752 ret = debuginfo__find_line_range(dinfo, lr); 778 ret = debuginfo__find_line_range(dinfo, lr);
779 if (!ret) { /* Not found, retry with an alternative */
780 ret = get_alternative_line_range(dinfo, lr, module, user);
781 if (!ret)
782 ret = debuginfo__find_line_range(dinfo, lr);
783 }
753 debuginfo__delete(dinfo); 784 debuginfo__delete(dinfo);
754 if (ret == 0 || ret == -ENOENT) { 785 if (ret == 0 || ret == -ENOENT) {
755 pr_warning("Specified source line is not found.\n"); 786 pr_warning("Specified source line is not found.\n");
@@ -819,7 +850,7 @@ int show_line_range(struct line_range *lr, const char *module, bool user)
819 ret = init_symbol_maps(user); 850 ret = init_symbol_maps(user);
820 if (ret < 0) 851 if (ret < 0)
821 return ret; 852 return ret;
822 ret = __show_line_range(lr, module); 853 ret = __show_line_range(lr, module, user);
823 exit_symbol_maps(); 854 exit_symbol_maps();
824 855
825 return ret; 856 return ret;