linux/tools/perf/util/evsel_fprintf.c
<<
>>
Prefs
   1#include <inttypes.h>
   2#include <stdio.h>
   3#include <stdbool.h>
   4#include <traceevent/event-parse.h>
   5#include "evsel.h"
   6#include "callchain.h"
   7#include "map.h"
   8#include "strlist.h"
   9#include "symbol.h"
  10#include "srcline.h"
  11
  12static int comma_fprintf(FILE *fp, bool *first, const char *fmt, ...)
  13{
  14        va_list args;
  15        int ret = 0;
  16
  17        if (!*first) {
  18                ret += fprintf(fp, ",");
  19        } else {
  20                ret += fprintf(fp, ":");
  21                *first = false;
  22        }
  23
  24        va_start(args, fmt);
  25        ret += vfprintf(fp, fmt, args);
  26        va_end(args);
  27        return ret;
  28}
  29
  30static int __print_attr__fprintf(FILE *fp, const char *name, const char *val, void *priv)
  31{
  32        return comma_fprintf(fp, (bool *)priv, " %s: %s", name, val);
  33}
  34
  35int perf_evsel__fprintf(struct perf_evsel *evsel,
  36                        struct perf_attr_details *details, FILE *fp)
  37{
  38        bool first = true;
  39        int printed = 0;
  40
  41        if (details->event_group) {
  42                struct perf_evsel *pos;
  43
  44                if (!perf_evsel__is_group_leader(evsel))
  45                        return 0;
  46
  47                if (evsel->nr_members > 1)
  48                        printed += fprintf(fp, "%s{", evsel->group_name ?: "");
  49
  50                printed += fprintf(fp, "%s", perf_evsel__name(evsel));
  51                for_each_group_member(pos, evsel)
  52                        printed += fprintf(fp, ",%s", perf_evsel__name(pos));
  53
  54                if (evsel->nr_members > 1)
  55                        printed += fprintf(fp, "}");
  56                goto out;
  57        }
  58
  59        printed += fprintf(fp, "%s", perf_evsel__name(evsel));
  60
  61        if (details->verbose) {
  62                printed += perf_event_attr__fprintf(fp, &evsel->attr,
  63                                                    __print_attr__fprintf, &first);
  64        } else if (details->freq) {
  65                const char *term = "sample_freq";
  66
  67                if (!evsel->attr.freq)
  68                        term = "sample_period";
  69
  70                printed += comma_fprintf(fp, &first, " %s=%" PRIu64,
  71                                         term, (u64)evsel->attr.sample_freq);
  72        }
  73
  74        if (details->trace_fields) {
  75                struct format_field *field;
  76
  77                if (evsel->attr.type != PERF_TYPE_TRACEPOINT) {
  78                        printed += comma_fprintf(fp, &first, " (not a tracepoint)");
  79                        goto out;
  80                }
  81
  82                field = evsel->tp_format->format.fields;
  83                if (field == NULL) {
  84                        printed += comma_fprintf(fp, &first, " (no trace field)");
  85                        goto out;
  86                }
  87
  88                printed += comma_fprintf(fp, &first, " trace_fields: %s", field->name);
  89
  90                field = field->next;
  91                while (field) {
  92                        printed += comma_fprintf(fp, &first, "%s", field->name);
  93                        field = field->next;
  94                }
  95        }
  96out:
  97        fputc('\n', fp);
  98        return ++printed;
  99}
 100
 101int sample__fprintf_callchain(struct perf_sample *sample, int left_alignment,
 102                              unsigned int print_opts, struct callchain_cursor *cursor,
 103                              FILE *fp)
 104{
 105        int printed = 0;
 106        struct callchain_cursor_node *node;
 107        int print_ip = print_opts & EVSEL__PRINT_IP;
 108        int print_sym = print_opts & EVSEL__PRINT_SYM;
 109        int print_dso = print_opts & EVSEL__PRINT_DSO;
 110        int print_symoffset = print_opts & EVSEL__PRINT_SYMOFFSET;
 111        int print_oneline = print_opts & EVSEL__PRINT_ONELINE;
 112        int print_srcline = print_opts & EVSEL__PRINT_SRCLINE;
 113        int print_unknown_as_addr = print_opts & EVSEL__PRINT_UNKNOWN_AS_ADDR;
 114        int print_arrow = print_opts & EVSEL__PRINT_CALLCHAIN_ARROW;
 115        int print_skip_ignored = print_opts & EVSEL__PRINT_SKIP_IGNORED;
 116        char s = print_oneline ? ' ' : '\t';
 117        bool first = true;
 118
 119        if (sample->callchain) {
 120                struct addr_location node_al;
 121
 122                callchain_cursor_commit(cursor);
 123
 124                while (1) {
 125                        u64 addr = 0;
 126
 127                        node = callchain_cursor_current(cursor);
 128                        if (!node)
 129                                break;
 130
 131                        if (node->sym && node->sym->ignore && print_skip_ignored)
 132                                goto next;
 133
 134                        printed += fprintf(fp, "%-*.*s", left_alignment, left_alignment, " ");
 135
 136                        if (print_arrow && !first)
 137                                printed += fprintf(fp, " <-");
 138
 139                        if (print_ip)
 140                                printed += fprintf(fp, "%c%16" PRIx64, s, node->ip);
 141
 142                        if (node->map)
 143                                addr = node->map->map_ip(node->map, node->ip);
 144
 145                        if (print_sym) {
 146                                printed += fprintf(fp, " ");
 147                                node_al.addr = addr;
 148                                node_al.map  = node->map;
 149
 150                                if (print_symoffset) {
 151                                        printed += __symbol__fprintf_symname_offs(node->sym, &node_al,
 152                                                                                  print_unknown_as_addr,
 153                                                                                  true, fp);
 154                                } else {
 155                                        printed += __symbol__fprintf_symname(node->sym, &node_al,
 156                                                                             print_unknown_as_addr, fp);
 157                                }
 158                        }
 159
 160                        if (print_dso) {
 161                                printed += fprintf(fp, " (");
 162                                printed += map__fprintf_dsoname(node->map, fp);
 163                                printed += fprintf(fp, ")");
 164                        }
 165
 166                        if (print_srcline)
 167                                printed += map__fprintf_srcline(node->map, addr, "\n  ", fp);
 168
 169                        if (!print_oneline)
 170                                printed += fprintf(fp, "\n");
 171
 172                        if (symbol_conf.inline_name && node->map) {
 173                                struct inline_node *inode;
 174
 175                                addr = map__rip_2objdump(node->map, node->ip),
 176                                inode = dso__parse_addr_inlines(node->map->dso, addr);
 177
 178                                if (inode) {
 179                                        struct inline_list *ilist;
 180
 181                                        list_for_each_entry(ilist, &inode->val, list) {
 182                                                if (print_arrow)
 183                                                        printed += fprintf(fp, " <-");
 184
 185                                                /* IP is same, just skip it */
 186                                                if (print_ip)
 187                                                        printed += fprintf(fp, "%c%16s",
 188                                                                           s, "");
 189                                                if (print_sym)
 190                                                        printed += fprintf(fp, " %s",
 191                                                                           ilist->funcname);
 192                                                if (print_srcline)
 193                                                        printed += fprintf(fp, "\n  %s:%d",
 194                                                                           ilist->filename,
 195                                                                           ilist->line_nr);
 196                                                if (!print_oneline)
 197                                                        printed += fprintf(fp, "\n");
 198                                        }
 199
 200                                        inline_node__delete(inode);
 201                                }
 202                        }
 203
 204                        if (symbol_conf.bt_stop_list &&
 205                            node->sym &&
 206                            strlist__has_entry(symbol_conf.bt_stop_list,
 207                                               node->sym->name)) {
 208                                break;
 209                        }
 210
 211                        first = false;
 212next:
 213                        callchain_cursor_advance(cursor);
 214                }
 215        }
 216
 217        return printed;
 218}
 219
 220int sample__fprintf_sym(struct perf_sample *sample, struct addr_location *al,
 221                        int left_alignment, unsigned int print_opts,
 222                        struct callchain_cursor *cursor, FILE *fp)
 223{
 224        int printed = 0;
 225        int print_ip = print_opts & EVSEL__PRINT_IP;
 226        int print_sym = print_opts & EVSEL__PRINT_SYM;
 227        int print_dso = print_opts & EVSEL__PRINT_DSO;
 228        int print_symoffset = print_opts & EVSEL__PRINT_SYMOFFSET;
 229        int print_srcline = print_opts & EVSEL__PRINT_SRCLINE;
 230        int print_unknown_as_addr = print_opts & EVSEL__PRINT_UNKNOWN_AS_ADDR;
 231
 232        if (cursor != NULL) {
 233                printed += sample__fprintf_callchain(sample, left_alignment,
 234                                                     print_opts, cursor, fp);
 235        } else {
 236                printed += fprintf(fp, "%-*.*s", left_alignment, left_alignment, " ");
 237
 238                if (print_ip)
 239                        printed += fprintf(fp, "%16" PRIx64, sample->ip);
 240
 241                if (print_sym) {
 242                        printed += fprintf(fp, " ");
 243                        if (print_symoffset) {
 244                                printed += __symbol__fprintf_symname_offs(al->sym, al,
 245                                                                          print_unknown_as_addr,
 246                                                                          true, fp);
 247                        } else {
 248                                printed += __symbol__fprintf_symname(al->sym, al,
 249                                                                     print_unknown_as_addr, fp);
 250                        }
 251                }
 252
 253                if (print_dso) {
 254                        printed += fprintf(fp, " (");
 255                        printed += map__fprintf_dsoname(al->map, fp);
 256                        printed += fprintf(fp, ")");
 257                }
 258
 259                if (print_srcline)
 260                        printed += map__fprintf_srcline(al->map, al->addr, "\n  ", fp);
 261        }
 262
 263        return printed;
 264}
 265