aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMasami Hiramatsu <mhiramat@kernel.org>2017-12-08 11:28:12 -0500
committerArnaldo Carvalho de Melo <acme@redhat.com>2017-12-27 10:15:54 -0500
commit4b3a2716dd785fabb9f6ac80c1d53cb29a88169d (patch)
tree82c60e830f99a86a779031834e68ff2e915f6b61
parente63c625a1e417edbe513b75b347a7238e9e7fea0 (diff)
perf probe: Find versioned symbols from map
Commit d80406453ad4 ("perf symbols: Allow user probes on versioned symbols") allows user to find default versioned symbols (with "@@") in map. However, it did not enable normal versioned symbol (with "@") for perf-probe. E.g. ===== # ./perf probe -x /lib64/libc-2.25.so malloc_get_state Failed to find symbol malloc_get_state in /usr/lib64/libc-2.25.so Error: Failed to add events. ===== This solves above issue by improving perf-probe symbol search function, as below. ===== # ./perf probe -x /lib64/libc-2.25.so malloc_get_state Added new event: probe_libc:malloc_get_state (on malloc_get_state in /usr/lib64/libc-2.25.so) You can now use it in all perf tools, such as: perf record -e probe_libc:malloc_get_state -aR sleep 1 # ./perf probe -l probe_libc:malloc_get_state (on malloc_get_state@GLIBC_2.2.5 in /usr/lib64/libc-2.25.so) ===== Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org> Reviewed-by: Thomas Richter <tmricht@linux.vnet.ibm.com> Acked-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Paul Clarke <pc@us.ibm.com> Cc: bhargavb <bhargavaramudu@gmail.com> Cc: linux-rt-users@vger.kernel.org Link: http://lkml.kernel.org/r/151275049269.24652.1639103455496216255.stgit@devbox Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r--tools/perf/arch/powerpc/util/sym-handling.c8
-rw-r--r--tools/perf/util/probe-event.c20
-rw-r--r--tools/perf/util/symbol.c5
-rw-r--r--tools/perf/util/symbol.h1
4 files changed, 32 insertions, 2 deletions
diff --git a/tools/perf/arch/powerpc/util/sym-handling.c b/tools/perf/arch/powerpc/util/sym-handling.c
index 9c4e23d8c8ce..53d83d7e6a09 100644
--- a/tools/perf/arch/powerpc/util/sym-handling.c
+++ b/tools/perf/arch/powerpc/util/sym-handling.c
@@ -64,6 +64,14 @@ int arch__compare_symbol_names_n(const char *namea, const char *nameb,
64 64
65 return strncmp(namea, nameb, n); 65 return strncmp(namea, nameb, n);
66} 66}
67
68const char *arch__normalize_symbol_name(const char *name)
69{
70 /* Skip over initial dot */
71 if (name && *name == '.')
72 name++;
73 return name;
74}
67#endif 75#endif
68 76
69#if defined(_CALL_ELF) && _CALL_ELF == 2 77#if defined(_CALL_ELF) && _CALL_ELF == 2
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index a68141d360b0..0d6c66d51939 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -2801,16 +2801,32 @@ static int find_probe_functions(struct map *map, char *name,
2801 int found = 0; 2801 int found = 0;
2802 struct symbol *sym; 2802 struct symbol *sym;
2803 struct rb_node *tmp; 2803 struct rb_node *tmp;
2804 const char *norm, *ver;
2805 char *buf = NULL;
2804 2806
2805 if (map__load(map) < 0) 2807 if (map__load(map) < 0)
2806 return 0; 2808 return 0;
2807 2809
2808 map__for_each_symbol(map, sym, tmp) { 2810 map__for_each_symbol(map, sym, tmp) {
2809 if (strglobmatch(sym->name, name)) { 2811 norm = arch__normalize_symbol_name(sym->name);
2812 if (!norm)
2813 continue;
2814
2815 /* We don't care about default symbol or not */
2816 ver = strchr(norm, '@');
2817 if (ver) {
2818 buf = strndup(norm, ver - norm);
2819 if (!buf)
2820 return -ENOMEM;
2821 norm = buf;
2822 }
2823 if (strglobmatch(norm, name)) {
2810 found++; 2824 found++;
2811 if (syms && found < probe_conf.max_probes) 2825 if (syms && found < probe_conf.max_probes)
2812 syms[found - 1] = sym; 2826 syms[found - 1] = sym;
2813 } 2827 }
2828 if (buf)
2829 zfree(&buf);
2814 } 2830 }
2815 2831
2816 return found; 2832 return found;
@@ -2856,7 +2872,7 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev,
2856 * same name but different addresses, this lists all the symbols. 2872 * same name but different addresses, this lists all the symbols.
2857 */ 2873 */
2858 num_matched_functions = find_probe_functions(map, pp->function, syms); 2874 num_matched_functions = find_probe_functions(map, pp->function, syms);
2859 if (num_matched_functions == 0) { 2875 if (num_matched_functions <= 0) {
2860 pr_err("Failed to find symbol %s in %s\n", pp->function, 2876 pr_err("Failed to find symbol %s in %s\n", pp->function,
2861 pev->target ? : "kernel"); 2877 pev->target ? : "kernel");
2862 ret = -ENOENT; 2878 ret = -ENOENT;
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 1b67a8639dfe..cc065d4bfafc 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -94,6 +94,11 @@ static int prefix_underscores_count(const char *str)
94 return tail - str; 94 return tail - str;
95} 95}
96 96
97const char * __weak arch__normalize_symbol_name(const char *name)
98{
99 return name;
100}
101
97int __weak arch__compare_symbol_names(const char *namea, const char *nameb) 102int __weak arch__compare_symbol_names(const char *namea, const char *nameb)
98{ 103{
99 return strcmp(namea, nameb); 104 return strcmp(namea, nameb);
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index a4f0075b4e5c..0563f33c1eb3 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -349,6 +349,7 @@ bool elf__needs_adjust_symbols(GElf_Ehdr ehdr);
349void arch__sym_update(struct symbol *s, GElf_Sym *sym); 349void arch__sym_update(struct symbol *s, GElf_Sym *sym);
350#endif 350#endif
351 351
352const char *arch__normalize_symbol_name(const char *name);
352#define SYMBOL_A 0 353#define SYMBOL_A 0
353#define SYMBOL_B 1 354#define SYMBOL_B 1
354 355