Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

tools lib traceevent: Add support for __print_hex()

Since the __print_hex() function is used in print fmt now, add
corresponding parser routines. This makes the output of perf script on
the kvm_emulate_insn event not to fail any more.

before:
kvm_emulate_insn: [FAILED TO PARSE] rip=3238197797 ...

after:
kvm_emulate_insn: 0:c102fa25:89 10 (prot32)

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Steven Rostedt <rostedt@goodmis.org>
Link: http://lkml.kernel.org/r/1340757701-10711-4-git-send-email-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Namhyung Kim and committed by
Arnaldo Carvalho de Melo
e080e6f1 b7008071

+89 -1
+74 -1
tools/lib/traceevent/event-parse.c
··· 697 697 free_arg(arg->symbol.field); 698 698 free_flag_sym(arg->symbol.symbols); 699 699 break; 700 + case PRINT_HEX: 701 + free_arg(arg->hex.field); 702 + free_arg(arg->hex.size); 703 + break; 700 704 case PRINT_TYPE: 701 705 free(arg->typecast.type); 702 706 free_arg(arg->typecast.item); ··· 2264 2260 } 2265 2261 2266 2262 static enum event_type 2263 + process_hex(struct event_format *event, struct print_arg *arg, char **tok) 2264 + { 2265 + struct print_arg *field; 2266 + enum event_type type; 2267 + char *token; 2268 + 2269 + memset(arg, 0, sizeof(*arg)); 2270 + arg->type = PRINT_HEX; 2271 + 2272 + field = alloc_arg(); 2273 + type = process_arg(event, field, &token); 2274 + 2275 + if (test_type_token(type, token, EVENT_DELIM, ",")) 2276 + goto out_free; 2277 + 2278 + arg->hex.field = field; 2279 + 2280 + free_token(token); 2281 + 2282 + field = alloc_arg(); 2283 + type = process_arg(event, field, &token); 2284 + 2285 + if (test_type_token(type, token, EVENT_DELIM, ")")) 2286 + goto out_free; 2287 + 2288 + arg->hex.size = field; 2289 + 2290 + free_token(token); 2291 + type = read_token_item(tok); 2292 + return type; 2293 + 2294 + out_free: 2295 + free_arg(field); 2296 + free_token(token); 2297 + *tok = NULL; 2298 + return EVENT_ERROR; 2299 + } 2300 + 2301 + static enum event_type 2267 2302 process_dynamic_array(struct event_format *event, struct print_arg *arg, char **tok) 2268 2303 { 2269 2304 struct format_field *field; ··· 2530 2487 free_token(token); 2531 2488 is_symbolic_field = 1; 2532 2489 return process_symbols(event, arg, tok); 2490 + } 2491 + if (strcmp(token, "__print_hex") == 0) { 2492 + free_token(token); 2493 + return process_hex(event, arg, tok); 2533 2494 } 2534 2495 if (strcmp(token, "__get_str") == 0) { 2535 2496 free_token(token); ··· 3042 2995 break; 3043 2996 case PRINT_FLAGS: 3044 2997 case PRINT_SYMBOL: 2998 + case PRINT_HEX: 3045 2999 break; 3046 3000 case PRINT_TYPE: 3047 3001 val = eval_num_arg(data, size, event, arg->typecast.item); ··· 3266 3218 unsigned long long val, fval; 3267 3219 unsigned long addr; 3268 3220 char *str; 3221 + unsigned char *hex; 3269 3222 int print; 3270 - int len; 3223 + int i, len; 3271 3224 3272 3225 switch (arg->type) { 3273 3226 case PRINT_NULL: ··· 3331 3282 print_str_to_seq(s, format, len_arg, flag->str); 3332 3283 break; 3333 3284 } 3285 + } 3286 + break; 3287 + case PRINT_HEX: 3288 + field = arg->hex.field->field.field; 3289 + if (!field) { 3290 + str = arg->hex.field->field.name; 3291 + field = pevent_find_any_field(event, str); 3292 + if (!field) 3293 + die("field %s not found", str); 3294 + arg->hex.field->field.field = field; 3295 + } 3296 + hex = data + field->offset; 3297 + len = eval_num_arg(data, size, event, arg->hex.size); 3298 + for (i = 0; i < len; i++) { 3299 + if (i) 3300 + trace_seq_putc(s, ' '); 3301 + trace_seq_printf(s, "%02x", hex[i]); 3334 3302 } 3335 3303 break; 3336 3304 ··· 4358 4292 print_fields(&s, args->symbol.symbols); 4359 4293 trace_seq_do_printf(&s); 4360 4294 trace_seq_destroy(&s); 4295 + printf(")"); 4296 + break; 4297 + case PRINT_HEX: 4298 + printf("__print_hex("); 4299 + print_args(args->hex.field); 4300 + printf(", "); 4301 + print_args(args->hex.size); 4361 4302 printf(")"); 4362 4303 break; 4363 4304 case PRINT_STRING:
+7
tools/lib/traceevent/event-parse.h
··· 226 226 struct print_flag_sym *symbols; 227 227 }; 228 228 229 + struct print_arg_hex { 230 + struct print_arg *field; 231 + struct print_arg *size; 232 + }; 233 + 229 234 struct print_arg_dynarray { 230 235 struct format_field *field; 231 236 struct print_arg *index; ··· 258 253 PRINT_FIELD, 259 254 PRINT_FLAGS, 260 255 PRINT_SYMBOL, 256 + PRINT_HEX, 261 257 PRINT_TYPE, 262 258 PRINT_STRING, 263 259 PRINT_BSTRING, ··· 276 270 struct print_arg_typecast typecast; 277 271 struct print_arg_flags flags; 278 272 struct print_arg_symbol symbol; 273 + struct print_arg_hex hex; 279 274 struct print_arg_func func; 280 275 struct print_arg_string string; 281 276 struct print_arg_op op;
+4
tools/perf/util/scripting-engines/trace-event-perl.c
··· 209 209 define_symbolic_values(args->symbol.symbols, ev_name, 210 210 cur_field_name); 211 211 break; 212 + case PRINT_HEX: 213 + define_event_symbols(event, ev_name, args->hex.field); 214 + define_event_symbols(event, ev_name, args->hex.size); 215 + break; 212 216 case PRINT_BSTRING: 213 217 case PRINT_DYNAMIC_ARRAY: 214 218 case PRINT_STRING:
+4
tools/perf/util/scripting-engines/trace-event-python.c
··· 166 166 define_values(PRINT_SYMBOL, args->symbol.symbols, ev_name, 167 167 cur_field_name); 168 168 break; 169 + case PRINT_HEX: 170 + define_event_symbols(event, ev_name, args->hex.field); 171 + define_event_symbols(event, ev_name, args->hex.size); 172 + break; 169 173 case PRINT_STRING: 170 174 break; 171 175 case PRINT_TYPE: