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                        printed += fprintf(fp, "%-*.*s", left_alignment, left_alignment, " ");
 126
 127                        if (print_ip)
 128                                printed += fprintf(fp, "%c%16" PRIx64, s, node->ip);
 129
 130                        if (node->map)
 131                                addr = node->map->map_ip(node->map, node->ip);
 132
 133                        if (print_sym) {
 134                                printed += fprintf(fp, " ");
 135                                node_al.addr = addr;
 136                                node_al.map  = node->map;
 137
 138                                if (print_symoffset) {
 139                                        printed += __symbol__fprintf_symname_offs(node->sym, &node_al,
 140                                                                                  print_unknown_as_addr, fp);
 141                                } else {
 142                                        printed += __symbol__fprintf_symname(node->sym, &node_al,
 143                                                                             print_unknown_as_addr, fp);
 144                                }
 145                        }
 146
 147                        if (print_dso) {
 148                                printed += fprintf(fp, " (");
 149                                printed += map__fprintf_dsoname(node->map, fp);
 150                                printed += fprintf(fp, ")");
 151                        }
 152
 153                        if (print_srcline)
 154                                printed += map__fprintf_srcline(node->map, addr, "\n  ", fp);
 155
 156                        if (!print_oneline)
 157                                printed += fprintf(fp, "\n");
 158
 159                        callchain_cursor_advance(cursor);
 160                }
 161        }
 162
 163        return printed;
 164}
 165
 166int sample__fprintf_sym(struct perf_sample *sample, struct addr_location *al,
 167                        int left_alignment, unsigned int print_opts,
 168                        struct callchain_cursor *cursor, FILE *fp)
 169{
 170        int printed = 0;
 171        int print_ip = print_opts & EVSEL__PRINT_IP;
 172        int print_sym = print_opts & EVSEL__PRINT_SYM;
 173        int print_dso = print_opts & EVSEL__PRINT_DSO;
 174        int print_symoffset = print_opts & EVSEL__PRINT_SYMOFFSET;
 175        int print_srcline = print_opts & EVSEL__PRINT_SRCLINE;
 176        int print_unknown_as_addr = print_opts & EVSEL__PRINT_UNKNOWN_AS_ADDR;
 177
 178        if (cursor != NULL) {
 179                printed += sample__fprintf_callchain(sample, left_alignment,
 180                                                     print_opts, cursor, fp);
 181        } else {
 182                printed += fprintf(fp, "%-*.*s", left_alignment, left_alignment, " ");
 183
 184                if (print_ip)
 185                        printed += fprintf(fp, "%16" PRIx64, sample->ip);
 186
 187                if (print_sym) {
 188                        printed += fprintf(fp, " ");
 189                        if (print_symoffset) {
 190                                printed += __symbol__fprintf_symname_offs(al->sym, al,
 191                                                                          print_unknown_as_addr, fp);
 192                        } else {
 193                                printed += __symbol__fprintf_symname(al->sym, al,
 194                                                                     print_unknown_as_addr, fp);
 195                        }
 196                }
 197
 198                if (print_dso) {
 199                        printed += fprintf(fp, " (");
 200                        printed += map__fprintf_dsoname(al->map, fp);
 201                        printed += fprintf(fp, ")");
 202                }
 203
 204                if (print_srcline)
 205                        printed += map__fprintf_srcline(al->map, al->addr, "\n  ", fp);
 206        }
 207
 208        return printed;
 209}
 210