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.c86
1 files changed, 77 insertions, 9 deletions
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
index 4935c09dd5b5..e215ae61b2ae 100644
--- a/tools/perf/builtin-probe.c
+++ b/tools/perf/builtin-probe.c
@@ -54,6 +54,7 @@ static struct {
54 bool show_ext_vars; 54 bool show_ext_vars;
55 bool show_funcs; 55 bool show_funcs;
56 bool mod_events; 56 bool mod_events;
57 bool uprobes;
57 int nevents; 58 int nevents;
58 struct perf_probe_event events[MAX_PROBES]; 59 struct perf_probe_event events[MAX_PROBES];
59 struct strlist *dellist; 60 struct strlist *dellist;
@@ -75,6 +76,8 @@ static int parse_probe_event(const char *str)
75 return -1; 76 return -1;
76 } 77 }
77 78
79 pev->uprobes = params.uprobes;
80
78 /* Parse a perf-probe command into event */ 81 /* Parse a perf-probe command into event */
79 ret = parse_perf_probe_command(str, pev); 82 ret = parse_perf_probe_command(str, pev);
80 pr_debug("%d arguments\n", pev->nargs); 83 pr_debug("%d arguments\n", pev->nargs);
@@ -82,21 +85,58 @@ static int parse_probe_event(const char *str)
82 return ret; 85 return ret;
83} 86}
84 87
88static int set_target(const char *ptr)
89{
90 int found = 0;
91 const char *buf;
92
93 /*
94 * The first argument after options can be an absolute path
95 * to an executable / library or kernel module.
96 *
97 * TODO: Support relative path, and $PATH, $LD_LIBRARY_PATH,
98 * short module name.
99 */
100 if (!params.target && ptr && *ptr == '/') {
101 params.target = ptr;
102 found = 1;
103 buf = ptr + (strlen(ptr) - 3);
104
105 if (strcmp(buf, ".ko"))
106 params.uprobes = true;
107
108 }
109
110 return found;
111}
112
85static int parse_probe_event_argv(int argc, const char **argv) 113static int parse_probe_event_argv(int argc, const char **argv)
86{ 114{
87 int i, len, ret; 115 int i, len, ret, found_target;
88 char *buf; 116 char *buf;
89 117
118 found_target = set_target(argv[0]);
119 if (found_target && argc == 1)
120 return 0;
121
90 /* Bind up rest arguments */ 122 /* Bind up rest arguments */
91 len = 0; 123 len = 0;
92 for (i = 0; i < argc; i++) 124 for (i = 0; i < argc; i++) {
125 if (i == 0 && found_target)
126 continue;
127
93 len += strlen(argv[i]) + 1; 128 len += strlen(argv[i]) + 1;
129 }
94 buf = zalloc(len + 1); 130 buf = zalloc(len + 1);
95 if (buf == NULL) 131 if (buf == NULL)
96 return -ENOMEM; 132 return -ENOMEM;
97 len = 0; 133 len = 0;
98 for (i = 0; i < argc; i++) 134 for (i = 0; i < argc; i++) {
135 if (i == 0 && found_target)
136 continue;
137
99 len += sprintf(&buf[len], "%s ", argv[i]); 138 len += sprintf(&buf[len], "%s ", argv[i]);
139 }
100 params.mod_events = true; 140 params.mod_events = true;
101 ret = parse_probe_event(buf); 141 ret = parse_probe_event(buf);
102 free(buf); 142 free(buf);
@@ -125,6 +165,28 @@ static int opt_del_probe_event(const struct option *opt __used,
125 return 0; 165 return 0;
126} 166}
127 167
168static int opt_set_target(const struct option *opt, const char *str,
169 int unset __used)
170{
171 int ret = -ENOENT;
172
173 if (str && !params.target) {
174 if (!strcmp(opt->long_name, "exec"))
175 params.uprobes = true;
176#ifdef DWARF_SUPPORT
177 else if (!strcmp(opt->long_name, "module"))
178 params.uprobes = false;
179#endif
180 else
181 return ret;
182
183 params.target = str;
184 ret = 0;
185 }
186
187 return ret;
188}
189
128#ifdef DWARF_SUPPORT 190#ifdef DWARF_SUPPORT
129static int opt_show_lines(const struct option *opt __used, 191static int opt_show_lines(const struct option *opt __used,
130 const char *str, int unset __used) 192 const char *str, int unset __used)
@@ -246,9 +308,9 @@ static const struct option options[] = {
246 "file", "vmlinux pathname"), 308 "file", "vmlinux pathname"),
247 OPT_STRING('s', "source", &symbol_conf.source_prefix, 309 OPT_STRING('s', "source", &symbol_conf.source_prefix,
248 "directory", "path to kernel source"), 310 "directory", "path to kernel source"),
249 OPT_STRING('m', "module", &params.target, 311 OPT_CALLBACK('m', "module", NULL, "modname|path",
250 "modname|path", 312 "target module name (for online) or path (for offline)",
251 "target module name (for online) or path (for offline)"), 313 opt_set_target),
252#endif 314#endif
253 OPT__DRY_RUN(&probe_event_dry_run), 315 OPT__DRY_RUN(&probe_event_dry_run),
254 OPT_INTEGER('\0', "max-probes", &params.max_probe_points, 316 OPT_INTEGER('\0', "max-probes", &params.max_probe_points,
@@ -260,6 +322,8 @@ static const struct option options[] = {
260 "\t\t\t(default: \"" DEFAULT_VAR_FILTER "\" for --vars,\n" 322 "\t\t\t(default: \"" DEFAULT_VAR_FILTER "\" for --vars,\n"
261 "\t\t\t \"" DEFAULT_FUNC_FILTER "\" for --funcs)", 323 "\t\t\t \"" DEFAULT_FUNC_FILTER "\" for --funcs)",
262 opt_set_filter), 324 opt_set_filter),
325 OPT_CALLBACK('x', "exec", NULL, "executable|path",
326 "target executable name or path", opt_set_target),
263 OPT_END() 327 OPT_END()
264}; 328};
265 329
@@ -310,6 +374,10 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used)
310 pr_err(" Error: Don't use --list with --funcs.\n"); 374 pr_err(" Error: Don't use --list with --funcs.\n");
311 usage_with_options(probe_usage, options); 375 usage_with_options(probe_usage, options);
312 } 376 }
377 if (params.uprobes) {
378 pr_warning(" Error: Don't use --list with --exec.\n");
379 usage_with_options(probe_usage, options);
380 }
313 ret = show_perf_probe_events(); 381 ret = show_perf_probe_events();
314 if (ret < 0) 382 if (ret < 0)
315 pr_err(" Error: Failed to show event list. (%d)\n", 383 pr_err(" Error: Failed to show event list. (%d)\n",
@@ -333,8 +401,8 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used)
333 if (!params.filter) 401 if (!params.filter)
334 params.filter = strfilter__new(DEFAULT_FUNC_FILTER, 402 params.filter = strfilter__new(DEFAULT_FUNC_FILTER,
335 NULL); 403 NULL);
336 ret = show_available_funcs(params.target, 404 ret = show_available_funcs(params.target, params.filter,
337 params.filter); 405 params.uprobes);
338 strfilter__delete(params.filter); 406 strfilter__delete(params.filter);
339 if (ret < 0) 407 if (ret < 0)
340 pr_err(" Error: Failed to show functions." 408 pr_err(" Error: Failed to show functions."
@@ -343,7 +411,7 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used)
343 } 411 }
344 412
345#ifdef DWARF_SUPPORT 413#ifdef DWARF_SUPPORT
346 if (params.show_lines) { 414 if (params.show_lines && !params.uprobes) {
347 if (params.mod_events) { 415 if (params.mod_events) {
348 pr_err(" Error: Don't use --line with" 416 pr_err(" Error: Don't use --line with"
349 " --add/--del.\n"); 417 " --add/--del.\n");