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