Merge tag 'char-misc-4.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh...
[linux-2.6-block.git] / tools / perf / util / debug.c
1 /* For general debugging purposes */
2
3 #include "../perf.h"
4
5 #include <string.h>
6 #include <stdarg.h>
7 #include <stdio.h>
8 #include <api/debug.h>
9
10 #include "cache.h"
11 #include "color.h"
12 #include "event.h"
13 #include "debug.h"
14 #include "util.h"
15 #include "target.h"
16
17 #define NSECS_PER_SEC  1000000000ULL
18 #define NSECS_PER_USEC 1000ULL
19
20 int verbose;
21 bool dump_trace = false, quiet = false;
22 int debug_ordered_events;
23 static int redirect_to_stderr;
24 int debug_data_convert;
25
26 int veprintf(int level, int var, const char *fmt, va_list args)
27 {
28         int ret = 0;
29
30         if (var >= level) {
31                 if (use_browser >= 1 && !redirect_to_stderr)
32                         ui_helpline__vshow(fmt, args);
33                 else
34                         ret = vfprintf(stderr, fmt, args);
35         }
36
37         return ret;
38 }
39
40 int eprintf(int level, int var, const char *fmt, ...)
41 {
42         va_list args;
43         int ret;
44
45         va_start(args, fmt);
46         ret = veprintf(level, var, fmt, args);
47         va_end(args);
48
49         return ret;
50 }
51
52 static int veprintf_time(u64 t, const char *fmt, va_list args)
53 {
54         int ret = 0;
55         u64 secs, usecs, nsecs = t;
56
57         secs   = nsecs / NSECS_PER_SEC;
58         nsecs -= secs  * NSECS_PER_SEC;
59         usecs  = nsecs / NSECS_PER_USEC;
60
61         ret = fprintf(stderr, "[%13" PRIu64 ".%06" PRIu64 "] ",
62                       secs, usecs);
63         ret += vfprintf(stderr, fmt, args);
64         return ret;
65 }
66
67 int eprintf_time(int level, int var, u64 t, const char *fmt, ...)
68 {
69         int ret = 0;
70         va_list args;
71
72         if (var >= level) {
73                 va_start(args, fmt);
74                 ret = veprintf_time(t, fmt, args);
75                 va_end(args);
76         }
77
78         return ret;
79 }
80
81 /*
82  * Overloading libtraceevent standard info print
83  * function, display with -v in perf.
84  */
85 void pr_stat(const char *fmt, ...)
86 {
87         va_list args;
88
89         va_start(args, fmt);
90         veprintf(1, verbose, fmt, args);
91         va_end(args);
92         eprintf(1, verbose, "\n");
93 }
94
95 int dump_printf(const char *fmt, ...)
96 {
97         va_list args;
98         int ret = 0;
99
100         if (dump_trace) {
101                 va_start(args, fmt);
102                 ret = vprintf(fmt, args);
103                 va_end(args);
104         }
105
106         return ret;
107 }
108
109 static void trace_event_printer(enum binary_printer_ops op,
110                                 unsigned int val, void *extra)
111 {
112         const char *color = PERF_COLOR_BLUE;
113         union perf_event *event = (union perf_event *)extra;
114         unsigned char ch = (unsigned char)val;
115
116         switch (op) {
117         case BINARY_PRINT_DATA_BEGIN:
118                 printf(".");
119                 color_fprintf(stdout, color, "\n. ... raw event: size %d bytes\n",
120                                 event->header.size);
121                 break;
122         case BINARY_PRINT_LINE_BEGIN:
123                 printf(".");
124                 break;
125         case BINARY_PRINT_ADDR:
126                 color_fprintf(stdout, color, "  %04x: ", val);
127                 break;
128         case BINARY_PRINT_NUM_DATA:
129                 color_fprintf(stdout, color, " %02x", val);
130                 break;
131         case BINARY_PRINT_NUM_PAD:
132                 color_fprintf(stdout, color, "   ");
133                 break;
134         case BINARY_PRINT_SEP:
135                 color_fprintf(stdout, color, "  ");
136                 break;
137         case BINARY_PRINT_CHAR_DATA:
138                 color_fprintf(stdout, color, "%c",
139                               isprint(ch) ? ch : '.');
140                 break;
141         case BINARY_PRINT_CHAR_PAD:
142                 color_fprintf(stdout, color, " ");
143                 break;
144         case BINARY_PRINT_LINE_END:
145                 color_fprintf(stdout, color, "\n");
146                 break;
147         case BINARY_PRINT_DATA_END:
148                 printf("\n");
149                 break;
150         default:
151                 break;
152         }
153 }
154
155 void trace_event(union perf_event *event)
156 {
157         unsigned char *raw_event = (void *)event;
158
159         if (!dump_trace)
160                 return;
161
162         print_binary(raw_event, event->header.size, 16,
163                      trace_event_printer, event);
164 }
165
166 static struct debug_variable {
167         const char *name;
168         int *ptr;
169 } debug_variables[] = {
170         { .name = "verbose",            .ptr = &verbose },
171         { .name = "ordered-events",     .ptr = &debug_ordered_events},
172         { .name = "stderr",             .ptr = &redirect_to_stderr},
173         { .name = "data-convert",       .ptr = &debug_data_convert },
174         { .name = NULL, }
175 };
176
177 int perf_debug_option(const char *str)
178 {
179         struct debug_variable *var = &debug_variables[0];
180         char *vstr, *s = strdup(str);
181         int v = 1;
182
183         vstr = strchr(s, '=');
184         if (vstr)
185                 *vstr++ = 0;
186
187         while (var->name) {
188                 if (!strcmp(s, var->name))
189                         break;
190                 var++;
191         }
192
193         if (!var->name) {
194                 pr_err("Unknown debug variable name '%s'\n", s);
195                 free(s);
196                 return -1;
197         }
198
199         if (vstr) {
200                 v = atoi(vstr);
201                 /*
202                  * Allow only values in range (0, 10),
203                  * otherwise set 0.
204                  */
205                 v = (v < 0) || (v > 10) ? 0 : v;
206         }
207
208         *var->ptr = v;
209         free(s);
210         return 0;
211 }
212
213 #define DEBUG_WRAPPER(__n, __l)                         \
214 static int pr_ ## __n ## _wrapper(const char *fmt, ...) \
215 {                                                       \
216         va_list args;                                   \
217         int ret;                                        \
218                                                         \
219         va_start(args, fmt);                            \
220         ret = veprintf(__l, verbose, fmt, args);        \
221         va_end(args);                                   \
222         return ret;                                     \
223 }
224
225 DEBUG_WRAPPER(warning, 0);
226 DEBUG_WRAPPER(debug, 1);
227
228 void perf_debug_setup(void)
229 {
230         libapi_set_print(pr_warning_wrapper, pr_warning_wrapper, pr_debug_wrapper);
231 }