diff options
Diffstat (limited to 'tools/perf/util/probe-event.c')
-rw-r--r-- | tools/perf/util/probe-event.c | 69 |
1 files changed, 50 insertions, 19 deletions
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 0dda25d82d06..49a256e6e0a2 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c | |||
@@ -41,7 +41,7 @@ | |||
41 | #include "symbol.h" | 41 | #include "symbol.h" |
42 | #include "thread.h" | 42 | #include "thread.h" |
43 | #include "debugfs.h" | 43 | #include "debugfs.h" |
44 | #include "trace-event.h" /* For __unused */ | 44 | #include "trace-event.h" /* For __maybe_unused */ |
45 | #include "probe-event.h" | 45 | #include "probe-event.h" |
46 | #include "probe-finder.h" | 46 | #include "probe-finder.h" |
47 | #include "session.h" | 47 | #include "session.h" |
@@ -647,8 +647,8 @@ static int kprobe_convert_to_perf_probe(struct probe_trace_point *tp, | |||
647 | } | 647 | } |
648 | 648 | ||
649 | static int try_to_find_probe_trace_events(struct perf_probe_event *pev, | 649 | static int try_to_find_probe_trace_events(struct perf_probe_event *pev, |
650 | struct probe_trace_event **tevs __unused, | 650 | struct probe_trace_event **tevs __maybe_unused, |
651 | int max_tevs __unused, const char *target) | 651 | int max_tevs __maybe_unused, const char *target) |
652 | { | 652 | { |
653 | if (perf_probe_event_need_dwarf(pev)) { | 653 | if (perf_probe_event_need_dwarf(pev)) { |
654 | pr_warning("Debuginfo-analysis is not supported.\n"); | 654 | pr_warning("Debuginfo-analysis is not supported.\n"); |
@@ -661,17 +661,18 @@ static int try_to_find_probe_trace_events(struct perf_probe_event *pev, | |||
661 | return 0; | 661 | return 0; |
662 | } | 662 | } |
663 | 663 | ||
664 | int show_line_range(struct line_range *lr __unused, const char *module __unused) | 664 | int show_line_range(struct line_range *lr __maybe_unused, |
665 | const char *module __maybe_unused) | ||
665 | { | 666 | { |
666 | pr_warning("Debuginfo-analysis is not supported.\n"); | 667 | pr_warning("Debuginfo-analysis is not supported.\n"); |
667 | return -ENOSYS; | 668 | return -ENOSYS; |
668 | } | 669 | } |
669 | 670 | ||
670 | int show_available_vars(struct perf_probe_event *pevs __unused, | 671 | int show_available_vars(struct perf_probe_event *pevs __maybe_unused, |
671 | int npevs __unused, int max_vls __unused, | 672 | int npevs __maybe_unused, int max_vls __maybe_unused, |
672 | const char *module __unused, | 673 | const char *module __maybe_unused, |
673 | struct strfilter *filter __unused, | 674 | struct strfilter *filter __maybe_unused, |
674 | bool externs __unused) | 675 | bool externs __maybe_unused) |
675 | { | 676 | { |
676 | pr_warning("Debuginfo-analysis is not supported.\n"); | 677 | pr_warning("Debuginfo-analysis is not supported.\n"); |
677 | return -ENOSYS; | 678 | return -ENOSYS; |
@@ -1099,6 +1100,7 @@ static int parse_probe_trace_command(const char *cmd, | |||
1099 | struct probe_trace_point *tp = &tev->point; | 1100 | struct probe_trace_point *tp = &tev->point; |
1100 | char pr; | 1101 | char pr; |
1101 | char *p; | 1102 | char *p; |
1103 | char *argv0_str = NULL, *fmt, *fmt1_str, *fmt2_str, *fmt3_str; | ||
1102 | int ret, i, argc; | 1104 | int ret, i, argc; |
1103 | char **argv; | 1105 | char **argv; |
1104 | 1106 | ||
@@ -1115,14 +1117,27 @@ static int parse_probe_trace_command(const char *cmd, | |||
1115 | } | 1117 | } |
1116 | 1118 | ||
1117 | /* Scan event and group name. */ | 1119 | /* Scan event and group name. */ |
1118 | ret = sscanf(argv[0], "%c:%a[^/ \t]/%a[^ \t]", | 1120 | argv0_str = strdup(argv[0]); |
1119 | &pr, (float *)(void *)&tev->group, | 1121 | if (argv0_str == NULL) { |
1120 | (float *)(void *)&tev->event); | 1122 | ret = -ENOMEM; |
1121 | if (ret != 3) { | 1123 | goto out; |
1124 | } | ||
1125 | fmt1_str = strtok_r(argv0_str, ":", &fmt); | ||
1126 | fmt2_str = strtok_r(NULL, "/", &fmt); | ||
1127 | fmt3_str = strtok_r(NULL, " \t", &fmt); | ||
1128 | if (fmt1_str == NULL || strlen(fmt1_str) != 1 || fmt2_str == NULL | ||
1129 | || fmt3_str == NULL) { | ||
1122 | semantic_error("Failed to parse event name: %s\n", argv[0]); | 1130 | semantic_error("Failed to parse event name: %s\n", argv[0]); |
1123 | ret = -EINVAL; | 1131 | ret = -EINVAL; |
1124 | goto out; | 1132 | goto out; |
1125 | } | 1133 | } |
1134 | pr = fmt1_str[0]; | ||
1135 | tev->group = strdup(fmt2_str); | ||
1136 | tev->event = strdup(fmt3_str); | ||
1137 | if (tev->group == NULL || tev->event == NULL) { | ||
1138 | ret = -ENOMEM; | ||
1139 | goto out; | ||
1140 | } | ||
1126 | pr_debug("Group:%s Event:%s probe:%c\n", tev->group, tev->event, pr); | 1141 | pr_debug("Group:%s Event:%s probe:%c\n", tev->group, tev->event, pr); |
1127 | 1142 | ||
1128 | tp->retprobe = (pr == 'r'); | 1143 | tp->retprobe = (pr == 'r'); |
@@ -1134,10 +1149,17 @@ static int parse_probe_trace_command(const char *cmd, | |||
1134 | p++; | 1149 | p++; |
1135 | } else | 1150 | } else |
1136 | p = argv[1]; | 1151 | p = argv[1]; |
1137 | ret = sscanf(p, "%a[^+]+%lu", (float *)(void *)&tp->symbol, | 1152 | fmt1_str = strtok_r(p, "+", &fmt); |
1138 | &tp->offset); | 1153 | tp->symbol = strdup(fmt1_str); |
1139 | if (ret == 1) | 1154 | if (tp->symbol == NULL) { |
1155 | ret = -ENOMEM; | ||
1156 | goto out; | ||
1157 | } | ||
1158 | fmt2_str = strtok_r(NULL, "", &fmt); | ||
1159 | if (fmt2_str == NULL) | ||
1140 | tp->offset = 0; | 1160 | tp->offset = 0; |
1161 | else | ||
1162 | tp->offset = strtoul(fmt2_str, NULL, 10); | ||
1141 | 1163 | ||
1142 | tev->nargs = argc - 2; | 1164 | tev->nargs = argc - 2; |
1143 | tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs); | 1165 | tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs); |
@@ -1161,6 +1183,7 @@ static int parse_probe_trace_command(const char *cmd, | |||
1161 | } | 1183 | } |
1162 | ret = 0; | 1184 | ret = 0; |
1163 | out: | 1185 | out: |
1186 | free(argv0_str); | ||
1164 | argv_free(argv); | 1187 | argv_free(argv); |
1165 | return ret; | 1188 | return ret; |
1166 | } | 1189 | } |
@@ -2183,7 +2206,7 @@ static struct strfilter *available_func_filter; | |||
2183 | * If a symbol corresponds to a function with global binding and | 2206 | * If a symbol corresponds to a function with global binding and |
2184 | * matches filter return 0. For all others return 1. | 2207 | * matches filter return 0. For all others return 1. |
2185 | */ | 2208 | */ |
2186 | static int filter_available_functions(struct map *map __unused, | 2209 | static int filter_available_functions(struct map *map __maybe_unused, |
2187 | struct symbol *sym) | 2210 | struct symbol *sym) |
2188 | { | 2211 | { |
2189 | if (sym->binding == STB_GLOBAL && | 2212 | if (sym->binding == STB_GLOBAL && |
@@ -2307,10 +2330,17 @@ static int convert_name_to_addr(struct perf_probe_event *pev, const char *exec) | |||
2307 | function = NULL; | 2330 | function = NULL; |
2308 | } | 2331 | } |
2309 | if (!pev->group) { | 2332 | if (!pev->group) { |
2310 | char *ptr1, *ptr2; | 2333 | char *ptr1, *ptr2, *exec_copy; |
2311 | 2334 | ||
2312 | pev->group = zalloc(sizeof(char *) * 64); | 2335 | pev->group = zalloc(sizeof(char *) * 64); |
2313 | ptr1 = strdup(basename(exec)); | 2336 | exec_copy = strdup(exec); |
2337 | if (!exec_copy) { | ||
2338 | ret = -ENOMEM; | ||
2339 | pr_warning("Failed to copy exec string.\n"); | ||
2340 | goto out; | ||
2341 | } | ||
2342 | |||
2343 | ptr1 = strdup(basename(exec_copy)); | ||
2314 | if (ptr1) { | 2344 | if (ptr1) { |
2315 | ptr2 = strpbrk(ptr1, "-._"); | 2345 | ptr2 = strpbrk(ptr1, "-._"); |
2316 | if (ptr2) | 2346 | if (ptr2) |
@@ -2319,6 +2349,7 @@ static int convert_name_to_addr(struct perf_probe_event *pev, const char *exec) | |||
2319 | ptr1); | 2349 | ptr1); |
2320 | free(ptr1); | 2350 | free(ptr1); |
2321 | } | 2351 | } |
2352 | free(exec_copy); | ||
2322 | } | 2353 | } |
2323 | free(pp->function); | 2354 | free(pp->function); |
2324 | pp->function = zalloc(sizeof(char *) * MAX_PROBE_ARGS); | 2355 | pp->function = zalloc(sizeof(char *) * MAX_PROBE_ARGS); |