at v4.11 4.6 kB view raw
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#include <linux/time64.h> 10 11#include "cache.h" 12#include "color.h" 13#include "event.h" 14#include "debug.h" 15#include "util.h" 16#include "target.h" 17 18int verbose; 19bool dump_trace = false, quiet = false; 20int debug_ordered_events; 21static int redirect_to_stderr; 22int debug_data_convert; 23 24int veprintf(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 38int eprintf(int level, int var, const char *fmt, ...) 39{ 40 va_list args; 41 int ret; 42 43 va_start(args, fmt); 44 ret = veprintf(level, var, fmt, args); 45 va_end(args); 46 47 return ret; 48} 49 50static int veprintf_time(u64 t, const char *fmt, va_list args) 51{ 52 int ret = 0; 53 u64 secs, usecs, nsecs = t; 54 55 secs = nsecs / NSEC_PER_SEC; 56 nsecs -= secs * NSEC_PER_SEC; 57 usecs = nsecs / NSEC_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 65int 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 = veprintf_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 */ 83void pr_stat(const char *fmt, ...) 84{ 85 va_list args; 86 87 va_start(args, fmt); 88 veprintf(1, verbose, fmt, args); 89 va_end(args); 90 eprintf(1, verbose, "\n"); 91} 92 93int 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 107static void trace_event_printer(enum binary_printer_ops op, 108 unsigned int val, void *extra) 109{ 110 const char *color = PERF_COLOR_BLUE; 111 union perf_event *event = (union perf_event *)extra; 112 unsigned char ch = (unsigned char)val; 113 114 switch (op) { 115 case BINARY_PRINT_DATA_BEGIN: 116 printf("."); 117 color_fprintf(stdout, color, "\n. ... raw event: size %d bytes\n", 118 event->header.size); 119 break; 120 case BINARY_PRINT_LINE_BEGIN: 121 printf("."); 122 break; 123 case BINARY_PRINT_ADDR: 124 color_fprintf(stdout, color, " %04x: ", val); 125 break; 126 case BINARY_PRINT_NUM_DATA: 127 color_fprintf(stdout, color, " %02x", val); 128 break; 129 case BINARY_PRINT_NUM_PAD: 130 color_fprintf(stdout, color, " "); 131 break; 132 case BINARY_PRINT_SEP: 133 color_fprintf(stdout, color, " "); 134 break; 135 case BINARY_PRINT_CHAR_DATA: 136 color_fprintf(stdout, color, "%c", 137 isprint(ch) ? ch : '.'); 138 break; 139 case BINARY_PRINT_CHAR_PAD: 140 color_fprintf(stdout, color, " "); 141 break; 142 case BINARY_PRINT_LINE_END: 143 color_fprintf(stdout, color, "\n"); 144 break; 145 case BINARY_PRINT_DATA_END: 146 printf("\n"); 147 break; 148 default: 149 break; 150 } 151} 152 153void trace_event(union perf_event *event) 154{ 155 unsigned char *raw_event = (void *)event; 156 157 if (!dump_trace) 158 return; 159 160 print_binary(raw_event, event->header.size, 16, 161 trace_event_printer, event); 162} 163 164static struct debug_variable { 165 const char *name; 166 int *ptr; 167} debug_variables[] = { 168 { .name = "verbose", .ptr = &verbose }, 169 { .name = "ordered-events", .ptr = &debug_ordered_events}, 170 { .name = "stderr", .ptr = &redirect_to_stderr}, 171 { .name = "data-convert", .ptr = &debug_data_convert }, 172 { .name = NULL, } 173}; 174 175int perf_debug_option(const char *str) 176{ 177 struct debug_variable *var = &debug_variables[0]; 178 char *vstr, *s = strdup(str); 179 int v = 1; 180 181 vstr = strchr(s, '='); 182 if (vstr) 183 *vstr++ = 0; 184 185 while (var->name) { 186 if (!strcmp(s, var->name)) 187 break; 188 var++; 189 } 190 191 if (!var->name) { 192 pr_err("Unknown debug variable name '%s'\n", s); 193 free(s); 194 return -1; 195 } 196 197 if (vstr) { 198 v = atoi(vstr); 199 /* 200 * Allow only values in range (0, 10), 201 * otherwise set 0. 202 */ 203 v = (v < 0) || (v > 10) ? 0 : v; 204 } 205 206 if (quiet) 207 v = -1; 208 209 *var->ptr = v; 210 free(s); 211 return 0; 212} 213 214int perf_quiet_option(void) 215{ 216 struct debug_variable *var = &debug_variables[0]; 217 218 /* disable all debug messages */ 219 while (var->name) { 220 *var->ptr = -1; 221 var++; 222 } 223 224 quiet = true; 225 return 0; 226} 227 228#define DEBUG_WRAPPER(__n, __l) \ 229static int pr_ ## __n ## _wrapper(const char *fmt, ...) \ 230{ \ 231 va_list args; \ 232 int ret; \ 233 \ 234 va_start(args, fmt); \ 235 ret = veprintf(__l, verbose, fmt, args); \ 236 va_end(args); \ 237 return ret; \ 238} 239 240DEBUG_WRAPPER(warning, 0); 241DEBUG_WRAPPER(debug, 1); 242 243void perf_debug_setup(void) 244{ 245 libapi_set_print(pr_warning_wrapper, pr_warning_wrapper, pr_debug_wrapper); 246}