aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorMasami Hiramatsu <masami.hiramatsu.pt@hitachi.com>2011-01-13 07:46:11 -0500
committerArnaldo Carvalho de Melo <acme@redhat.com>2011-01-24 07:57:55 -0500
commite80711ca8512c8586da0c3e18e2f1caf73c88731 (patch)
tree2b6493cd34b5a68ec9008c34a47f8f145711132f /tools
parent5069ed86be3c2f28bcdf7fae1374ec0c325aafba (diff)
perf probe: Add --funcs to show available functions in symtab
Add --funcs to show available functions in symtab. Originally this feature came from Srikar's uprobes patches ( http://lkml.org/lkml/2010/8/27/244 ) e.g. ... __ablkcipher_walk_complete __absent_pages_in_range __account_scheduler_latency __add_pages __alloc_pages_nodemask __alloc_percpu __alloc_reserved_percpu __alloc_skb __alloc_workqueue_key __any_online_cpu __ata_ehi_push_desc ... This also supports symbols in module, e.g. ... cleanup_module cpuid_maxphyaddr emulate_clts emulate_instruction emulate_int_real emulate_invlpg emulator_get_dr emulator_set_dr emulator_task_switch emulator_write_emulated emulator_write_phys fx_init ... Original-patch-from: Srikar Dronamraju <srikar@linux.vnet.ibm.com> Cc: 2nddept-manager@sdl.hitachi.co.jp Cc: Franck Bui-Huu <fbuihuu@gmail.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com> Cc: Steven Rostedt <rostedt@goodmis.org> LKML-Reference: <20110113124611.22426.10835.stgit@ltc236.sdl.hitachi.co.jp> Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> [ committer note: Add missing elf.h for STB_GLOBAL that broke a RHEL4 build ] Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/Documentation/perf-probe.txt4
-rw-r--r--tools/perf/builtin-probe.c29
-rw-r--r--tools/perf/util/probe-event.c68
-rw-r--r--tools/perf/util/probe-event.h1
4 files changed, 99 insertions, 3 deletions
diff --git a/tools/perf/Documentation/perf-probe.txt b/tools/perf/Documentation/perf-probe.txt
index 86b797a35aa6..fcc51fe0195c 100644
--- a/tools/perf/Documentation/perf-probe.txt
+++ b/tools/perf/Documentation/perf-probe.txt
@@ -73,6 +73,10 @@ OPTIONS
73 (Only for --vars) Show external defined variables in addition to local 73 (Only for --vars) Show external defined variables in addition to local
74 variables. 74 variables.
75 75
76-F::
77--funcs::
78 Show available functions in given module or kernel.
79
76-f:: 80-f::
77--force:: 81--force::
78 Forcibly add events with existing name. 82 Forcibly add events with existing name.
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
index add163c9f0e7..6cf708aba7c9 100644
--- a/tools/perf/builtin-probe.c
+++ b/tools/perf/builtin-probe.c
@@ -52,6 +52,7 @@ static struct {
52 bool show_lines; 52 bool show_lines;
53 bool show_vars; 53 bool show_vars;
54 bool show_ext_vars; 54 bool show_ext_vars;
55 bool show_funcs;
55 bool mod_events; 56 bool mod_events;
56 int nevents; 57 int nevents;
57 struct perf_probe_event events[MAX_PROBES]; 58 struct perf_probe_event events[MAX_PROBES];
@@ -221,6 +222,8 @@ static const struct option options[] = {
221 OPT__DRY_RUN(&probe_event_dry_run), 222 OPT__DRY_RUN(&probe_event_dry_run),
222 OPT_INTEGER('\0', "max-probes", &params.max_probe_points, 223 OPT_INTEGER('\0', "max-probes", &params.max_probe_points,
223 "Set how many probe points can be found for a probe."), 224 "Set how many probe points can be found for a probe."),
225 OPT_BOOLEAN('F', "funcs", &params.show_funcs,
226 "Show potential probe-able functions."),
224 OPT_END() 227 OPT_END()
225}; 228};
226 229
@@ -246,7 +249,7 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used)
246 params.max_probe_points = MAX_PROBES; 249 params.max_probe_points = MAX_PROBES;
247 250
248 if ((!params.nevents && !params.dellist && !params.list_events && 251 if ((!params.nevents && !params.dellist && !params.list_events &&
249 !params.show_lines)) 252 !params.show_lines && !params.show_funcs))
250 usage_with_options(probe_usage, options); 253 usage_with_options(probe_usage, options);
251 254
252 /* 255 /*
@@ -267,12 +270,36 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used)
267 pr_err(" Error: Don't use --list with --vars.\n"); 270 pr_err(" Error: Don't use --list with --vars.\n");
268 usage_with_options(probe_usage, options); 271 usage_with_options(probe_usage, options);
269 } 272 }
273 if (params.show_funcs) {
274 pr_err(" Error: Don't use --list with --funcs.\n");
275 usage_with_options(probe_usage, options);
276 }
270 ret = show_perf_probe_events(); 277 ret = show_perf_probe_events();
271 if (ret < 0) 278 if (ret < 0)
272 pr_err(" Error: Failed to show event list. (%d)\n", 279 pr_err(" Error: Failed to show event list. (%d)\n",
273 ret); 280 ret);
274 return ret; 281 return ret;
275 } 282 }
283 if (params.show_funcs) {
284 if (params.nevents != 0 || params.dellist) {
285 pr_err(" Error: Don't use --funcs with"
286 " --add/--del.\n");
287 usage_with_options(probe_usage, options);
288 }
289 if (params.show_lines) {
290 pr_err(" Error: Don't use --funcs with --line.\n");
291 usage_with_options(probe_usage, options);
292 }
293 if (params.show_vars) {
294 pr_err(" Error: Don't use --funcs with --vars.\n");
295 usage_with_options(probe_usage, options);
296 }
297 ret = show_available_funcs(params.target_module);
298 if (ret < 0)
299 pr_err(" Error: Failed to show functions."
300 " (%d)\n", ret);
301 return ret;
302 }
276 303
277#ifdef DWARF_SUPPORT 304#ifdef DWARF_SUPPORT
278 if (params.show_lines) { 305 if (params.show_lines) {
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 6e29d9c9dccc..859d377a3df3 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -31,6 +31,7 @@
31#include <string.h> 31#include <string.h>
32#include <stdarg.h> 32#include <stdarg.h>
33#include <limits.h> 33#include <limits.h>
34#include <elf.h>
34 35
35#undef _GNU_SOURCE 36#undef _GNU_SOURCE
36#include "util.h" 37#include "util.h"
@@ -111,7 +112,25 @@ static struct symbol *__find_kernel_function_by_name(const char *name,
111 NULL); 112 NULL);
112} 113}
113 114
114const char *kernel_get_module_path(const char *module) 115static struct map *kernel_get_module_map(const char *module)
116{
117 struct rb_node *nd;
118 struct map_groups *grp = &machine.kmaps;
119
120 if (!module)
121 module = "kernel";
122
123 for (nd = rb_first(&grp->maps[MAP__FUNCTION]); nd; nd = rb_next(nd)) {
124 struct map *pos = rb_entry(nd, struct map, rb_node);
125 if (strncmp(pos->dso->short_name + 1, module,
126 pos->dso->short_name_len - 2) == 0) {
127 return pos;
128 }
129 }
130 return NULL;
131}
132
133static struct dso *kernel_get_module_dso(const char *module)
115{ 134{
116 struct dso *dso; 135 struct dso *dso;
117 struct map *map; 136 struct map *map;
@@ -141,7 +160,13 @@ const char *kernel_get_module_path(const char *module)
141 } 160 }
142 } 161 }
143found: 162found:
144 return dso->long_name; 163 return dso;
164}
165
166const char *kernel_get_module_path(const char *module)
167{
168 struct dso *dso = kernel_get_module_dso(module);
169 return (dso) ? dso->long_name : NULL;
145} 170}
146 171
147#ifdef DWARF_SUPPORT 172#ifdef DWARF_SUPPORT
@@ -1913,3 +1938,42 @@ int del_perf_probe_events(struct strlist *dellist)
1913 return ret; 1938 return ret;
1914} 1939}
1915 1940
1941/*
1942 * If a symbol corresponds to a function with global binding return 0.
1943 * For all others return 1.
1944 */
1945static int filter_non_global_functions(struct map *map __unused,
1946 struct symbol *sym)
1947{
1948 if (sym->binding != STB_GLOBAL)
1949 return 1;
1950
1951 return 0;
1952}
1953
1954int show_available_funcs(const char *module)
1955{
1956 struct map *map;
1957 int ret;
1958
1959 setup_pager();
1960
1961 ret = init_vmlinux();
1962 if (ret < 0)
1963 return ret;
1964
1965 map = kernel_get_module_map(module);
1966 if (!map) {
1967 pr_err("Failed to find %s map.\n", (module) ? : "kernel");
1968 return -EINVAL;
1969 }
1970 if (map__load(map, filter_non_global_functions)) {
1971 pr_err("Failed to load map.\n");
1972 return -EINVAL;
1973 }
1974 if (!dso__sorted_by_name(map->dso, map->type))
1975 dso__sort_by_name(map->dso, map->type);
1976
1977 dso__fprintf_symbols_by_name(map->dso, map->type, stdout);
1978 return 0;
1979}
diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h
index 5accbedfea37..1fb4f18337d3 100644
--- a/tools/perf/util/probe-event.h
+++ b/tools/perf/util/probe-event.h
@@ -127,6 +127,7 @@ extern int show_line_range(struct line_range *lr, const char *module);
127extern int show_available_vars(struct perf_probe_event *pevs, int npevs, 127extern int show_available_vars(struct perf_probe_event *pevs, int npevs,
128 int max_probe_points, const char *module, 128 int max_probe_points, const char *module,
129 bool externs); 129 bool externs);
130extern int show_available_funcs(const char *module);
130 131
131 132
132/* Maximum index number of event-name postfix */ 133/* Maximum index number of event-name postfix */