xref: /linux/tools/perf/builtin-list.c (revision 021bc4b9)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * builtin-list.c
4  *
5  * Builtin list command: list all event types
6  *
7  * Copyright (C) 2009, Thomas Gleixner <tglx@linutronix.de>
8  * Copyright (C) 2008-2009, Red Hat Inc, Ingo Molnar <mingo@redhat.com>
9  * Copyright (C) 2011, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com>
10  */
11 #include "builtin.h"
12 
13 #include "util/print-events.h"
14 #include "util/pmus.h"
15 #include "util/pmu.h"
16 #include "util/debug.h"
17 #include "util/metricgroup.h"
18 #include "util/pfm.h"
19 #include "util/string2.h"
20 #include "util/strlist.h"
21 #include "util/strbuf.h"
22 #include <subcmd/pager.h>
23 #include <subcmd/parse-options.h>
24 #include <linux/zalloc.h>
25 #include <stdarg.h>
26 #include <stdio.h>
27 
28 /**
29  * struct print_state - State and configuration passed to the default_print
30  * functions.
31  */
32 struct print_state {
33 	/** @fp: File to write output to. */
34 	FILE *fp;
35 	/**
36 	 * @pmu_glob: Optionally restrict PMU and metric matching to PMU or
37 	 * debugfs subsystem name.
38 	 */
39 	char *pmu_glob;
40 	/** @event_glob: Optional pattern matching glob. */
41 	char *event_glob;
42 	/** @name_only: Print event or metric names only. */
43 	bool name_only;
44 	/** @desc: Print the event or metric description. */
45 	bool desc;
46 	/** @long_desc: Print longer event or metric description. */
47 	bool long_desc;
48 	/** @deprecated: Print deprecated events or metrics. */
49 	bool deprecated;
50 	/**
51 	 * @detailed: Print extra information on the perf event such as names
52 	 * and expressions used internally by events.
53 	 */
54 	bool detailed;
55 	/** @metrics: Controls printing of metric and metric groups. */
56 	bool metrics;
57 	/** @metricgroups: Controls printing of metric and metric groups. */
58 	bool metricgroups;
59 	/** @last_topic: The last printed event topic. */
60 	char *last_topic;
61 	/** @last_metricgroups: The last printed metric group. */
62 	char *last_metricgroups;
63 	/** @visited_metrics: Metrics that are printed to avoid duplicates. */
64 	struct strlist *visited_metrics;
65 };
66 
67 static void default_print_start(void *ps)
68 {
69 	struct print_state *print_state = ps;
70 
71 	if (!print_state->name_only && pager_in_use()) {
72 		fprintf(print_state->fp,
73 			"\nList of pre-defined events (to be used in -e or -M):\n\n");
74 	}
75 }
76 
77 static void default_print_end(void *print_state __maybe_unused) {}
78 
79 static void wordwrap(FILE *fp, const char *s, int start, int max, int corr)
80 {
81 	int column = start;
82 	int n;
83 	bool saw_newline = false;
84 
85 	while (*s) {
86 		int wlen = strcspn(s, " \t\n");
87 
88 		if ((column + wlen >= max && column > start) || saw_newline) {
89 			fprintf(fp, "\n%*s", start, "");
90 			column = start + corr;
91 		}
92 		n = fprintf(fp, "%s%.*s", column > start ? " " : "", wlen, s);
93 		if (n <= 0)
94 			break;
95 		saw_newline = s[wlen] == '\n';
96 		s += wlen;
97 		column += n;
98 		s = skip_spaces(s);
99 	}
100 }
101 
102 static void default_print_event(void *ps, const char *pmu_name, const char *topic,
103 				const char *event_name, const char *event_alias,
104 				const char *scale_unit __maybe_unused,
105 				bool deprecated, const char *event_type_desc,
106 				const char *desc, const char *long_desc,
107 				const char *encoding_desc)
108 {
109 	struct print_state *print_state = ps;
110 	int pos;
111 	FILE *fp = print_state->fp;
112 
113 	if (deprecated && !print_state->deprecated)
114 		return;
115 
116 	if (print_state->pmu_glob && pmu_name && !strglobmatch(pmu_name, print_state->pmu_glob))
117 		return;
118 
119 	if (print_state->event_glob &&
120 	    (!event_name || !strglobmatch(event_name, print_state->event_glob)) &&
121 	    (!event_alias || !strglobmatch(event_alias, print_state->event_glob)) &&
122 	    (!topic || !strglobmatch_nocase(topic, print_state->event_glob)))
123 		return;
124 
125 	if (print_state->name_only) {
126 		if (event_alias && strlen(event_alias))
127 			fprintf(fp, "%s ", event_alias);
128 		else
129 			fprintf(fp, "%s ", event_name);
130 		return;
131 	}
132 
133 	if (strcmp(print_state->last_topic, topic ?: "")) {
134 		if (topic)
135 			fprintf(fp, "\n%s:\n", topic);
136 		zfree(&print_state->last_topic);
137 		print_state->last_topic = strdup(topic ?: "");
138 	}
139 
140 	if (event_alias && strlen(event_alias))
141 		pos = fprintf(fp, "  %s OR %s", event_name, event_alias);
142 	else
143 		pos = fprintf(fp, "  %s", event_name);
144 
145 	if (!topic && event_type_desc) {
146 		for (; pos < 53; pos++)
147 			fputc(' ', fp);
148 		fprintf(fp, "[%s]\n", event_type_desc);
149 	} else
150 		fputc('\n', fp);
151 
152 	if (desc && print_state->desc) {
153 		char *desc_with_unit = NULL;
154 		int desc_len = -1;
155 
156 		if (pmu_name && strcmp(pmu_name, "default_core")) {
157 			desc_len = strlen(desc);
158 			desc_len = asprintf(&desc_with_unit,
159 					    desc[desc_len - 1] != '.'
160 					      ? "%s. Unit: %s" : "%s Unit: %s",
161 					    desc, pmu_name);
162 		}
163 		fprintf(fp, "%*s", 8, "[");
164 		wordwrap(fp, desc_len > 0 ? desc_with_unit : desc, 8, pager_get_columns(), 0);
165 		fprintf(fp, "]\n");
166 		free(desc_with_unit);
167 	}
168 	long_desc = long_desc ?: desc;
169 	if (long_desc && print_state->long_desc) {
170 		fprintf(fp, "%*s", 8, "[");
171 		wordwrap(fp, long_desc, 8, pager_get_columns(), 0);
172 		fprintf(fp, "]\n");
173 	}
174 
175 	if (print_state->detailed && encoding_desc) {
176 		fprintf(fp, "%*s", 8, "");
177 		wordwrap(fp, encoding_desc, 8, pager_get_columns(), 0);
178 		fputc('\n', fp);
179 	}
180 }
181 
182 static void default_print_metric(void *ps,
183 				const char *group,
184 				const char *name,
185 				const char *desc,
186 				const char *long_desc,
187 				const char *expr,
188 				const char *threshold,
189 				const char *unit __maybe_unused)
190 {
191 	struct print_state *print_state = ps;
192 	FILE *fp = print_state->fp;
193 
194 	if (print_state->event_glob &&
195 	    (!print_state->metrics || !name || !strglobmatch(name, print_state->event_glob)) &&
196 	    (!print_state->metricgroups || !group || !strglobmatch(group, print_state->event_glob)))
197 		return;
198 
199 	if (!print_state->name_only && !print_state->last_metricgroups) {
200 		if (print_state->metricgroups) {
201 			fprintf(fp, "\nMetric Groups:\n");
202 			if (!print_state->metrics)
203 				fputc('\n', fp);
204 		} else {
205 			fprintf(fp, "\nMetrics:\n\n");
206 		}
207 	}
208 	if (!print_state->last_metricgroups ||
209 	    strcmp(print_state->last_metricgroups, group ?: "")) {
210 		if (group && print_state->metricgroups) {
211 			if (print_state->name_only)
212 				fprintf(fp, "%s ", group);
213 			else if (print_state->metrics) {
214 				const char *gdesc = describe_metricgroup(group);
215 
216 				if (gdesc)
217 					fprintf(fp, "\n%s: [%s]\n", group, gdesc);
218 				else
219 					fprintf(fp, "\n%s:\n", group);
220 			} else
221 				fprintf(fp, "%s\n", group);
222 		}
223 		zfree(&print_state->last_metricgroups);
224 		print_state->last_metricgroups = strdup(group ?: "");
225 	}
226 	if (!print_state->metrics)
227 		return;
228 
229 	if (print_state->name_only) {
230 		if (print_state->metrics &&
231 		    !strlist__has_entry(print_state->visited_metrics, name)) {
232 			fprintf(fp, "%s ", name);
233 			strlist__add(print_state->visited_metrics, name);
234 		}
235 		return;
236 	}
237 	fprintf(fp, "  %s\n", name);
238 
239 	if (desc && print_state->desc) {
240 		fprintf(fp, "%*s", 8, "[");
241 		wordwrap(fp, desc, 8, pager_get_columns(), 0);
242 		fprintf(fp, "]\n");
243 	}
244 	if (long_desc && print_state->long_desc) {
245 		fprintf(fp, "%*s", 8, "[");
246 		wordwrap(fp, long_desc, 8, pager_get_columns(), 0);
247 		fprintf(fp, "]\n");
248 	}
249 	if (expr && print_state->detailed) {
250 		fprintf(fp, "%*s", 8, "[");
251 		wordwrap(fp, expr, 8, pager_get_columns(), 0);
252 		fprintf(fp, "]\n");
253 	}
254 	if (threshold && print_state->detailed) {
255 		fprintf(fp, "%*s", 8, "[");
256 		wordwrap(fp, threshold, 8, pager_get_columns(), 0);
257 		fprintf(fp, "]\n");
258 	}
259 }
260 
261 struct json_print_state {
262 	/** @fp: File to write output to. */
263 	FILE *fp;
264 	/** Should a separator be printed prior to the next item? */
265 	bool need_sep;
266 };
267 
268 static void json_print_start(void *ps)
269 {
270 	struct json_print_state *print_state = ps;
271 	FILE *fp = print_state->fp;
272 
273 	fprintf(fp, "[\n");
274 }
275 
276 static void json_print_end(void *ps)
277 {
278 	struct json_print_state *print_state = ps;
279 	FILE *fp = print_state->fp;
280 
281 	fprintf(fp, "%s]\n", print_state->need_sep ? "\n" : "");
282 }
283 
284 static void fix_escape_fprintf(FILE *fp, struct strbuf *buf, const char *fmt, ...)
285 {
286 	va_list args;
287 
288 	va_start(args, fmt);
289 	strbuf_setlen(buf, 0);
290 	for (size_t fmt_pos = 0; fmt_pos < strlen(fmt); fmt_pos++) {
291 		switch (fmt[fmt_pos]) {
292 		case '%':
293 			fmt_pos++;
294 			switch (fmt[fmt_pos]) {
295 			case 's': {
296 				const char *s = va_arg(args, const char*);
297 
298 				strbuf_addstr(buf, s);
299 				break;
300 			}
301 			case 'S': {
302 				const char *s = va_arg(args, const char*);
303 
304 				for (size_t s_pos = 0; s_pos < strlen(s); s_pos++) {
305 					switch (s[s_pos]) {
306 					case '\n':
307 						strbuf_addstr(buf, "\\n");
308 						break;
309 					case '\\':
310 						fallthrough;
311 					case '\"':
312 						strbuf_addch(buf, '\\');
313 						fallthrough;
314 					default:
315 						strbuf_addch(buf, s[s_pos]);
316 						break;
317 					}
318 				}
319 				break;
320 			}
321 			default:
322 				pr_err("Unexpected format character '%c'\n", fmt[fmt_pos]);
323 				strbuf_addch(buf, '%');
324 				strbuf_addch(buf, fmt[fmt_pos]);
325 			}
326 			break;
327 		default:
328 			strbuf_addch(buf, fmt[fmt_pos]);
329 			break;
330 		}
331 	}
332 	va_end(args);
333 	fputs(buf->buf, fp);
334 }
335 
336 static void json_print_event(void *ps, const char *pmu_name, const char *topic,
337 			     const char *event_name, const char *event_alias,
338 			     const char *scale_unit,
339 			     bool deprecated, const char *event_type_desc,
340 			     const char *desc, const char *long_desc,
341 			     const char *encoding_desc)
342 {
343 	struct json_print_state *print_state = ps;
344 	bool need_sep = false;
345 	FILE *fp = print_state->fp;
346 	struct strbuf buf;
347 
348 	strbuf_init(&buf, 0);
349 	fprintf(fp, "%s{\n", print_state->need_sep ? ",\n" : "");
350 	print_state->need_sep = true;
351 	if (pmu_name) {
352 		fix_escape_fprintf(fp, &buf, "\t\"Unit\": \"%S\"", pmu_name);
353 		need_sep = true;
354 	}
355 	if (topic) {
356 		fix_escape_fprintf(fp, &buf, "%s\t\"Topic\": \"%S\"",
357 				   need_sep ? ",\n" : "",
358 				   topic);
359 		need_sep = true;
360 	}
361 	if (event_name) {
362 		fix_escape_fprintf(fp, &buf, "%s\t\"EventName\": \"%S\"",
363 				   need_sep ? ",\n" : "",
364 				   event_name);
365 		need_sep = true;
366 	}
367 	if (event_alias && strlen(event_alias)) {
368 		fix_escape_fprintf(fp, &buf, "%s\t\"EventAlias\": \"%S\"",
369 				   need_sep ? ",\n" : "",
370 				   event_alias);
371 		need_sep = true;
372 	}
373 	if (scale_unit && strlen(scale_unit)) {
374 		fix_escape_fprintf(fp, &buf, "%s\t\"ScaleUnit\": \"%S\"",
375 				   need_sep ? ",\n" : "",
376 				   scale_unit);
377 		need_sep = true;
378 	}
379 	if (event_type_desc) {
380 		fix_escape_fprintf(fp, &buf, "%s\t\"EventType\": \"%S\"",
381 				   need_sep ? ",\n" : "",
382 				   event_type_desc);
383 		need_sep = true;
384 	}
385 	if (deprecated) {
386 		fix_escape_fprintf(fp, &buf, "%s\t\"Deprecated\": \"%S\"",
387 				   need_sep ? ",\n" : "",
388 				   deprecated ? "1" : "0");
389 		need_sep = true;
390 	}
391 	if (desc) {
392 		fix_escape_fprintf(fp, &buf, "%s\t\"BriefDescription\": \"%S\"",
393 				   need_sep ? ",\n" : "",
394 				   desc);
395 		need_sep = true;
396 	}
397 	if (long_desc) {
398 		fix_escape_fprintf(fp, &buf, "%s\t\"PublicDescription\": \"%S\"",
399 				   need_sep ? ",\n" : "",
400 				   long_desc);
401 		need_sep = true;
402 	}
403 	if (encoding_desc) {
404 		fix_escape_fprintf(fp, &buf, "%s\t\"Encoding\": \"%S\"",
405 				   need_sep ? ",\n" : "",
406 				   encoding_desc);
407 		need_sep = true;
408 	}
409 	fprintf(fp, "%s}", need_sep ? "\n" : "");
410 	strbuf_release(&buf);
411 }
412 
413 static void json_print_metric(void *ps __maybe_unused, const char *group,
414 			      const char *name, const char *desc,
415 			      const char *long_desc, const char *expr,
416 			      const char *threshold, const char *unit)
417 {
418 	struct json_print_state *print_state = ps;
419 	bool need_sep = false;
420 	FILE *fp = print_state->fp;
421 	struct strbuf buf;
422 
423 	strbuf_init(&buf, 0);
424 	fprintf(fp, "%s{\n", print_state->need_sep ? ",\n" : "");
425 	print_state->need_sep = true;
426 	if (group) {
427 		fix_escape_fprintf(fp, &buf, "\t\"MetricGroup\": \"%S\"", group);
428 		need_sep = true;
429 	}
430 	if (name) {
431 		fix_escape_fprintf(fp, &buf, "%s\t\"MetricName\": \"%S\"",
432 				   need_sep ? ",\n" : "",
433 				   name);
434 		need_sep = true;
435 	}
436 	if (expr) {
437 		fix_escape_fprintf(fp, &buf, "%s\t\"MetricExpr\": \"%S\"",
438 				   need_sep ? ",\n" : "",
439 				   expr);
440 		need_sep = true;
441 	}
442 	if (threshold) {
443 		fix_escape_fprintf(fp, &buf, "%s\t\"MetricThreshold\": \"%S\"",
444 				   need_sep ? ",\n" : "",
445 				   threshold);
446 		need_sep = true;
447 	}
448 	if (unit) {
449 		fix_escape_fprintf(fp, &buf, "%s\t\"ScaleUnit\": \"%S\"",
450 				   need_sep ? ",\n" : "",
451 				   unit);
452 		need_sep = true;
453 	}
454 	if (desc) {
455 		fix_escape_fprintf(fp, &buf, "%s\t\"BriefDescription\": \"%S\"",
456 				   need_sep ? ",\n" : "",
457 				   desc);
458 		need_sep = true;
459 	}
460 	if (long_desc) {
461 		fix_escape_fprintf(fp, &buf, "%s\t\"PublicDescription\": \"%S\"",
462 				   need_sep ? ",\n" : "",
463 				   long_desc);
464 		need_sep = true;
465 	}
466 	fprintf(fp, "%s}", need_sep ? "\n" : "");
467 	strbuf_release(&buf);
468 }
469 
470 static bool json_skip_duplicate_pmus(void *ps __maybe_unused)
471 {
472 	return false;
473 }
474 
475 static bool default_skip_duplicate_pmus(void *ps)
476 {
477 	struct print_state *print_state = ps;
478 
479 	return !print_state->long_desc;
480 }
481 
482 int cmd_list(int argc, const char **argv)
483 {
484 	int i, ret = 0;
485 	struct print_state default_ps = {
486 		.fp = stdout,
487 	};
488 	struct print_state json_ps = {
489 		.fp = stdout,
490 	};
491 	void *ps = &default_ps;
492 	struct print_callbacks print_cb = {
493 		.print_start = default_print_start,
494 		.print_end = default_print_end,
495 		.print_event = default_print_event,
496 		.print_metric = default_print_metric,
497 		.skip_duplicate_pmus = default_skip_duplicate_pmus,
498 	};
499 	const char *cputype = NULL;
500 	const char *unit_name = NULL;
501 	const char *output_path = NULL;
502 	bool json = false;
503 	struct option list_options[] = {
504 		OPT_BOOLEAN(0, "raw-dump", &default_ps.name_only, "Dump raw events"),
505 		OPT_BOOLEAN('j', "json", &json, "JSON encode events and metrics"),
506 		OPT_BOOLEAN('d', "desc", &default_ps.desc,
507 			    "Print extra event descriptions. --no-desc to not print."),
508 		OPT_BOOLEAN('v', "long-desc", &default_ps.long_desc,
509 			    "Print longer event descriptions."),
510 		OPT_BOOLEAN(0, "details", &default_ps.detailed,
511 			    "Print information on the perf event names and expressions used internally by events."),
512 		OPT_STRING('o', "output", &output_path, "file", "output file name"),
513 		OPT_BOOLEAN(0, "deprecated", &default_ps.deprecated,
514 			    "Print deprecated events."),
515 		OPT_STRING(0, "cputype", &cputype, "cpu type",
516 			   "Limit PMU or metric printing to the given PMU (e.g. cpu, core or atom)."),
517 		OPT_STRING(0, "unit", &unit_name, "PMU name",
518 			   "Limit PMU or metric printing to the specified PMU."),
519 		OPT_INCR(0, "debug", &verbose,
520 			     "Enable debugging output"),
521 		OPT_END()
522 	};
523 	const char * const list_usage[] = {
524 #ifdef HAVE_LIBPFM
525 		"perf list [<options>] [hw|sw|cache|tracepoint|pmu|sdt|metric|metricgroup|event_glob|pfm]",
526 #else
527 		"perf list [<options>] [hw|sw|cache|tracepoint|pmu|sdt|metric|metricgroup|event_glob]",
528 #endif
529 		NULL
530 	};
531 
532 	set_option_flag(list_options, 0, "raw-dump", PARSE_OPT_HIDDEN);
533 	/* Hide hybrid flag for the more generic 'unit' flag. */
534 	set_option_flag(list_options, 0, "cputype", PARSE_OPT_HIDDEN);
535 
536 	argc = parse_options(argc, argv, list_options, list_usage,
537 			     PARSE_OPT_STOP_AT_NON_OPTION);
538 
539 	if (output_path) {
540 		default_ps.fp = fopen(output_path, "w");
541 		json_ps.fp = default_ps.fp;
542 	}
543 
544 	setup_pager();
545 
546 	if (!default_ps.name_only)
547 		setup_pager();
548 
549 	if (json) {
550 		print_cb = (struct print_callbacks){
551 			.print_start = json_print_start,
552 			.print_end = json_print_end,
553 			.print_event = json_print_event,
554 			.print_metric = json_print_metric,
555 			.skip_duplicate_pmus = json_skip_duplicate_pmus,
556 		};
557 		ps = &json_ps;
558 	} else {
559 		default_ps.desc = !default_ps.long_desc;
560 		default_ps.last_topic = strdup("");
561 		assert(default_ps.last_topic);
562 		default_ps.visited_metrics = strlist__new(NULL, NULL);
563 		assert(default_ps.visited_metrics);
564 		if (unit_name)
565 			default_ps.pmu_glob = strdup(unit_name);
566 		else if (cputype) {
567 			const struct perf_pmu *pmu = perf_pmus__pmu_for_pmu_filter(cputype);
568 
569 			if (!pmu) {
570 				pr_err("ERROR: cputype is not supported!\n");
571 				ret = -1;
572 				goto out;
573 			}
574 			default_ps.pmu_glob = strdup(pmu->name);
575 		}
576 	}
577 	print_cb.print_start(ps);
578 
579 	if (argc == 0) {
580 		default_ps.metrics = true;
581 		default_ps.metricgroups = true;
582 		print_events(&print_cb, ps);
583 		goto out;
584 	}
585 
586 	for (i = 0; i < argc; ++i) {
587 		char *sep, *s;
588 
589 		if (strcmp(argv[i], "tracepoint") == 0)
590 			print_tracepoint_events(&print_cb, ps);
591 		else if (strcmp(argv[i], "hw") == 0 ||
592 			 strcmp(argv[i], "hardware") == 0)
593 			print_symbol_events(&print_cb, ps, PERF_TYPE_HARDWARE,
594 					event_symbols_hw, PERF_COUNT_HW_MAX);
595 		else if (strcmp(argv[i], "sw") == 0 ||
596 			 strcmp(argv[i], "software") == 0) {
597 			print_symbol_events(&print_cb, ps, PERF_TYPE_SOFTWARE,
598 					event_symbols_sw, PERF_COUNT_SW_MAX);
599 			print_tool_events(&print_cb, ps);
600 		} else if (strcmp(argv[i], "cache") == 0 ||
601 			 strcmp(argv[i], "hwcache") == 0)
602 			print_hwcache_events(&print_cb, ps);
603 		else if (strcmp(argv[i], "pmu") == 0)
604 			perf_pmus__print_pmu_events(&print_cb, ps);
605 		else if (strcmp(argv[i], "sdt") == 0)
606 			print_sdt_events(&print_cb, ps);
607 		else if (strcmp(argv[i], "metric") == 0 || strcmp(argv[i], "metrics") == 0) {
608 			default_ps.metricgroups = false;
609 			default_ps.metrics = true;
610 			metricgroup__print(&print_cb, ps);
611 		} else if (strcmp(argv[i], "metricgroup") == 0 ||
612 			   strcmp(argv[i], "metricgroups") == 0) {
613 			default_ps.metricgroups = true;
614 			default_ps.metrics = false;
615 			metricgroup__print(&print_cb, ps);
616 		}
617 #ifdef HAVE_LIBPFM
618 		else if (strcmp(argv[i], "pfm") == 0)
619 			print_libpfm_events(&print_cb, ps);
620 #endif
621 		else if ((sep = strchr(argv[i], ':')) != NULL) {
622 			char *old_pmu_glob = default_ps.pmu_glob;
623 
624 			default_ps.event_glob = strdup(argv[i]);
625 			if (!default_ps.event_glob) {
626 				ret = -1;
627 				goto out;
628 			}
629 
630 			print_tracepoint_events(&print_cb, ps);
631 			print_sdt_events(&print_cb, ps);
632 			default_ps.metrics = true;
633 			default_ps.metricgroups = true;
634 			metricgroup__print(&print_cb, ps);
635 			zfree(&default_ps.event_glob);
636 			default_ps.pmu_glob = old_pmu_glob;
637 		} else {
638 			if (asprintf(&s, "*%s*", argv[i]) < 0) {
639 				printf("Critical: Not enough memory! Trying to continue...\n");
640 				continue;
641 			}
642 			default_ps.event_glob = s;
643 			print_symbol_events(&print_cb, ps, PERF_TYPE_HARDWARE,
644 					event_symbols_hw, PERF_COUNT_HW_MAX);
645 			print_symbol_events(&print_cb, ps, PERF_TYPE_SOFTWARE,
646 					event_symbols_sw, PERF_COUNT_SW_MAX);
647 			print_tool_events(&print_cb, ps);
648 			print_hwcache_events(&print_cb, ps);
649 			perf_pmus__print_pmu_events(&print_cb, ps);
650 			print_tracepoint_events(&print_cb, ps);
651 			print_sdt_events(&print_cb, ps);
652 			default_ps.metrics = true;
653 			default_ps.metricgroups = true;
654 			metricgroup__print(&print_cb, ps);
655 			free(s);
656 		}
657 	}
658 
659 out:
660 	print_cb.print_end(ps);
661 	free(default_ps.pmu_glob);
662 	free(default_ps.last_topic);
663 	free(default_ps.last_metricgroups);
664 	strlist__delete(default_ps.visited_metrics);
665 	if (output_path)
666 		fclose(default_ps.fp);
667 
668 	return ret;
669 }
670