aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-probe.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/builtin-probe.c')
-rw-r--r--tools/perf/builtin-probe.c78
1 files changed, 67 insertions, 11 deletions
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
index 199d5e19554f..2e000c068cc5 100644
--- a/tools/perf/builtin-probe.c
+++ b/tools/perf/builtin-probe.c
@@ -50,14 +50,17 @@ 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 show_ext_vars;
55 bool mod_events;
53 int nevents; 56 int nevents;
54 struct perf_probe_event events[MAX_PROBES]; 57 struct perf_probe_event events[MAX_PROBES];
55 struct strlist *dellist; 58 struct strlist *dellist;
56 struct line_range line_range; 59 struct line_range line_range;
60 const char *target_module;
57 int max_probe_points; 61 int max_probe_points;
58} params; 62} params;
59 63
60
61/* Parse an event definition. Note that any error must die. */ 64/* Parse an event definition. Note that any error must die. */
62static int parse_probe_event(const char *str) 65static int parse_probe_event(const char *str)
63{ 66{
@@ -92,6 +95,7 @@ static int parse_probe_event_argv(int argc, const char **argv)
92 len = 0; 95 len = 0;
93 for (i = 0; i < argc; i++) 96 for (i = 0; i < argc; i++)
94 len += sprintf(&buf[len], "%s ", argv[i]); 97 len += sprintf(&buf[len], "%s ", argv[i]);
98 params.mod_events = true;
95 ret = parse_probe_event(buf); 99 ret = parse_probe_event(buf);
96 free(buf); 100 free(buf);
97 return ret; 101 return ret;
@@ -100,9 +104,10 @@ static int parse_probe_event_argv(int argc, const char **argv)
100static int opt_add_probe_event(const struct option *opt __used, 104static int opt_add_probe_event(const struct option *opt __used,
101 const char *str, int unset __used) 105 const char *str, int unset __used)
102{ 106{
103 if (str) 107 if (str) {
108 params.mod_events = true;
104 return parse_probe_event(str); 109 return parse_probe_event(str);
105 else 110 } else
106 return 0; 111 return 0;
107} 112}
108 113
@@ -110,6 +115,7 @@ static int opt_del_probe_event(const struct option *opt __used,
110 const char *str, int unset __used) 115 const char *str, int unset __used)
111{ 116{
112 if (str) { 117 if (str) {
118 params.mod_events = true;
113 if (!params.dellist) 119 if (!params.dellist)
114 params.dellist = strlist__new(true, NULL); 120 params.dellist = strlist__new(true, NULL);
115 strlist__add(params.dellist, str); 121 strlist__add(params.dellist, str);
@@ -130,6 +136,25 @@ static int opt_show_lines(const struct option *opt __used,
130 136
131 return ret; 137 return ret;
132} 138}
139
140static int opt_show_vars(const struct option *opt __used,
141 const char *str, int unset __used)
142{
143 struct perf_probe_event *pev = &params.events[params.nevents];
144 int ret;
145
146 if (!str)
147 return 0;
148
149 ret = parse_probe_event(str);
150 if (!ret && pev->nargs != 0) {
151 pr_err(" Error: '--vars' doesn't accept arguments.\n");
152 return -EINVAL;
153 }
154 params.show_vars = true;
155
156 return ret;
157}
133#endif 158#endif
134 159
135static const char * const probe_usage[] = { 160static const char * const probe_usage[] = {
@@ -138,7 +163,8 @@ static const char * const probe_usage[] = {
138 "perf probe [<options>] --del '[GROUP:]EVENT' ...", 163 "perf probe [<options>] --del '[GROUP:]EVENT' ...",
139 "perf probe --list", 164 "perf probe --list",
140#ifdef DWARF_SUPPORT 165#ifdef DWARF_SUPPORT
141 "perf probe --line 'LINEDESC'", 166 "perf probe [<options>] --line 'LINEDESC'",
167 "perf probe [<options>] --vars 'PROBEPOINT'",
142#endif 168#endif
143 NULL 169 NULL
144}; 170};
@@ -180,10 +206,17 @@ static const struct option options[] = {
180 OPT_CALLBACK('L', "line", NULL, 206 OPT_CALLBACK('L', "line", NULL,
181 "FUNC[:RLN[+NUM|-RLN2]]|SRC:ALN[+NUM|-ALN2]", 207 "FUNC[:RLN[+NUM|-RLN2]]|SRC:ALN[+NUM|-ALN2]",
182 "Show source code lines.", opt_show_lines), 208 "Show source code lines.", opt_show_lines),
209 OPT_CALLBACK('V', "vars", NULL,
210 "FUNC[@SRC][+OFF|%return|:RL|;PT]|SRC:AL|SRC;PT",
211 "Show accessible variables on PROBEDEF", opt_show_vars),
212 OPT_BOOLEAN('\0', "externs", &params.show_ext_vars,
213 "Show external variables too (with --vars only)"),
183 OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name, 214 OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
184 "file", "vmlinux pathname"), 215 "file", "vmlinux pathname"),
185 OPT_STRING('s', "source", &symbol_conf.source_prefix, 216 OPT_STRING('s', "source", &symbol_conf.source_prefix,
186 "directory", "path to kernel source"), 217 "directory", "path to kernel source"),
218 OPT_STRING('m', "module", &params.target_module,
219 "modname", "target module name"),
187#endif 220#endif
188 OPT__DRY_RUN(&probe_event_dry_run), 221 OPT__DRY_RUN(&probe_event_dry_run),
189 OPT_INTEGER('\0', "max-probes", &params.max_probe_points, 222 OPT_INTEGER('\0', "max-probes", &params.max_probe_points,
@@ -217,7 +250,7 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used)
217 usage_with_options(probe_usage, options); 250 usage_with_options(probe_usage, options);
218 251
219 if (params.list_events) { 252 if (params.list_events) {
220 if (params.nevents != 0 || params.dellist) { 253 if (params.mod_events) {
221 pr_err(" Error: Don't use --list with --add/--del.\n"); 254 pr_err(" Error: Don't use --list with --add/--del.\n");
222 usage_with_options(probe_usage, options); 255 usage_with_options(probe_usage, options);
223 } 256 }
@@ -225,6 +258,10 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used)
225 pr_err(" Error: Don't use --list with --line.\n"); 258 pr_err(" Error: Don't use --list with --line.\n");
226 usage_with_options(probe_usage, options); 259 usage_with_options(probe_usage, options);
227 } 260 }
261 if (params.show_vars) {
262 pr_err(" Error: Don't use --list with --vars.\n");
263 usage_with_options(probe_usage, options);
264 }
228 ret = show_perf_probe_events(); 265 ret = show_perf_probe_events();
229 if (ret < 0) 266 if (ret < 0)
230 pr_err(" Error: Failed to show event list. (%d)\n", 267 pr_err(" Error: Failed to show event list. (%d)\n",
@@ -234,17 +271,35 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used)
234 271
235#ifdef DWARF_SUPPORT 272#ifdef DWARF_SUPPORT
236 if (params.show_lines) { 273 if (params.show_lines) {
237 if (params.nevents != 0 || params.dellist) { 274 if (params.mod_events) {
238 pr_warning(" Error: Don't use --line with" 275 pr_err(" Error: Don't use --line with"
239 " --add/--del.\n"); 276 " --add/--del.\n");
277 usage_with_options(probe_usage, options);
278 }
279 if (params.show_vars) {
280 pr_err(" Error: Don't use --line with --vars.\n");
240 usage_with_options(probe_usage, options); 281 usage_with_options(probe_usage, options);
241 } 282 }
242 283
243 ret = show_line_range(&params.line_range); 284 ret = show_line_range(&params.line_range, params.target_module);
244 if (ret < 0) 285 if (ret < 0)
245 pr_err(" Error: Failed to show lines. (%d)\n", ret); 286 pr_err(" Error: Failed to show lines. (%d)\n", ret);
246 return ret; 287 return ret;
247 } 288 }
289 if (params.show_vars) {
290 if (params.mod_events) {
291 pr_err(" Error: Don't use --vars with"
292 " --add/--del.\n");
293 usage_with_options(probe_usage, options);
294 }
295 ret = show_available_vars(params.events, params.nevents,
296 params.max_probe_points,
297 params.target_module,
298 params.show_ext_vars);
299 if (ret < 0)
300 pr_err(" Error: Failed to show vars. (%d)\n", ret);
301 return ret;
302 }
248#endif 303#endif
249 304
250 if (params.dellist) { 305 if (params.dellist) {
@@ -258,8 +313,9 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used)
258 313
259 if (params.nevents) { 314 if (params.nevents) {
260 ret = add_perf_probe_events(params.events, params.nevents, 315 ret = add_perf_probe_events(params.events, params.nevents,
261 params.force_add, 316 params.max_probe_points,
262 params.max_probe_points); 317 params.target_module,
318 params.force_add);
263 if (ret < 0) { 319 if (ret < 0) {
264 pr_err(" Error: Failed to add events. (%d)\n", ret); 320 pr_err(" Error: Failed to add events. (%d)\n", ret);
265 return ret; 321 return ret;