1 /* 2 * probe-event.c : perf-probe definition to kprobe_events format converter 3 * 4 * Written by Masami Hiramatsu <mhiramat@redhat.com> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 19 * 20 */ 21 22 #define _GNU_SOURCE 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 #include <stdarg.h> 33 #include <limits.h> 34 35 #undef _GNU_SOURCE 36 #include "util.h" 37 #include "event.h" 38 #include "string.h" 39 #include "strlist.h" 40 #include "debug.h" 41 #include "cache.h" 42 #include "color.h" 43 #include "symbol.h" 44 #include "thread.h" 45 #include "debugfs.h" 46 #include "trace-event.h" /* For __unused */ 47 #include "probe-event.h" 48 #include "probe-finder.h" 49 50 #define MAX_CMDLEN 256 51 #define MAX_PROBE_ARGS 128 52 #define PERFPROBE_GROUP "probe" 53 54 bool probe_event_dry_run; /* Dry run flag */ 55 56 #define semantic_error(msg ...) pr_err("Semantic error :" msg) 57 58 /* If there is no space to write, returns -E2BIG. */ 59 static int e_snprintf(char *str, size_t size, const char *format, ...) 60 __attribute__((format(printf, 3, 4))); 61 62 static int e_snprintf(char *str, size_t size, const char *format, ...) 63 { 64 int ret; 65 va_list ap; 66 va_start(ap, format); 67 ret = vsnprintf(str, size, format, ap); 68 va_end(ap); 69 if (ret >= (int)size) 70 ret = -E2BIG; 71 return ret; 72 } 73 74 static char *synthesize_perf_probe_point(struct perf_probe_point *pp); 75 static struct machine machine; 76 77 /* Initialize symbol maps and path of vmlinux */ 78 static int init_vmlinux(void) 79 { 80 struct dso *kernel; 81 int ret; 82 83 symbol_conf.sort_by_name = true; 84 if (symbol_conf.vmlinux_name == NULL) 85 symbol_conf.try_vmlinux_path = true; 86 else 87 pr_debug("Use vmlinux: %s\n", symbol_conf.vmlinux_name); 88 ret = symbol__init(); 89 if (ret < 0) { 90 pr_debug("Failed to init symbol map.\n"); 91 goto out; 92 } 93 94 ret = machine__init(&machine, "/", 0); 95 if (ret < 0) 96 goto out; 97 98 kernel = dso__new_kernel(symbol_conf.vmlinux_name); 99 if (kernel == NULL) 100 die("Failed to create kernel dso."); 101 102 ret = __machine__create_kernel_maps(&machine, kernel); 103 if (ret < 0) 104 pr_debug("Failed to create kernel maps.\n"); 105 106 out: 107 if (ret < 0) 108 pr_warning("Failed to init vmlinux path.\n"); 109 return ret; 110 } 111 112 #ifdef DWARF_SUPPORT 113 static int open_vmlinux(void) 114 { 115 if (map__load(machine.vmlinux_maps[MAP__FUNCTION], NULL) < 0) { 116 pr_debug("Failed to load kernel map.\n"); 117 return -EINVAL; 118 } 119 pr_debug("Try to open %s\n", machine.vmlinux_maps[MAP__FUNCTION]->dso->long_name); 120 return open(machine.vmlinux_maps[MAP__FUNCTION]->dso->long_name, O_RDONLY); 121 } 122 123 /* Convert trace point to probe point with debuginfo */ 124 static int convert_to_perf_probe_point(struct kprobe_trace_point *tp, 125 struct perf_probe_point *pp) 126 { 127 struct symbol *sym; 128 int fd, ret = -ENOENT; 129 130 sym = map__find_symbol_by_name(machine.vmlinux_maps[MAP__FUNCTION], 131 tp->symbol, NULL); 132 if (sym) { 133 fd = open_vmlinux(); 134 if (fd >= 0) { 135 ret = find_perf_probe_point(fd, 136 sym->start + tp->offset, pp); 137 close(fd); 138 } 139 } 140 if (ret <= 0) { 141 pr_debug("Failed to find corresponding probes from " 142 "debuginfo. Use kprobe event information.\n"); 143 pp->function = strdup(tp->symbol); 144 if (pp->function == NULL) 145 return -ENOMEM; 146 pp->offset = tp->offset; 147 } 148 pp->retprobe = tp->retprobe; 149 150 return 0; 151 } 152 153 /* Try to find perf_probe_event with debuginfo */ 154 static int try_to_find_kprobe_trace_events(struct perf_probe_event *pev, 155 struct kprobe_trace_event **tevs, 156 int max_tevs) 157 { 158 bool need_dwarf = perf_probe_event_need_dwarf(pev); 159 int fd, ntevs; 160 161 fd = open_vmlinux(); 162 if (fd < 0) { 163 if (need_dwarf) { 164 pr_warning("Failed to open debuginfo file.\n"); 165 return fd; 166 } 167 pr_debug("Could not open vmlinux. Try to use symbols.\n"); 168 return 0; 169 } 170 171 /* Searching trace events corresponding to probe event */ 172 ntevs = find_kprobe_trace_events(fd, pev, tevs, max_tevs); 173 close(fd); 174 175 if (ntevs > 0) { /* Succeeded to find trace events */ 176 pr_debug("find %d kprobe_trace_events.\n", ntevs); 177 return ntevs; 178 } 179 180 if (ntevs == 0) { /* No error but failed to find probe point. */ 181 pr_warning("Probe point '%s' not found.\n", 182 synthesize_perf_probe_point(&pev->point)); 183 return -ENOENT; 184 } 185 /* Error path : ntevs < 0 */ 186 pr_debug("An error occurred in debuginfo analysis (%d).\n", ntevs); 187 if (ntevs == -EBADF) { 188 pr_warning("Warning: No dwarf info found in the vmlinux - " 189 "please rebuild kernel with CONFIG_DEBUG_INFO=y.\n"); 190 if (!need_dwarf) { 191 pr_debug("Trying to use symbols.\nn"); 192 return 0; 193 } 194 } 195 return ntevs; 196 } 197 198 #define LINEBUF_SIZE 256 199 #define NR_ADDITIONAL_LINES 2 200 201 static int show_one_line(FILE *fp, int l, bool skip, bool show_num) 202 { 203 char buf[LINEBUF_SIZE]; 204 const char *color = PERF_COLOR_BLUE; 205 206 if (fgets(buf, LINEBUF_SIZE, fp) == NULL) 207 goto error; 208 if (!skip) { 209 if (show_num) 210 fprintf(stdout, "%7d %s", l, buf); 211 else 212 color_fprintf(stdout, color, " %s", buf); 213 } 214 215 while (strlen(buf) == LINEBUF_SIZE - 1 && 216 buf[LINEBUF_SIZE - 2] != '\n') { 217 if (fgets(buf, LINEBUF_SIZE, fp) == NULL) 218 goto error; 219 if (!skip) { 220 if (show_num) 221 fprintf(stdout, "%s", buf); 222 else 223 color_fprintf(stdout, color, "%s", buf); 224 } 225 } 226 227 return 0; 228 error: 229 if (feof(fp)) 230 pr_warning("Source file is shorter than expected.\n"); 231 else 232 pr_warning("File read error: %s\n", strerror(errno)); 233 234 return -1; 235 } 236 237 /* 238 * Show line-range always requires debuginfo to find source file and 239 * line number. 240 */ 241 int show_line_range(struct line_range *lr) 242 { 243 int l = 1; 244 struct line_node *ln; 245 FILE *fp; 246 int fd, ret; 247 248 /* Search a line range */ 249 ret = init_vmlinux(); 250 if (ret < 0) 251 return ret; 252 253 fd = open_vmlinux(); 254 if (fd < 0) { 255 pr_warning("Failed to open debuginfo file.\n"); 256 return fd; 257 } 258 259 ret = find_line_range(fd, lr); 260 close(fd); 261 if (ret == 0) { 262 pr_warning("Specified source line is not found.\n"); 263 return -ENOENT; 264 } else if (ret < 0) { 265 pr_warning("Debuginfo analysis failed. (%d)\n", ret); 266 return ret; 267 } 268 269 setup_pager(); 270 271 if (lr->function) 272 fprintf(stdout, "<%s:%d>\n", lr->function, 273 lr->start - lr->offset); 274 else 275 fprintf(stdout, "<%s:%d>\n", lr->file, lr->start); 276 277 fp = fopen(lr->path, "r"); 278 if (fp == NULL) { 279 pr_warning("Failed to open %s: %s\n", lr->path, 280 strerror(errno)); 281 return -errno; 282 } 283 /* Skip to starting line number */ 284 while (l < lr->start && ret >= 0) 285 ret = show_one_line(fp, l++, true, false); 286 if (ret < 0) 287 goto end; 288 289 list_for_each_entry(ln, &lr->line_list, list) { 290 while (ln->line > l && ret >= 0) 291 ret = show_one_line(fp, (l++) - lr->offset, 292 false, false); 293 if (ret >= 0) 294 ret = show_one_line(fp, (l++) - lr->offset, 295 false, true); 296 if (ret < 0) 297 goto end; 298 } 299 300 if (lr->end == INT_MAX) 301 lr->end = l + NR_ADDITIONAL_LINES; 302 while (l <= lr->end && !feof(fp) && ret >= 0) 303 ret = show_one_line(fp, (l++) - lr->offset, false, false); 304 end: 305 fclose(fp); 306 return ret; 307 } 308 309 #else /* !DWARF_SUPPORT */ 310 311 static int convert_to_perf_probe_point(struct kprobe_trace_point *tp, 312 struct perf_probe_point *pp) 313 { 314 pp->function = strdup(tp->symbol); 315 if (pp->function == NULL) 316 return -ENOMEM; 317 pp->offset = tp->offset; 318 pp->retprobe = tp->retprobe; 319 320 return 0; 321 } 322 323 static int try_to_find_kprobe_trace_events(struct perf_probe_event *pev, 324 struct kprobe_trace_event **tevs __unused, 325 int max_tevs __unused) 326 { 327 if (perf_probe_event_need_dwarf(pev)) { 328 pr_warning("Debuginfo-analysis is not supported.\n"); 329 return -ENOSYS; 330 } 331 return 0; 332 } 333 334 int show_line_range(struct line_range *lr __unused) 335 { 336 pr_warning("Debuginfo-analysis is not supported.\n"); 337 return -ENOSYS; 338 } 339 340 #endif 341 342 int parse_line_range_desc(const char *arg, struct line_range *lr) 343 { 344 const char *ptr; 345 char *tmp; 346 /* 347 * <Syntax> 348 * SRC:SLN[+NUM|-ELN] 349 * FUNC[:SLN[+NUM|-ELN]] 350 */ 351 ptr = strchr(arg, ':'); 352 if (ptr) { 353 lr->start = (int)strtoul(ptr + 1, &tmp, 0); 354 if (*tmp == '+') { 355 lr->end = lr->start + (int)strtoul(tmp + 1, &tmp, 0); 356 lr->end--; /* 357 * Adjust the number of lines here. 358 * If the number of lines == 1, the 359 * the end of line should be equal to 360 * the start of line. 361 */ 362 } else if (*tmp == '-') 363 lr->end = (int)strtoul(tmp + 1, &tmp, 0); 364 else 365 lr->end = INT_MAX; 366 pr_debug("Line range is %d to %d\n", lr->start, lr->end); 367 if (lr->start > lr->end) { 368 semantic_error("Start line must be smaller" 369 " than end line.\n"); 370 return -EINVAL; 371 } 372 if (*tmp != '\0') { 373 semantic_error("Tailing with invalid character '%d'.\n", 374 *tmp); 375 return -EINVAL; 376 } 377 tmp = strndup(arg, (ptr - arg)); 378 } else { 379 tmp = strdup(arg); 380 lr->end = INT_MAX; 381 } 382 383 if (tmp == NULL) 384 return -ENOMEM; 385 386 if (strchr(tmp, '.')) 387 lr->file = tmp; 388 else 389 lr->function = tmp; 390 391 return 0; 392 } 393 394 /* Check the name is good for event/group */ 395 static bool check_event_name(const char *name) 396 { 397 if (!isalpha(*name) && *name != '_') 398 return false; 399 while (*++name != '\0') { 400 if (!isalpha(*name) && !isdigit(*name) && *name != '_') 401 return false; 402 } 403 return true; 404 } 405 406 /* Parse probepoint definition. */ 407 static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev) 408 { 409 struct perf_probe_point *pp = &pev->point; 410 char *ptr, *tmp; 411 char c, nc = 0; 412 /* 413 * <Syntax> 414 * perf probe [EVENT=]SRC[:LN|;PTN] 415 * perf probe [EVENT=]FUNC[@SRC][+OFFS|%return|:LN|;PAT] 416 * 417 * TODO:Group name support 418 */ 419 420 ptr = strpbrk(arg, ";=@+%"); 421 if (ptr && *ptr == '=') { /* Event name */ 422 *ptr = '\0'; 423 tmp = ptr + 1; 424 if (strchr(arg, ':')) { 425 semantic_error("Group name is not supported yet.\n"); 426 return -ENOTSUP; 427 } 428 if (!check_event_name(arg)) { 429 semantic_error("%s is bad for event name -it must " 430 "follow C symbol-naming rule.\n", arg); 431 return -EINVAL; 432 } 433 pev->event = strdup(arg); 434 if (pev->event == NULL) 435 return -ENOMEM; 436 pev->group = NULL; 437 arg = tmp; 438 } 439 440 ptr = strpbrk(arg, ";:+@%"); 441 if (ptr) { 442 nc = *ptr; 443 *ptr++ = '\0'; 444 } 445 446 tmp = strdup(arg); 447 if (tmp == NULL) 448 return -ENOMEM; 449 450 /* Check arg is function or file and copy it */ 451 if (strchr(tmp, '.')) /* File */ 452 pp->file = tmp; 453 else /* Function */ 454 pp->function = tmp; 455 456 /* Parse other options */ 457 while (ptr) { 458 arg = ptr; 459 c = nc; 460 if (c == ';') { /* Lazy pattern must be the last part */ 461 pp->lazy_line = strdup(arg); 462 if (pp->lazy_line == NULL) 463 return -ENOMEM; 464 break; 465 } 466 ptr = strpbrk(arg, ";:+@%"); 467 if (ptr) { 468 nc = *ptr; 469 *ptr++ = '\0'; 470 } 471 switch (c) { 472 case ':': /* Line number */ 473 pp->line = strtoul(arg, &tmp, 0); 474 if (*tmp != '\0') { 475 semantic_error("There is non-digit char" 476 " in line number.\n"); 477 return -EINVAL; 478 } 479 break; 480 case '+': /* Byte offset from a symbol */ 481 pp->offset = strtoul(arg, &tmp, 0); 482 if (*tmp != '\0') { 483 semantic_error("There is non-digit character" 484 " in offset.\n"); 485 return -EINVAL; 486 } 487 break; 488 case '@': /* File name */ 489 if (pp->file) { 490 semantic_error("SRC@SRC is not allowed.\n"); 491 return -EINVAL; 492 } 493 pp->file = strdup(arg); 494 if (pp->file == NULL) 495 return -ENOMEM; 496 break; 497 case '%': /* Probe places */ 498 if (strcmp(arg, "return") == 0) { 499 pp->retprobe = 1; 500 } else { /* Others not supported yet */ 501 semantic_error("%%%s is not supported.\n", arg); 502 return -ENOTSUP; 503 } 504 break; 505 default: /* Buggy case */ 506 pr_err("This program has a bug at %s:%d.\n", 507 __FILE__, __LINE__); 508 return -ENOTSUP; 509 break; 510 } 511 } 512 513 /* Exclusion check */ 514 if (pp->lazy_line && pp->line) { 515 semantic_error("Lazy pattern can't be used with line number."); 516 return -EINVAL; 517 } 518 519 if (pp->lazy_line && pp->offset) { 520 semantic_error("Lazy pattern can't be used with offset."); 521 return -EINVAL; 522 } 523 524 if (pp->line && pp->offset) { 525 semantic_error("Offset can't be used with line number."); 526 return -EINVAL; 527 } 528 529 if (!pp->line && !pp->lazy_line && pp->file && !pp->function) { 530 semantic_error("File always requires line number or " 531 "lazy pattern."); 532 return -EINVAL; 533 } 534 535 if (pp->offset && !pp->function) { 536 semantic_error("Offset requires an entry function."); 537 return -EINVAL; 538 } 539 540 if (pp->retprobe && !pp->function) { 541 semantic_error("Return probe requires an entry function."); 542 return -EINVAL; 543 } 544 545 if ((pp->offset || pp->line || pp->lazy_line) && pp->retprobe) { 546 semantic_error("Offset/Line/Lazy pattern can't be used with " 547 "return probe."); 548 return -EINVAL; 549 } 550 551 pr_debug("symbol:%s file:%s line:%d offset:%lu return:%d lazy:%s\n", 552 pp->function, pp->file, pp->line, pp->offset, pp->retprobe, 553 pp->lazy_line); 554 return 0; 555 } 556 557 /* Parse perf-probe event argument */ 558 static int parse_perf_probe_arg(char *str, struct perf_probe_arg *arg) 559 { 560 char *tmp; 561 struct perf_probe_arg_field **fieldp; 562 563 pr_debug("parsing arg: %s into ", str); 564 565 tmp = strchr(str, '='); 566 if (tmp) { 567 arg->name = strndup(str, tmp - str); 568 if (arg->name == NULL) 569 return -ENOMEM; 570 pr_debug("name:%s ", arg->name); 571 str = tmp + 1; 572 } 573 574 tmp = strchr(str, ':'); 575 if (tmp) { /* Type setting */ 576 *tmp = '\0'; 577 arg->type = strdup(tmp + 1); 578 if (arg->type == NULL) 579 return -ENOMEM; 580 pr_debug("type:%s ", arg->type); 581 } 582 583 tmp = strpbrk(str, "-."); 584 if (!is_c_varname(str) || !tmp) { 585 /* A variable, register, symbol or special value */ 586 arg->var = strdup(str); 587 if (arg->var == NULL) 588 return -ENOMEM; 589 pr_debug("%s\n", arg->var); 590 return 0; 591 } 592 593 /* Structure fields */ 594 arg->var = strndup(str, tmp - str); 595 if (arg->var == NULL) 596 return -ENOMEM; 597 pr_debug("%s, ", arg->var); 598 fieldp = &arg->field; 599 600 do { 601 *fieldp = zalloc(sizeof(struct perf_probe_arg_field)); 602 if (*fieldp == NULL) 603 return -ENOMEM; 604 if (*tmp == '.') { 605 str = tmp + 1; 606 (*fieldp)->ref = false; 607 } else if (tmp[1] == '>') { 608 str = tmp + 2; 609 (*fieldp)->ref = true; 610 } else { 611 semantic_error("Argument parse error: %s\n", str); 612 return -EINVAL; 613 } 614 615 tmp = strpbrk(str, "-."); 616 if (tmp) { 617 (*fieldp)->name = strndup(str, tmp - str); 618 if ((*fieldp)->name == NULL) 619 return -ENOMEM; 620 pr_debug("%s(%d), ", (*fieldp)->name, (*fieldp)->ref); 621 fieldp = &(*fieldp)->next; 622 } 623 } while (tmp); 624 (*fieldp)->name = strdup(str); 625 if ((*fieldp)->name == NULL) 626 return -ENOMEM; 627 pr_debug("%s(%d)\n", (*fieldp)->name, (*fieldp)->ref); 628 629 /* If no name is specified, set the last field name */ 630 if (!arg->name) { 631 arg->name = strdup((*fieldp)->name); 632 if (arg->name == NULL) 633 return -ENOMEM; 634 } 635 return 0; 636 } 637 638 /* Parse perf-probe event command */ 639 int parse_perf_probe_command(const char *cmd, struct perf_probe_event *pev) 640 { 641 char **argv; 642 int argc, i, ret = 0; 643 644 argv = argv_split(cmd, &argc); 645 if (!argv) { 646 pr_debug("Failed to split arguments.\n"); 647 return -ENOMEM; 648 } 649 if (argc - 1 > MAX_PROBE_ARGS) { 650 semantic_error("Too many probe arguments (%d).\n", argc - 1); 651 ret = -ERANGE; 652 goto out; 653 } 654 /* Parse probe point */ 655 ret = parse_perf_probe_point(argv[0], pev); 656 if (ret < 0) 657 goto out; 658 659 /* Copy arguments and ensure return probe has no C argument */ 660 pev->nargs = argc - 1; 661 pev->args = zalloc(sizeof(struct perf_probe_arg) * pev->nargs); 662 if (pev->args == NULL) { 663 ret = -ENOMEM; 664 goto out; 665 } 666 for (i = 0; i < pev->nargs && ret >= 0; i++) { 667 ret = parse_perf_probe_arg(argv[i + 1], &pev->args[i]); 668 if (ret >= 0 && 669 is_c_varname(pev->args[i].var) && pev->point.retprobe) { 670 semantic_error("You can't specify local variable for" 671 " kretprobe.\n"); 672 ret = -EINVAL; 673 } 674 } 675 out: 676 argv_free(argv); 677 678 return ret; 679 } 680 681 /* Return true if this perf_probe_event requires debuginfo */ 682 bool perf_probe_event_need_dwarf(struct perf_probe_event *pev) 683 { 684 int i; 685 686 if (pev->point.file || pev->point.line || pev->point.lazy_line) 687 return true; 688 689 for (i = 0; i < pev->nargs; i++) 690 if (is_c_varname(pev->args[i].var)) 691 return true; 692 693 return false; 694 } 695 696 /* Parse kprobe_events event into struct probe_point */ 697 int parse_kprobe_trace_command(const char *cmd, struct kprobe_trace_event *tev) 698 { 699 struct kprobe_trace_point *tp = &tev->point; 700 char pr; 701 char *p; 702 int ret, i, argc; 703 char **argv; 704 705 pr_debug("Parsing kprobe_events: %s\n", cmd); 706 argv = argv_split(cmd, &argc); 707 if (!argv) { 708 pr_debug("Failed to split arguments.\n"); 709 return -ENOMEM; 710 } 711 if (argc < 2) { 712 semantic_error("Too few probe arguments.\n"); 713 ret = -ERANGE; 714 goto out; 715 } 716 717 /* Scan event and group name. */ 718 ret = sscanf(argv[0], "%c:%a[^/ \t]/%a[^ \t]", 719 &pr, (float *)(void *)&tev->group, 720 (float *)(void *)&tev->event); 721 if (ret != 3) { 722 semantic_error("Failed to parse event name: %s\n", argv[0]); 723 ret = -EINVAL; 724 goto out; 725 } 726 pr_debug("Group:%s Event:%s probe:%c\n", tev->group, tev->event, pr); 727 728 tp->retprobe = (pr == 'r'); 729 730 /* Scan function name and offset */ 731 ret = sscanf(argv[1], "%a[^+]+%lu", (float *)(void *)&tp->symbol, 732 &tp->offset); 733 if (ret == 1) 734 tp->offset = 0; 735 736 tev->nargs = argc - 2; 737 tev->args = zalloc(sizeof(struct kprobe_trace_arg) * tev->nargs); 738 if (tev->args == NULL) { 739 ret = -ENOMEM; 740 goto out; 741 } 742 for (i = 0; i < tev->nargs; i++) { 743 p = strchr(argv[i + 2], '='); 744 if (p) /* We don't need which register is assigned. */ 745 *p++ = '\0'; 746 else 747 p = argv[i + 2]; 748 tev->args[i].name = strdup(argv[i + 2]); 749 /* TODO: parse regs and offset */ 750 tev->args[i].value = strdup(p); 751 if (tev->args[i].name == NULL || tev->args[i].value == NULL) { 752 ret = -ENOMEM; 753 goto out; 754 } 755 } 756 ret = 0; 757 out: 758 argv_free(argv); 759 return ret; 760 } 761 762 /* Compose only probe arg */ 763 int synthesize_perf_probe_arg(struct perf_probe_arg *pa, char *buf, size_t len) 764 { 765 struct perf_probe_arg_field *field = pa->field; 766 int ret; 767 char *tmp = buf; 768 769 if (pa->name && pa->var) 770 ret = e_snprintf(tmp, len, "%s=%s", pa->name, pa->var); 771 else 772 ret = e_snprintf(tmp, len, "%s", pa->name ? pa->name : pa->var); 773 if (ret <= 0) 774 goto error; 775 tmp += ret; 776 len -= ret; 777 778 while (field) { 779 ret = e_snprintf(tmp, len, "%s%s", field->ref ? "->" : ".", 780 field->name); 781 if (ret <= 0) 782 goto error; 783 tmp += ret; 784 len -= ret; 785 field = field->next; 786 } 787 788 if (pa->type) { 789 ret = e_snprintf(tmp, len, ":%s", pa->type); 790 if (ret <= 0) 791 goto error; 792 tmp += ret; 793 len -= ret; 794 } 795 796 return tmp - buf; 797 error: 798 pr_debug("Failed to synthesize perf probe argument: %s", 799 strerror(-ret)); 800 return ret; 801 } 802 803 /* Compose only probe point (not argument) */ 804 static char *synthesize_perf_probe_point(struct perf_probe_point *pp) 805 { 806 char *buf, *tmp; 807 char offs[32] = "", line[32] = "", file[32] = ""; 808 int ret, len; 809 810 buf = zalloc(MAX_CMDLEN); 811 if (buf == NULL) { 812 ret = -ENOMEM; 813 goto error; 814 } 815 if (pp->offset) { 816 ret = e_snprintf(offs, 32, "+%lu", pp->offset); 817 if (ret <= 0) 818 goto error; 819 } 820 if (pp->line) { 821 ret = e_snprintf(line, 32, ":%d", pp->line); 822 if (ret <= 0) 823 goto error; 824 } 825 if (pp->file) { 826 len = strlen(pp->file) - 31; 827 if (len < 0) 828 len = 0; 829 tmp = strchr(pp->file + len, '/'); 830 if (!tmp) 831 tmp = pp->file + len; 832 ret = e_snprintf(file, 32, "@%s", tmp + 1); 833 if (ret <= 0) 834 goto error; 835 } 836 837 if (pp->function) 838 ret = e_snprintf(buf, MAX_CMDLEN, "%s%s%s%s%s", pp->function, 839 offs, pp->retprobe ? "%return" : "", line, 840 file); 841 else 842 ret = e_snprintf(buf, MAX_CMDLEN, "%s%s", file, line); 843 if (ret <= 0) 844 goto error; 845 846 return buf; 847 error: 848 pr_debug("Failed to synthesize perf probe point: %s", 849 strerror(-ret)); 850 if (buf) 851 free(buf); 852 return NULL; 853 } 854 855 #if 0 856 char *synthesize_perf_probe_command(struct perf_probe_event *pev) 857 { 858 char *buf; 859 int i, len, ret; 860 861 buf = synthesize_perf_probe_point(&pev->point); 862 if (!buf) 863 return NULL; 864 865 len = strlen(buf); 866 for (i = 0; i < pev->nargs; i++) { 867 ret = e_snprintf(&buf[len], MAX_CMDLEN - len, " %s", 868 pev->args[i].name); 869 if (ret <= 0) { 870 free(buf); 871 return NULL; 872 } 873 len += ret; 874 } 875 876 return buf; 877 } 878 #endif 879 880 static int __synthesize_kprobe_trace_arg_ref(struct kprobe_trace_arg_ref *ref, 881 char **buf, size_t *buflen, 882 int depth) 883 { 884 int ret; 885 if (ref->next) { 886 depth = __synthesize_kprobe_trace_arg_ref(ref->next, buf, 887 buflen, depth + 1); 888 if (depth < 0) 889 goto out; 890 } 891 892 ret = e_snprintf(*buf, *buflen, "%+ld(", ref->offset); 893 if (ret < 0) 894 depth = ret; 895 else { 896 *buf += ret; 897 *buflen -= ret; 898 } 899 out: 900 return depth; 901 902 } 903 904 static int synthesize_kprobe_trace_arg(struct kprobe_trace_arg *arg, 905 char *buf, size_t buflen) 906 { 907 int ret, depth = 0; 908 char *tmp = buf; 909 910 /* Argument name or separator */ 911 if (arg->name) 912 ret = e_snprintf(buf, buflen, " %s=", arg->name); 913 else 914 ret = e_snprintf(buf, buflen, " "); 915 if (ret < 0) 916 return ret; 917 buf += ret; 918 buflen -= ret; 919 920 /* Dereferencing arguments */ 921 if (arg->ref) { 922 depth = __synthesize_kprobe_trace_arg_ref(arg->ref, &buf, 923 &buflen, 1); 924 if (depth < 0) 925 return depth; 926 } 927 928 /* Print argument value */ 929 ret = e_snprintf(buf, buflen, "%s", arg->value); 930 if (ret < 0) 931 return ret; 932 buf += ret; 933 buflen -= ret; 934 935 /* Closing */ 936 while (depth--) { 937 ret = e_snprintf(buf, buflen, ")"); 938 if (ret < 0) 939 return ret; 940 buf += ret; 941 buflen -= ret; 942 } 943 /* Print argument type */ 944 if (arg->type) { 945 ret = e_snprintf(buf, buflen, ":%s", arg->type); 946 if (ret <= 0) 947 return ret; 948 buf += ret; 949 } 950 951 return buf - tmp; 952 } 953 954 char *synthesize_kprobe_trace_command(struct kprobe_trace_event *tev) 955 { 956 struct kprobe_trace_point *tp = &tev->point; 957 char *buf; 958 int i, len, ret; 959 960 buf = zalloc(MAX_CMDLEN); 961 if (buf == NULL) 962 return NULL; 963 964 len = e_snprintf(buf, MAX_CMDLEN, "%c:%s/%s %s+%lu", 965 tp->retprobe ? 'r' : 'p', 966 tev->group, tev->event, 967 tp->symbol, tp->offset); 968 if (len <= 0) 969 goto error; 970 971 for (i = 0; i < tev->nargs; i++) { 972 ret = synthesize_kprobe_trace_arg(&tev->args[i], buf + len, 973 MAX_CMDLEN - len); 974 if (ret <= 0) 975 goto error; 976 len += ret; 977 } 978 979 return buf; 980 error: 981 free(buf); 982 return NULL; 983 } 984 985 int convert_to_perf_probe_event(struct kprobe_trace_event *tev, 986 struct perf_probe_event *pev) 987 { 988 char buf[64] = ""; 989 int i, ret; 990 991 /* Convert event/group name */ 992 pev->event = strdup(tev->event); 993 pev->group = strdup(tev->group); 994 if (pev->event == NULL || pev->group == NULL) 995 return -ENOMEM; 996 997 /* Convert trace_point to probe_point */ 998 ret = convert_to_perf_probe_point(&tev->point, &pev->point); 999 if (ret < 0) 1000 return ret; 1001 1002 /* Convert trace_arg to probe_arg */ 1003 pev->nargs = tev->nargs; 1004 pev->args = zalloc(sizeof(struct perf_probe_arg) * pev->nargs); 1005 if (pev->args == NULL) 1006 return -ENOMEM; 1007 for (i = 0; i < tev->nargs && ret >= 0; i++) { 1008 if (tev->args[i].name) 1009 pev->args[i].name = strdup(tev->args[i].name); 1010 else { 1011 ret = synthesize_kprobe_trace_arg(&tev->args[i], 1012 buf, 64); 1013 pev->args[i].name = strdup(buf); 1014 } 1015 if (pev->args[i].name == NULL && ret >= 0) 1016 ret = -ENOMEM; 1017 } 1018 1019 if (ret < 0) 1020 clear_perf_probe_event(pev); 1021 1022 return ret; 1023 } 1024 1025 void clear_perf_probe_event(struct perf_probe_event *pev) 1026 { 1027 struct perf_probe_point *pp = &pev->point; 1028 struct perf_probe_arg_field *field, *next; 1029 int i; 1030 1031 if (pev->event) 1032 free(pev->event); 1033 if (pev->group) 1034 free(pev->group); 1035 if (pp->file) 1036 free(pp->file); 1037 if (pp->function) 1038 free(pp->function); 1039 if (pp->lazy_line) 1040 free(pp->lazy_line); 1041 for (i = 0; i < pev->nargs; i++) { 1042 if (pev->args[i].name) 1043 free(pev->args[i].name); 1044 if (pev->args[i].var) 1045 free(pev->args[i].var); 1046 if (pev->args[i].type) 1047 free(pev->args[i].type); 1048 field = pev->args[i].field; 1049 while (field) { 1050 next = field->next; 1051 if (field->name) 1052 free(field->name); 1053 free(field); 1054 field = next; 1055 } 1056 } 1057 if (pev->args) 1058 free(pev->args); 1059 memset(pev, 0, sizeof(*pev)); 1060 } 1061 1062 void clear_kprobe_trace_event(struct kprobe_trace_event *tev) 1063 { 1064 struct kprobe_trace_arg_ref *ref, *next; 1065 int i; 1066 1067 if (tev->event) 1068 free(tev->event); 1069 if (tev->group) 1070 free(tev->group); 1071 if (tev->point.symbol) 1072 free(tev->point.symbol); 1073 for (i = 0; i < tev->nargs; i++) { 1074 if (tev->args[i].name) 1075 free(tev->args[i].name); 1076 if (tev->args[i].value) 1077 free(tev->args[i].value); 1078 if (tev->args[i].type) 1079 free(tev->args[i].type); 1080 ref = tev->args[i].ref; 1081 while (ref) { 1082 next = ref->next; 1083 free(ref); 1084 ref = next; 1085 } 1086 } 1087 if (tev->args) 1088 free(tev->args); 1089 memset(tev, 0, sizeof(*tev)); 1090 } 1091 1092 static int open_kprobe_events(bool readwrite) 1093 { 1094 char buf[PATH_MAX]; 1095 const char *__debugfs; 1096 int ret; 1097 1098 __debugfs = debugfs_find_mountpoint(); 1099 if (__debugfs == NULL) { 1100 pr_warning("Debugfs is not mounted.\n"); 1101 return -ENOENT; 1102 } 1103 1104 ret = e_snprintf(buf, PATH_MAX, "%stracing/kprobe_events", __debugfs); 1105 if (ret >= 0) { 1106 pr_debug("Opening %s write=%d\n", buf, readwrite); 1107 if (readwrite && !probe_event_dry_run) 1108 ret = open(buf, O_RDWR, O_APPEND); 1109 else 1110 ret = open(buf, O_RDONLY, 0); 1111 } 1112 1113 if (ret < 0) { 1114 if (errno == ENOENT) 1115 pr_warning("kprobe_events file does not exist - please" 1116 " rebuild kernel with CONFIG_KPROBE_EVENT.\n"); 1117 else 1118 pr_warning("Failed to open kprobe_events file: %s\n", 1119 strerror(errno)); 1120 } 1121 return ret; 1122 } 1123 1124 /* Get raw string list of current kprobe_events */ 1125 static struct strlist *get_kprobe_trace_command_rawlist(int fd) 1126 { 1127 int ret, idx; 1128 FILE *fp; 1129 char buf[MAX_CMDLEN]; 1130 char *p; 1131 struct strlist *sl; 1132 1133 sl = strlist__new(true, NULL); 1134 1135 fp = fdopen(dup(fd), "r"); 1136 while (!feof(fp)) { 1137 p = fgets(buf, MAX_CMDLEN, fp); 1138 if (!p) 1139 break; 1140 1141 idx = strlen(p) - 1; 1142 if (p[idx] == '\n') 1143 p[idx] = '\0'; 1144 ret = strlist__add(sl, buf); 1145 if (ret < 0) { 1146 pr_debug("strlist__add failed: %s\n", strerror(-ret)); 1147 strlist__delete(sl); 1148 return NULL; 1149 } 1150 } 1151 fclose(fp); 1152 1153 return sl; 1154 } 1155 1156 /* Show an event */ 1157 static int show_perf_probe_event(struct perf_probe_event *pev) 1158 { 1159 int i, ret; 1160 char buf[128]; 1161 char *place; 1162 1163 /* Synthesize only event probe point */ 1164 place = synthesize_perf_probe_point(&pev->point); 1165 if (!place) 1166 return -EINVAL; 1167 1168 ret = e_snprintf(buf, 128, "%s:%s", pev->group, pev->event); 1169 if (ret < 0) 1170 return ret; 1171 1172 printf(" %-20s (on %s", buf, place); 1173 1174 if (pev->nargs > 0) { 1175 printf(" with"); 1176 for (i = 0; i < pev->nargs; i++) { 1177 ret = synthesize_perf_probe_arg(&pev->args[i], 1178 buf, 128); 1179 if (ret < 0) 1180 break; 1181 printf(" %s", buf); 1182 } 1183 } 1184 printf(")\n"); 1185 free(place); 1186 return ret; 1187 } 1188 1189 /* List up current perf-probe events */ 1190 int show_perf_probe_events(void) 1191 { 1192 int fd, ret; 1193 struct kprobe_trace_event tev; 1194 struct perf_probe_event pev; 1195 struct strlist *rawlist; 1196 struct str_node *ent; 1197 1198 setup_pager(); 1199 ret = init_vmlinux(); 1200 if (ret < 0) 1201 return ret; 1202 1203 memset(&tev, 0, sizeof(tev)); 1204 memset(&pev, 0, sizeof(pev)); 1205 1206 fd = open_kprobe_events(false); 1207 if (fd < 0) 1208 return fd; 1209 1210 rawlist = get_kprobe_trace_command_rawlist(fd); 1211 close(fd); 1212 if (!rawlist) 1213 return -ENOENT; 1214 1215 strlist__for_each(ent, rawlist) { 1216 ret = parse_kprobe_trace_command(ent->s, &tev); 1217 if (ret >= 0) { 1218 ret = convert_to_perf_probe_event(&tev, &pev); 1219 if (ret >= 0) 1220 ret = show_perf_probe_event(&pev); 1221 } 1222 clear_perf_probe_event(&pev); 1223 clear_kprobe_trace_event(&tev); 1224 if (ret < 0) 1225 break; 1226 } 1227 strlist__delete(rawlist); 1228 1229 return ret; 1230 } 1231 1232 /* Get current perf-probe event names */ 1233 static struct strlist *get_kprobe_trace_event_names(int fd, bool include_group) 1234 { 1235 char buf[128]; 1236 struct strlist *sl, *rawlist; 1237 struct str_node *ent; 1238 struct kprobe_trace_event tev; 1239 int ret = 0; 1240 1241 memset(&tev, 0, sizeof(tev)); 1242 1243 rawlist = get_kprobe_trace_command_rawlist(fd); 1244 sl = strlist__new(true, NULL); 1245 strlist__for_each(ent, rawlist) { 1246 ret = parse_kprobe_trace_command(ent->s, &tev); 1247 if (ret < 0) 1248 break; 1249 if (include_group) { 1250 ret = e_snprintf(buf, 128, "%s:%s", tev.group, 1251 tev.event); 1252 if (ret >= 0) 1253 ret = strlist__add(sl, buf); 1254 } else 1255 ret = strlist__add(sl, tev.event); 1256 clear_kprobe_trace_event(&tev); 1257 if (ret < 0) 1258 break; 1259 } 1260 strlist__delete(rawlist); 1261 1262 if (ret < 0) { 1263 strlist__delete(sl); 1264 return NULL; 1265 } 1266 return sl; 1267 } 1268 1269 static int write_kprobe_trace_event(int fd, struct kprobe_trace_event *tev) 1270 { 1271 int ret = 0; 1272 char *buf = synthesize_kprobe_trace_command(tev); 1273 1274 if (!buf) { 1275 pr_debug("Failed to synthesize kprobe trace event.\n"); 1276 return -EINVAL; 1277 } 1278 1279 pr_debug("Writing event: %s\n", buf); 1280 if (!probe_event_dry_run) { 1281 ret = write(fd, buf, strlen(buf)); 1282 if (ret <= 0) 1283 pr_warning("Failed to write event: %s\n", 1284 strerror(errno)); 1285 } 1286 free(buf); 1287 return ret; 1288 } 1289 1290 static int get_new_event_name(char *buf, size_t len, const char *base, 1291 struct strlist *namelist, bool allow_suffix) 1292 { 1293 int i, ret; 1294 1295 /* Try no suffix */ 1296 ret = e_snprintf(buf, len, "%s", base); 1297 if (ret < 0) { 1298 pr_debug("snprintf() failed: %s\n", strerror(-ret)); 1299 return ret; 1300 } 1301 if (!strlist__has_entry(namelist, buf)) 1302 return 0; 1303 1304 if (!allow_suffix) { 1305 pr_warning("Error: event \"%s\" already exists. " 1306 "(Use -f to force duplicates.)\n", base); 1307 return -EEXIST; 1308 } 1309 1310 /* Try to add suffix */ 1311 for (i = 1; i < MAX_EVENT_INDEX; i++) { 1312 ret = e_snprintf(buf, len, "%s_%d", base, i); 1313 if (ret < 0) { 1314 pr_debug("snprintf() failed: %s\n", strerror(-ret)); 1315 return ret; 1316 } 1317 if (!strlist__has_entry(namelist, buf)) 1318 break; 1319 } 1320 if (i == MAX_EVENT_INDEX) { 1321 pr_warning("Too many events are on the same function.\n"); 1322 ret = -ERANGE; 1323 } 1324 1325 return ret; 1326 } 1327 1328 static int __add_kprobe_trace_events(struct perf_probe_event *pev, 1329 struct kprobe_trace_event *tevs, 1330 int ntevs, bool allow_suffix) 1331 { 1332 int i, fd, ret; 1333 struct kprobe_trace_event *tev = NULL; 1334 char buf[64]; 1335 const char *event, *group; 1336 struct strlist *namelist; 1337 1338 fd = open_kprobe_events(true); 1339 if (fd < 0) 1340 return fd; 1341 /* Get current event names */ 1342 namelist = get_kprobe_trace_event_names(fd, false); 1343 if (!namelist) { 1344 pr_debug("Failed to get current event list.\n"); 1345 return -EIO; 1346 } 1347 1348 ret = 0; 1349 printf("Add new event%s\n", (ntevs > 1) ? "s:" : ":"); 1350 for (i = 0; i < ntevs; i++) { 1351 tev = &tevs[i]; 1352 if (pev->event) 1353 event = pev->event; 1354 else 1355 if (pev->point.function) 1356 event = pev->point.function; 1357 else 1358 event = tev->point.symbol; 1359 if (pev->group) 1360 group = pev->group; 1361 else 1362 group = PERFPROBE_GROUP; 1363 1364 /* Get an unused new event name */ 1365 ret = get_new_event_name(buf, 64, event, 1366 namelist, allow_suffix); 1367 if (ret < 0) 1368 break; 1369 event = buf; 1370 1371 tev->event = strdup(event); 1372 tev->group = strdup(group); 1373 if (tev->event == NULL || tev->group == NULL) { 1374 ret = -ENOMEM; 1375 break; 1376 } 1377 ret = write_kprobe_trace_event(fd, tev); 1378 if (ret < 0) 1379 break; 1380 /* Add added event name to namelist */ 1381 strlist__add(namelist, event); 1382 1383 /* Trick here - save current event/group */ 1384 event = pev->event; 1385 group = pev->group; 1386 pev->event = tev->event; 1387 pev->group = tev->group; 1388 show_perf_probe_event(pev); 1389 /* Trick here - restore current event/group */ 1390 pev->event = (char *)event; 1391 pev->group = (char *)group; 1392 1393 /* 1394 * Probes after the first probe which comes from same 1395 * user input are always allowed to add suffix, because 1396 * there might be several addresses corresponding to 1397 * one code line. 1398 */ 1399 allow_suffix = true; 1400 } 1401 1402 if (ret >= 0) { 1403 /* Show how to use the event. */ 1404 printf("\nYou can now use it on all perf tools, such as:\n\n"); 1405 printf("\tperf record -e %s:%s -aR sleep 1\n\n", tev->group, 1406 tev->event); 1407 } 1408 1409 strlist__delete(namelist); 1410 close(fd); 1411 return ret; 1412 } 1413 1414 static int convert_to_kprobe_trace_events(struct perf_probe_event *pev, 1415 struct kprobe_trace_event **tevs, 1416 int max_tevs) 1417 { 1418 struct symbol *sym; 1419 int ret = 0, i; 1420 struct kprobe_trace_event *tev; 1421 1422 /* Convert perf_probe_event with debuginfo */ 1423 ret = try_to_find_kprobe_trace_events(pev, tevs, max_tevs); 1424 if (ret != 0) 1425 return ret; 1426 1427 /* Allocate trace event buffer */ 1428 tev = *tevs = zalloc(sizeof(struct kprobe_trace_event)); 1429 if (tev == NULL) 1430 return -ENOMEM; 1431 1432 /* Copy parameters */ 1433 tev->point.symbol = strdup(pev->point.function); 1434 if (tev->point.symbol == NULL) { 1435 ret = -ENOMEM; 1436 goto error; 1437 } 1438 tev->point.offset = pev->point.offset; 1439 tev->nargs = pev->nargs; 1440 if (tev->nargs) { 1441 tev->args = zalloc(sizeof(struct kprobe_trace_arg) 1442 * tev->nargs); 1443 if (tev->args == NULL) { 1444 ret = -ENOMEM; 1445 goto error; 1446 } 1447 for (i = 0; i < tev->nargs; i++) { 1448 if (pev->args[i].name) { 1449 tev->args[i].name = strdup(pev->args[i].name); 1450 if (tev->args[i].name == NULL) { 1451 ret = -ENOMEM; 1452 goto error; 1453 } 1454 } 1455 tev->args[i].value = strdup(pev->args[i].var); 1456 if (tev->args[i].value == NULL) { 1457 ret = -ENOMEM; 1458 goto error; 1459 } 1460 if (pev->args[i].type) { 1461 tev->args[i].type = strdup(pev->args[i].type); 1462 if (tev->args[i].type == NULL) { 1463 ret = -ENOMEM; 1464 goto error; 1465 } 1466 } 1467 } 1468 } 1469 1470 /* Currently just checking function name from symbol map */ 1471 sym = map__find_symbol_by_name(machine.vmlinux_maps[MAP__FUNCTION], 1472 tev->point.symbol, NULL); 1473 if (!sym) { 1474 pr_warning("Kernel symbol \'%s\' not found.\n", 1475 tev->point.symbol); 1476 ret = -ENOENT; 1477 goto error; 1478 } 1479 1480 return 1; 1481 error: 1482 clear_kprobe_trace_event(tev); 1483 free(tev); 1484 *tevs = NULL; 1485 return ret; 1486 } 1487 1488 struct __event_package { 1489 struct perf_probe_event *pev; 1490 struct kprobe_trace_event *tevs; 1491 int ntevs; 1492 }; 1493 1494 int add_perf_probe_events(struct perf_probe_event *pevs, int npevs, 1495 bool force_add, int max_tevs) 1496 { 1497 int i, j, ret; 1498 struct __event_package *pkgs; 1499 1500 pkgs = zalloc(sizeof(struct __event_package) * npevs); 1501 if (pkgs == NULL) 1502 return -ENOMEM; 1503 1504 /* Init vmlinux path */ 1505 ret = init_vmlinux(); 1506 if (ret < 0) 1507 return ret; 1508 1509 /* Loop 1: convert all events */ 1510 for (i = 0; i < npevs; i++) { 1511 pkgs[i].pev = &pevs[i]; 1512 /* Convert with or without debuginfo */ 1513 ret = convert_to_kprobe_trace_events(pkgs[i].pev, 1514 &pkgs[i].tevs, max_tevs); 1515 if (ret < 0) 1516 goto end; 1517 pkgs[i].ntevs = ret; 1518 } 1519 1520 /* Loop 2: add all events */ 1521 for (i = 0; i < npevs && ret >= 0; i++) 1522 ret = __add_kprobe_trace_events(pkgs[i].pev, pkgs[i].tevs, 1523 pkgs[i].ntevs, force_add); 1524 end: 1525 /* Loop 3: cleanup trace events */ 1526 for (i = 0; i < npevs; i++) 1527 for (j = 0; j < pkgs[i].ntevs; j++) 1528 clear_kprobe_trace_event(&pkgs[i].tevs[j]); 1529 1530 return ret; 1531 } 1532 1533 static int __del_trace_kprobe_event(int fd, struct str_node *ent) 1534 { 1535 char *p; 1536 char buf[128]; 1537 int ret; 1538 1539 /* Convert from perf-probe event to trace-kprobe event */ 1540 ret = e_snprintf(buf, 128, "-:%s", ent->s); 1541 if (ret < 0) 1542 goto error; 1543 1544 p = strchr(buf + 2, ':'); 1545 if (!p) { 1546 pr_debug("Internal error: %s should have ':' but not.\n", 1547 ent->s); 1548 ret = -ENOTSUP; 1549 goto error; 1550 } 1551 *p = '/'; 1552 1553 pr_debug("Writing event: %s\n", buf); 1554 ret = write(fd, buf, strlen(buf)); 1555 if (ret < 0) 1556 goto error; 1557 1558 printf("Remove event: %s\n", ent->s); 1559 return 0; 1560 error: 1561 pr_warning("Failed to delete event: %s\n", strerror(-ret)); 1562 return ret; 1563 } 1564 1565 static int del_trace_kprobe_event(int fd, const char *group, 1566 const char *event, struct strlist *namelist) 1567 { 1568 char buf[128]; 1569 struct str_node *ent, *n; 1570 int found = 0, ret = 0; 1571 1572 ret = e_snprintf(buf, 128, "%s:%s", group, event); 1573 if (ret < 0) { 1574 pr_err("Failed to copy event."); 1575 return ret; 1576 } 1577 1578 if (strpbrk(buf, "*?")) { /* Glob-exp */ 1579 strlist__for_each_safe(ent, n, namelist) 1580 if (strglobmatch(ent->s, buf)) { 1581 found++; 1582 ret = __del_trace_kprobe_event(fd, ent); 1583 if (ret < 0) 1584 break; 1585 strlist__remove(namelist, ent); 1586 } 1587 } else { 1588 ent = strlist__find(namelist, buf); 1589 if (ent) { 1590 found++; 1591 ret = __del_trace_kprobe_event(fd, ent); 1592 if (ret >= 0) 1593 strlist__remove(namelist, ent); 1594 } 1595 } 1596 if (found == 0 && ret >= 0) 1597 pr_info("Info: Event \"%s\" does not exist.\n", buf); 1598 1599 return ret; 1600 } 1601 1602 int del_perf_probe_events(struct strlist *dellist) 1603 { 1604 int fd, ret = 0; 1605 const char *group, *event; 1606 char *p, *str; 1607 struct str_node *ent; 1608 struct strlist *namelist; 1609 1610 fd = open_kprobe_events(true); 1611 if (fd < 0) 1612 return fd; 1613 1614 /* Get current event names */ 1615 namelist = get_kprobe_trace_event_names(fd, true); 1616 if (namelist == NULL) 1617 return -EINVAL; 1618 1619 strlist__for_each(ent, dellist) { 1620 str = strdup(ent->s); 1621 if (str == NULL) { 1622 ret = -ENOMEM; 1623 break; 1624 } 1625 pr_debug("Parsing: %s\n", str); 1626 p = strchr(str, ':'); 1627 if (p) { 1628 group = str; 1629 *p = '\0'; 1630 event = p + 1; 1631 } else { 1632 group = "*"; 1633 event = str; 1634 } 1635 pr_debug("Group: %s, Event: %s\n", group, event); 1636 ret = del_trace_kprobe_event(fd, group, event, namelist); 1637 free(str); 1638 if (ret < 0) 1639 break; 1640 } 1641 strlist__delete(namelist); 1642 close(fd); 1643 1644 return ret; 1645 } 1646 1647