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