1 // SPDX-License-Identifier: GPL-2.0
5 #include "util/evlist.h"
7 #include "util/evsel_fprintf.h"
8 #include "util/event.h"
16 #ifdef HAVE_LIBTRACEEVENT
17 #include <event-parse.h>
20 static int comma_fprintf(FILE *fp
, bool *first
, const char *fmt
, ...)
26 ret
+= fprintf(fp
, ",");
28 ret
+= fprintf(fp
, ":");
33 ret
+= vfprintf(fp
, fmt
, args
);
38 static int __print_attr__fprintf(FILE *fp
, const char *name
, const char *val
, void *priv
)
40 return comma_fprintf(fp
, (bool *)priv
, " %s: %s", name
, val
);
43 int evsel__fprintf(struct evsel
*evsel
, struct perf_attr_details
*details
, FILE *fp
)
48 if (details
->event_group
) {
51 if (!evsel__is_group_leader(evsel
))
54 if (evsel
->core
.nr_members
> 1)
55 printed
+= fprintf(fp
, "%s{", evsel
->group_name
?: "");
57 printed
+= fprintf(fp
, "%s", evsel__name(evsel
));
58 for_each_group_member(pos
, evsel
)
59 printed
+= fprintf(fp
, ",%s", evsel__name(pos
));
61 if (evsel
->core
.nr_members
> 1)
62 printed
+= fprintf(fp
, "}");
66 printed
+= fprintf(fp
, "%s", evsel__name(evsel
));
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";
74 if (!evsel
->core
.attr
.freq
)
75 term
= "sample_period";
77 printed
+= comma_fprintf(fp
, &first
, " %s=%" PRIu64
,
78 term
, (u64
)evsel
->core
.attr
.sample_freq
);
81 #ifdef HAVE_LIBTRACEEVENT
82 if (details
->trace_fields
) {
83 struct tep_format_field
*field
;
85 if (evsel
->core
.attr
.type
!= PERF_TYPE_TRACEPOINT
) {
86 printed
+= comma_fprintf(fp
, &first
, " (not a tracepoint)");
90 field
= evsel
->tp_format
->format
.fields
;
92 printed
+= comma_fprintf(fp
, &first
, " (no trace field)");
96 printed
+= comma_fprintf(fp
, &first
, " trace_fields: %s", field
->name
);
100 printed
+= comma_fprintf(fp
, &first
, "%s", field
->name
);
110 int sample__fprintf_callchain(struct perf_sample
*sample
, int left_alignment
,
111 unsigned int print_opts
, struct callchain_cursor
*cursor
,
112 struct strlist
*bt_stop_list
, FILE *fp
)
115 struct callchain_cursor_node
*node
;
116 int print_ip
= print_opts
& EVSEL__PRINT_IP
;
117 int print_sym
= print_opts
& EVSEL__PRINT_SYM
;
118 int print_dso
= print_opts
& EVSEL__PRINT_DSO
;
119 int print_dsoff
= print_opts
& EVSEL__PRINT_DSOFF
;
120 int print_symoffset
= print_opts
& EVSEL__PRINT_SYMOFFSET
;
121 int print_oneline
= print_opts
& EVSEL__PRINT_ONELINE
;
122 int print_srcline
= print_opts
& EVSEL__PRINT_SRCLINE
;
123 int print_unknown_as_addr
= print_opts
& EVSEL__PRINT_UNKNOWN_AS_ADDR
;
124 int print_arrow
= print_opts
& EVSEL__PRINT_CALLCHAIN_ARROW
;
125 int print_skip_ignored
= print_opts
& EVSEL__PRINT_SKIP_IGNORED
;
126 char s
= print_oneline
? ' ' : '\t';
130 return fprintf(fp
, "<not enough memory for the callchain cursor>%s", print_oneline
? "" : "\n");
132 if (sample
->callchain
) {
133 callchain_cursor_commit(cursor
);
140 node
= callchain_cursor_current(cursor
);
147 if (sym
&& sym
->ignore
&& print_skip_ignored
)
150 printed
+= fprintf(fp
, "%-*.*s", left_alignment
, left_alignment
, " ");
152 if (print_arrow
&& !first
)
153 printed
+= fprintf(fp
, " <-");
156 addr
= map__map_ip(map
, node
->ip
);
159 printed
+= fprintf(fp
, "%c%16" PRIx64
, s
, node
->ip
);
162 struct addr_location node_al
;
164 addr_location__init(&node_al
);
165 printed
+= fprintf(fp
, " ");
167 node_al
.map
= map__get(map
);
169 if (print_symoffset
) {
170 printed
+= __symbol__fprintf_symname_offs(sym
, &node_al
,
171 print_unknown_as_addr
,
174 printed
+= __symbol__fprintf_symname(sym
, &node_al
,
175 print_unknown_as_addr
, fp
);
177 addr_location__exit(&node_al
);
180 if (print_dso
&& (!sym
|| !sym
->inlined
))
181 printed
+= map__fprintf_dsoname_dsoff(map
, print_dsoff
, addr
, fp
);
184 printed
+= map__fprintf_srcline(map
, addr
, "\n ", fp
);
186 if (sym
&& sym
->inlined
)
187 printed
+= fprintf(fp
, " (inlined)");
190 printed
+= fprintf(fp
, "\n");
192 /* Add srccode here too? */
193 if (bt_stop_list
&& sym
&&
194 strlist__has_entry(bt_stop_list
, sym
->name
)) {
200 callchain_cursor_advance(cursor
);
207 int sample__fprintf_sym(struct perf_sample
*sample
, struct addr_location
*al
,
208 int left_alignment
, unsigned int print_opts
,
209 struct callchain_cursor
*cursor
, struct strlist
*bt_stop_list
, FILE *fp
)
212 int print_ip
= print_opts
& EVSEL__PRINT_IP
;
213 int print_sym
= print_opts
& EVSEL__PRINT_SYM
;
214 int print_dso
= print_opts
& EVSEL__PRINT_DSO
;
215 int print_dsoff
= print_opts
& EVSEL__PRINT_DSOFF
;
216 int print_symoffset
= print_opts
& EVSEL__PRINT_SYMOFFSET
;
217 int print_srcline
= print_opts
& EVSEL__PRINT_SRCLINE
;
218 int print_unknown_as_addr
= print_opts
& EVSEL__PRINT_UNKNOWN_AS_ADDR
;
220 if (cursor
!= NULL
) {
221 printed
+= sample__fprintf_callchain(sample
, left_alignment
, print_opts
,
222 cursor
, bt_stop_list
, fp
);
224 printed
+= fprintf(fp
, "%-*.*s", left_alignment
, left_alignment
, " ");
227 printed
+= fprintf(fp
, "%16" PRIx64
, sample
->ip
);
230 printed
+= fprintf(fp
, " ");
231 if (print_symoffset
) {
232 printed
+= __symbol__fprintf_symname_offs(al
->sym
, al
,
233 print_unknown_as_addr
,
236 printed
+= __symbol__fprintf_symname(al
->sym
, al
,
237 print_unknown_as_addr
, fp
);
242 printed
+= map__fprintf_dsoname_dsoff(al
->map
, print_dsoff
, al
->addr
, fp
);
245 printed
+= map__fprintf_srcline(al
->map
, al
->addr
, "\n ", fp
);