diff options
author | Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> | 2015-03-06 02:31:22 -0500 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2015-03-12 11:39:53 -0400 |
commit | 811dd2ae7cd670fefbb3b220b529bb9876edde70 (patch) | |
tree | b9baecbe353e4f7e91aea1021e106fffce52f1c6 /tools/perf/util/probe-event.c | |
parent | 9b118acae310f57baee770b5db402500d8695e50 (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.c | 35 |
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 | ||
356 | static 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 */ |
357 | static struct debuginfo *open_debuginfo(const char *module, bool silent) | 382 | static 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 | */ |
737 | static int __show_line_range(struct line_range *lr, const char *module) | 762 | static 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; |