1 /* For general debugging purposes */ 2 3 #include "../perf.h" 4 5 #include <inttypes.h> 6 #include <string.h> 7 #include <stdarg.h> 8 #include <stdio.h> 9 #include <sys/wait.h> 10 #include <api/debug.h> 11 #include <linux/time64.h> 12 #ifdef HAVE_BACKTRACE_SUPPORT 13 #include <execinfo.h> 14 #endif 15 #include "cache.h" 16 #include "color.h" 17 #include "event.h" 18 #include "debug.h" 19 #include "print_binary.h" 20 #include "util.h" 21 #include "target.h" 22 23 #include "sane_ctype.h" 24 25 int verbose; 26 bool dump_trace = false, quiet = false; 27 int debug_ordered_events; 28 static int redirect_to_stderr; 29 int debug_data_convert; 30 31 int veprintf(int level, int var, const char *fmt, va_list args) 32 { 33 int ret = 0; 34 35 if (var >= level) { 36 if (use_browser >= 1 && !redirect_to_stderr) 37 ui_helpline__vshow(fmt, args); 38 else 39 ret = vfprintf(stderr, fmt, args); 40 } 41 42 return ret; 43 } 44 45 int eprintf(int level, int var, const char *fmt, ...) 46 { 47 va_list args; 48 int ret; 49 50 va_start(args, fmt); 51 ret = veprintf(level, var, fmt, args); 52 va_end(args); 53 54 return ret; 55 } 56 57 static int veprintf_time(u64 t, const char *fmt, va_list args) 58 { 59 int ret = 0; 60 u64 secs, usecs, nsecs = t; 61 62 secs = nsecs / NSEC_PER_SEC; 63 nsecs -= secs * NSEC_PER_SEC; 64 usecs = nsecs / NSEC_PER_USEC; 65 66 ret = fprintf(stderr, "[%13" PRIu64 ".%06" PRIu64 "] ", 67 secs, usecs); 68 ret += vfprintf(stderr, fmt, args); 69 return ret; 70 } 71 72 int eprintf_time(int level, int var, u64 t, const char *fmt, ...) 73 { 74 int ret = 0; 75 va_list args; 76 77 if (var >= level) { 78 va_start(args, fmt); 79 ret = veprintf_time(t, fmt, args); 80 va_end(args); 81 } 82 83 return ret; 84 } 85 86 /* 87 * Overloading libtraceevent standard info print 88 * function, display with -v in perf. 89 */ 90 void pr_stat(const char *fmt, ...) 91 { 92 va_list args; 93 94 va_start(args, fmt); 95 veprintf(1, verbose, fmt, args); 96 va_end(args); 97 eprintf(1, verbose, "\n"); 98 } 99 100 int dump_printf(const char *fmt, ...) 101 { 102 va_list args; 103 int ret = 0; 104 105 if (dump_trace) { 106 va_start(args, fmt); 107 ret = vprintf(fmt, args); 108 va_end(args); 109 } 110 111 return ret; 112 } 113 114 static int trace_event_printer(enum binary_printer_ops op, 115 unsigned int val, void *extra, FILE *fp) 116 { 117 const char *color = PERF_COLOR_BLUE; 118 union perf_event *event = (union perf_event *)extra; 119 unsigned char ch = (unsigned char)val; 120 int printed = 0; 121 122 switch (op) { 123 case BINARY_PRINT_DATA_BEGIN: 124 printed += fprintf(fp, "."); 125 printed += color_fprintf(fp, color, "\n. ... raw event: size %d bytes\n", 126 event->header.size); 127 break; 128 case BINARY_PRINT_LINE_BEGIN: 129 printed += fprintf(fp, "."); 130 break; 131 case BINARY_PRINT_ADDR: 132 printed += color_fprintf(fp, color, " %04x: ", val); 133 break; 134 case BINARY_PRINT_NUM_DATA: 135 printed += color_fprintf(fp, color, " %02x", val); 136 break; 137 case BINARY_PRINT_NUM_PAD: 138 printed += color_fprintf(fp, color, " "); 139 break; 140 case BINARY_PRINT_SEP: 141 printed += color_fprintf(fp, color, " "); 142 break; 143 case BINARY_PRINT_CHAR_DATA: 144 printed += color_fprintf(fp, color, "%c", 145 isprint(ch) ? ch : '.'); 146 break; 147 case BINARY_PRINT_CHAR_PAD: 148 printed += color_fprintf(fp, color, " "); 149 break; 150 case BINARY_PRINT_LINE_END: 151 printed += color_fprintf(fp, color, "\n"); 152 break; 153 case BINARY_PRINT_DATA_END: 154 printed += fprintf(fp, "\n"); 155 break; 156 default: 157 break; 158 } 159 160 return printed; 161 } 162 163 void trace_event(union perf_event *event) 164 { 165 unsigned char *raw_event = (void *)event; 166 167 if (!dump_trace) 168 return; 169 170 print_binary(raw_event, event->header.size, 16, 171 trace_event_printer, event); 172 } 173 174 static struct debug_variable { 175 const char *name; 176 int *ptr; 177 } debug_variables[] = { 178 { .name = "verbose", .ptr = &verbose }, 179 { .name = "ordered-events", .ptr = &debug_ordered_events}, 180 { .name = "stderr", .ptr = &redirect_to_stderr}, 181 { .name = "data-convert", .ptr = &debug_data_convert }, 182 { .name = NULL, } 183 }; 184 185 int perf_debug_option(const char *str) 186 { 187 struct debug_variable *var = &debug_variables[0]; 188 char *vstr, *s = strdup(str); 189 int v = 1; 190 191 vstr = strchr(s, '='); 192 if (vstr) 193 *vstr++ = 0; 194 195 while (var->name) { 196 if (!strcmp(s, var->name)) 197 break; 198 var++; 199 } 200 201 if (!var->name) { 202 pr_err("Unknown debug variable name '%s'\n", s); 203 free(s); 204 return -1; 205 } 206 207 if (vstr) { 208 v = atoi(vstr); 209 /* 210 * Allow only values in range (0, 10), 211 * otherwise set 0. 212 */ 213 v = (v < 0) || (v > 10) ? 0 : v; 214 } 215 216 if (quiet) 217 v = -1; 218 219 *var->ptr = v; 220 free(s); 221 return 0; 222 } 223 224 int perf_quiet_option(void) 225 { 226 struct debug_variable *var = &debug_variables[0]; 227 228 /* disable all debug messages */ 229 while (var->name) { 230 *var->ptr = -1; 231 var++; 232 } 233 234 quiet = true; 235 return 0; 236 } 237 238 #define DEBUG_WRAPPER(__n, __l) \ 239 static int pr_ ## __n ## _wrapper(const char *fmt, ...) \ 240 { \ 241 va_list args; \ 242 int ret; \ 243 \ 244 va_start(args, fmt); \ 245 ret = veprintf(__l, verbose, fmt, args); \ 246 va_end(args); \ 247 return ret; \ 248 } 249 250 DEBUG_WRAPPER(warning, 0); 251 DEBUG_WRAPPER(debug, 1); 252 253 void perf_debug_setup(void) 254 { 255 libapi_set_print(pr_warning_wrapper, pr_warning_wrapper, pr_debug_wrapper); 256 } 257 258 /* Obtain a backtrace and print it to stdout. */ 259 #ifdef HAVE_BACKTRACE_SUPPORT 260 void dump_stack(void) 261 { 262 void *array[16]; 263 size_t size = backtrace(array, ARRAY_SIZE(array)); 264 char **strings = backtrace_symbols(array, size); 265 size_t i; 266 267 printf("Obtained %zd stack frames.\n", size); 268 269 for (i = 0; i < size; i++) 270 printf("%s\n", strings[i]); 271 272 free(strings); 273 } 274 #else 275 void dump_stack(void) {} 276 #endif 277 278 void sighandler_dump_stack(int sig) 279 { 280 psignal(sig, "perf"); 281 dump_stack(); 282 signal(sig, SIG_DFL); 283 raise(sig); 284 } 285