diff options
Diffstat (limited to 'tools/perf/util/probe-event.c')
-rw-r--r-- | tools/perf/util/probe-event.c | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index a22141a773bc..71b0dd590a37 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include "strlist.h" | 38 | #include "strlist.h" |
39 | #include "debug.h" | 39 | #include "debug.h" |
40 | #include "cache.h" | 40 | #include "cache.h" |
41 | #include "color.h" | ||
41 | #include "parse-events.h" /* For debugfs_path */ | 42 | #include "parse-events.h" /* For debugfs_path */ |
42 | #include "probe-event.h" | 43 | #include "probe-event.h" |
43 | 44 | ||
@@ -63,6 +64,42 @@ static int e_snprintf(char *str, size_t size, const char *format, ...) | |||
63 | return ret; | 64 | return ret; |
64 | } | 65 | } |
65 | 66 | ||
67 | void parse_line_range_desc(const char *arg, struct line_range *lr) | ||
68 | { | ||
69 | const char *ptr; | ||
70 | char *tmp; | ||
71 | /* | ||
72 | * <Syntax> | ||
73 | * SRC:SLN[+NUM|-ELN] | ||
74 | * FUNC[:SLN[+NUM|-ELN]] | ||
75 | */ | ||
76 | ptr = strchr(arg, ':'); | ||
77 | if (ptr) { | ||
78 | lr->start = (unsigned int)strtoul(ptr + 1, &tmp, 0); | ||
79 | if (*tmp == '+') | ||
80 | lr->end = lr->start + (unsigned int)strtoul(tmp + 1, | ||
81 | &tmp, 0); | ||
82 | else if (*tmp == '-') | ||
83 | lr->end = (unsigned int)strtoul(tmp + 1, &tmp, 0); | ||
84 | else | ||
85 | lr->end = 0; | ||
86 | pr_debug("Line range is %u to %u\n", lr->start, lr->end); | ||
87 | if (lr->end && lr->start > lr->end) | ||
88 | semantic_error("Start line must be smaller" | ||
89 | " than end line."); | ||
90 | if (*tmp != '\0') | ||
91 | semantic_error("Tailing with invalid character '%d'.", | ||
92 | *tmp); | ||
93 | tmp = strndup(arg, (ptr - arg)); | ||
94 | } else | ||
95 | tmp = strdup(arg); | ||
96 | |||
97 | if (strchr(tmp, '.')) | ||
98 | lr->file = tmp; | ||
99 | else | ||
100 | lr->function = tmp; | ||
101 | } | ||
102 | |||
66 | /* Check the name is good for event/group */ | 103 | /* Check the name is good for event/group */ |
67 | static bool check_event_name(const char *name) | 104 | static bool check_event_name(const char *name) |
68 | { | 105 | { |
@@ -678,3 +715,66 @@ void del_trace_kprobe_events(struct strlist *dellist) | |||
678 | close(fd); | 715 | close(fd); |
679 | } | 716 | } |
680 | 717 | ||
718 | #define LINEBUF_SIZE 256 | ||
719 | |||
720 | static void show_one_line(FILE *fp, unsigned int l, bool skip, bool show_num) | ||
721 | { | ||
722 | char buf[LINEBUF_SIZE]; | ||
723 | const char *color = PERF_COLOR_BLUE; | ||
724 | |||
725 | if (fgets(buf, LINEBUF_SIZE, fp) == NULL) | ||
726 | goto error; | ||
727 | if (!skip) { | ||
728 | if (show_num) | ||
729 | fprintf(stdout, "%7u %s", l, buf); | ||
730 | else | ||
731 | color_fprintf(stdout, color, " %s", buf); | ||
732 | } | ||
733 | |||
734 | while (strlen(buf) == LINEBUF_SIZE - 1 && | ||
735 | buf[LINEBUF_SIZE - 2] != '\n') { | ||
736 | if (fgets(buf, LINEBUF_SIZE, fp) == NULL) | ||
737 | goto error; | ||
738 | if (!skip) { | ||
739 | if (show_num) | ||
740 | fprintf(stdout, "%s", buf); | ||
741 | else | ||
742 | color_fprintf(stdout, color, "%s", buf); | ||
743 | } | ||
744 | } | ||
745 | return; | ||
746 | error: | ||
747 | if (feof(fp)) | ||
748 | die("Source file is shorter than expected."); | ||
749 | else | ||
750 | die("File read error: %s", strerror(errno)); | ||
751 | } | ||
752 | |||
753 | void show_line_range(struct line_range *lr) | ||
754 | { | ||
755 | unsigned int l = 1; | ||
756 | struct line_node *ln; | ||
757 | FILE *fp; | ||
758 | |||
759 | setup_pager(); | ||
760 | |||
761 | if (lr->function) | ||
762 | fprintf(stdout, "<%s:%d>\n", lr->function, | ||
763 | lr->start - lr->offset); | ||
764 | else | ||
765 | fprintf(stdout, "<%s:%d>\n", lr->file, lr->start); | ||
766 | |||
767 | fp = fopen(lr->path, "r"); | ||
768 | if (fp == NULL) | ||
769 | die("Failed to open %s: %s", lr->path, strerror(errno)); | ||
770 | /* Skip to starting line number */ | ||
771 | while (l < lr->start) | ||
772 | show_one_line(fp, l++, true, false); | ||
773 | |||
774 | list_for_each_entry(ln, &lr->line_list, list) { | ||
775 | while (ln->line > l) | ||
776 | show_one_line(fp, (l++) - lr->offset, false, false); | ||
777 | show_one_line(fp, (l++) - lr->offset, false, true); | ||
778 | } | ||
779 | fclose(fp); | ||
780 | } | ||