linux/tools/perf/util/evsel_fprintf.c
<<
>>
Prefs
   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
   9static 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
  27static 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
  32int 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        }
  93out:
  94        fputc('\n', fp);
  95        return ++printed;
  96}
  97
  98int 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");
 161next:
 162                        callchain_cursor_advance(cursor);
 163                }
 164        }
 165
 166        return printed;
 167}
 168
 169int 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}
 213