1 /* 2 * probe-file.c : operate ftrace k/uprobe events files 3 * 4 * Written by Masami Hiramatsu <masami.hiramatsu.pt@hitachi.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 */ 17 #include <sys/uio.h> 18 #include "util.h" 19 #include "event.h" 20 #include "strlist.h" 21 #include "debug.h" 22 #include "cache.h" 23 #include "color.h" 24 #include "symbol.h" 25 #include "thread.h" 26 #include <api/fs/tracing_path.h> 27 #include "probe-event.h" 28 #include "probe-file.h" 29 #include "session.h" 30 31 #define MAX_CMDLEN 256 32 33 static void print_open_warning(int err, bool uprobe) 34 { 35 char sbuf[STRERR_BUFSIZE]; 36 37 if (err == -ENOENT) { 38 const char *config; 39 40 if (uprobe) 41 config = "CONFIG_UPROBE_EVENTS"; 42 else 43 config = "CONFIG_KPROBE_EVENTS"; 44 45 pr_warning("%cprobe_events file does not exist" 46 " - please rebuild kernel with %s.\n", 47 uprobe ? 'u' : 'k', config); 48 } else if (err == -ENOTSUP) 49 pr_warning("Tracefs or debugfs is not mounted.\n"); 50 else 51 pr_warning("Failed to open %cprobe_events: %s\n", 52 uprobe ? 'u' : 'k', 53 str_error_r(-err, sbuf, sizeof(sbuf))); 54 } 55 56 static void print_both_open_warning(int kerr, int uerr) 57 { 58 /* Both kprobes and uprobes are disabled, warn it. */ 59 if (kerr == -ENOTSUP && uerr == -ENOTSUP) 60 pr_warning("Tracefs or debugfs is not mounted.\n"); 61 else if (kerr == -ENOENT && uerr == -ENOENT) 62 pr_warning("Please rebuild kernel with CONFIG_KPROBE_EVENTS " 63 "or/and CONFIG_UPROBE_EVENTS.\n"); 64 else { 65 char sbuf[STRERR_BUFSIZE]; 66 pr_warning("Failed to open kprobe events: %s.\n", 67 str_error_r(-kerr, sbuf, sizeof(sbuf))); 68 pr_warning("Failed to open uprobe events: %s.\n", 69 str_error_r(-uerr, sbuf, sizeof(sbuf))); 70 } 71 } 72 73 static int open_probe_events(const char *trace_file, bool readwrite) 74 { 75 char buf[PATH_MAX]; 76 const char *tracing_dir = ""; 77 int ret; 78 79 ret = e_snprintf(buf, PATH_MAX, "%s/%s%s", 80 tracing_path, tracing_dir, trace_file); 81 if (ret >= 0) { 82 pr_debug("Opening %s write=%d\n", buf, readwrite); 83 if (readwrite && !probe_event_dry_run) 84 ret = open(buf, O_RDWR | O_APPEND, 0); 85 else 86 ret = open(buf, O_RDONLY, 0); 87 88 if (ret < 0) 89 ret = -errno; 90 } 91 return ret; 92 } 93 94 static int open_kprobe_events(bool readwrite) 95 { 96 return open_probe_events("kprobe_events", readwrite); 97 } 98 99 static int open_uprobe_events(bool readwrite) 100 { 101 return open_probe_events("uprobe_events", readwrite); 102 } 103 104 int probe_file__open(int flag) 105 { 106 int fd; 107 108 if (flag & PF_FL_UPROBE) 109 fd = open_uprobe_events(flag & PF_FL_RW); 110 else 111 fd = open_kprobe_events(flag & PF_FL_RW); 112 if (fd < 0) 113 print_open_warning(fd, flag & PF_FL_UPROBE); 114 115 return fd; 116 } 117 118 int probe_file__open_both(int *kfd, int *ufd, int flag) 119 { 120 if (!kfd || !ufd) 121 return -EINVAL; 122 123 *kfd = open_kprobe_events(flag & PF_FL_RW); 124 *ufd = open_uprobe_events(flag & PF_FL_RW); 125 if (*kfd < 0 && *ufd < 0) { 126 print_both_open_warning(*kfd, *ufd); 127 return *kfd; 128 } 129 130 return 0; 131 } 132 133 /* Get raw string list of current kprobe_events or uprobe_events */ 134 struct strlist *probe_file__get_rawlist(int fd) 135 { 136 int ret, idx; 137 FILE *fp; 138 char buf[MAX_CMDLEN]; 139 char *p; 140 struct strlist *sl; 141 142 if (fd < 0) 143 return NULL; 144 145 sl = strlist__new(NULL, NULL); 146 147 fp = fdopen(dup(fd), "r"); 148 while (!feof(fp)) { 149 p = fgets(buf, MAX_CMDLEN, fp); 150 if (!p) 151 break; 152 153 idx = strlen(p) - 1; 154 if (p[idx] == '\n') 155 p[idx] = '\0'; 156 ret = strlist__add(sl, buf); 157 if (ret < 0) { 158 pr_debug("strlist__add failed (%d)\n", ret); 159 strlist__delete(sl); 160 return NULL; 161 } 162 } 163 fclose(fp); 164 165 return sl; 166 } 167 168 static struct strlist *__probe_file__get_namelist(int fd, bool include_group) 169 { 170 char buf[128]; 171 struct strlist *sl, *rawlist; 172 struct str_node *ent; 173 struct probe_trace_event tev; 174 int ret = 0; 175 176 memset(&tev, 0, sizeof(tev)); 177 rawlist = probe_file__get_rawlist(fd); 178 if (!rawlist) 179 return NULL; 180 sl = strlist__new(NULL, NULL); 181 strlist__for_each_entry(ent, rawlist) { 182 ret = parse_probe_trace_command(ent->s, &tev); 183 if (ret < 0) 184 break; 185 if (include_group) { 186 ret = e_snprintf(buf, 128, "%s:%s", tev.group, 187 tev.event); 188 if (ret >= 0) 189 ret = strlist__add(sl, buf); 190 } else 191 ret = strlist__add(sl, tev.event); 192 clear_probe_trace_event(&tev); 193 if (ret < 0) 194 break; 195 } 196 strlist__delete(rawlist); 197 198 if (ret < 0) { 199 strlist__delete(sl); 200 return NULL; 201 } 202 return sl; 203 } 204 205 /* Get current perf-probe event names */ 206 struct strlist *probe_file__get_namelist(int fd) 207 { 208 return __probe_file__get_namelist(fd, false); 209 } 210 211 int probe_file__add_event(int fd, struct probe_trace_event *tev) 212 { 213 int ret = 0; 214 char *buf = synthesize_probe_trace_command(tev); 215 char sbuf[STRERR_BUFSIZE]; 216 217 if (!buf) { 218 pr_debug("Failed to synthesize probe trace event.\n"); 219 return -EINVAL; 220 } 221 222 pr_debug("Writing event: %s\n", buf); 223 if (!probe_event_dry_run) { 224 if (write(fd, buf, strlen(buf)) < (int)strlen(buf)) { 225 ret = -errno; 226 pr_warning("Failed to write event: %s\n", 227 str_error_r(errno, sbuf, sizeof(sbuf))); 228 } 229 } 230 free(buf); 231 232 return ret; 233 } 234 235 static int __del_trace_probe_event(int fd, struct str_node *ent) 236 { 237 char *p; 238 char buf[128]; 239 int ret; 240 241 /* Convert from perf-probe event to trace-probe event */ 242 ret = e_snprintf(buf, 128, "-:%s", ent->s); 243 if (ret < 0) 244 goto error; 245 246 p = strchr(buf + 2, ':'); 247 if (!p) { 248 pr_debug("Internal error: %s should have ':' but not.\n", 249 ent->s); 250 ret = -ENOTSUP; 251 goto error; 252 } 253 *p = '/'; 254 255 pr_debug("Writing event: %s\n", buf); 256 ret = write(fd, buf, strlen(buf)); 257 if (ret < 0) { 258 ret = -errno; 259 goto error; 260 } 261 262 return 0; 263 error: 264 pr_warning("Failed to delete event: %s\n", 265 str_error_r(-ret, buf, sizeof(buf))); 266 return ret; 267 } 268 269 int probe_file__get_events(int fd, struct strfilter *filter, 270 struct strlist *plist) 271 { 272 struct strlist *namelist; 273 struct str_node *ent; 274 const char *p; 275 int ret = -ENOENT; 276 277 if (!plist) 278 return -EINVAL; 279 280 namelist = __probe_file__get_namelist(fd, true); 281 if (!namelist) 282 return -ENOENT; 283 284 strlist__for_each_entry(ent, namelist) { 285 p = strchr(ent->s, ':'); 286 if ((p && strfilter__compare(filter, p + 1)) || 287 strfilter__compare(filter, ent->s)) { 288 strlist__add(plist, ent->s); 289 ret = 0; 290 } 291 } 292 strlist__delete(namelist); 293 294 return ret; 295 } 296 297 int probe_file__del_strlist(int fd, struct strlist *namelist) 298 { 299 int ret = 0; 300 struct str_node *ent; 301 302 strlist__for_each_entry(ent, namelist) { 303 ret = __del_trace_probe_event(fd, ent); 304 if (ret < 0) 305 break; 306 } 307 return ret; 308 } 309 310 int probe_file__del_events(int fd, struct strfilter *filter) 311 { 312 struct strlist *namelist; 313 int ret; 314 315 namelist = strlist__new(NULL, NULL); 316 if (!namelist) 317 return -ENOMEM; 318 319 ret = probe_file__get_events(fd, filter, namelist); 320 if (ret < 0) 321 return ret; 322 323 ret = probe_file__del_strlist(fd, namelist); 324 strlist__delete(namelist); 325 326 return ret; 327 } 328 329 /* Caller must ensure to remove this entry from list */ 330 static void probe_cache_entry__delete(struct probe_cache_entry *entry) 331 { 332 if (entry) { 333 BUG_ON(!list_empty(&entry->node)); 334 335 strlist__delete(entry->tevlist); 336 clear_perf_probe_event(&entry->pev); 337 zfree(&entry->spev); 338 free(entry); 339 } 340 } 341 342 static struct probe_cache_entry * 343 probe_cache_entry__new(struct perf_probe_event *pev) 344 { 345 struct probe_cache_entry *entry = zalloc(sizeof(*entry)); 346 347 if (entry) { 348 INIT_LIST_HEAD(&entry->node); 349 entry->tevlist = strlist__new(NULL, NULL); 350 if (!entry->tevlist) 351 zfree(&entry); 352 else if (pev) { 353 entry->spev = synthesize_perf_probe_command(pev); 354 if (!entry->spev || 355 perf_probe_event__copy(&entry->pev, pev) < 0) { 356 probe_cache_entry__delete(entry); 357 return NULL; 358 } 359 } 360 } 361 362 return entry; 363 } 364 365 int probe_cache_entry__get_event(struct probe_cache_entry *entry, 366 struct probe_trace_event **tevs) 367 { 368 struct probe_trace_event *tev; 369 struct str_node *node; 370 int ret, i; 371 372 ret = strlist__nr_entries(entry->tevlist); 373 if (ret > probe_conf.max_probes) 374 return -E2BIG; 375 376 *tevs = zalloc(ret * sizeof(*tev)); 377 if (!*tevs) 378 return -ENOMEM; 379 380 i = 0; 381 strlist__for_each_entry(node, entry->tevlist) { 382 tev = &(*tevs)[i++]; 383 ret = parse_probe_trace_command(node->s, tev); 384 if (ret < 0) 385 break; 386 } 387 return i; 388 } 389 390 /* For the kernel probe caches, pass target = NULL or DSO__NAME_KALLSYMS */ 391 static int probe_cache__open(struct probe_cache *pcache, const char *target) 392 { 393 char cpath[PATH_MAX]; 394 char sbuildid[SBUILD_ID_SIZE]; 395 char *dir_name = NULL; 396 bool is_kallsyms = false; 397 int ret, fd; 398 399 if (target && build_id_cache__cached(target)) { 400 /* This is a cached buildid */ 401 strncpy(sbuildid, target, SBUILD_ID_SIZE); 402 dir_name = build_id_cache__linkname(sbuildid, NULL, 0); 403 goto found; 404 } 405 406 if (!target || !strcmp(target, DSO__NAME_KALLSYMS)) { 407 target = DSO__NAME_KALLSYMS; 408 is_kallsyms = true; 409 ret = sysfs__sprintf_build_id("/", sbuildid); 410 } else 411 ret = filename__sprintf_build_id(target, sbuildid); 412 413 if (ret < 0) { 414 pr_debug("Failed to get build-id from %s.\n", target); 415 return ret; 416 } 417 418 /* If we have no buildid cache, make it */ 419 if (!build_id_cache__cached(sbuildid)) { 420 ret = build_id_cache__add_s(sbuildid, target, 421 is_kallsyms, NULL); 422 if (ret < 0) { 423 pr_debug("Failed to add build-id cache: %s\n", target); 424 return ret; 425 } 426 } 427 428 dir_name = build_id_cache__cachedir(sbuildid, target, is_kallsyms, 429 false); 430 found: 431 if (!dir_name) { 432 pr_debug("Failed to get cache from %s\n", target); 433 return -ENOMEM; 434 } 435 436 snprintf(cpath, PATH_MAX, "%s/probes", dir_name); 437 fd = open(cpath, O_CREAT | O_RDWR, 0644); 438 if (fd < 0) 439 pr_debug("Failed to open cache(%d): %s\n", fd, cpath); 440 free(dir_name); 441 pcache->fd = fd; 442 443 return fd; 444 } 445 446 static int probe_cache__load(struct probe_cache *pcache) 447 { 448 struct probe_cache_entry *entry = NULL; 449 char buf[MAX_CMDLEN], *p; 450 int ret = 0; 451 FILE *fp; 452 453 fp = fdopen(dup(pcache->fd), "r"); 454 if (!fp) 455 return -EINVAL; 456 457 while (!feof(fp)) { 458 if (!fgets(buf, MAX_CMDLEN, fp)) 459 break; 460 p = strchr(buf, '\n'); 461 if (p) 462 *p = '\0'; 463 /* #perf_probe_event or %sdt_event */ 464 if (buf[0] == '#' || buf[0] == '%') { 465 entry = probe_cache_entry__new(NULL); 466 if (!entry) { 467 ret = -ENOMEM; 468 goto out; 469 } 470 if (buf[0] == '%') 471 entry->sdt = true; 472 entry->spev = strdup(buf + 1); 473 if (entry->spev) 474 ret = parse_perf_probe_command(buf + 1, 475 &entry->pev); 476 else 477 ret = -ENOMEM; 478 if (ret < 0) { 479 probe_cache_entry__delete(entry); 480 goto out; 481 } 482 list_add_tail(&entry->node, &pcache->entries); 483 } else { /* trace_probe_event */ 484 if (!entry) { 485 ret = -EINVAL; 486 goto out; 487 } 488 strlist__add(entry->tevlist, buf); 489 } 490 } 491 out: 492 fclose(fp); 493 return ret; 494 } 495 496 static struct probe_cache *probe_cache__alloc(void) 497 { 498 struct probe_cache *pcache = zalloc(sizeof(*pcache)); 499 500 if (pcache) { 501 INIT_LIST_HEAD(&pcache->entries); 502 pcache->fd = -EINVAL; 503 } 504 return pcache; 505 } 506 507 void probe_cache__purge(struct probe_cache *pcache) 508 { 509 struct probe_cache_entry *entry, *n; 510 511 list_for_each_entry_safe(entry, n, &pcache->entries, node) { 512 list_del_init(&entry->node); 513 probe_cache_entry__delete(entry); 514 } 515 } 516 517 void probe_cache__delete(struct probe_cache *pcache) 518 { 519 if (!pcache) 520 return; 521 522 probe_cache__purge(pcache); 523 if (pcache->fd > 0) 524 close(pcache->fd); 525 free(pcache); 526 } 527 528 struct probe_cache *probe_cache__new(const char *target) 529 { 530 struct probe_cache *pcache = probe_cache__alloc(); 531 int ret; 532 533 if (!pcache) 534 return NULL; 535 536 ret = probe_cache__open(pcache, target); 537 if (ret < 0) { 538 pr_debug("Cache open error: %d\n", ret); 539 goto out_err; 540 } 541 542 ret = probe_cache__load(pcache); 543 if (ret < 0) { 544 pr_debug("Cache read error: %d\n", ret); 545 goto out_err; 546 } 547 548 return pcache; 549 550 out_err: 551 probe_cache__delete(pcache); 552 return NULL; 553 } 554 555 static bool streql(const char *a, const char *b) 556 { 557 if (a == b) 558 return true; 559 560 if (!a || !b) 561 return false; 562 563 return !strcmp(a, b); 564 } 565 566 struct probe_cache_entry * 567 probe_cache__find(struct probe_cache *pcache, struct perf_probe_event *pev) 568 { 569 struct probe_cache_entry *entry = NULL; 570 char *cmd = synthesize_perf_probe_command(pev); 571 572 if (!cmd) 573 return NULL; 574 575 for_each_probe_cache_entry(entry, pcache) { 576 if (pev->sdt) { 577 if (entry->pev.event && 578 streql(entry->pev.event, pev->event) && 579 (!pev->group || 580 streql(entry->pev.group, pev->group))) 581 goto found; 582 583 continue; 584 } 585 /* Hit if same event name or same command-string */ 586 if ((pev->event && 587 (streql(entry->pev.group, pev->group) && 588 streql(entry->pev.event, pev->event))) || 589 (!strcmp(entry->spev, cmd))) 590 goto found; 591 } 592 entry = NULL; 593 594 found: 595 free(cmd); 596 return entry; 597 } 598 599 struct probe_cache_entry * 600 probe_cache__find_by_name(struct probe_cache *pcache, 601 const char *group, const char *event) 602 { 603 struct probe_cache_entry *entry = NULL; 604 605 for_each_probe_cache_entry(entry, pcache) { 606 /* Hit if same event name or same command-string */ 607 if (streql(entry->pev.group, group) && 608 streql(entry->pev.event, event)) 609 goto found; 610 } 611 entry = NULL; 612 613 found: 614 return entry; 615 } 616 617 int probe_cache__add_entry(struct probe_cache *pcache, 618 struct perf_probe_event *pev, 619 struct probe_trace_event *tevs, int ntevs) 620 { 621 struct probe_cache_entry *entry = NULL; 622 char *command; 623 int i, ret = 0; 624 625 if (!pcache || !pev || !tevs || ntevs <= 0) { 626 ret = -EINVAL; 627 goto out_err; 628 } 629 630 /* Remove old cache entry */ 631 entry = probe_cache__find(pcache, pev); 632 if (entry) { 633 list_del_init(&entry->node); 634 probe_cache_entry__delete(entry); 635 } 636 637 ret = -ENOMEM; 638 entry = probe_cache_entry__new(pev); 639 if (!entry) 640 goto out_err; 641 642 for (i = 0; i < ntevs; i++) { 643 if (!tevs[i].point.symbol) 644 continue; 645 646 command = synthesize_probe_trace_command(&tevs[i]); 647 if (!command) 648 goto out_err; 649 strlist__add(entry->tevlist, command); 650 free(command); 651 } 652 list_add_tail(&entry->node, &pcache->entries); 653 pr_debug("Added probe cache: %d\n", ntevs); 654 return 0; 655 656 out_err: 657 pr_debug("Failed to add probe caches\n"); 658 probe_cache_entry__delete(entry); 659 return ret; 660 } 661 662 #ifdef HAVE_GELF_GETNOTE_SUPPORT 663 static unsigned long long sdt_note__get_addr(struct sdt_note *note) 664 { 665 return note->bit32 ? (unsigned long long)note->addr.a32[0] 666 : (unsigned long long)note->addr.a64[0]; 667 } 668 669 int probe_cache__scan_sdt(struct probe_cache *pcache, const char *pathname) 670 { 671 struct probe_cache_entry *entry = NULL; 672 struct list_head sdtlist; 673 struct sdt_note *note; 674 char *buf; 675 char sdtgrp[64]; 676 int ret; 677 678 INIT_LIST_HEAD(&sdtlist); 679 ret = get_sdt_note_list(&sdtlist, pathname); 680 if (ret < 0) { 681 pr_debug("Failed to get sdt note: %d\n", ret); 682 return ret; 683 } 684 list_for_each_entry(note, &sdtlist, note_list) { 685 ret = snprintf(sdtgrp, 64, "sdt_%s", note->provider); 686 if (ret < 0) 687 break; 688 /* Try to find same-name entry */ 689 entry = probe_cache__find_by_name(pcache, sdtgrp, note->name); 690 if (!entry) { 691 entry = probe_cache_entry__new(NULL); 692 if (!entry) { 693 ret = -ENOMEM; 694 break; 695 } 696 entry->sdt = true; 697 ret = asprintf(&entry->spev, "%s:%s=%s", sdtgrp, 698 note->name, note->name); 699 if (ret < 0) 700 break; 701 entry->pev.event = strdup(note->name); 702 entry->pev.group = strdup(sdtgrp); 703 list_add_tail(&entry->node, &pcache->entries); 704 } 705 ret = asprintf(&buf, "p:%s/%s %s:0x%llx", 706 sdtgrp, note->name, pathname, 707 sdt_note__get_addr(note)); 708 if (ret < 0) 709 break; 710 strlist__add(entry->tevlist, buf); 711 free(buf); 712 entry = NULL; 713 } 714 if (entry) { 715 list_del_init(&entry->node); 716 probe_cache_entry__delete(entry); 717 } 718 cleanup_sdt_note_list(&sdtlist); 719 return ret; 720 } 721 #endif 722 723 static int probe_cache_entry__write(struct probe_cache_entry *entry, int fd) 724 { 725 struct str_node *snode; 726 struct stat st; 727 struct iovec iov[3]; 728 const char *prefix = entry->sdt ? "%" : "#"; 729 int ret; 730 /* Save stat for rollback */ 731 ret = fstat(fd, &st); 732 if (ret < 0) 733 return ret; 734 735 pr_debug("Writing cache: %s%s\n", prefix, entry->spev); 736 iov[0].iov_base = (void *)prefix; iov[0].iov_len = 1; 737 iov[1].iov_base = entry->spev; iov[1].iov_len = strlen(entry->spev); 738 iov[2].iov_base = (void *)"\n"; iov[2].iov_len = 1; 739 ret = writev(fd, iov, 3); 740 if (ret < (int)iov[1].iov_len + 2) 741 goto rollback; 742 743 strlist__for_each_entry(snode, entry->tevlist) { 744 iov[0].iov_base = (void *)snode->s; 745 iov[0].iov_len = strlen(snode->s); 746 iov[1].iov_base = (void *)"\n"; iov[1].iov_len = 1; 747 ret = writev(fd, iov, 2); 748 if (ret < (int)iov[0].iov_len + 1) 749 goto rollback; 750 } 751 return 0; 752 753 rollback: 754 /* Rollback to avoid cache file corruption */ 755 if (ret > 0) 756 ret = -1; 757 if (ftruncate(fd, st.st_size) < 0) 758 ret = -2; 759 760 return ret; 761 } 762 763 int probe_cache__commit(struct probe_cache *pcache) 764 { 765 struct probe_cache_entry *entry; 766 int ret = 0; 767 768 /* TBD: if we do not update existing entries, skip it */ 769 ret = lseek(pcache->fd, 0, SEEK_SET); 770 if (ret < 0) 771 goto out; 772 773 ret = ftruncate(pcache->fd, 0); 774 if (ret < 0) 775 goto out; 776 777 for_each_probe_cache_entry(entry, pcache) { 778 ret = probe_cache_entry__write(entry, pcache->fd); 779 pr_debug("Cache committed: %d\n", ret); 780 if (ret < 0) 781 break; 782 } 783 out: 784 return ret; 785 } 786 787 static bool probe_cache_entry__compare(struct probe_cache_entry *entry, 788 struct strfilter *filter) 789 { 790 char buf[128], *ptr = entry->spev; 791 792 if (entry->pev.event) { 793 snprintf(buf, 128, "%s:%s", entry->pev.group, entry->pev.event); 794 ptr = buf; 795 } 796 return strfilter__compare(filter, ptr); 797 } 798 799 int probe_cache__filter_purge(struct probe_cache *pcache, 800 struct strfilter *filter) 801 { 802 struct probe_cache_entry *entry, *tmp; 803 804 list_for_each_entry_safe(entry, tmp, &pcache->entries, node) { 805 if (probe_cache_entry__compare(entry, filter)) { 806 pr_info("Removed cached event: %s\n", entry->spev); 807 list_del_init(&entry->node); 808 probe_cache_entry__delete(entry); 809 } 810 } 811 return 0; 812 } 813 814 static int probe_cache__show_entries(struct probe_cache *pcache, 815 struct strfilter *filter) 816 { 817 struct probe_cache_entry *entry; 818 819 for_each_probe_cache_entry(entry, pcache) { 820 if (probe_cache_entry__compare(entry, filter)) 821 printf("%s\n", entry->spev); 822 } 823 return 0; 824 } 825 826 /* Show all cached probes */ 827 int probe_cache__show_all_caches(struct strfilter *filter) 828 { 829 struct probe_cache *pcache; 830 struct strlist *bidlist; 831 struct str_node *nd; 832 char *buf = strfilter__string(filter); 833 834 pr_debug("list cache with filter: %s\n", buf); 835 free(buf); 836 837 bidlist = build_id_cache__list_all(true); 838 if (!bidlist) { 839 pr_debug("Failed to get buildids: %d\n", errno); 840 return -EINVAL; 841 } 842 strlist__for_each_entry(nd, bidlist) { 843 pcache = probe_cache__new(nd->s); 844 if (!pcache) 845 continue; 846 if (!list_empty(&pcache->entries)) { 847 buf = build_id_cache__origname(nd->s); 848 printf("%s (%s):\n", buf, nd->s); 849 free(buf); 850 probe_cache__show_entries(pcache, filter); 851 } 852 probe_cache__delete(pcache); 853 } 854 strlist__delete(bidlist); 855 856 return 0; 857 } 858