aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/probe-event.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/probe-event.c')
-rw-r--r--tools/perf/util/probe-event.c249
1 files changed, 151 insertions, 98 deletions
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 3b6a5297bf16..128aaab0aeda 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -95,7 +95,7 @@ static int init_vmlinux(void)
95 goto out; 95 goto out;
96 96
97 if (machine__create_kernel_maps(&machine) < 0) { 97 if (machine__create_kernel_maps(&machine) < 0) {
98 pr_debug("machine__create_kernel_maps "); 98 pr_debug("machine__create_kernel_maps() failed.\n");
99 goto out; 99 goto out;
100 } 100 }
101out: 101out:
@@ -114,6 +114,8 @@ static struct symbol *__find_kernel_function_by_name(const char *name,
114const char *kernel_get_module_path(const char *module) 114const char *kernel_get_module_path(const char *module)
115{ 115{
116 struct dso *dso; 116 struct dso *dso;
117 struct map *map;
118 const char *vmlinux_name;
117 119
118 if (module) { 120 if (module) {
119 list_for_each_entry(dso, &machine.kernel_dsos, node) { 121 list_for_each_entry(dso, &machine.kernel_dsos, node) {
@@ -123,10 +125,17 @@ const char *kernel_get_module_path(const char *module)
123 } 125 }
124 pr_debug("Failed to find module %s.\n", module); 126 pr_debug("Failed to find module %s.\n", module);
125 return NULL; 127 return NULL;
128 }
129
130 map = machine.vmlinux_maps[MAP__FUNCTION];
131 dso = map->dso;
132
133 vmlinux_name = symbol_conf.vmlinux_name;
134 if (vmlinux_name) {
135 if (dso__load_vmlinux(dso, map, vmlinux_name, NULL) <= 0)
136 return NULL;
126 } else { 137 } else {
127 dso = machine.vmlinux_maps[MAP__FUNCTION]->dso; 138 if (dso__load_vmlinux_path(dso, map, NULL) <= 0) {
128 if (dso__load_vmlinux_path(dso,
129 machine.vmlinux_maps[MAP__FUNCTION], NULL) < 0) {
130 pr_debug("Failed to load kernel map.\n"); 139 pr_debug("Failed to load kernel map.\n");
131 return NULL; 140 return NULL;
132 } 141 }
@@ -140,7 +149,8 @@ static int open_vmlinux(const char *module)
140{ 149{
141 const char *path = kernel_get_module_path(module); 150 const char *path = kernel_get_module_path(module);
142 if (!path) { 151 if (!path) {
143 pr_err("Failed to find path of %s module", module ?: "kernel"); 152 pr_err("Failed to find path of %s module.\n",
153 module ?: "kernel");
144 return -ENOENT; 154 return -ENOENT;
145 } 155 }
146 pr_debug("Try to open %s\n", path); 156 pr_debug("Try to open %s\n", path);
@@ -217,7 +227,7 @@ static int try_to_find_probe_trace_events(struct perf_probe_event *pev,
217 pr_warning("Warning: No dwarf info found in the vmlinux - " 227 pr_warning("Warning: No dwarf info found in the vmlinux - "
218 "please rebuild kernel with CONFIG_DEBUG_INFO=y.\n"); 228 "please rebuild kernel with CONFIG_DEBUG_INFO=y.\n");
219 if (!need_dwarf) { 229 if (!need_dwarf) {
220 pr_debug("Trying to use symbols.\nn"); 230 pr_debug("Trying to use symbols.\n");
221 return 0; 231 return 0;
222 } 232 }
223 } 233 }
@@ -286,42 +296,49 @@ static int get_real_path(const char *raw_path, const char *comp_dir,
286#define LINEBUF_SIZE 256 296#define LINEBUF_SIZE 256
287#define NR_ADDITIONAL_LINES 2 297#define NR_ADDITIONAL_LINES 2
288 298
289static int show_one_line(FILE *fp, int l, bool skip, bool show_num) 299static int __show_one_line(FILE *fp, int l, bool skip, bool show_num)
290{ 300{
291 char buf[LINEBUF_SIZE]; 301 char buf[LINEBUF_SIZE];
292 const char *color = PERF_COLOR_BLUE; 302 const char *color = show_num ? "" : PERF_COLOR_BLUE;
293 303 const char *prefix = NULL;
294 if (fgets(buf, LINEBUF_SIZE, fp) == NULL)
295 goto error;
296 if (!skip) {
297 if (show_num)
298 fprintf(stdout, "%7d %s", l, buf);
299 else
300 color_fprintf(stdout, color, " %s", buf);
301 }
302 304
303 while (strlen(buf) == LINEBUF_SIZE - 1 && 305 do {
304 buf[LINEBUF_SIZE - 2] != '\n') {
305 if (fgets(buf, LINEBUF_SIZE, fp) == NULL) 306 if (fgets(buf, LINEBUF_SIZE, fp) == NULL)
306 goto error; 307 goto error;
307 if (!skip) { 308 if (skip)
308 if (show_num) 309 continue;
309 fprintf(stdout, "%s", buf); 310 if (!prefix) {
310 else 311 prefix = show_num ? "%7d " : " ";
311 color_fprintf(stdout, color, "%s", buf); 312 color_fprintf(stdout, color, prefix, l);
312 } 313 }
313 } 314 color_fprintf(stdout, color, "%s", buf);
314 315
315 return 0; 316 } while (strchr(buf, '\n') == NULL);
317
318 return 1;
316error: 319error:
317 if (feof(fp)) 320 if (ferror(fp)) {
318 pr_warning("Source file is shorter than expected.\n");
319 else
320 pr_warning("File read error: %s\n", strerror(errno)); 321 pr_warning("File read error: %s\n", strerror(errno));
322 return -1;
323 }
324 return 0;
325}
321 326
322 return -1; 327static int _show_one_line(FILE *fp, int l, bool skip, bool show_num)
328{
329 int rv = __show_one_line(fp, l, skip, show_num);
330 if (rv == 0) {
331 pr_warning("Source file is shorter than expected.\n");
332 rv = -1;
333 }
334 return rv;
323} 335}
324 336
337#define show_one_line_with_num(f,l) _show_one_line(f,l,false,true)
338#define show_one_line(f,l) _show_one_line(f,l,false,false)
339#define skip_one_line(f,l) _show_one_line(f,l,true,false)
340#define show_one_line_or_eof(f,l) __show_one_line(f,l,false,false)
341
325/* 342/*
326 * Show line-range always requires debuginfo to find source file and 343 * Show line-range always requires debuginfo to find source file and
327 * line number. 344 * line number.
@@ -370,7 +387,7 @@ int show_line_range(struct line_range *lr, const char *module)
370 fprintf(stdout, "<%s:%d>\n", lr->function, 387 fprintf(stdout, "<%s:%d>\n", lr->function,
371 lr->start - lr->offset); 388 lr->start - lr->offset);
372 else 389 else
373 fprintf(stdout, "<%s:%d>\n", lr->file, lr->start); 390 fprintf(stdout, "<%s:%d>\n", lr->path, lr->start);
374 391
375 fp = fopen(lr->path, "r"); 392 fp = fopen(lr->path, "r");
376 if (fp == NULL) { 393 if (fp == NULL) {
@@ -379,26 +396,30 @@ int show_line_range(struct line_range *lr, const char *module)
379 return -errno; 396 return -errno;
380 } 397 }
381 /* Skip to starting line number */ 398 /* Skip to starting line number */
382 while (l < lr->start && ret >= 0) 399 while (l < lr->start) {
383 ret = show_one_line(fp, l++, true, false); 400 ret = skip_one_line(fp, l++);
384 if (ret < 0) 401 if (ret < 0)
385 goto end; 402 goto end;
403 }
386 404
387 list_for_each_entry(ln, &lr->line_list, list) { 405 list_for_each_entry(ln, &lr->line_list, list) {
388 while (ln->line > l && ret >= 0) 406 for (; ln->line > l; l++) {
389 ret = show_one_line(fp, (l++) - lr->offset, 407 ret = show_one_line(fp, l - lr->offset);
390 false, false); 408 if (ret < 0)
391 if (ret >= 0) 409 goto end;
392 ret = show_one_line(fp, (l++) - lr->offset, 410 }
393 false, true); 411 ret = show_one_line_with_num(fp, l++ - lr->offset);
394 if (ret < 0) 412 if (ret < 0)
395 goto end; 413 goto end;
396 } 414 }
397 415
398 if (lr->end == INT_MAX) 416 if (lr->end == INT_MAX)
399 lr->end = l + NR_ADDITIONAL_LINES; 417 lr->end = l + NR_ADDITIONAL_LINES;
400 while (l <= lr->end && !feof(fp) && ret >= 0) 418 while (l <= lr->end) {
401 ret = show_one_line(fp, (l++) - lr->offset, false, false); 419 ret = show_one_line_or_eof(fp, l++ - lr->offset);
420 if (ret <= 0)
421 break;
422 }
402end: 423end:
403 fclose(fp); 424 fclose(fp);
404 return ret; 425 return ret;
@@ -457,7 +478,7 @@ int show_available_vars(struct perf_probe_event *pevs, int npevs,
457 478
458 fd = open_vmlinux(module); 479 fd = open_vmlinux(module);
459 if (fd < 0) { 480 if (fd < 0) {
460 pr_warning("Failed to open debuginfo file.\n"); 481 pr_warning("Failed to open debug information file.\n");
461 return fd; 482 return fd;
462 } 483 }
463 484
@@ -517,56 +538,87 @@ int show_available_vars(struct perf_probe_event *pevs __unused,
517} 538}
518#endif 539#endif
519 540
541static int parse_line_num(char **ptr, int *val, const char *what)
542{
543 const char *start = *ptr;
544
545 errno = 0;
546 *val = strtol(*ptr, ptr, 0);
547 if (errno || *ptr == start) {
548 semantic_error("'%s' is not a valid number.\n", what);
549 return -EINVAL;
550 }
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]]
559 * FNC[:SLN[+NUM|-ELN]]
560 */
520int parse_line_range_desc(const char *arg, struct line_range *lr) 561int parse_line_range_desc(const char *arg, struct line_range *lr)
521{ 562{
522 const char *ptr; 563 char *range, *name = strdup(arg);
523 char *tmp; 564 int err;
524 /* 565
525 * <Syntax> 566 if (!name)
526 * SRC:SLN[+NUM|-ELN] 567 return -ENOMEM;
527 * FUNC[:SLN[+NUM|-ELN]] 568
528 */ 569 lr->start = 0;
529 ptr = strchr(arg, ':'); 570 lr->end = INT_MAX;
530 if (ptr) { 571
531 lr->start = (int)strtoul(ptr + 1, &tmp, 0); 572 range = strchr(name, ':');
532 if (*tmp == '+') { 573 if (range) {
533 lr->end = lr->start + (int)strtoul(tmp + 1, &tmp, 0); 574 *range++ = '\0';
534 lr->end--; /* 575
535 * Adjust the number of lines here. 576 err = parse_line_num(&range, &lr->start, "start line");
536 * If the number of lines == 1, the 577 if (err)
537 * the end of line should be equal to 578 goto err;
538 * the start of line. 579
539 */ 580 if (*range == '+' || *range == '-') {
540 } else if (*tmp == '-') 581 const char c = *range++;
541 lr->end = (int)strtoul(tmp + 1, &tmp, 0); 582
542 else 583 err = parse_line_num(&range, &lr->end, "end line");
543 lr->end = INT_MAX; 584 if (err)
585 goto err;
586
587 if (c == '+') {
588 lr->end += lr->start;
589 /*
590 * Adjust the number of lines here.
591 * If the number of lines == 1, the
592 * the end of line should be equal to
593 * the start of line.
594 */
595 lr->end--;
596 }
597 }
598
544 pr_debug("Line range is %d to %d\n", lr->start, lr->end); 599 pr_debug("Line range is %d to %d\n", lr->start, lr->end);
600
601 err = -EINVAL;
545 if (lr->start > lr->end) { 602 if (lr->start > lr->end) {
546 semantic_error("Start line must be smaller" 603 semantic_error("Start line must be smaller"
547 " than end line.\n"); 604 " than end line.\n");
548 return -EINVAL; 605 goto err;
549 } 606 }
550 if (*tmp != '\0') { 607 if (*range != '\0') {
551 semantic_error("Tailing with invalid character '%d'.\n", 608 semantic_error("Tailing with invalid str '%s'.\n", range);
552 *tmp); 609 goto err;
553 return -EINVAL;
554 } 610 }
555 tmp = strndup(arg, (ptr - arg));
556 } else {
557 tmp = strdup(arg);
558 lr->end = INT_MAX;
559 } 611 }
560 612
561 if (tmp == NULL) 613 if (strchr(name, '.'))
562 return -ENOMEM; 614 lr->file = name;
563
564 if (strchr(tmp, '.'))
565 lr->file = tmp;
566 else 615 else
567 lr->function = tmp; 616 lr->function = name;
568 617
569 return 0; 618 return 0;
619err:
620 free(name);
621 return err;
570} 622}
571 623
572/* Check the name is good for event/group */ 624/* Check the name is good for event/group */
@@ -690,39 +742,40 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
690 742
691 /* Exclusion check */ 743 /* Exclusion check */
692 if (pp->lazy_line && pp->line) { 744 if (pp->lazy_line && pp->line) {
693 semantic_error("Lazy pattern can't be used with line number."); 745 semantic_error("Lazy pattern can't be used with"
746 " line number.\n");
694 return -EINVAL; 747 return -EINVAL;
695 } 748 }
696 749
697 if (pp->lazy_line && pp->offset) { 750 if (pp->lazy_line && pp->offset) {
698 semantic_error("Lazy pattern can't be used with offset."); 751 semantic_error("Lazy pattern can't be used with offset.\n");
699 return -EINVAL; 752 return -EINVAL;
700 } 753 }
701 754
702 if (pp->line && pp->offset) { 755 if (pp->line && pp->offset) {
703 semantic_error("Offset can't be used with line number."); 756 semantic_error("Offset can't be used with line number.\n");
704 return -EINVAL; 757 return -EINVAL;
705 } 758 }
706 759
707 if (!pp->line && !pp->lazy_line && pp->file && !pp->function) { 760 if (!pp->line && !pp->lazy_line && pp->file && !pp->function) {
708 semantic_error("File always requires line number or " 761 semantic_error("File always requires line number or "
709 "lazy pattern."); 762 "lazy pattern.\n");
710 return -EINVAL; 763 return -EINVAL;
711 } 764 }
712 765
713 if (pp->offset && !pp->function) { 766 if (pp->offset && !pp->function) {
714 semantic_error("Offset requires an entry function."); 767 semantic_error("Offset requires an entry function.\n");
715 return -EINVAL; 768 return -EINVAL;
716 } 769 }
717 770
718 if (pp->retprobe && !pp->function) { 771 if (pp->retprobe && !pp->function) {
719 semantic_error("Return probe requires an entry function."); 772 semantic_error("Return probe requires an entry function.\n");
720 return -EINVAL; 773 return -EINVAL;
721 } 774 }
722 775
723 if ((pp->offset || pp->line || pp->lazy_line) && pp->retprobe) { 776 if ((pp->offset || pp->line || pp->lazy_line) && pp->retprobe) {
724 semantic_error("Offset/Line/Lazy pattern can't be used with " 777 semantic_error("Offset/Line/Lazy pattern can't be used with "
725 "return probe."); 778 "return probe.\n");
726 return -EINVAL; 779 return -EINVAL;
727 } 780 }
728 781
@@ -996,7 +1049,7 @@ int synthesize_perf_probe_arg(struct perf_probe_arg *pa, char *buf, size_t len)
996 1049
997 return tmp - buf; 1050 return tmp - buf;
998error: 1051error:
999 pr_debug("Failed to synthesize perf probe argument: %s", 1052 pr_debug("Failed to synthesize perf probe argument: %s\n",
1000 strerror(-ret)); 1053 strerror(-ret));
1001 return ret; 1054 return ret;
1002} 1055}
@@ -1024,13 +1077,13 @@ static char *synthesize_perf_probe_point(struct perf_probe_point *pp)
1024 goto error; 1077 goto error;
1025 } 1078 }
1026 if (pp->file) { 1079 if (pp->file) {
1027 len = strlen(pp->file) - 31; 1080 tmp = pp->file;
1028 if (len < 0) 1081 len = strlen(tmp);
1029 len = 0; 1082 if (len > 30) {
1030 tmp = strchr(pp->file + len, '/'); 1083 tmp = strchr(pp->file + len - 30, '/');
1031 if (!tmp) 1084 tmp = tmp ? tmp + 1 : pp->file + len - 30;
1032 tmp = pp->file + len; 1085 }
1033 ret = e_snprintf(file, 32, "@%s", tmp + 1); 1086 ret = e_snprintf(file, 32, "@%s", tmp);
1034 if (ret <= 0) 1087 if (ret <= 0)
1035 goto error; 1088 goto error;
1036 } 1089 }
@@ -1046,7 +1099,7 @@ static char *synthesize_perf_probe_point(struct perf_probe_point *pp)
1046 1099
1047 return buf; 1100 return buf;
1048error: 1101error:
1049 pr_debug("Failed to synthesize perf probe point: %s", 1102 pr_debug("Failed to synthesize perf probe point: %s\n",
1050 strerror(-ret)); 1103 strerror(-ret));
1051 if (buf) 1104 if (buf)
1052 free(buf); 1105 free(buf);
@@ -1787,7 +1840,7 @@ static int del_trace_probe_event(int fd, const char *group,
1787 1840
1788 ret = e_snprintf(buf, 128, "%s:%s", group, event); 1841 ret = e_snprintf(buf, 128, "%s:%s", group, event);
1789 if (ret < 0) { 1842 if (ret < 0) {
1790 pr_err("Failed to copy event."); 1843 pr_err("Failed to copy event.\n");
1791 return ret; 1844 return ret;
1792 } 1845 }
1793 1846