diff options
| -rw-r--r-- | tools/perf/util/Build | 1 | ||||
| -rw-r--r-- | tools/perf/util/evsel.c | 206 | ||||
| -rw-r--r-- | tools/perf/util/evsel_fprintf.c | 212 |
3 files changed, 213 insertions, 206 deletions
diff --git a/tools/perf/util/Build b/tools/perf/util/Build index 61021334e958..85a9ab62e23f 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build | |||
| @@ -8,6 +8,7 @@ libperf-y += env.o | |||
| 8 | libperf-y += event.o | 8 | libperf-y += event.o |
| 9 | libperf-y += evlist.o | 9 | libperf-y += evlist.o |
| 10 | libperf-y += evsel.o | 10 | libperf-y += evsel.o |
| 11 | libperf-y += evsel_fprintf.o | ||
| 11 | libperf-y += find_bit.o | 12 | libperf-y += find_bit.o |
| 12 | libperf-y += kallsyms.o | 13 | libperf-y += kallsyms.o |
| 13 | libperf-y += levenshtein.o | 14 | libperf-y += levenshtein.o |
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 060f619dea88..545bb3f0b2b0 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c | |||
| @@ -2254,212 +2254,6 @@ u64 perf_evsel__intval(struct perf_evsel *evsel, struct perf_sample *sample, | |||
| 2254 | return 0; | 2254 | return 0; |
| 2255 | } | 2255 | } |
| 2256 | 2256 | ||
| 2257 | static int comma_fprintf(FILE *fp, bool *first, const char *fmt, ...) | ||
| 2258 | { | ||
| 2259 | va_list args; | ||
| 2260 | int ret = 0; | ||
| 2261 | |||
| 2262 | if (!*first) { | ||
| 2263 | ret += fprintf(fp, ","); | ||
| 2264 | } else { | ||
| 2265 | ret += fprintf(fp, ":"); | ||
| 2266 | *first = false; | ||
| 2267 | } | ||
| 2268 | |||
| 2269 | va_start(args, fmt); | ||
| 2270 | ret += vfprintf(fp, fmt, args); | ||
| 2271 | va_end(args); | ||
| 2272 | return ret; | ||
| 2273 | } | ||
| 2274 | |||
| 2275 | static int __print_attr__fprintf(FILE *fp, const char *name, const char *val, void *priv) | ||
| 2276 | { | ||
| 2277 | return comma_fprintf(fp, (bool *)priv, " %s: %s", name, val); | ||
| 2278 | } | ||
| 2279 | |||
| 2280 | int perf_evsel__fprintf(struct perf_evsel *evsel, | ||
| 2281 | struct perf_attr_details *details, FILE *fp) | ||
| 2282 | { | ||
| 2283 | bool first = true; | ||
| 2284 | int printed = 0; | ||
| 2285 | |||
| 2286 | if (details->event_group) { | ||
| 2287 | struct perf_evsel *pos; | ||
| 2288 | |||
| 2289 | if (!perf_evsel__is_group_leader(evsel)) | ||
| 2290 | return 0; | ||
| 2291 | |||
| 2292 | if (evsel->nr_members > 1) | ||
| 2293 | printed += fprintf(fp, "%s{", evsel->group_name ?: ""); | ||
| 2294 | |||
| 2295 | printed += fprintf(fp, "%s", perf_evsel__name(evsel)); | ||
| 2296 | for_each_group_member(pos, evsel) | ||
| 2297 | printed += fprintf(fp, ",%s", perf_evsel__name(pos)); | ||
| 2298 | |||
| 2299 | if (evsel->nr_members > 1) | ||
| 2300 | printed += fprintf(fp, "}"); | ||
| 2301 | goto out; | ||
| 2302 | } | ||
| 2303 | |||
| 2304 | printed += fprintf(fp, "%s", perf_evsel__name(evsel)); | ||
| 2305 | |||
| 2306 | if (details->verbose) { | ||
| 2307 | printed += perf_event_attr__fprintf(fp, &evsel->attr, | ||
| 2308 | __print_attr__fprintf, &first); | ||
| 2309 | } else if (details->freq) { | ||
| 2310 | const char *term = "sample_freq"; | ||
| 2311 | |||
| 2312 | if (!evsel->attr.freq) | ||
| 2313 | term = "sample_period"; | ||
| 2314 | |||
| 2315 | printed += comma_fprintf(fp, &first, " %s=%" PRIu64, | ||
| 2316 | term, (u64)evsel->attr.sample_freq); | ||
| 2317 | } | ||
| 2318 | |||
| 2319 | if (details->trace_fields) { | ||
| 2320 | struct format_field *field; | ||
| 2321 | |||
| 2322 | if (evsel->attr.type != PERF_TYPE_TRACEPOINT) { | ||
| 2323 | printed += comma_fprintf(fp, &first, " (not a tracepoint)"); | ||
| 2324 | goto out; | ||
| 2325 | } | ||
| 2326 | |||
| 2327 | field = evsel->tp_format->format.fields; | ||
| 2328 | if (field == NULL) { | ||
| 2329 | printed += comma_fprintf(fp, &first, " (no trace field)"); | ||
| 2330 | goto out; | ||
| 2331 | } | ||
| 2332 | |||
| 2333 | printed += comma_fprintf(fp, &first, " trace_fields: %s", field->name); | ||
| 2334 | |||
| 2335 | field = field->next; | ||
| 2336 | while (field) { | ||
| 2337 | printed += comma_fprintf(fp, &first, "%s", field->name); | ||
| 2338 | field = field->next; | ||
| 2339 | } | ||
| 2340 | } | ||
| 2341 | out: | ||
| 2342 | fputc('\n', fp); | ||
| 2343 | return ++printed; | ||
| 2344 | } | ||
| 2345 | |||
| 2346 | int sample__fprintf_callchain(struct perf_sample *sample, int left_alignment, | ||
| 2347 | unsigned int print_opts, struct callchain_cursor *cursor, | ||
| 2348 | FILE *fp) | ||
| 2349 | { | ||
| 2350 | int printed = 0; | ||
| 2351 | struct callchain_cursor_node *node; | ||
| 2352 | int print_ip = print_opts & EVSEL__PRINT_IP; | ||
| 2353 | int print_sym = print_opts & EVSEL__PRINT_SYM; | ||
| 2354 | int print_dso = print_opts & EVSEL__PRINT_DSO; | ||
| 2355 | int print_symoffset = print_opts & EVSEL__PRINT_SYMOFFSET; | ||
| 2356 | int print_oneline = print_opts & EVSEL__PRINT_ONELINE; | ||
| 2357 | int print_srcline = print_opts & EVSEL__PRINT_SRCLINE; | ||
| 2358 | int print_unknown_as_addr = print_opts & EVSEL__PRINT_UNKNOWN_AS_ADDR; | ||
| 2359 | char s = print_oneline ? ' ' : '\t'; | ||
| 2360 | |||
| 2361 | if (sample->callchain) { | ||
| 2362 | struct addr_location node_al; | ||
| 2363 | |||
| 2364 | callchain_cursor_commit(cursor); | ||
| 2365 | |||
| 2366 | while (1) { | ||
| 2367 | u64 addr = 0; | ||
| 2368 | |||
| 2369 | node = callchain_cursor_current(cursor); | ||
| 2370 | if (!node) | ||
| 2371 | break; | ||
| 2372 | |||
| 2373 | if (node->sym && node->sym->ignore) | ||
| 2374 | goto next; | ||
| 2375 | |||
| 2376 | printed += fprintf(fp, "%-*.*s", left_alignment, left_alignment, " "); | ||
| 2377 | |||
| 2378 | if (print_ip) | ||
| 2379 | printed += fprintf(fp, "%c%16" PRIx64, s, node->ip); | ||
| 2380 | |||
| 2381 | if (node->map) | ||
| 2382 | addr = node->map->map_ip(node->map, node->ip); | ||
| 2383 | |||
| 2384 | if (print_sym) { | ||
| 2385 | printed += fprintf(fp, " "); | ||
| 2386 | node_al.addr = addr; | ||
| 2387 | node_al.map = node->map; | ||
| 2388 | |||
| 2389 | if (print_symoffset) { | ||
| 2390 | printed += __symbol__fprintf_symname_offs(node->sym, &node_al, | ||
| 2391 | print_unknown_as_addr, fp); | ||
| 2392 | } else { | ||
| 2393 | printed += __symbol__fprintf_symname(node->sym, &node_al, | ||
| 2394 | print_unknown_as_addr, fp); | ||
| 2395 | } | ||
| 2396 | } | ||
| 2397 | |||
| 2398 | if (print_dso) { | ||
| 2399 | printed += fprintf(fp, " ("); | ||
| 2400 | printed += map__fprintf_dsoname(node->map, fp); | ||
| 2401 | printed += fprintf(fp, ")"); | ||
| 2402 | } | ||
| 2403 | |||
| 2404 | if (print_srcline) | ||
| 2405 | printed += map__fprintf_srcline(node->map, addr, "\n ", fp); | ||
| 2406 | |||
| 2407 | if (!print_oneline) | ||
| 2408 | printed += fprintf(fp, "\n"); | ||
| 2409 | next: | ||
| 2410 | callchain_cursor_advance(cursor); | ||
| 2411 | } | ||
| 2412 | } | ||
| 2413 | |||
| 2414 | return printed; | ||
| 2415 | } | ||
| 2416 | |||
| 2417 | int sample__fprintf_sym(struct perf_sample *sample, struct addr_location *al, | ||
| 2418 | int left_alignment, unsigned int print_opts, | ||
| 2419 | struct callchain_cursor *cursor, FILE *fp) | ||
| 2420 | { | ||
| 2421 | int printed = 0; | ||
| 2422 | int print_ip = print_opts & EVSEL__PRINT_IP; | ||
| 2423 | int print_sym = print_opts & EVSEL__PRINT_SYM; | ||
| 2424 | int print_dso = print_opts & EVSEL__PRINT_DSO; | ||
| 2425 | int print_symoffset = print_opts & EVSEL__PRINT_SYMOFFSET; | ||
| 2426 | int print_srcline = print_opts & EVSEL__PRINT_SRCLINE; | ||
| 2427 | int print_unknown_as_addr = print_opts & EVSEL__PRINT_UNKNOWN_AS_ADDR; | ||
| 2428 | |||
| 2429 | if (cursor != NULL) { | ||
| 2430 | printed += sample__fprintf_callchain(sample, left_alignment, | ||
| 2431 | print_opts, cursor, fp); | ||
| 2432 | } else if (!(al->sym && al->sym->ignore)) { | ||
| 2433 | printed += fprintf(fp, "%-*.*s", left_alignment, left_alignment, " "); | ||
| 2434 | |||
| 2435 | if (print_ip) | ||
| 2436 | printed += fprintf(fp, "%16" PRIx64, sample->ip); | ||
| 2437 | |||
| 2438 | if (print_sym) { | ||
| 2439 | printed += fprintf(fp, " "); | ||
| 2440 | if (print_symoffset) { | ||
| 2441 | printed += __symbol__fprintf_symname_offs(al->sym, al, | ||
| 2442 | print_unknown_as_addr, fp); | ||
| 2443 | } else { | ||
| 2444 | printed += __symbol__fprintf_symname(al->sym, al, | ||
| 2445 | print_unknown_as_addr, fp); | ||
| 2446 | } | ||
| 2447 | } | ||
| 2448 | |||
| 2449 | if (print_dso) { | ||
| 2450 | printed += fprintf(fp, " ("); | ||
| 2451 | printed += map__fprintf_dsoname(al->map, fp); | ||
| 2452 | printed += fprintf(fp, ")"); | ||
| 2453 | } | ||
| 2454 | |||
| 2455 | if (print_srcline) | ||
| 2456 | printed += map__fprintf_srcline(al->map, al->addr, "\n ", fp); | ||
| 2457 | } | ||
| 2458 | |||
| 2459 | return printed; | ||
| 2460 | } | ||
| 2461 | |||
| 2462 | |||
| 2463 | bool perf_evsel__fallback(struct perf_evsel *evsel, int err, | 2257 | bool perf_evsel__fallback(struct perf_evsel *evsel, int err, |
| 2464 | char *msg, size_t msgsize) | 2258 | char *msg, size_t msgsize) |
| 2465 | { | 2259 | { |
diff --git a/tools/perf/util/evsel_fprintf.c b/tools/perf/util/evsel_fprintf.c new file mode 100644 index 000000000000..3674e77ad640 --- /dev/null +++ b/tools/perf/util/evsel_fprintf.c | |||
| @@ -0,0 +1,212 @@ | |||
| 1 | #include <stdio.h> | ||
| 2 | #include <stdbool.h> | ||
| 3 | #include <traceevent/event-parse.h> | ||
| 4 | #include "evsel.h" | ||
| 5 | #include "callchain.h" | ||
| 6 | #include "map.h" | ||
| 7 | #include "symbol.h" | ||
| 8 | |||
| 9 | static int comma_fprintf(FILE *fp, bool *first, const char *fmt, ...) | ||
| 10 | { | ||
| 11 | va_list args; | ||
| 12 | int ret = 0; | ||
| 13 | |||
| 14 | if (!*first) { | ||
| 15 | ret += fprintf(fp, ","); | ||
| 16 | } else { | ||
| 17 | ret += fprintf(fp, ":"); | ||
| 18 | *first = false; | ||
| 19 | } | ||
| 20 | |||
| 21 | va_start(args, fmt); | ||
| 22 | ret += vfprintf(fp, fmt, args); | ||
| 23 | va_end(args); | ||
| 24 | return ret; | ||
| 25 | } | ||
| 26 | |||
| 27 | static int __print_attr__fprintf(FILE *fp, const char *name, const char *val, void *priv) | ||
| 28 | { | ||
| 29 | return comma_fprintf(fp, (bool *)priv, " %s: %s", name, val); | ||
| 30 | } | ||
| 31 | |||
| 32 | int perf_evsel__fprintf(struct perf_evsel *evsel, | ||
| 33 | struct perf_attr_details *details, FILE *fp) | ||
| 34 | { | ||
| 35 | bool first = true; | ||
| 36 | int printed = 0; | ||
| 37 | |||
| 38 | if (details->event_group) { | ||
| 39 | struct perf_evsel *pos; | ||
| 40 | |||
| 41 | if (!perf_evsel__is_group_leader(evsel)) | ||
| 42 | return 0; | ||
| 43 | |||
| 44 | if (evsel->nr_members > 1) | ||
| 45 | printed += fprintf(fp, "%s{", evsel->group_name ?: ""); | ||
| 46 | |||
| 47 | printed += fprintf(fp, "%s", perf_evsel__name(evsel)); | ||
| 48 | for_each_group_member(pos, evsel) | ||
| 49 | printed += fprintf(fp, ",%s", perf_evsel__name(pos)); | ||
| 50 | |||
| 51 | if (evsel->nr_members > 1) | ||
| 52 | printed += fprintf(fp, "}"); | ||
| 53 | goto out; | ||
| 54 | } | ||
| 55 | |||
| 56 | printed += fprintf(fp, "%s", perf_evsel__name(evsel)); | ||
| 57 | |||
| 58 | if (details->verbose) { | ||
| 59 | printed += perf_event_attr__fprintf(fp, &evsel->attr, | ||
| 60 | __print_attr__fprintf, &first); | ||
| 61 | } else if (details->freq) { | ||
| 62 | const char *term = "sample_freq"; | ||
| 63 | |||
| 64 | if (!evsel->attr.freq) | ||
| 65 | term = "sample_period"; | ||
| 66 | |||
| 67 | printed += comma_fprintf(fp, &first, " %s=%" PRIu64, | ||
| 68 | term, (u64)evsel->attr.sample_freq); | ||
| 69 | } | ||
| 70 | |||
| 71 | if (details->trace_fields) { | ||
| 72 | struct format_field *field; | ||
| 73 | |||
| 74 | if (evsel->attr.type != PERF_TYPE_TRACEPOINT) { | ||
| 75 | printed += comma_fprintf(fp, &first, " (not a tracepoint)"); | ||
| 76 | goto out; | ||
| 77 | } | ||
| 78 | |||
| 79 | field = evsel->tp_format->format.fields; | ||
| 80 | if (field == NULL) { | ||
| 81 | printed += comma_fprintf(fp, &first, " (no trace field)"); | ||
| 82 | goto out; | ||
| 83 | } | ||
| 84 | |||
| 85 | printed += comma_fprintf(fp, &first, " trace_fields: %s", field->name); | ||
| 86 | |||
| 87 | field = field->next; | ||
| 88 | while (field) { | ||
| 89 | printed += comma_fprintf(fp, &first, "%s", field->name); | ||
| 90 | field = field->next; | ||
| 91 | } | ||
| 92 | } | ||
| 93 | out: | ||
| 94 | fputc('\n', fp); | ||
| 95 | return ++printed; | ||
| 96 | } | ||
| 97 | |||
| 98 | int sample__fprintf_callchain(struct perf_sample *sample, int left_alignment, | ||
| 99 | unsigned int print_opts, struct callchain_cursor *cursor, | ||
| 100 | FILE *fp) | ||
| 101 | { | ||
| 102 | int printed = 0; | ||
| 103 | struct callchain_cursor_node *node; | ||
| 104 | int print_ip = print_opts & EVSEL__PRINT_IP; | ||
| 105 | int print_sym = print_opts & EVSEL__PRINT_SYM; | ||
| 106 | int print_dso = print_opts & EVSEL__PRINT_DSO; | ||
| 107 | int print_symoffset = print_opts & EVSEL__PRINT_SYMOFFSET; | ||
| 108 | int print_oneline = print_opts & EVSEL__PRINT_ONELINE; | ||
| 109 | int print_srcline = print_opts & EVSEL__PRINT_SRCLINE; | ||
| 110 | int print_unknown_as_addr = print_opts & EVSEL__PRINT_UNKNOWN_AS_ADDR; | ||
| 111 | char s = print_oneline ? ' ' : '\t'; | ||
| 112 | |||
| 113 | if (sample->callchain) { | ||
| 114 | struct addr_location node_al; | ||
| 115 | |||
| 116 | callchain_cursor_commit(cursor); | ||
| 117 | |||
| 118 | while (1) { | ||
| 119 | u64 addr = 0; | ||
| 120 | |||
| 121 | node = callchain_cursor_current(cursor); | ||
| 122 | if (!node) | ||
| 123 | break; | ||
| 124 | |||
| 125 | if (node->sym && node->sym->ignore) | ||
| 126 | goto next; | ||
| 127 | |||
| 128 | printed += fprintf(fp, "%-*.*s", left_alignment, left_alignment, " "); | ||
| 129 | |||
| 130 | if (print_ip) | ||
| 131 | printed += fprintf(fp, "%c%16" PRIx64, s, node->ip); | ||
| 132 | |||
| 133 | if (node->map) | ||
| 134 | addr = node->map->map_ip(node->map, node->ip); | ||
| 135 | |||
| 136 | if (print_sym) { | ||
| 137 | printed += fprintf(fp, " "); | ||
| 138 | node_al.addr = addr; | ||
| 139 | node_al.map = node->map; | ||
| 140 | |||
| 141 | if (print_symoffset) { | ||
| 142 | printed += __symbol__fprintf_symname_offs(node->sym, &node_al, | ||
| 143 | print_unknown_as_addr, fp); | ||
| 144 | } else { | ||
| 145 | printed += __symbol__fprintf_symname(node->sym, &node_al, | ||
| 146 | print_unknown_as_addr, fp); | ||
| 147 | } | ||
| 148 | } | ||
| 149 | |||
| 150 | if (print_dso) { | ||
| 151 | printed += fprintf(fp, " ("); | ||
| 152 | printed += map__fprintf_dsoname(node->map, fp); | ||
| 153 | printed += fprintf(fp, ")"); | ||
| 154 | } | ||
| 155 | |||
| 156 | if (print_srcline) | ||
| 157 | printed += map__fprintf_srcline(node->map, addr, "\n ", fp); | ||
| 158 | |||
| 159 | if (!print_oneline) | ||
| 160 | printed += fprintf(fp, "\n"); | ||
| 161 | next: | ||
| 162 | callchain_cursor_advance(cursor); | ||
| 163 | } | ||
| 164 | } | ||
| 165 | |||
| 166 | return printed; | ||
| 167 | } | ||
| 168 | |||
| 169 | int sample__fprintf_sym(struct perf_sample *sample, struct addr_location *al, | ||
| 170 | int left_alignment, unsigned int print_opts, | ||
| 171 | struct callchain_cursor *cursor, FILE *fp) | ||
| 172 | { | ||
| 173 | int printed = 0; | ||
| 174 | int print_ip = print_opts & EVSEL__PRINT_IP; | ||
| 175 | int print_sym = print_opts & EVSEL__PRINT_SYM; | ||
| 176 | int print_dso = print_opts & EVSEL__PRINT_DSO; | ||
| 177 | int print_symoffset = print_opts & EVSEL__PRINT_SYMOFFSET; | ||
| 178 | int print_srcline = print_opts & EVSEL__PRINT_SRCLINE; | ||
| 179 | int print_unknown_as_addr = print_opts & EVSEL__PRINT_UNKNOWN_AS_ADDR; | ||
| 180 | |||
| 181 | if (cursor != NULL) { | ||
| 182 | printed += sample__fprintf_callchain(sample, left_alignment, | ||
| 183 | print_opts, cursor, fp); | ||
| 184 | } else if (!(al->sym && al->sym->ignore)) { | ||
| 185 | printed += fprintf(fp, "%-*.*s", left_alignment, left_alignment, " "); | ||
| 186 | |||
| 187 | if (print_ip) | ||
| 188 | printed += fprintf(fp, "%16" PRIx64, sample->ip); | ||
| 189 | |||
| 190 | if (print_sym) { | ||
| 191 | printed += fprintf(fp, " "); | ||
| 192 | if (print_symoffset) { | ||
| 193 | printed += __symbol__fprintf_symname_offs(al->sym, al, | ||
| 194 | print_unknown_as_addr, fp); | ||
| 195 | } else { | ||
| 196 | printed += __symbol__fprintf_symname(al->sym, al, | ||
| 197 | print_unknown_as_addr, fp); | ||
| 198 | } | ||
| 199 | } | ||
| 200 | |||
| 201 | if (print_dso) { | ||
| 202 | printed += fprintf(fp, " ("); | ||
| 203 | printed += map__fprintf_dsoname(al->map, fp); | ||
| 204 | printed += fprintf(fp, ")"); | ||
| 205 | } | ||
| 206 | |||
| 207 | if (print_srcline) | ||
| 208 | printed += map__fprintf_srcline(al->map, al->addr, "\n ", fp); | ||
| 209 | } | ||
| 210 | |||
| 211 | return printed; | ||
| 212 | } | ||
