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        int print_arrow = print_opts & EVSEL__PRINT_CALLCHAIN_ARROW;
 112        int print_skip_ignored = print_opts & EVSEL__PRINT_SKIP_IGNORED;
 113        char s = print_oneline ? ' ' : '\t';
 114        bool first = true;
 115
 116        if (sample->callchain) {
 117                struct addr_location node_al;
 118
 119                callchain_cursor_commit(cursor);
 120
 121                while (1) {
 122                        u64 addr = 0;
 123
 124                        node = callchain_cursor_current(cursor);
 125                        if (!node)
 126                                break;
 127
 128                        if (node->sym && node->sym->ignore && print_skip_ignored)
 129                                goto next;
 130
 131                        printed += fprintf(fp, "%-*.*s", left_alignment, left_alignment, " ");
 132
 133                        if (print_arrow && !first)
 134                                printed += fprintf(fp, " <-");
 135
 136                        if (print_ip)
 137                                printed += fprintf(fp, "%c%16" PRIx64, s, node->ip);
 138
 139                        if (node->map)
 140                                addr = node->map->map_ip(node->map, node->ip);
 141
 142                        if (print_sym) {
 143                                printed += fprintf(fp, " ");
 144                                node_al.addr = addr;
 145                                node_al.map  = node->map;
 146
 147                                if (print_symoffset) {
 148                                        printed += __symbol__fprintf_symname_offs(node->sym, &node_al,
 149                                                                                  print_unknown_as_addr,
 150                                                                                  true, fp);
 151                                } else {
 152                                        printed += __symbol__fprintf_symname(node->sym, &node_al,
 153                                                                             print_unknown_as_addr, fp);
 154                                }
 155                        }
 156
 157                        if (print_dso) {
 158                                printed += fprintf(fp, " (");
 159                                printed += map__fprintf_dsoname(node->map, fp);
 160                                printed += fprintf(fp, ")");
 161                        }
 162
 163                        if (print_srcline)
 164                                printed += map__fprintf_srcline(node->map, addr, "\n  ", fp);
 165
 166                        if (!print_oneline)
 167                                printed += fprintf(fp, "\n");
 168
 169                        if (symbol_conf.bt_stop_list &&
 170                            node->sym &&
 171                            node->sym->name &&
 172                            strlist__has_entry(symbol_conf.bt_stop_list,
 173                                               node->sym->name)) {
 174                                break;
 175                        }
 176
 177                        first = false;
 178next:
 179                        callchain_cursor_advance(cursor);
 180                }
 181        }
 182
 183        return printed;
 184}
 185
 186int sample__fprintf_sym(struct perf_sample *sample, struct addr_location *al,
 187                        int left_alignment, unsigned int print_opts,
 188                        struct callchain_cursor *cursor, FILE *fp)
 189{
 190        int printed = 0;
 191        int print_ip = print_opts & EVSEL__PRINT_IP;
 192        int print_sym = print_opts & EVSEL__PRINT_SYM;
 193        int print_dso = print_opts & EVSEL__PRINT_DSO;
 194        int print_symoffset = print_opts & EVSEL__PRINT_SYMOFFSET;
 195        int print_srcline = print_opts & EVSEL__PRINT_SRCLINE;
 196        int print_unknown_as_addr = print_opts & EVSEL__PRINT_UNKNOWN_AS_ADDR;
 197
 198        if (cursor != NULL) {
 199                printed += sample__fprintf_callchain(sample, left_alignment,
 200                                                     print_opts, cursor, fp);
 201        } else {
 202                printed += fprintf(fp, "%-*.*s", left_alignment, left_alignment, " ");
 203
 204                if (print_ip)
 205                        printed += fprintf(fp, "%16" PRIx64, sample->ip);
 206
 207                if (print_sym) {
 208                        printed += fprintf(fp, " ");
 209                        if (print_symoffset) {
 210                                printed += __symbol__fprintf_symname_offs(al->sym, al,
 211                                                                          print_unknown_as_addr,
 212                                                                          true, fp);
 213                        } else {
 214                                printed += __symbol__fprintf_symname(al->sym, al,
 215                                                                     print_unknown_as_addr, fp);
 216                        }
 217                }
 218
 219                if (print_dso) {
 220                        printed += fprintf(fp, " (");
 221                        printed += map__fprintf_dsoname(al->map, fp);
 222                        printed += fprintf(fp, ")");
 223                }
 224
 225                if (print_srcline)
 226                        printed += map__fprintf_srcline(al->map, al->addr, "\n  ", fp);
 227        }
 228
 229        return printed;
 230}
 231