~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/perf/util/evsel_fprintf.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php