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_array()

Since 6ea22486ba46 ("tracing: Add array printing helper") trace can
generate traces with variable element size arrays. Add support to
parse them.

Signed-off-by: Javi Merino <javi.merino@arm.com>
Acked-by: Namhyung Kim <namhyung@kernel.org>
Acked-by: Steven Rostedt <rostedt@goodmis.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Link: http://lkml.kernel.org/r/1427195239-15730-1-git-send-email-javi.merino@arm.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Javi Merino and committed by
Arnaldo Carvalho de Melo
b839e1e8 e1644aae

+111
+93
tools/lib/traceevent/event-parse.c
··· 766 766 free_arg(arg->hex.field); 767 767 free_arg(arg->hex.size); 768 768 break; 769 + case PRINT_INT_ARRAY: 770 + free_arg(arg->int_array.field); 771 + free_arg(arg->int_array.count); 772 + free_arg(arg->int_array.el_size); 773 + break; 769 774 case PRINT_TYPE: 770 775 free(arg->typecast.type); 771 776 free_arg(arg->typecast.item); ··· 2550 2545 } 2551 2546 2552 2547 static enum event_type 2548 + process_int_array(struct event_format *event, struct print_arg *arg, char **tok) 2549 + { 2550 + memset(arg, 0, sizeof(*arg)); 2551 + arg->type = PRINT_INT_ARRAY; 2552 + 2553 + if (alloc_and_process_delim(event, ",", &arg->int_array.field)) 2554 + goto out; 2555 + 2556 + if (alloc_and_process_delim(event, ",", &arg->int_array.count)) 2557 + goto free_field; 2558 + 2559 + if (alloc_and_process_delim(event, ")", &arg->int_array.el_size)) 2560 + goto free_size; 2561 + 2562 + return read_token_item(tok); 2563 + 2564 + free_size: 2565 + free_arg(arg->int_array.count); 2566 + free_field: 2567 + free_arg(arg->int_array.field); 2568 + out: 2569 + *tok = NULL; 2570 + return EVENT_ERROR; 2571 + } 2572 + 2573 + static enum event_type 2553 2574 process_dynamic_array(struct event_format *event, struct print_arg *arg, char **tok) 2554 2575 { 2555 2576 struct format_field *field; ··· 2869 2838 if (strcmp(token, "__print_hex") == 0) { 2870 2839 free_token(token); 2871 2840 return process_hex(event, arg, tok); 2841 + } 2842 + if (strcmp(token, "__print_array") == 0) { 2843 + free_token(token); 2844 + return process_int_array(event, arg, tok); 2872 2845 } 2873 2846 if (strcmp(token, "__get_str") == 0) { 2874 2847 free_token(token); ··· 3402 3367 break; 3403 3368 case PRINT_FLAGS: 3404 3369 case PRINT_SYMBOL: 3370 + case PRINT_INT_ARRAY: 3405 3371 case PRINT_HEX: 3406 3372 break; 3407 3373 case PRINT_TYPE: ··· 3813 3777 } 3814 3778 break; 3815 3779 3780 + case PRINT_INT_ARRAY: { 3781 + void *num; 3782 + int el_size; 3783 + 3784 + if (arg->int_array.field->type == PRINT_DYNAMIC_ARRAY) { 3785 + unsigned long offset; 3786 + struct format_field *field = 3787 + arg->int_array.field->dynarray.field; 3788 + offset = pevent_read_number(pevent, 3789 + data + field->offset, 3790 + field->size); 3791 + num = data + (offset & 0xffff); 3792 + } else { 3793 + field = arg->int_array.field->field.field; 3794 + if (!field) { 3795 + str = arg->int_array.field->field.name; 3796 + field = pevent_find_any_field(event, str); 3797 + if (!field) 3798 + goto out_warning_field; 3799 + arg->int_array.field->field.field = field; 3800 + } 3801 + num = data + field->offset; 3802 + } 3803 + len = eval_num_arg(data, size, event, arg->int_array.count); 3804 + el_size = eval_num_arg(data, size, event, 3805 + arg->int_array.el_size); 3806 + for (i = 0; i < len; i++) { 3807 + if (i) 3808 + trace_seq_putc(s, ' '); 3809 + 3810 + if (el_size == 1) { 3811 + trace_seq_printf(s, "%u", *(uint8_t *)num); 3812 + } else if (el_size == 2) { 3813 + trace_seq_printf(s, "%u", *(uint16_t *)num); 3814 + } else if (el_size == 4) { 3815 + trace_seq_printf(s, "%u", *(uint32_t *)num); 3816 + } else if (el_size == 8) { 3817 + trace_seq_printf(s, "%lu", *(uint64_t *)num); 3818 + } else { 3819 + trace_seq_printf(s, "BAD SIZE:%d 0x%x", 3820 + el_size, *(uint8_t *)num); 3821 + el_size = 1; 3822 + } 3823 + 3824 + num += el_size; 3825 + } 3826 + break; 3827 + } 3816 3828 case PRINT_TYPE: 3817 3829 break; 3818 3830 case PRINT_STRING: { ··· 5443 5359 print_args(args->hex.field); 5444 5360 printf(", "); 5445 5361 print_args(args->hex.size); 5362 + printf(")"); 5363 + break; 5364 + case PRINT_INT_ARRAY: 5365 + printf("__print_array("); 5366 + print_args(args->int_array.field); 5367 + printf(", "); 5368 + print_args(args->int_array.count); 5369 + printf(", "); 5370 + print_args(args->int_array.el_size); 5446 5371 printf(")"); 5447 5372 break; 5448 5373 case PRINT_STRING:
+8
tools/lib/traceevent/event-parse.h
··· 251 251 struct print_arg *size; 252 252 }; 253 253 254 + struct print_arg_int_array { 255 + struct print_arg *field; 256 + struct print_arg *count; 257 + struct print_arg *el_size; 258 + }; 259 + 254 260 struct print_arg_dynarray { 255 261 struct format_field *field; 256 262 struct print_arg *index; ··· 285 279 PRINT_FLAGS, 286 280 PRINT_SYMBOL, 287 281 PRINT_HEX, 282 + PRINT_INT_ARRAY, 288 283 PRINT_TYPE, 289 284 PRINT_STRING, 290 285 PRINT_BSTRING, ··· 305 298 struct print_arg_flags flags; 306 299 struct print_arg_symbol symbol; 307 300 struct print_arg_hex hex; 301 + struct print_arg_int_array int_array; 308 302 struct print_arg_func func; 309 303 struct print_arg_string string; 310 304 struct print_arg_bitmask bitmask;
+5
tools/perf/util/scripting-engines/trace-event-perl.c
··· 214 214 define_event_symbols(event, ev_name, args->hex.field); 215 215 define_event_symbols(event, ev_name, args->hex.size); 216 216 break; 217 + case PRINT_INT_ARRAY: 218 + define_event_symbols(event, ev_name, args->int_array.field); 219 + define_event_symbols(event, ev_name, args->int_array.count); 220 + define_event_symbols(event, ev_name, args->int_array.el_size); 221 + break; 217 222 case PRINT_BSTRING: 218 223 case PRINT_DYNAMIC_ARRAY: 219 224 case PRINT_STRING:
+5
tools/perf/util/scripting-engines/trace-event-python.c
··· 231 231 define_event_symbols(event, ev_name, args->hex.field); 232 232 define_event_symbols(event, ev_name, args->hex.size); 233 233 break; 234 + case PRINT_INT_ARRAY: 235 + define_event_symbols(event, ev_name, args->int_array.field); 236 + define_event_symbols(event, ev_name, args->int_array.count); 237 + define_event_symbols(event, ev_name, args->int_array.el_size); 238 + break; 234 239 case PRINT_STRING: 235 240 break; 236 241 case PRINT_TYPE: