Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 #include <inttypes.h>
0003 #include <stdio.h>
0004 #include <stdbool.h>
0005 #include <traceevent/event-parse.h>
0006 #include "evsel.h"
0007 #include "util/evsel_fprintf.h"
0008 #include "util/event.h"
0009 #include "callchain.h"
0010 #include "map.h"
0011 #include "strlist.h"
0012 #include "symbol.h"
0013 #include "srcline.h"
0014 #include "dso.h"
0015 
0016 static int comma_fprintf(FILE *fp, bool *first, const char *fmt, ...)
0017 {
0018     va_list args;
0019     int ret = 0;
0020 
0021     if (!*first) {
0022         ret += fprintf(fp, ",");
0023     } else {
0024         ret += fprintf(fp, ":");
0025         *first = false;
0026     }
0027 
0028     va_start(args, fmt);
0029     ret += vfprintf(fp, fmt, args);
0030     va_end(args);
0031     return ret;
0032 }
0033 
0034 static int __print_attr__fprintf(FILE *fp, const char *name, const char *val, void *priv)
0035 {
0036     return comma_fprintf(fp, (bool *)priv, " %s: %s", name, val);
0037 }
0038 
0039 int evsel__fprintf(struct evsel *evsel, struct perf_attr_details *details, FILE *fp)
0040 {
0041     bool first = true;
0042     int printed = 0;
0043 
0044     if (details->event_group) {
0045         struct evsel *pos;
0046 
0047         if (!evsel__is_group_leader(evsel))
0048             return 0;
0049 
0050         if (evsel->core.nr_members > 1)
0051             printed += fprintf(fp, "%s{", evsel->group_name ?: "");
0052 
0053         printed += fprintf(fp, "%s", evsel__name(evsel));
0054         for_each_group_member(pos, evsel)
0055             printed += fprintf(fp, ",%s", evsel__name(pos));
0056 
0057         if (evsel->core.nr_members > 1)
0058             printed += fprintf(fp, "}");
0059         goto out;
0060     }
0061 
0062     printed += fprintf(fp, "%s", evsel__name(evsel));
0063 
0064     if (details->verbose) {
0065         printed += perf_event_attr__fprintf(fp, &evsel->core.attr,
0066                             __print_attr__fprintf, &first);
0067     } else if (details->freq) {
0068         const char *term = "sample_freq";
0069 
0070         if (!evsel->core.attr.freq)
0071             term = "sample_period";
0072 
0073         printed += comma_fprintf(fp, &first, " %s=%" PRIu64,
0074                      term, (u64)evsel->core.attr.sample_freq);
0075     }
0076 
0077     if (details->trace_fields) {
0078         struct tep_format_field *field;
0079 
0080         if (evsel->core.attr.type != PERF_TYPE_TRACEPOINT) {
0081             printed += comma_fprintf(fp, &first, " (not a tracepoint)");
0082             goto out;
0083         }
0084 
0085         field = evsel->tp_format->format.fields;
0086         if (field == NULL) {
0087             printed += comma_fprintf(fp, &first, " (no trace field)");
0088             goto out;
0089         }
0090 
0091         printed += comma_fprintf(fp, &first, " trace_fields: %s", field->name);
0092 
0093         field = field->next;
0094         while (field) {
0095             printed += comma_fprintf(fp, &first, "%s", field->name);
0096             field = field->next;
0097         }
0098     }
0099 out:
0100     fputc('\n', fp);
0101     return ++printed;
0102 }
0103 
0104 #ifndef PYTHON_PERF
0105 int sample__fprintf_callchain(struct perf_sample *sample, int left_alignment,
0106                   unsigned int print_opts, struct callchain_cursor *cursor,
0107                   struct strlist *bt_stop_list, FILE *fp)
0108 {
0109     int printed = 0;
0110     struct callchain_cursor_node *node;
0111     int print_ip = print_opts & EVSEL__PRINT_IP;
0112     int print_sym = print_opts & EVSEL__PRINT_SYM;
0113     int print_dso = print_opts & EVSEL__PRINT_DSO;
0114     int print_symoffset = print_opts & EVSEL__PRINT_SYMOFFSET;
0115     int print_oneline = print_opts & EVSEL__PRINT_ONELINE;
0116     int print_srcline = print_opts & EVSEL__PRINT_SRCLINE;
0117     int print_unknown_as_addr = print_opts & EVSEL__PRINT_UNKNOWN_AS_ADDR;
0118     int print_arrow = print_opts & EVSEL__PRINT_CALLCHAIN_ARROW;
0119     int print_skip_ignored = print_opts & EVSEL__PRINT_SKIP_IGNORED;
0120     char s = print_oneline ? ' ' : '\t';
0121     bool first = true;
0122 
0123     if (sample->callchain) {
0124         struct addr_location node_al;
0125 
0126         callchain_cursor_commit(cursor);
0127 
0128         while (1) {
0129             struct symbol *sym;
0130             struct map *map;
0131             u64 addr = 0;
0132 
0133             node = callchain_cursor_current(cursor);
0134             if (!node)
0135                 break;
0136 
0137             sym = node->ms.sym;
0138             map = node->ms.map;
0139 
0140             if (sym && sym->ignore && print_skip_ignored)
0141                 goto next;
0142 
0143             printed += fprintf(fp, "%-*.*s", left_alignment, left_alignment, " ");
0144 
0145             if (print_arrow && !first)
0146                 printed += fprintf(fp, " <-");
0147 
0148             if (map)
0149                 addr = map->map_ip(map, node->ip);
0150 
0151             if (print_ip) {
0152                 /* Show binary offset for userspace addr */
0153                 if (map && !map->dso->kernel)
0154                     printed += fprintf(fp, "%c%16" PRIx64, s, addr);
0155                 else
0156                     printed += fprintf(fp, "%c%16" PRIx64, s, node->ip);
0157             }
0158 
0159             if (print_sym) {
0160                 printed += fprintf(fp, " ");
0161                 node_al.addr = addr;
0162                 node_al.map  = map;
0163 
0164                 if (print_symoffset) {
0165                     printed += __symbol__fprintf_symname_offs(sym, &node_al,
0166                                           print_unknown_as_addr,
0167                                           true, fp);
0168                 } else {
0169                     printed += __symbol__fprintf_symname(sym, &node_al,
0170                                          print_unknown_as_addr, fp);
0171                 }
0172             }
0173 
0174             if (print_dso && (!sym || !sym->inlined)) {
0175                 printed += fprintf(fp, " (");
0176                 printed += map__fprintf_dsoname(map, fp);
0177                 printed += fprintf(fp, ")");
0178             }
0179 
0180             if (print_srcline)
0181                 printed += map__fprintf_srcline(map, addr, "\n  ", fp);
0182 
0183             if (sym && sym->inlined)
0184                 printed += fprintf(fp, " (inlined)");
0185 
0186             if (!print_oneline)
0187                 printed += fprintf(fp, "\n");
0188 
0189             /* Add srccode here too? */
0190             if (bt_stop_list && sym &&
0191                 strlist__has_entry(bt_stop_list, sym->name)) {
0192                 break;
0193             }
0194 
0195             first = false;
0196 next:
0197             callchain_cursor_advance(cursor);
0198         }
0199     }
0200 
0201     return printed;
0202 }
0203 
0204 int sample__fprintf_sym(struct perf_sample *sample, struct addr_location *al,
0205             int left_alignment, unsigned int print_opts,
0206             struct callchain_cursor *cursor, struct strlist *bt_stop_list, FILE *fp)
0207 {
0208     int printed = 0;
0209     int print_ip = print_opts & EVSEL__PRINT_IP;
0210     int print_sym = print_opts & EVSEL__PRINT_SYM;
0211     int print_dso = print_opts & EVSEL__PRINT_DSO;
0212     int print_symoffset = print_opts & EVSEL__PRINT_SYMOFFSET;
0213     int print_srcline = print_opts & EVSEL__PRINT_SRCLINE;
0214     int print_unknown_as_addr = print_opts & EVSEL__PRINT_UNKNOWN_AS_ADDR;
0215 
0216     if (cursor != NULL) {
0217         printed += sample__fprintf_callchain(sample, left_alignment, print_opts,
0218                              cursor, bt_stop_list, fp);
0219     } else {
0220         printed += fprintf(fp, "%-*.*s", left_alignment, left_alignment, " ");
0221 
0222         if (print_ip)
0223             printed += fprintf(fp, "%16" PRIx64, sample->ip);
0224 
0225         if (print_sym) {
0226             printed += fprintf(fp, " ");
0227             if (print_symoffset) {
0228                 printed += __symbol__fprintf_symname_offs(al->sym, al,
0229                                       print_unknown_as_addr,
0230                                       true, fp);
0231             } else {
0232                 printed += __symbol__fprintf_symname(al->sym, al,
0233                                      print_unknown_as_addr, fp);
0234             }
0235         }
0236 
0237         if (print_dso) {
0238             printed += fprintf(fp, " (");
0239             printed += map__fprintf_dsoname(al->map, fp);
0240             printed += fprintf(fp, ")");
0241         }
0242 
0243         if (print_srcline)
0244             printed += map__fprintf_srcline(al->map, al->addr, "\n  ", fp);
0245     }
0246 
0247     return printed;
0248 }
0249 #endif /* PYTHON_PERF */