aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-probe.c
diff options
context:
space:
mode:
authorMasami Hiramatsu <masami.hiramatsu.pt@hitachi.com>2010-10-21 06:13:23 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2010-10-21 13:59:06 -0400
commitcf6eb489e5c04c8f8d5fd7bf90b8346c987688bc (patch)
tree3da471c3ae3f99cdcbec26cc95412a4b44506f3c /tools/perf/builtin-probe.c
parent632941c4f8fbd5b90dcb1672cd0422dfd7332bc9 (diff)
perf probe: Show accessible local variables
Add -V (--vars) option for listing accessible local variables at given probe point. This will help finding which local variables are available for event arguments. e.g.) # perf probe -V call_timer_fn:23 Available variables at call_timer_fn:23 @<run_timer_softirq+345> function_type* fn int preempt_count long unsigned int data struct list_head work_list struct list_head* head struct timer_list* timer struct tvec_base* base Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Paul Mackerras <paulus@samba.org> Cc: Ingo Molnar <mingo@elte.hu> Cc: Frederic Weisbecker <fweisbec@gmail.com> LKML-Reference: <20101021101323.3542.40282.stgit@ltc236.sdl.hitachi.co.jp> Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/builtin-probe.c')
-rw-r--r--tools/perf/builtin-probe.c61
1 files changed, 54 insertions, 7 deletions
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
index 199d5e19554f..91bb6cf4e025 100644
--- a/tools/perf/builtin-probe.c
+++ b/tools/perf/builtin-probe.c
@@ -50,6 +50,8 @@ static struct {
50 bool list_events; 50 bool list_events;
51 bool force_add; 51 bool force_add;
52 bool show_lines; 52 bool show_lines;
53 bool show_vars;
54 bool mod_events;
53 int nevents; 55 int nevents;
54 struct perf_probe_event events[MAX_PROBES]; 56 struct perf_probe_event events[MAX_PROBES];
55 struct strlist *dellist; 57 struct strlist *dellist;
@@ -57,7 +59,6 @@ static struct {
57 int max_probe_points; 59 int max_probe_points;
58} params; 60} params;
59 61
60
61/* Parse an event definition. Note that any error must die. */ 62/* Parse an event definition. Note that any error must die. */
62static int parse_probe_event(const char *str) 63static int parse_probe_event(const char *str)
63{ 64{
@@ -92,6 +93,7 @@ static int parse_probe_event_argv(int argc, const char **argv)
92 len = 0; 93 len = 0;
93 for (i = 0; i < argc; i++) 94 for (i = 0; i < argc; i++)
94 len += sprintf(&buf[len], "%s ", argv[i]); 95 len += sprintf(&buf[len], "%s ", argv[i]);
96 params.mod_events = true;
95 ret = parse_probe_event(buf); 97 ret = parse_probe_event(buf);
96 free(buf); 98 free(buf);
97 return ret; 99 return ret;
@@ -100,9 +102,10 @@ static int parse_probe_event_argv(int argc, const char **argv)
100static int opt_add_probe_event(const struct option *opt __used, 102static int opt_add_probe_event(const struct option *opt __used,
101 const char *str, int unset __used) 103 const char *str, int unset __used)
102{ 104{
103 if (str) 105 if (str) {
106 params.mod_events = true;
104 return parse_probe_event(str); 107 return parse_probe_event(str);
105 else 108 } else
106 return 0; 109 return 0;
107} 110}
108 111
@@ -110,6 +113,7 @@ static int opt_del_probe_event(const struct option *opt __used,
110 const char *str, int unset __used) 113 const char *str, int unset __used)
111{ 114{
112 if (str) { 115 if (str) {
116 params.mod_events = true;
113 if (!params.dellist) 117 if (!params.dellist)
114 params.dellist = strlist__new(true, NULL); 118 params.dellist = strlist__new(true, NULL);
115 strlist__add(params.dellist, str); 119 strlist__add(params.dellist, str);
@@ -130,6 +134,25 @@ static int opt_show_lines(const struct option *opt __used,
130 134
131 return ret; 135 return ret;
132} 136}
137
138static int opt_show_vars(const struct option *opt __used,
139 const char *str, int unset __used)
140{
141 struct perf_probe_event *pev = &params.events[params.nevents];
142 int ret;
143
144 if (!str)
145 return 0;
146
147 ret = parse_probe_event(str);
148 if (!ret && pev->nargs != 0) {
149 pr_err(" Error: '--vars' doesn't accept arguments.\n");
150 return -EINVAL;
151 }
152 params.show_vars = true;
153
154 return ret;
155}
133#endif 156#endif
134 157
135static const char * const probe_usage[] = { 158static const char * const probe_usage[] = {
@@ -139,6 +162,7 @@ static const char * const probe_usage[] = {
139 "perf probe --list", 162 "perf probe --list",
140#ifdef DWARF_SUPPORT 163#ifdef DWARF_SUPPORT
141 "perf probe --line 'LINEDESC'", 164 "perf probe --line 'LINEDESC'",
165 "perf probe --vars 'PROBEPOINT'",
142#endif 166#endif
143 NULL 167 NULL
144}; 168};
@@ -180,6 +204,9 @@ static const struct option options[] = {
180 OPT_CALLBACK('L', "line", NULL, 204 OPT_CALLBACK('L', "line", NULL,
181 "FUNC[:RLN[+NUM|-RLN2]]|SRC:ALN[+NUM|-ALN2]", 205 "FUNC[:RLN[+NUM|-RLN2]]|SRC:ALN[+NUM|-ALN2]",
182 "Show source code lines.", opt_show_lines), 206 "Show source code lines.", opt_show_lines),
207 OPT_CALLBACK('V', "vars", NULL,
208 "FUNC[@SRC][+OFF|%return|:RL|;PT]|SRC:AL|SRC;PT",
209 "Show accessible variables on PROBEDEF", opt_show_vars),
183 OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name, 210 OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
184 "file", "vmlinux pathname"), 211 "file", "vmlinux pathname"),
185 OPT_STRING('s', "source", &symbol_conf.source_prefix, 212 OPT_STRING('s', "source", &symbol_conf.source_prefix,
@@ -217,7 +244,7 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used)
217 usage_with_options(probe_usage, options); 244 usage_with_options(probe_usage, options);
218 245
219 if (params.list_events) { 246 if (params.list_events) {
220 if (params.nevents != 0 || params.dellist) { 247 if (params.mod_events) {
221 pr_err(" Error: Don't use --list with --add/--del.\n"); 248 pr_err(" Error: Don't use --list with --add/--del.\n");
222 usage_with_options(probe_usage, options); 249 usage_with_options(probe_usage, options);
223 } 250 }
@@ -225,6 +252,10 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used)
225 pr_err(" Error: Don't use --list with --line.\n"); 252 pr_err(" Error: Don't use --list with --line.\n");
226 usage_with_options(probe_usage, options); 253 usage_with_options(probe_usage, options);
227 } 254 }
255 if (params.show_vars) {
256 pr_err(" Error: Don't use --list with --vars.\n");
257 usage_with_options(probe_usage, options);
258 }
228 ret = show_perf_probe_events(); 259 ret = show_perf_probe_events();
229 if (ret < 0) 260 if (ret < 0)
230 pr_err(" Error: Failed to show event list. (%d)\n", 261 pr_err(" Error: Failed to show event list. (%d)\n",
@@ -234,9 +265,13 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used)
234 265
235#ifdef DWARF_SUPPORT 266#ifdef DWARF_SUPPORT
236 if (params.show_lines) { 267 if (params.show_lines) {
237 if (params.nevents != 0 || params.dellist) { 268 if (params.mod_events) {
238 pr_warning(" Error: Don't use --line with" 269 pr_err(" Error: Don't use --line with"
239 " --add/--del.\n"); 270 " --add/--del.\n");
271 usage_with_options(probe_usage, options);
272 }
273 if (params.show_vars) {
274 pr_err(" Error: Don't use --line with --vars.\n");
240 usage_with_options(probe_usage, options); 275 usage_with_options(probe_usage, options);
241 } 276 }
242 277
@@ -245,6 +280,18 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used)
245 pr_err(" Error: Failed to show lines. (%d)\n", ret); 280 pr_err(" Error: Failed to show lines. (%d)\n", ret);
246 return ret; 281 return ret;
247 } 282 }
283 if (params.show_vars) {
284 if (params.mod_events) {
285 pr_err(" Error: Don't use --vars with"
286 " --add/--del.\n");
287 usage_with_options(probe_usage, options);
288 }
289 ret = show_available_vars(params.events, params.nevents,
290 params.max_probe_points);
291 if (ret < 0)
292 pr_err(" Error: Failed to show vars. (%d)\n", ret);
293 return ret;
294 }
248#endif 295#endif
249 296
250 if (params.dellist) { 297 if (params.dellist) {