xref: /openbmc/linux/tools/perf/util/debug.c (revision 6774def6)
1 /* For general debugging purposes */
2 
3 #include "../perf.h"
4 
5 #include <string.h>
6 #include <stdarg.h>
7 #include <stdio.h>
8 
9 #include "cache.h"
10 #include "color.h"
11 #include "event.h"
12 #include "debug.h"
13 #include "util.h"
14 #include "target.h"
15 
16 #define NSECS_PER_SEC  1000000000ULL
17 #define NSECS_PER_USEC 1000ULL
18 
19 int verbose;
20 bool dump_trace = false, quiet = false;
21 int debug_ordered_events;
22 
23 static int _eprintf(int level, int var, const char *fmt, va_list args)
24 {
25 	int ret = 0;
26 
27 	if (var >= level) {
28 		if (use_browser >= 1)
29 			ui_helpline__vshow(fmt, args);
30 		else
31 			ret = vfprintf(stderr, fmt, args);
32 	}
33 
34 	return ret;
35 }
36 
37 int eprintf(int level, int var, const char *fmt, ...)
38 {
39 	va_list args;
40 	int ret;
41 
42 	va_start(args, fmt);
43 	ret = _eprintf(level, var, fmt, args);
44 	va_end(args);
45 
46 	return ret;
47 }
48 
49 static int __eprintf_time(u64 t, const char *fmt, va_list args)
50 {
51 	int ret = 0;
52 	u64 secs, usecs, nsecs = t;
53 
54 	secs   = nsecs / NSECS_PER_SEC;
55 	nsecs -= secs  * NSECS_PER_SEC;
56 	usecs  = nsecs / NSECS_PER_USEC;
57 
58 	ret = fprintf(stderr, "[%13" PRIu64 ".%06" PRIu64 "] ",
59 		      secs, usecs);
60 	ret += vfprintf(stderr, fmt, args);
61 	return ret;
62 }
63 
64 int eprintf_time(int level, int var, u64 t, const char *fmt, ...)
65 {
66 	int ret = 0;
67 	va_list args;
68 
69 	if (var >= level) {
70 		va_start(args, fmt);
71 		ret = __eprintf_time(t, fmt, args);
72 		va_end(args);
73 	}
74 
75 	return ret;
76 }
77 
78 /*
79  * Overloading libtraceevent standard info print
80  * function, display with -v in perf.
81  */
82 void pr_stat(const char *fmt, ...)
83 {
84 	va_list args;
85 
86 	va_start(args, fmt);
87 	_eprintf(1, verbose, fmt, args);
88 	va_end(args);
89 	eprintf(1, verbose, "\n");
90 }
91 
92 int dump_printf(const char *fmt, ...)
93 {
94 	va_list args;
95 	int ret = 0;
96 
97 	if (dump_trace) {
98 		va_start(args, fmt);
99 		ret = vprintf(fmt, args);
100 		va_end(args);
101 	}
102 
103 	return ret;
104 }
105 
106 void trace_event(union perf_event *event)
107 {
108 	unsigned char *raw_event = (void *)event;
109 	const char *color = PERF_COLOR_BLUE;
110 	int i, j;
111 
112 	if (!dump_trace)
113 		return;
114 
115 	printf(".");
116 	color_fprintf(stdout, color, "\n. ... raw event: size %d bytes\n",
117 		      event->header.size);
118 
119 	for (i = 0; i < event->header.size; i++) {
120 		if ((i & 15) == 0) {
121 			printf(".");
122 			color_fprintf(stdout, color, "  %04x: ", i);
123 		}
124 
125 		color_fprintf(stdout, color, " %02x", raw_event[i]);
126 
127 		if (((i & 15) == 15) || i == event->header.size-1) {
128 			color_fprintf(stdout, color, "  ");
129 			for (j = 0; j < 15-(i & 15); j++)
130 				color_fprintf(stdout, color, "   ");
131 			for (j = i & ~15; j <= i; j++) {
132 				color_fprintf(stdout, color, "%c",
133 					      isprint(raw_event[j]) ?
134 					      raw_event[j] : '.');
135 			}
136 			color_fprintf(stdout, color, "\n");
137 		}
138 	}
139 	printf(".\n");
140 }
141 
142 static struct debug_variable {
143 	const char *name;
144 	int *ptr;
145 } debug_variables[] = {
146 	{ .name = "verbose",		.ptr = &verbose },
147 	{ .name = "ordered-events",	.ptr = &debug_ordered_events},
148 	{ .name = NULL, }
149 };
150 
151 int perf_debug_option(const char *str)
152 {
153 	struct debug_variable *var = &debug_variables[0];
154 	char *vstr, *s = strdup(str);
155 	int v = 1;
156 
157 	vstr = strchr(s, '=');
158 	if (vstr)
159 		*vstr++ = 0;
160 
161 	while (var->name) {
162 		if (!strcmp(s, var->name))
163 			break;
164 		var++;
165 	}
166 
167 	if (!var->name) {
168 		pr_err("Unknown debug variable name '%s'\n", s);
169 		free(s);
170 		return -1;
171 	}
172 
173 	if (vstr) {
174 		v = atoi(vstr);
175 		/*
176 		 * Allow only values in range (0, 10),
177 		 * otherwise set 0.
178 		 */
179 		v = (v < 0) || (v > 10) ? 0 : v;
180 	}
181 
182 	*var->ptr = v;
183 	free(s);
184 	return 0;
185 }
186