1 /* 2 * builtin-probe.c 3 * 4 * Builtin probe command: Set up probe events by C expression 5 * 6 * Written by Masami Hiramatsu <mhiramat@redhat.com> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 21 * 22 */ 23 #include <sys/utsname.h> 24 #include <sys/types.h> 25 #include <sys/stat.h> 26 #include <fcntl.h> 27 #include <errno.h> 28 #include <stdio.h> 29 #include <unistd.h> 30 #include <stdlib.h> 31 #include <string.h> 32 33 #include "perf.h" 34 #include "builtin.h" 35 #include "util/util.h" 36 #include "util/strlist.h" 37 #include "util/strfilter.h" 38 #include "util/symbol.h" 39 #include "util/debug.h" 40 #include <api/fs/debugfs.h> 41 #include "util/parse-options.h" 42 #include "util/probe-finder.h" 43 #include "util/probe-event.h" 44 45 #define DEFAULT_VAR_FILTER "!__k???tab_* & !__crc_*" 46 #define DEFAULT_FUNC_FILTER "!_*" 47 48 /* Session management structure */ 49 static struct { 50 bool list_events; 51 bool force_add; 52 bool show_lines; 53 bool show_vars; 54 bool show_ext_vars; 55 bool show_funcs; 56 bool mod_events; 57 bool uprobes; 58 bool quiet; 59 int nevents; 60 struct perf_probe_event events[MAX_PROBES]; 61 struct strlist *dellist; 62 struct line_range line_range; 63 char *target; 64 int max_probe_points; 65 struct strfilter *filter; 66 } params; 67 68 /* Parse an event definition. Note that any error must die. */ 69 static int parse_probe_event(const char *str) 70 { 71 struct perf_probe_event *pev = ¶ms.events[params.nevents]; 72 int ret; 73 74 pr_debug("probe-definition(%d): %s\n", params.nevents, str); 75 if (++params.nevents == MAX_PROBES) { 76 pr_err("Too many probes (> %d) were specified.", MAX_PROBES); 77 return -1; 78 } 79 80 pev->uprobes = params.uprobes; 81 82 /* Parse a perf-probe command into event */ 83 ret = parse_perf_probe_command(str, pev); 84 pr_debug("%d arguments\n", pev->nargs); 85 86 return ret; 87 } 88 89 static int set_target(const char *ptr) 90 { 91 int found = 0; 92 const char *buf; 93 94 /* 95 * The first argument after options can be an absolute path 96 * to an executable / library or kernel module. 97 * 98 * TODO: Support relative path, and $PATH, $LD_LIBRARY_PATH, 99 * short module name. 100 */ 101 if (!params.target && ptr && *ptr == '/') { 102 params.target = strdup(ptr); 103 if (!params.target) 104 return -ENOMEM; 105 106 found = 1; 107 buf = ptr + (strlen(ptr) - 3); 108 109 if (strcmp(buf, ".ko")) 110 params.uprobes = true; 111 112 } 113 114 return found; 115 } 116 117 static int parse_probe_event_argv(int argc, const char **argv) 118 { 119 int i, len, ret, found_target; 120 char *buf; 121 122 found_target = set_target(argv[0]); 123 if (found_target < 0) 124 return found_target; 125 126 if (found_target && argc == 1) 127 return 0; 128 129 /* Bind up rest arguments */ 130 len = 0; 131 for (i = 0; i < argc; i++) { 132 if (i == 0 && found_target) 133 continue; 134 135 len += strlen(argv[i]) + 1; 136 } 137 buf = zalloc(len + 1); 138 if (buf == NULL) 139 return -ENOMEM; 140 len = 0; 141 for (i = 0; i < argc; i++) { 142 if (i == 0 && found_target) 143 continue; 144 145 len += sprintf(&buf[len], "%s ", argv[i]); 146 } 147 params.mod_events = true; 148 ret = parse_probe_event(buf); 149 free(buf); 150 return ret; 151 } 152 153 static int opt_add_probe_event(const struct option *opt __maybe_unused, 154 const char *str, int unset __maybe_unused) 155 { 156 if (str) { 157 params.mod_events = true; 158 return parse_probe_event(str); 159 } else 160 return 0; 161 } 162 163 static int opt_del_probe_event(const struct option *opt __maybe_unused, 164 const char *str, int unset __maybe_unused) 165 { 166 if (str) { 167 params.mod_events = true; 168 if (!params.dellist) 169 params.dellist = strlist__new(true, NULL); 170 strlist__add(params.dellist, str); 171 } 172 return 0; 173 } 174 175 static int opt_set_target(const struct option *opt, const char *str, 176 int unset __maybe_unused) 177 { 178 int ret = -ENOENT; 179 char *tmp; 180 181 if (str && !params.target) { 182 if (!strcmp(opt->long_name, "exec")) 183 params.uprobes = true; 184 #ifdef HAVE_DWARF_SUPPORT 185 else if (!strcmp(opt->long_name, "module")) 186 params.uprobes = false; 187 #endif 188 else 189 return ret; 190 191 /* Expand given path to absolute path, except for modulename */ 192 if (params.uprobes || strchr(str, '/')) { 193 tmp = realpath(str, NULL); 194 if (!tmp) { 195 pr_warning("Failed to get the absolute path of %s: %m\n", str); 196 return ret; 197 } 198 } else { 199 tmp = strdup(str); 200 if (!tmp) 201 return -ENOMEM; 202 } 203 params.target = tmp; 204 ret = 0; 205 } 206 207 return ret; 208 } 209 210 #ifdef HAVE_DWARF_SUPPORT 211 static int opt_show_lines(const struct option *opt __maybe_unused, 212 const char *str, int unset __maybe_unused) 213 { 214 int ret = 0; 215 216 if (!str) 217 return 0; 218 219 if (params.show_lines) { 220 pr_warning("Warning: more than one --line options are" 221 " detected. Only the first one is valid.\n"); 222 return 0; 223 } 224 225 params.show_lines = true; 226 ret = parse_line_range_desc(str, ¶ms.line_range); 227 228 return ret; 229 } 230 231 static int opt_show_vars(const struct option *opt __maybe_unused, 232 const char *str, int unset __maybe_unused) 233 { 234 struct perf_probe_event *pev = ¶ms.events[params.nevents]; 235 int ret; 236 237 if (!str) 238 return 0; 239 240 ret = parse_probe_event(str); 241 if (!ret && pev->nargs != 0) { 242 pr_err(" Error: '--vars' doesn't accept arguments.\n"); 243 return -EINVAL; 244 } 245 params.show_vars = true; 246 247 return ret; 248 } 249 #endif 250 251 static int opt_set_filter(const struct option *opt __maybe_unused, 252 const char *str, int unset __maybe_unused) 253 { 254 const char *err; 255 256 if (str) { 257 pr_debug2("Set filter: %s\n", str); 258 if (params.filter) 259 strfilter__delete(params.filter); 260 params.filter = strfilter__new(str, &err); 261 if (!params.filter) { 262 pr_err("Filter parse error at %td.\n", err - str + 1); 263 pr_err("Source: \"%s\"\n", str); 264 pr_err(" %*c\n", (int)(err - str + 1), '^'); 265 return -EINVAL; 266 } 267 } 268 269 return 0; 270 } 271 272 static int init_params(void) 273 { 274 return line_range__init(¶ms.line_range); 275 } 276 277 static void cleanup_params(void) 278 { 279 int i; 280 281 for (i = 0; i < params.nevents; i++) 282 clear_perf_probe_event(params.events + i); 283 if (params.dellist) 284 strlist__delete(params.dellist); 285 line_range__clear(¶ms.line_range); 286 free(params.target); 287 if (params.filter) 288 strfilter__delete(params.filter); 289 memset(¶ms, 0, sizeof(params)); 290 } 291 292 static void pr_err_with_code(const char *msg, int err) 293 { 294 char sbuf[STRERR_BUFSIZE]; 295 296 pr_err("%s", msg); 297 pr_debug(" Reason: %s (Code: %d)", 298 strerror_r(-err, sbuf, sizeof(sbuf)), err); 299 pr_err("\n"); 300 } 301 302 static int 303 __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused) 304 { 305 const char * const probe_usage[] = { 306 "perf probe [<options>] 'PROBEDEF' ['PROBEDEF' ...]", 307 "perf probe [<options>] --add 'PROBEDEF' [--add 'PROBEDEF' ...]", 308 "perf probe [<options>] --del '[GROUP:]EVENT' ...", 309 "perf probe --list", 310 #ifdef HAVE_DWARF_SUPPORT 311 "perf probe [<options>] --line 'LINEDESC'", 312 "perf probe [<options>] --vars 'PROBEPOINT'", 313 #endif 314 NULL 315 }; 316 struct option options[] = { 317 OPT_INCR('v', "verbose", &verbose, 318 "be more verbose (show parsed arguments, etc)"), 319 OPT_BOOLEAN('q', "quiet", ¶ms.quiet, 320 "be quiet (do not show any mesages)"), 321 OPT_BOOLEAN('l', "list", ¶ms.list_events, 322 "list up current probe events"), 323 OPT_CALLBACK('d', "del", NULL, "[GROUP:]EVENT", "delete a probe event.", 324 opt_del_probe_event), 325 OPT_CALLBACK('a', "add", NULL, 326 #ifdef HAVE_DWARF_SUPPORT 327 "[EVENT=]FUNC[@SRC][+OFF|%return|:RL|;PT]|SRC:AL|SRC;PT" 328 " [[NAME=]ARG ...]", 329 #else 330 "[EVENT=]FUNC[+OFF|%return] [[NAME=]ARG ...]", 331 #endif 332 "probe point definition, where\n" 333 "\t\tGROUP:\tGroup name (optional)\n" 334 "\t\tEVENT:\tEvent name\n" 335 "\t\tFUNC:\tFunction name\n" 336 "\t\tOFF:\tOffset from function entry (in byte)\n" 337 "\t\t%return:\tPut the probe at function return\n" 338 #ifdef HAVE_DWARF_SUPPORT 339 "\t\tSRC:\tSource code path\n" 340 "\t\tRL:\tRelative line number from function entry.\n" 341 "\t\tAL:\tAbsolute line number in file.\n" 342 "\t\tPT:\tLazy expression of line code.\n" 343 "\t\tARG:\tProbe argument (local variable name or\n" 344 "\t\t\tkprobe-tracer argument format.)\n", 345 #else 346 "\t\tARG:\tProbe argument (kprobe-tracer argument format.)\n", 347 #endif 348 opt_add_probe_event), 349 OPT_BOOLEAN('f', "force", ¶ms.force_add, "forcibly add events" 350 " with existing name"), 351 #ifdef HAVE_DWARF_SUPPORT 352 OPT_CALLBACK('L', "line", NULL, 353 "FUNC[:RLN[+NUM|-RLN2]]|SRC:ALN[+NUM|-ALN2]", 354 "Show source code lines.", opt_show_lines), 355 OPT_CALLBACK('V', "vars", NULL, 356 "FUNC[@SRC][+OFF|%return|:RL|;PT]|SRC:AL|SRC;PT", 357 "Show accessible variables on PROBEDEF", opt_show_vars), 358 OPT_BOOLEAN('\0', "externs", ¶ms.show_ext_vars, 359 "Show external variables too (with --vars only)"), 360 OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name, 361 "file", "vmlinux pathname"), 362 OPT_STRING('s', "source", &symbol_conf.source_prefix, 363 "directory", "path to kernel source"), 364 OPT_CALLBACK('m', "module", NULL, "modname|path", 365 "target module name (for online) or path (for offline)", 366 opt_set_target), 367 #endif 368 OPT__DRY_RUN(&probe_event_dry_run), 369 OPT_INTEGER('\0', "max-probes", ¶ms.max_probe_points, 370 "Set how many probe points can be found for a probe."), 371 OPT_BOOLEAN('F', "funcs", ¶ms.show_funcs, 372 "Show potential probe-able functions."), 373 OPT_CALLBACK('\0', "filter", NULL, 374 "[!]FILTER", "Set a filter (with --vars/funcs only)\n" 375 "\t\t\t(default: \"" DEFAULT_VAR_FILTER "\" for --vars,\n" 376 "\t\t\t \"" DEFAULT_FUNC_FILTER "\" for --funcs)", 377 opt_set_filter), 378 OPT_CALLBACK('x', "exec", NULL, "executable|path", 379 "target executable name or path", opt_set_target), 380 OPT_BOOLEAN(0, "demangle", &symbol_conf.demangle, 381 "Enable symbol demangling"), 382 OPT_BOOLEAN(0, "demangle-kernel", &symbol_conf.demangle_kernel, 383 "Enable kernel symbol demangling"), 384 OPT_END() 385 }; 386 int ret; 387 388 set_option_flag(options, 'a', "add", PARSE_OPT_EXCLUSIVE); 389 set_option_flag(options, 'd', "del", PARSE_OPT_EXCLUSIVE); 390 set_option_flag(options, 'l', "list", PARSE_OPT_EXCLUSIVE); 391 #ifdef HAVE_DWARF_SUPPORT 392 set_option_flag(options, 'L', "line", PARSE_OPT_EXCLUSIVE); 393 set_option_flag(options, 'V', "vars", PARSE_OPT_EXCLUSIVE); 394 #endif 395 396 argc = parse_options(argc, argv, options, probe_usage, 397 PARSE_OPT_STOP_AT_NON_OPTION); 398 if (argc > 0) { 399 if (strcmp(argv[0], "-") == 0) { 400 pr_warning(" Error: '-' is not supported.\n"); 401 usage_with_options(probe_usage, options); 402 } 403 ret = parse_probe_event_argv(argc, argv); 404 if (ret < 0) { 405 pr_err_with_code(" Error: Command Parse Error.", ret); 406 return ret; 407 } 408 } 409 410 if (params.quiet) { 411 if (verbose != 0) { 412 pr_err(" Error: -v and -q are exclusive.\n"); 413 return -EINVAL; 414 } 415 verbose = -1; 416 } 417 418 if (params.max_probe_points == 0) 419 params.max_probe_points = MAX_PROBES; 420 421 if ((!params.nevents && !params.dellist && !params.list_events && 422 !params.show_lines && !params.show_funcs)) 423 usage_with_options(probe_usage, options); 424 425 /* 426 * Only consider the user's kernel image path if given. 427 */ 428 symbol_conf.try_vmlinux_path = (symbol_conf.vmlinux_name == NULL); 429 430 if (params.list_events) { 431 if (params.uprobes) { 432 pr_warning(" Error: Don't use --list with --exec.\n"); 433 usage_with_options(probe_usage, options); 434 } 435 ret = show_perf_probe_events(); 436 if (ret < 0) 437 pr_err_with_code(" Error: Failed to show event list.", ret); 438 return ret; 439 } 440 if (params.show_funcs) { 441 if (!params.filter) 442 params.filter = strfilter__new(DEFAULT_FUNC_FILTER, 443 NULL); 444 ret = show_available_funcs(params.target, params.filter, 445 params.uprobes); 446 strfilter__delete(params.filter); 447 params.filter = NULL; 448 if (ret < 0) 449 pr_err_with_code(" Error: Failed to show functions.", ret); 450 return ret; 451 } 452 453 #ifdef HAVE_DWARF_SUPPORT 454 if (params.show_lines) { 455 ret = show_line_range(¶ms.line_range, params.target, 456 params.uprobes); 457 if (ret < 0) 458 pr_err_with_code(" Error: Failed to show lines.", ret); 459 return ret; 460 } 461 if (params.show_vars) { 462 if (!params.filter) 463 params.filter = strfilter__new(DEFAULT_VAR_FILTER, 464 NULL); 465 466 ret = show_available_vars(params.events, params.nevents, 467 params.max_probe_points, 468 params.target, 469 params.filter, 470 params.show_ext_vars); 471 strfilter__delete(params.filter); 472 params.filter = NULL; 473 if (ret < 0) 474 pr_err_with_code(" Error: Failed to show vars.", ret); 475 return ret; 476 } 477 #endif 478 479 if (params.dellist) { 480 ret = del_perf_probe_events(params.dellist); 481 if (ret < 0) { 482 pr_err_with_code(" Error: Failed to delete events.", ret); 483 return ret; 484 } 485 } 486 487 if (params.nevents) { 488 ret = add_perf_probe_events(params.events, params.nevents, 489 params.max_probe_points, 490 params.target, 491 params.force_add); 492 if (ret < 0) { 493 pr_err_with_code(" Error: Failed to add events.", ret); 494 return ret; 495 } 496 } 497 return 0; 498 } 499 500 int cmd_probe(int argc, const char **argv, const char *prefix) 501 { 502 int ret; 503 504 ret = init_params(); 505 if (!ret) { 506 ret = __cmd_probe(argc, argv, prefix); 507 cleanup_params(); 508 } 509 510 return ret; 511 } 512