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