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 /* For the kernel probe caches, pass target = NULL */ 366 static int probe_cache__open(struct probe_cache *pcache, const char *target) 367 { 368 char cpath[PATH_MAX]; 369 char sbuildid[SBUILD_ID_SIZE]; 370 char *dir_name = NULL; 371 bool is_kallsyms = !target; 372 int ret, fd; 373 374 if (target && build_id_cache__cached(target)) { 375 /* This is a cached buildid */ 376 strncpy(sbuildid, target, SBUILD_ID_SIZE); 377 dir_name = build_id_cache__linkname(sbuildid, NULL, 0); 378 goto found; 379 } 380 381 if (target) 382 ret = filename__sprintf_build_id(target, sbuildid); 383 else { 384 target = DSO__NAME_KALLSYMS; 385 ret = sysfs__sprintf_build_id("/", sbuildid); 386 } 387 if (ret < 0) { 388 pr_debug("Failed to get build-id from %s.\n", target); 389 return ret; 390 } 391 392 /* If we have no buildid cache, make it */ 393 if (!build_id_cache__cached(sbuildid)) { 394 ret = build_id_cache__add_s(sbuildid, target, 395 is_kallsyms, NULL); 396 if (ret < 0) { 397 pr_debug("Failed to add build-id cache: %s\n", target); 398 return ret; 399 } 400 } 401 402 dir_name = build_id_cache__cachedir(sbuildid, target, is_kallsyms, 403 false); 404 found: 405 if (!dir_name) { 406 pr_debug("Failed to get cache from %s\n", target); 407 return -ENOMEM; 408 } 409 410 snprintf(cpath, PATH_MAX, "%s/probes", dir_name); 411 fd = open(cpath, O_CREAT | O_RDWR, 0644); 412 if (fd < 0) 413 pr_debug("Failed to open cache(%d): %s\n", fd, cpath); 414 free(dir_name); 415 pcache->fd = fd; 416 417 return fd; 418 } 419 420 static int probe_cache__load(struct probe_cache *pcache) 421 { 422 struct probe_cache_entry *entry = NULL; 423 char buf[MAX_CMDLEN], *p; 424 int ret = 0; 425 FILE *fp; 426 427 fp = fdopen(dup(pcache->fd), "r"); 428 if (!fp) 429 return -EINVAL; 430 431 while (!feof(fp)) { 432 if (!fgets(buf, MAX_CMDLEN, fp)) 433 break; 434 p = strchr(buf, '\n'); 435 if (p) 436 *p = '\0'; 437 /* #perf_probe_event or %sdt_event */ 438 if (buf[0] == '#' || buf[0] == '%') { 439 entry = probe_cache_entry__new(NULL); 440 if (!entry) { 441 ret = -ENOMEM; 442 goto out; 443 } 444 if (buf[0] == '%') 445 entry->sdt = true; 446 entry->spev = strdup(buf + 1); 447 if (entry->spev) 448 ret = parse_perf_probe_command(buf + 1, 449 &entry->pev); 450 else 451 ret = -ENOMEM; 452 if (ret < 0) { 453 probe_cache_entry__delete(entry); 454 goto out; 455 } 456 list_add_tail(&entry->node, &pcache->entries); 457 } else { /* trace_probe_event */ 458 if (!entry) { 459 ret = -EINVAL; 460 goto out; 461 } 462 strlist__add(entry->tevlist, buf); 463 } 464 } 465 out: 466 fclose(fp); 467 return ret; 468 } 469 470 static struct probe_cache *probe_cache__alloc(void) 471 { 472 struct probe_cache *pcache = zalloc(sizeof(*pcache)); 473 474 if (pcache) { 475 INIT_LIST_HEAD(&pcache->entries); 476 pcache->fd = -EINVAL; 477 } 478 return pcache; 479 } 480 481 void probe_cache__purge(struct probe_cache *pcache) 482 { 483 struct probe_cache_entry *entry, *n; 484 485 list_for_each_entry_safe(entry, n, &pcache->entries, node) { 486 list_del_init(&entry->node); 487 probe_cache_entry__delete(entry); 488 } 489 } 490 491 void probe_cache__delete(struct probe_cache *pcache) 492 { 493 if (!pcache) 494 return; 495 496 probe_cache__purge(pcache); 497 if (pcache->fd > 0) 498 close(pcache->fd); 499 free(pcache); 500 } 501 502 struct probe_cache *probe_cache__new(const char *target) 503 { 504 struct probe_cache *pcache = probe_cache__alloc(); 505 int ret; 506 507 if (!pcache) 508 return NULL; 509 510 ret = probe_cache__open(pcache, target); 511 if (ret < 0) { 512 pr_debug("Cache open error: %d\n", ret); 513 goto out_err; 514 } 515 516 ret = probe_cache__load(pcache); 517 if (ret < 0) { 518 pr_debug("Cache read error: %d\n", ret); 519 goto out_err; 520 } 521 522 return pcache; 523 524 out_err: 525 probe_cache__delete(pcache); 526 return NULL; 527 } 528 529 static bool streql(const char *a, const char *b) 530 { 531 if (a == b) 532 return true; 533 534 if (!a || !b) 535 return false; 536 537 return !strcmp(a, b); 538 } 539 540 struct probe_cache_entry * 541 probe_cache__find(struct probe_cache *pcache, struct perf_probe_event *pev) 542 { 543 struct probe_cache_entry *entry = NULL; 544 char *cmd = synthesize_perf_probe_command(pev); 545 546 if (!cmd) 547 return NULL; 548 549 list_for_each_entry(entry, &pcache->entries, node) { 550 /* Hit if same event name or same command-string */ 551 if ((pev->event && 552 (streql(entry->pev.group, pev->group) && 553 streql(entry->pev.event, pev->event))) || 554 (!strcmp(entry->spev, cmd))) 555 goto found; 556 } 557 entry = NULL; 558 559 found: 560 free(cmd); 561 return entry; 562 } 563 564 struct probe_cache_entry * 565 probe_cache__find_by_name(struct probe_cache *pcache, 566 const char *group, const char *event) 567 { 568 struct probe_cache_entry *entry = NULL; 569 570 list_for_each_entry(entry, &pcache->entries, node) { 571 /* Hit if same event name or same command-string */ 572 if (streql(entry->pev.group, group) && 573 streql(entry->pev.event, event)) 574 goto found; 575 } 576 entry = NULL; 577 578 found: 579 return entry; 580 } 581 582 int probe_cache__add_entry(struct probe_cache *pcache, 583 struct perf_probe_event *pev, 584 struct probe_trace_event *tevs, int ntevs) 585 { 586 struct probe_cache_entry *entry = NULL; 587 char *command; 588 int i, ret = 0; 589 590 if (!pcache || !pev || !tevs || ntevs <= 0) { 591 ret = -EINVAL; 592 goto out_err; 593 } 594 595 /* Remove old cache entry */ 596 entry = probe_cache__find(pcache, pev); 597 if (entry) { 598 list_del_init(&entry->node); 599 probe_cache_entry__delete(entry); 600 } 601 602 ret = -ENOMEM; 603 entry = probe_cache_entry__new(pev); 604 if (!entry) 605 goto out_err; 606 607 for (i = 0; i < ntevs; i++) { 608 if (!tevs[i].point.symbol) 609 continue; 610 611 command = synthesize_probe_trace_command(&tevs[i]); 612 if (!command) 613 goto out_err; 614 strlist__add(entry->tevlist, command); 615 free(command); 616 } 617 list_add_tail(&entry->node, &pcache->entries); 618 pr_debug("Added probe cache: %d\n", ntevs); 619 return 0; 620 621 out_err: 622 pr_debug("Failed to add probe caches\n"); 623 probe_cache_entry__delete(entry); 624 return ret; 625 } 626 627 static unsigned long long sdt_note__get_addr(struct sdt_note *note) 628 { 629 return note->bit32 ? (unsigned long long)note->addr.a32[0] 630 : (unsigned long long)note->addr.a64[0]; 631 } 632 633 int probe_cache__scan_sdt(struct probe_cache *pcache, const char *pathname) 634 { 635 struct probe_cache_entry *entry = NULL; 636 struct list_head sdtlist; 637 struct sdt_note *note; 638 char *buf; 639 char sdtgrp[64]; 640 int ret; 641 642 INIT_LIST_HEAD(&sdtlist); 643 ret = get_sdt_note_list(&sdtlist, pathname); 644 if (ret < 0) { 645 pr_debug("Failed to get sdt note: %d\n", ret); 646 return ret; 647 } 648 list_for_each_entry(note, &sdtlist, note_list) { 649 ret = snprintf(sdtgrp, 64, "sdt_%s", note->provider); 650 if (ret < 0) 651 break; 652 /* Try to find same-name entry */ 653 entry = probe_cache__find_by_name(pcache, sdtgrp, note->name); 654 if (!entry) { 655 entry = probe_cache_entry__new(NULL); 656 if (!entry) { 657 ret = -ENOMEM; 658 break; 659 } 660 entry->sdt = true; 661 ret = asprintf(&entry->spev, "%s:%s=%s", sdtgrp, 662 note->name, note->name); 663 if (ret < 0) 664 break; 665 entry->pev.event = strdup(note->name); 666 entry->pev.group = strdup(sdtgrp); 667 list_add_tail(&entry->node, &pcache->entries); 668 } 669 ret = asprintf(&buf, "p:%s/%s %s:0x%llx", 670 sdtgrp, note->name, pathname, 671 sdt_note__get_addr(note)); 672 if (ret < 0) 673 break; 674 strlist__add(entry->tevlist, buf); 675 free(buf); 676 entry = NULL; 677 } 678 if (entry) { 679 list_del_init(&entry->node); 680 probe_cache_entry__delete(entry); 681 } 682 cleanup_sdt_note_list(&sdtlist); 683 return ret; 684 } 685 686 static int probe_cache_entry__write(struct probe_cache_entry *entry, int fd) 687 { 688 struct str_node *snode; 689 struct stat st; 690 struct iovec iov[3]; 691 const char *prefix = entry->sdt ? "%" : "#"; 692 int ret; 693 /* Save stat for rollback */ 694 ret = fstat(fd, &st); 695 if (ret < 0) 696 return ret; 697 698 pr_debug("Writing cache: %s%s\n", prefix, entry->spev); 699 iov[0].iov_base = (void *)prefix; iov[0].iov_len = 1; 700 iov[1].iov_base = entry->spev; iov[1].iov_len = strlen(entry->spev); 701 iov[2].iov_base = (void *)"\n"; iov[2].iov_len = 1; 702 ret = writev(fd, iov, 3); 703 if (ret < (int)iov[1].iov_len + 2) 704 goto rollback; 705 706 strlist__for_each_entry(snode, entry->tevlist) { 707 iov[0].iov_base = (void *)snode->s; 708 iov[0].iov_len = strlen(snode->s); 709 iov[1].iov_base = (void *)"\n"; iov[1].iov_len = 1; 710 ret = writev(fd, iov, 2); 711 if (ret < (int)iov[0].iov_len + 1) 712 goto rollback; 713 } 714 return 0; 715 716 rollback: 717 /* Rollback to avoid cache file corruption */ 718 if (ret > 0) 719 ret = -1; 720 if (ftruncate(fd, st.st_size) < 0) 721 ret = -2; 722 723 return ret; 724 } 725 726 int probe_cache__commit(struct probe_cache *pcache) 727 { 728 struct probe_cache_entry *entry; 729 int ret = 0; 730 731 /* TBD: if we do not update existing entries, skip it */ 732 ret = lseek(pcache->fd, 0, SEEK_SET); 733 if (ret < 0) 734 goto out; 735 736 ret = ftruncate(pcache->fd, 0); 737 if (ret < 0) 738 goto out; 739 740 list_for_each_entry(entry, &pcache->entries, node) { 741 ret = probe_cache_entry__write(entry, pcache->fd); 742 pr_debug("Cache committed: %d\n", ret); 743 if (ret < 0) 744 break; 745 } 746 out: 747 return ret; 748 } 749 750 static bool probe_cache_entry__compare(struct probe_cache_entry *entry, 751 struct strfilter *filter) 752 { 753 char buf[128], *ptr = entry->spev; 754 755 if (entry->pev.event) { 756 snprintf(buf, 128, "%s:%s", entry->pev.group, entry->pev.event); 757 ptr = buf; 758 } 759 return strfilter__compare(filter, ptr); 760 } 761 762 int probe_cache__filter_purge(struct probe_cache *pcache, 763 struct strfilter *filter) 764 { 765 struct probe_cache_entry *entry, *tmp; 766 767 list_for_each_entry_safe(entry, tmp, &pcache->entries, node) { 768 if (probe_cache_entry__compare(entry, filter)) { 769 pr_info("Removed cached event: %s\n", entry->spev); 770 list_del_init(&entry->node); 771 probe_cache_entry__delete(entry); 772 } 773 } 774 return 0; 775 } 776 777 static int probe_cache__show_entries(struct probe_cache *pcache, 778 struct strfilter *filter) 779 { 780 struct probe_cache_entry *entry; 781 782 list_for_each_entry(entry, &pcache->entries, node) { 783 if (probe_cache_entry__compare(entry, filter)) 784 printf("%s\n", entry->spev); 785 } 786 return 0; 787 } 788 789 /* Show all cached probes */ 790 int probe_cache__show_all_caches(struct strfilter *filter) 791 { 792 struct probe_cache *pcache; 793 struct strlist *bidlist; 794 struct str_node *nd; 795 char *buf = strfilter__string(filter); 796 797 pr_debug("list cache with filter: %s\n", buf); 798 free(buf); 799 800 bidlist = build_id_cache__list_all(); 801 if (!bidlist) { 802 pr_debug("Failed to get buildids: %d\n", errno); 803 return -EINVAL; 804 } 805 strlist__for_each_entry(nd, bidlist) { 806 pcache = probe_cache__new(nd->s); 807 if (!pcache) 808 continue; 809 if (!list_empty(&pcache->entries)) { 810 buf = build_id_cache__origname(nd->s); 811 printf("%s (%s):\n", buf, nd->s); 812 free(buf); 813 probe_cache__show_entries(pcache, filter); 814 } 815 probe_cache__delete(pcache); 816 } 817 strlist__delete(bidlist); 818 819 return 0; 820 } 821