Linux Perf
evsel_fprintf.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0
2 #include <inttypes.h>
3 #include <stdio.h>
4 #include <stdbool.h>
5 #include <traceevent/event-parse.h>
6 #include "evsel.h"
7 #include "callchain.h"
8 #include "map.h"
9 #include "strlist.h"
10 #include "symbol.h"
11 #include "srcline.h"
12 
13 static int comma_fprintf(FILE *fp, bool *first, const char *fmt, ...)
14 {
15  va_list args;
16  int ret = 0;
17 
18  if (!*first) {
19  ret += fprintf(fp, ",");
20  } else {
21  ret += fprintf(fp, ":");
22  *first = false;
23  }
24 
25  va_start(args, fmt);
26  ret += vfprintf(fp, fmt, args);
27  va_end(args);
28  return ret;
29 }
30 
31 static int __print_attr__fprintf(FILE *fp, const char *name, const char *val, void *priv)
32 {
33  return comma_fprintf(fp, (bool *)priv, " %s: %s", name, val);
34 }
35 
36 int perf_evsel__fprintf(struct perf_evsel *evsel,
37  struct perf_attr_details *details, FILE *fp)
38 {
39  bool first = true;
40  int printed = 0;
41 
42  if (details->event_group) {
43  struct perf_evsel *pos;
44 
45  if (!perf_evsel__is_group_leader(evsel))
46  return 0;
47 
48  if (evsel->nr_members > 1)
49  printed += fprintf(fp, "%s{", evsel->group_name ?: "");
50 
51  printed += fprintf(fp, "%s", perf_evsel__name(evsel));
52  for_each_group_member(pos, evsel)
53  printed += fprintf(fp, ",%s", perf_evsel__name(pos));
54 
55  if (evsel->nr_members > 1)
56  printed += fprintf(fp, "}");
57  goto out;
58  }
59 
60  printed += fprintf(fp, "%s", perf_evsel__name(evsel));
61 
62  if (details->verbose) {
63  printed += perf_event_attr__fprintf(fp, &evsel->attr,
64  __print_attr__fprintf, &first);
65  } else if (details->freq) {
66  const char *term = "sample_freq";
67 
68  if (!evsel->attr.freq)
69  term = "sample_period";
70 
71  printed += comma_fprintf(fp, &first, " %s=%" PRIu64,
72  term, (u64)evsel->attr.sample_freq);
73  }
74 
75  if (details->trace_fields) {
76  struct format_field *field;
77 
78  if (evsel->attr.type != PERF_TYPE_TRACEPOINT) {
79  printed += comma_fprintf(fp, &first, " (not a tracepoint)");
80  goto out;
81  }
82 
83  field = evsel->tp_format->format.fields;
84  if (field == NULL) {
85  printed += comma_fprintf(fp, &first, " (no trace field)");
86  goto out;
87  }
88 
89  printed += comma_fprintf(fp, &first, " trace_fields: %s", field->name);
90 
91  field = field->next;
92  while (field) {
93  printed += comma_fprintf(fp, &first, "%s", field->name);
94  field = field->next;
95  }
96  }
97 out:
98  fputc('\n', fp);
99  return ++printed;
100 }
101 
102 int sample__fprintf_callchain(struct perf_sample *sample, int left_alignment,
103  unsigned int print_opts, struct callchain_cursor *cursor,
104  FILE *fp)
105 {
106  int printed = 0;
107  struct callchain_cursor_node *node;
108  int print_ip = print_opts & EVSEL__PRINT_IP;
109  int print_sym = print_opts & EVSEL__PRINT_SYM;
110  int print_dso = print_opts & EVSEL__PRINT_DSO;
111  int print_symoffset = print_opts & EVSEL__PRINT_SYMOFFSET;
112  int print_oneline = print_opts & EVSEL__PRINT_ONELINE;
113  int print_srcline = print_opts & EVSEL__PRINT_SRCLINE;
114  int print_unknown_as_addr = print_opts & EVSEL__PRINT_UNKNOWN_AS_ADDR;
115  int print_arrow = print_opts & EVSEL__PRINT_CALLCHAIN_ARROW;
116  int print_skip_ignored = print_opts & EVSEL__PRINT_SKIP_IGNORED;
117  char s = print_oneline ? ' ' : '\t';
118  bool first = true;
119 
120  if (sample->callchain) {
121  struct addr_location node_al;
122 
123  callchain_cursor_commit(cursor);
124 
125  while (1) {
126  u64 addr = 0;
127 
128  node = callchain_cursor_current(cursor);
129  if (!node)
130  break;
131 
132  if (node->sym && node->sym->ignore && print_skip_ignored)
133  goto next;
134 
135  printed += fprintf(fp, "%-*.*s", left_alignment, left_alignment, " ");
136 
137  if (print_arrow && !first)
138  printed += fprintf(fp, " <-");
139 
140  if (print_ip)
141  printed += fprintf(fp, "%c%16" PRIx64, s, node->ip);
142 
143  if (node->map)
144  addr = node->map->map_ip(node->map, node->ip);
145 
146  if (print_sym) {
147  printed += fprintf(fp, " ");
148  node_al.addr = addr;
149  node_al.map = node->map;
150 
151  if (print_symoffset) {
152  printed += __symbol__fprintf_symname_offs(node->sym, &node_al,
153  print_unknown_as_addr,
154  true, fp);
155  } else {
156  printed += __symbol__fprintf_symname(node->sym, &node_al,
157  print_unknown_as_addr, fp);
158  }
159  }
160 
161  if (print_dso && (!node->sym || !node->sym->inlined)) {
162  printed += fprintf(fp, " (");
163  printed += map__fprintf_dsoname(node->map, fp);
164  printed += fprintf(fp, ")");
165  }
166 
167  if (print_srcline)
168  printed += map__fprintf_srcline(node->map, addr, "\n ", fp);
169 
170  if (node->sym && node->sym->inlined)
171  printed += fprintf(fp, " (inlined)");
172 
173  if (!print_oneline)
174  printed += fprintf(fp, "\n");
175 
177  node->sym &&
179  node->sym->name)) {
180  break;
181  }
182 
183  first = false;
184 next:
185  callchain_cursor_advance(cursor);
186  }
187  }
188 
189  return printed;
190 }
191 
193  int left_alignment, unsigned int print_opts,
194  struct callchain_cursor *cursor, FILE *fp)
195 {
196  int printed = 0;
197  int print_ip = print_opts & EVSEL__PRINT_IP;
198  int print_sym = print_opts & EVSEL__PRINT_SYM;
199  int print_dso = print_opts & EVSEL__PRINT_DSO;
200  int print_symoffset = print_opts & EVSEL__PRINT_SYMOFFSET;
201  int print_srcline = print_opts & EVSEL__PRINT_SRCLINE;
202  int print_unknown_as_addr = print_opts & EVSEL__PRINT_UNKNOWN_AS_ADDR;
203 
204  if (cursor != NULL) {
205  printed += sample__fprintf_callchain(sample, left_alignment,
206  print_opts, cursor, fp);
207  } else {
208  printed += fprintf(fp, "%-*.*s", left_alignment, left_alignment, " ");
209 
210  if (print_ip)
211  printed += fprintf(fp, "%16" PRIx64, sample->ip);
212 
213  if (print_sym) {
214  printed += fprintf(fp, " ");
215  if (print_symoffset) {
216  printed += __symbol__fprintf_symname_offs(al->sym, al,
217  print_unknown_as_addr,
218  true, fp);
219  } else {
220  printed += __symbol__fprintf_symname(al->sym, al,
221  print_unknown_as_addr, fp);
222  }
223  }
224 
225  if (print_dso) {
226  printed += fprintf(fp, " (");
227  printed += map__fprintf_dsoname(al->map, fp);
228  printed += fprintf(fp, ")");
229  }
230 
231  if (print_srcline)
232  printed += map__fprintf_srcline(al->map, al->addr, "\n ", fp);
233  }
234 
235  return printed;
236 }
u64(* map_ip)(struct map *, u64)
Definition: map.h:41
Definition: mem2node.c:7
bool event_group
Definition: evsel.h:414
#define EVSEL__PRINT_ONELINE
Definition: evsel.h:426
int perf_evsel__fprintf(struct perf_evsel *evsel, struct perf_attr_details *details, FILE *fp)
Definition: evsel_fprintf.c:36
bool trace_fields
Definition: evsel.h:416
#define EVSEL__PRINT_SYMOFFSET
Definition: evsel.h:425
#define EVSEL__PRINT_UNKNOWN_AS_ADDR
Definition: evsel.h:428
struct ip_callchain * callchain
Definition: event.h:211
struct symbol * sym
Definition: callchain.h:140
int perf_event_attr__fprintf(FILE *fp, struct perf_event_attr *attr, attr__fprintf_f attr__fprintf, void *priv)
Definition: evsel.c:1571
static int term(yyscan_t scanner, int type)
char * group_name
Definition: evsel.h:137
static void callchain_cursor_commit(struct callchain_cursor *cursor)
Definition: callchain.h:212
u64 ip
Definition: event.h:192
int map__fprintf_srcline(struct map *map, u64 addr, const char *prefix, FILE *fp)
Definition: map.c:425
#define EVSEL__PRINT_SRCLINE
Definition: evsel.h:427
#define EVSEL__PRINT_CALLCHAIN_ARROW
Definition: evsel.h:429
struct map * map
Definition: symbol.h:210
const char * name
const char * fmt
Definition: dso.c:193
static void callchain_cursor_advance(struct callchain_cursor *cursor)
Definition: callchain.h:228
int sample__fprintf_sym(struct perf_sample *sample, struct addr_location *al, int left_alignment, unsigned int print_opts, struct callchain_cursor *cursor, FILE *fp)
static int __print_attr__fprintf(FILE *fp, const char *name, const char *val, void *priv)
Definition: evsel_fprintf.c:31
struct event_format * tp_format
Definition: evsel.h:105
int sample__fprintf_callchain(struct perf_sample *sample, int left_alignment, unsigned int print_opts, struct callchain_cursor *cursor, FILE *fp)
Definition: jevents.c:169
char name[0]
Definition: symbol.h:66
struct symbol * sym
Definition: symbol.h:211
struct map * map
Definition: callchain.h:139
size_t __symbol__fprintf_symname(const struct symbol *sym, const struct addr_location *al, bool unknown_as_addr, FILE *fp)
const char * perf_evsel__name(struct perf_evsel *evsel)
Definition: evsel.c:577
#define EVSEL__PRINT_SKIP_IGNORED
Definition: evsel.h:430
u8 ignore
Definition: symbol.h:63
#define for_each_group_member(_evsel, _leader)
Definition: evsel.h:452
size_t map__fprintf_dsoname(struct map *map, FILE *fp)
Definition: map.c:404
#define EVSEL__PRINT_IP
Definition: evsel.h:422
int nr_members
Definition: evsel.h:133
#define EVSEL__PRINT_SYM
Definition: evsel.h:423
static bool perf_evsel__is_group_leader(const struct perf_evsel *evsel)
Definition: evsel.h:380
#define EVSEL__PRINT_DSO
Definition: evsel.h:424
u8 inlined
Definition: symbol.h:64
size_t __symbol__fprintf_symname_offs(const struct symbol *sym, const struct addr_location *al, bool unknown_as_addr, bool print_offsets, FILE *fp)
struct strlist * bt_stop_list
Definition: symbol.h:138
static int comma_fprintf(FILE *fp, bool *first, const char *fmt,...)
Definition: evsel_fprintf.c:13
static bool strlist__has_entry(struct strlist *slist, const char *entry)
Definition: strlist.h:42
struct perf_event_attr attr
Definition: evsel.h:93
static struct callchain_cursor_node * callchain_cursor_current(struct callchain_cursor *cursor)
Definition: callchain.h:220