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