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