probe-event.c (9035a97a32836d0e456ddafaaf249a844e6e4b5e) | probe-event.c (e116dfa1c357da49f55e1555767ec991225a8321) |
---|---|
1/* 2 * probe-event.c : perf-probe definition to probe_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 --- 17 unchanged lines hidden (view full) --- 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> | 1/* 2 * probe-event.c : perf-probe definition to probe_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 --- 17 unchanged lines hidden (view full) --- 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#include <elf.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" --- 64 unchanged lines hidden (view full) --- 106 107static struct symbol *__find_kernel_function_by_name(const char *name, 108 struct map **mapp) 109{ 110 return machine__find_kernel_function_by_name(&machine, name, mapp, 111 NULL); 112} 113 | 35 36#undef _GNU_SOURCE 37#include "util.h" 38#include "event.h" 39#include "string.h" 40#include "strlist.h" 41#include "debug.h" 42#include "cache.h" --- 64 unchanged lines hidden (view full) --- 107 108static struct symbol *__find_kernel_function_by_name(const char *name, 109 struct map **mapp) 110{ 111 return machine__find_kernel_function_by_name(&machine, name, mapp, 112 NULL); 113} 114 |
114const char *kernel_get_module_path(const char *module) | 115static struct map *kernel_get_module_map(const char *module) |
115{ | 116{ |
117 struct rb_node *nd; 118 struct map_groups *grp = &machine.kmaps; 119 120 if (!module) 121 module = "kernel"; 122 123 for (nd = rb_first(&grp->maps[MAP__FUNCTION]); nd; nd = rb_next(nd)) { 124 struct map *pos = rb_entry(nd, struct map, rb_node); 125 if (strncmp(pos->dso->short_name + 1, module, 126 pos->dso->short_name_len - 2) == 0) { 127 return pos; 128 } 129 } 130 return NULL; 131} 132 133static struct dso *kernel_get_module_dso(const char *module) 134{ |
|
116 struct dso *dso; 117 struct map *map; 118 const char *vmlinux_name; 119 120 if (module) { 121 list_for_each_entry(dso, &machine.kernel_dsos, node) { 122 if (strncmp(dso->short_name + 1, module, 123 dso->short_name_len - 2) == 0) --- 12 unchanged lines hidden (view full) --- 136 return NULL; 137 } else { 138 if (dso__load_vmlinux_path(dso, map, NULL) <= 0) { 139 pr_debug("Failed to load kernel map.\n"); 140 return NULL; 141 } 142 } 143found: | 135 struct dso *dso; 136 struct map *map; 137 const char *vmlinux_name; 138 139 if (module) { 140 list_for_each_entry(dso, &machine.kernel_dsos, node) { 141 if (strncmp(dso->short_name + 1, module, 142 dso->short_name_len - 2) == 0) --- 12 unchanged lines hidden (view full) --- 155 return NULL; 156 } else { 157 if (dso__load_vmlinux_path(dso, map, NULL) <= 0) { 158 pr_debug("Failed to load kernel map.\n"); 159 return NULL; 160 } 161 } 162found: |
144 return dso->long_name; | 163 return dso; |
145} 146 | 164} 165 |
166const char *kernel_get_module_path(const char *module) 167{ 168 struct dso *dso = kernel_get_module_dso(module); 169 return (dso) ? dso->long_name : NULL; 170} 171 |
|
147#ifdef DWARF_SUPPORT 148static int open_vmlinux(const char *module) 149{ 150 const char *path = kernel_get_module_path(module); 151 if (!path) { 152 pr_err("Failed to find path of %s module.\n", 153 module ?: "kernel"); 154 return -ENOENT; --- 266 unchanged lines hidden (view full) --- 421 break; 422 } 423end: 424 fclose(fp); 425 return ret; 426} 427 428static int show_available_vars_at(int fd, struct perf_probe_event *pev, | 172#ifdef DWARF_SUPPORT 173static int open_vmlinux(const char *module) 174{ 175 const char *path = kernel_get_module_path(module); 176 if (!path) { 177 pr_err("Failed to find path of %s module.\n", 178 module ?: "kernel"); 179 return -ENOENT; --- 266 unchanged lines hidden (view full) --- 446 break; 447 } 448end: 449 fclose(fp); 450 return ret; 451} 452 453static int show_available_vars_at(int fd, struct perf_probe_event *pev, |
429 int max_vls, bool externs) | 454 int max_vls, struct strfilter *_filter, 455 bool externs) |
430{ 431 char *buf; | 456{ 457 char *buf; |
432 int ret, i; | 458 int ret, i, nvars; |
433 struct str_node *node; 434 struct variable_list *vls = NULL, *vl; | 459 struct str_node *node; 460 struct variable_list *vls = NULL, *vl; |
461 const char *var; |
|
435 436 buf = synthesize_perf_probe_point(&pev->point); 437 if (!buf) 438 return -EINVAL; 439 pr_debug("Searching variables at %s\n", buf); 440 441 ret = find_available_vars_at(fd, pev, &vls, max_vls, externs); | 462 463 buf = synthesize_perf_probe_point(&pev->point); 464 if (!buf) 465 return -EINVAL; 466 pr_debug("Searching variables at %s\n", buf); 467 468 ret = find_available_vars_at(fd, pev, &vls, max_vls, externs); |
442 if (ret > 0) { 443 /* Some variables were found */ 444 fprintf(stdout, "Available variables at %s\n", buf); 445 for (i = 0; i < ret; i++) { 446 vl = &vls[i]; 447 /* 448 * A probe point might be converted to 449 * several trace points. 450 */ 451 fprintf(stdout, "\t@<%s+%lu>\n", vl->point.symbol, 452 vl->point.offset); 453 free(vl->point.symbol); 454 if (vl->vars) { 455 strlist__for_each(node, vl->vars) | 469 if (ret <= 0) { 470 pr_err("Failed to find variables at %s (%d)\n", buf, ret); 471 goto end; 472 } 473 /* Some variables are found */ 474 fprintf(stdout, "Available variables at %s\n", buf); 475 for (i = 0; i < ret; i++) { 476 vl = &vls[i]; 477 /* 478 * A probe point might be converted to 479 * several trace points. 480 */ 481 fprintf(stdout, "\t@<%s+%lu>\n", vl->point.symbol, 482 vl->point.offset); 483 free(vl->point.symbol); 484 nvars = 0; 485 if (vl->vars) { 486 strlist__for_each(node, vl->vars) { 487 var = strchr(node->s, '\t') + 1; 488 if (strfilter__compare(_filter, var)) { |
456 fprintf(stdout, "\t\t%s\n", node->s); | 489 fprintf(stdout, "\t\t%s\n", node->s); |
457 strlist__delete(vl->vars); 458 } else 459 fprintf(stdout, "(No variables)\n"); | 490 nvars++; 491 } 492 } 493 strlist__delete(vl->vars); |
460 } | 494 } |
461 free(vls); 462 } else 463 pr_err("Failed to find variables at %s (%d)\n", buf, ret); 464 | 495 if (nvars == 0) 496 fprintf(stdout, "\t\t(No matched variables)\n"); 497 } 498 free(vls); 499end: |
465 free(buf); 466 return ret; 467} 468 469/* Show available variables on given probe point */ 470int show_available_vars(struct perf_probe_event *pevs, int npevs, | 500 free(buf); 501 return ret; 502} 503 504/* Show available variables on given probe point */ 505int show_available_vars(struct perf_probe_event *pevs, int npevs, |
471 int max_vls, const char *module, bool externs) | 506 int max_vls, const char *module, 507 struct strfilter *_filter, bool externs) |
472{ 473 int i, fd, ret = 0; 474 475 ret = init_vmlinux(); 476 if (ret < 0) 477 return ret; 478 479 fd = open_vmlinux(module); 480 if (fd < 0) { 481 pr_warning("Failed to open debug information file.\n"); 482 return fd; 483 } 484 485 setup_pager(); 486 487 for (i = 0; i < npevs && ret >= 0; i++) | 508{ 509 int i, fd, ret = 0; 510 511 ret = init_vmlinux(); 512 if (ret < 0) 513 return ret; 514 515 fd = open_vmlinux(module); 516 if (fd < 0) { 517 pr_warning("Failed to open debug information file.\n"); 518 return fd; 519 } 520 521 setup_pager(); 522 523 for (i = 0; i < npevs && ret >= 0; i++) |
488 ret = show_available_vars_at(fd, &pevs[i], max_vls, externs); | 524 ret = show_available_vars_at(fd, &pevs[i], max_vls, _filter, 525 externs); |
489 490 close(fd); 491 return ret; 492} 493 494#else /* !DWARF_SUPPORT */ 495 496static int kprobe_convert_to_perf_probe(struct probe_trace_point *tp, --- 29 unchanged lines hidden (view full) --- 526int show_line_range(struct line_range *lr __unused, const char *module __unused) 527{ 528 pr_warning("Debuginfo-analysis is not supported.\n"); 529 return -ENOSYS; 530} 531 532int show_available_vars(struct perf_probe_event *pevs __unused, 533 int npevs __unused, int max_vls __unused, | 526 527 close(fd); 528 return ret; 529} 530 531#else /* !DWARF_SUPPORT */ 532 533static int kprobe_convert_to_perf_probe(struct probe_trace_point *tp, --- 29 unchanged lines hidden (view full) --- 563int show_line_range(struct line_range *lr __unused, const char *module __unused) 564{ 565 pr_warning("Debuginfo-analysis is not supported.\n"); 566 return -ENOSYS; 567} 568 569int show_available_vars(struct perf_probe_event *pevs __unused, 570 int npevs __unused, int max_vls __unused, |
534 const char *module __unused, bool externs __unused) | 571 const char *module __unused, 572 struct strfilter *filter __unused, 573 bool externs __unused) |
535{ 536 pr_warning("Debuginfo-analysis is not supported.\n"); 537 return -ENOSYS; 538} 539#endif 540 541static int parse_line_num(char **ptr, int *val, const char *what) 542{ --- 8 unchanged lines hidden (view full) --- 551 return 0; 552} 553 554/* 555 * Stuff 'lr' according to the line range described by 'arg'. 556 * The line range syntax is described by: 557 * 558 * SRC[:SLN[+NUM|-ELN]] | 574{ 575 pr_warning("Debuginfo-analysis is not supported.\n"); 576 return -ENOSYS; 577} 578#endif 579 580static int parse_line_num(char **ptr, int *val, const char *what) 581{ --- 8 unchanged lines hidden (view full) --- 590 return 0; 591} 592 593/* 594 * Stuff 'lr' according to the line range described by 'arg'. 595 * The line range syntax is described by: 596 * 597 * SRC[:SLN[+NUM|-ELN]] |
559 * FNC[:SLN[+NUM|-ELN]] | 598 * FNC[@SRC][:SLN[+NUM|-ELN]] |
560 */ 561int parse_line_range_desc(const char *arg, struct line_range *lr) 562{ | 599 */ 600int parse_line_range_desc(const char *arg, struct line_range *lr) 601{ |
563 char *range, *name = strdup(arg); | 602 char *range, *file, *name = strdup(arg); |
564 int err; 565 566 if (!name) 567 return -ENOMEM; 568 569 lr->start = 0; 570 lr->end = INT_MAX; 571 --- 33 unchanged lines hidden (view full) --- 605 goto err; 606 } 607 if (*range != '\0') { 608 semantic_error("Tailing with invalid str '%s'.\n", range); 609 goto err; 610 } 611 } 612 | 603 int err; 604 605 if (!name) 606 return -ENOMEM; 607 608 lr->start = 0; 609 lr->end = INT_MAX; 610 --- 33 unchanged lines hidden (view full) --- 644 goto err; 645 } 646 if (*range != '\0') { 647 semantic_error("Tailing with invalid str '%s'.\n", range); 648 goto err; 649 } 650 } 651 |
613 if (strchr(name, '.')) | 652 file = strchr(name, '@'); 653 if (file) { 654 *file = '\0'; 655 lr->file = strdup(++file); 656 if (lr->file == NULL) { 657 err = -ENOMEM; 658 goto err; 659 } 660 lr->function = name; 661 } else if (strchr(name, '.')) |
614 lr->file = name; 615 else 616 lr->function = name; 617 618 return 0; 619err: 620 free(name); 621 return err; --- 1285 unchanged lines hidden (view full) --- 1907 if (ret < 0) 1908 break; 1909 } 1910 strlist__delete(namelist); 1911 close(fd); 1912 1913 return ret; 1914} | 662 lr->file = name; 663 else 664 lr->function = name; 665 666 return 0; 667err: 668 free(name); 669 return err; --- 1285 unchanged lines hidden (view full) --- 1955 if (ret < 0) 1956 break; 1957 } 1958 strlist__delete(namelist); 1959 close(fd); 1960 1961 return ret; 1962} |
1963/* TODO: don't use a global variable for filter ... */ 1964static struct strfilter *available_func_filter; |
|
1915 | 1965 |
1966/* 1967 * If a symbol corresponds to a function with global binding and 1968 * matches filter return 0. For all others return 1. 1969 */ 1970static int filter_available_functions(struct map *map __unused, 1971 struct symbol *sym) 1972{ 1973 if (sym->binding == STB_GLOBAL && 1974 strfilter__compare(available_func_filter, sym->name)) 1975 return 0; 1976 return 1; 1977} 1978 1979int show_available_funcs(const char *module, struct strfilter *_filter) 1980{ 1981 struct map *map; 1982 int ret; 1983 1984 setup_pager(); 1985 1986 ret = init_vmlinux(); 1987 if (ret < 0) 1988 return ret; 1989 1990 map = kernel_get_module_map(module); 1991 if (!map) { 1992 pr_err("Failed to find %s map.\n", (module) ? : "kernel"); 1993 return -EINVAL; 1994 } 1995 available_func_filter = _filter; 1996 if (map__load(map, filter_available_functions)) { 1997 pr_err("Failed to load map.\n"); 1998 return -EINVAL; 1999 } 2000 if (!dso__sorted_by_name(map->dso, map->type)) 2001 dso__sort_by_name(map->dso, map->type); 2002 2003 dso__fprintf_symbols_by_name(map->dso, map->type, stdout); 2004 return 0; 2005} |
|