xref: /openbmc/linux/tools/perf/util/debug.c (revision edbe9817)
1cd84c2acSFrederic Weisbecker /* For general debugging purposes */
2cd84c2acSFrederic Weisbecker 
3cd84c2acSFrederic Weisbecker #include "../perf.h"
48f28827aSFrederic Weisbecker 
5cd84c2acSFrederic Weisbecker #include <string.h>
6cd84c2acSFrederic Weisbecker #include <stdarg.h>
7cd84c2acSFrederic Weisbecker #include <stdio.h>
8cd84c2acSFrederic Weisbecker 
9f9224c5cSArnaldo Carvalho de Melo #include "cache.h"
108f28827aSFrederic Weisbecker #include "color.h"
118f28827aSFrederic Weisbecker #include "event.h"
128f28827aSFrederic Weisbecker #include "debug.h"
134a58e611SArnaldo Carvalho de Melo #include "util.h"
1416ad2ffbSNamhyung Kim #include "target.h"
158f28827aSFrederic Weisbecker 
16cee3ab9cSJiri Olsa #define NSECS_PER_SEC  1000000000ULL
17cee3ab9cSJiri Olsa #define NSECS_PER_USEC 1000ULL
18cee3ab9cSJiri Olsa 
19b44308f5SArnaldo Carvalho de Melo int verbose;
20b44308f5SArnaldo Carvalho de Melo bool dump_trace = false, quiet = false;
21cee3ab9cSJiri Olsa int debug_ordered_events;
22f78eaef0SAndi Kleen static int redirect_to_stderr;
23edbe9817SJiri Olsa int debug_data_convert;
24cd84c2acSFrederic Weisbecker 
25c95688aaSJiri Olsa static int _eprintf(int level, int var, const char *fmt, va_list args)
26cd84c2acSFrederic Weisbecker {
27cd84c2acSFrederic Weisbecker 	int ret = 0;
28cd84c2acSFrederic Weisbecker 
29c95688aaSJiri Olsa 	if (var >= level) {
30f78eaef0SAndi Kleen 		if (use_browser >= 1 && !redirect_to_stderr)
31b56e5331SNamhyung Kim 			ui_helpline__vshow(fmt, args);
32f9224c5cSArnaldo Carvalho de Melo 		else
33cd84c2acSFrederic Weisbecker 			ret = vfprintf(stderr, fmt, args);
34cd84c2acSFrederic Weisbecker 	}
35cd84c2acSFrederic Weisbecker 
36cd84c2acSFrederic Weisbecker 	return ret;
37cd84c2acSFrederic Weisbecker }
382cec19d9SFrederic Weisbecker 
39c95688aaSJiri Olsa int eprintf(int level, int var, const char *fmt, ...)
40f772abc6SJiri Olsa {
41f772abc6SJiri Olsa 	va_list args;
42f772abc6SJiri Olsa 	int ret;
43f772abc6SJiri Olsa 
44f772abc6SJiri Olsa 	va_start(args, fmt);
45c95688aaSJiri Olsa 	ret = _eprintf(level, var, fmt, args);
46f772abc6SJiri Olsa 	va_end(args);
47f772abc6SJiri Olsa 
48f772abc6SJiri Olsa 	return ret;
49f772abc6SJiri Olsa }
50f772abc6SJiri Olsa 
51cee3ab9cSJiri Olsa static int __eprintf_time(u64 t, const char *fmt, va_list args)
52cee3ab9cSJiri Olsa {
53cee3ab9cSJiri Olsa 	int ret = 0;
54cee3ab9cSJiri Olsa 	u64 secs, usecs, nsecs = t;
55cee3ab9cSJiri Olsa 
56cee3ab9cSJiri Olsa 	secs   = nsecs / NSECS_PER_SEC;
57cee3ab9cSJiri Olsa 	nsecs -= secs  * NSECS_PER_SEC;
58cee3ab9cSJiri Olsa 	usecs  = nsecs / NSECS_PER_USEC;
59cee3ab9cSJiri Olsa 
60cee3ab9cSJiri Olsa 	ret = fprintf(stderr, "[%13" PRIu64 ".%06" PRIu64 "] ",
61cee3ab9cSJiri Olsa 		      secs, usecs);
62cee3ab9cSJiri Olsa 	ret += vfprintf(stderr, fmt, args);
63cee3ab9cSJiri Olsa 	return ret;
64cee3ab9cSJiri Olsa }
65cee3ab9cSJiri Olsa 
66cee3ab9cSJiri Olsa int eprintf_time(int level, int var, u64 t, const char *fmt, ...)
67cee3ab9cSJiri Olsa {
68cee3ab9cSJiri Olsa 	int ret = 0;
69cee3ab9cSJiri Olsa 	va_list args;
70cee3ab9cSJiri Olsa 
71cee3ab9cSJiri Olsa 	if (var >= level) {
72cee3ab9cSJiri Olsa 		va_start(args, fmt);
73cee3ab9cSJiri Olsa 		ret = __eprintf_time(t, fmt, args);
74cee3ab9cSJiri Olsa 		va_end(args);
75cee3ab9cSJiri Olsa 	}
76cee3ab9cSJiri Olsa 
77cee3ab9cSJiri Olsa 	return ret;
78cee3ab9cSJiri Olsa }
79cee3ab9cSJiri Olsa 
80f772abc6SJiri Olsa /*
81f772abc6SJiri Olsa  * Overloading libtraceevent standard info print
82f772abc6SJiri Olsa  * function, display with -v in perf.
83f772abc6SJiri Olsa  */
84f772abc6SJiri Olsa void pr_stat(const char *fmt, ...)
85f772abc6SJiri Olsa {
86f772abc6SJiri Olsa 	va_list args;
87f772abc6SJiri Olsa 
88f772abc6SJiri Olsa 	va_start(args, fmt);
89c95688aaSJiri Olsa 	_eprintf(1, verbose, fmt, args);
90f772abc6SJiri Olsa 	va_end(args);
91c95688aaSJiri Olsa 	eprintf(1, verbose, "\n");
92f772abc6SJiri Olsa }
93f772abc6SJiri Olsa 
942cec19d9SFrederic Weisbecker int dump_printf(const char *fmt, ...)
952cec19d9SFrederic Weisbecker {
962cec19d9SFrederic Weisbecker 	va_list args;
972cec19d9SFrederic Weisbecker 	int ret = 0;
982cec19d9SFrederic Weisbecker 
992cec19d9SFrederic Weisbecker 	if (dump_trace) {
1002cec19d9SFrederic Weisbecker 		va_start(args, fmt);
1012cec19d9SFrederic Weisbecker 		ret = vprintf(fmt, args);
1022cec19d9SFrederic Weisbecker 		va_end(args);
1032cec19d9SFrederic Weisbecker 	}
1042cec19d9SFrederic Weisbecker 
1052cec19d9SFrederic Weisbecker 	return ret;
1062cec19d9SFrederic Weisbecker }
1078f28827aSFrederic Weisbecker 
1088115d60cSArnaldo Carvalho de Melo void trace_event(union perf_event *event)
1098f28827aSFrederic Weisbecker {
1108f28827aSFrederic Weisbecker 	unsigned char *raw_event = (void *)event;
1118f28827aSFrederic Weisbecker 	const char *color = PERF_COLOR_BLUE;
1128f28827aSFrederic Weisbecker 	int i, j;
1138f28827aSFrederic Weisbecker 
1148f28827aSFrederic Weisbecker 	if (!dump_trace)
1158f28827aSFrederic Weisbecker 		return;
1168f28827aSFrederic Weisbecker 
1175b1c1444SArnaldo Carvalho de Melo 	printf(".");
1185b1c1444SArnaldo Carvalho de Melo 	color_fprintf(stdout, color, "\n. ... raw event: size %d bytes\n",
1198f28827aSFrederic Weisbecker 		      event->header.size);
1208f28827aSFrederic Weisbecker 
1218f28827aSFrederic Weisbecker 	for (i = 0; i < event->header.size; i++) {
1228f28827aSFrederic Weisbecker 		if ((i & 15) == 0) {
1235b1c1444SArnaldo Carvalho de Melo 			printf(".");
1245b1c1444SArnaldo Carvalho de Melo 			color_fprintf(stdout, color, "  %04x: ", i);
1258f28827aSFrederic Weisbecker 		}
1268f28827aSFrederic Weisbecker 
1275b1c1444SArnaldo Carvalho de Melo 		color_fprintf(stdout, color, " %02x", raw_event[i]);
1288f28827aSFrederic Weisbecker 
1298f28827aSFrederic Weisbecker 		if (((i & 15) == 15) || i == event->header.size-1) {
1305b1c1444SArnaldo Carvalho de Melo 			color_fprintf(stdout, color, "  ");
1318f28827aSFrederic Weisbecker 			for (j = 0; j < 15-(i & 15); j++)
1325b1c1444SArnaldo Carvalho de Melo 				color_fprintf(stdout, color, "   ");
13384c104adSAndy Isaacson 			for (j = i & ~15; j <= i; j++) {
1345b1c1444SArnaldo Carvalho de Melo 				color_fprintf(stdout, color, "%c",
13584c104adSAndy Isaacson 					      isprint(raw_event[j]) ?
13684c104adSAndy Isaacson 					      raw_event[j] : '.');
1378f28827aSFrederic Weisbecker 			}
1385b1c1444SArnaldo Carvalho de Melo 			color_fprintf(stdout, color, "\n");
1398f28827aSFrederic Weisbecker 		}
1408f28827aSFrederic Weisbecker 	}
1415b1c1444SArnaldo Carvalho de Melo 	printf(".\n");
1428f28827aSFrederic Weisbecker }
143bbb2cea7SJiri Olsa 
144bbb2cea7SJiri Olsa static struct debug_variable {
145bbb2cea7SJiri Olsa 	const char *name;
146bbb2cea7SJiri Olsa 	int *ptr;
147bbb2cea7SJiri Olsa } debug_variables[] = {
148bbb2cea7SJiri Olsa 	{ .name = "verbose",		.ptr = &verbose },
149cee3ab9cSJiri Olsa 	{ .name = "ordered-events",	.ptr = &debug_ordered_events},
150f78eaef0SAndi Kleen 	{ .name = "stderr",		.ptr = &redirect_to_stderr},
151edbe9817SJiri Olsa 	{ .name = "data-convert",	.ptr = &debug_data_convert },
152bbb2cea7SJiri Olsa 	{ .name = NULL, }
153bbb2cea7SJiri Olsa };
154bbb2cea7SJiri Olsa 
155bbb2cea7SJiri Olsa int perf_debug_option(const char *str)
156bbb2cea7SJiri Olsa {
157bbb2cea7SJiri Olsa 	struct debug_variable *var = &debug_variables[0];
158bbb2cea7SJiri Olsa 	char *vstr, *s = strdup(str);
159bbb2cea7SJiri Olsa 	int v = 1;
160bbb2cea7SJiri Olsa 
161bbb2cea7SJiri Olsa 	vstr = strchr(s, '=');
162bbb2cea7SJiri Olsa 	if (vstr)
163bbb2cea7SJiri Olsa 		*vstr++ = 0;
164bbb2cea7SJiri Olsa 
165bbb2cea7SJiri Olsa 	while (var->name) {
166bbb2cea7SJiri Olsa 		if (!strcmp(s, var->name))
167bbb2cea7SJiri Olsa 			break;
168bbb2cea7SJiri Olsa 		var++;
169bbb2cea7SJiri Olsa 	}
170bbb2cea7SJiri Olsa 
171bbb2cea7SJiri Olsa 	if (!var->name) {
172bbb2cea7SJiri Olsa 		pr_err("Unknown debug variable name '%s'\n", s);
173bbb2cea7SJiri Olsa 		free(s);
174bbb2cea7SJiri Olsa 		return -1;
175bbb2cea7SJiri Olsa 	}
176bbb2cea7SJiri Olsa 
177bbb2cea7SJiri Olsa 	if (vstr) {
178bbb2cea7SJiri Olsa 		v = atoi(vstr);
179bbb2cea7SJiri Olsa 		/*
180bbb2cea7SJiri Olsa 		 * Allow only values in range (0, 10),
181bbb2cea7SJiri Olsa 		 * otherwise set 0.
182bbb2cea7SJiri Olsa 		 */
183bbb2cea7SJiri Olsa 		v = (v < 0) || (v > 10) ? 0 : v;
184bbb2cea7SJiri Olsa 	}
185bbb2cea7SJiri Olsa 
186bbb2cea7SJiri Olsa 	*var->ptr = v;
187bbb2cea7SJiri Olsa 	free(s);
188bbb2cea7SJiri Olsa 	return 0;
189bbb2cea7SJiri Olsa }
190