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

tools lib traceevent: Check string is really printable

When libtraceevent parses format fields, it assumes that array of 1 byte
is string but it's not always true. The kvm_emulate_insn contains 15 u8
array of insn that contains (binary) instructions. Thus when it's
printed, it'll have broken output like below:

kvm_emulate_insn: [FAILED TO PARSE] rip=3238197797 csbase=0 len=2 \
insn=<89>P^]<B4>& flags=5 failed=0

With this patch:

kvm_emulate_insn: [FAILED TO PARSE] rip=3238197797 csbase=0 len=2 \
insn=ARRAY[89, 10, 5d, c3, 8d, b4, 26, 00, 00, 00, 00, 55, 89, e5, 3e] flags=5 failed=0

Suggested-by: Steven Rostedt <rostedt@goodmis.org>
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/1340352615-20737-2-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
600da3cf 860df583

+13 -1
+13 -1
tools/lib/traceevent/event-parse.c
··· 3589 3589 trace_seq_printf(s, fmt, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]); 3590 3590 } 3591 3591 3592 + static int is_printable_array(char *p, unsigned int len) 3593 + { 3594 + unsigned int i; 3595 + 3596 + for (i = 0; i < len && p[i]; i++) 3597 + if (!isprint(p[i])) 3598 + return 0; 3599 + return 1; 3600 + } 3601 + 3592 3602 static void print_event_fields(struct trace_seq *s, void *data, int size, 3593 3603 struct event_format *event) 3594 3604 { ··· 3618 3608 len = offset >> 16; 3619 3609 offset &= 0xffff; 3620 3610 } 3621 - if (field->flags & FIELD_IS_STRING) { 3611 + if (field->flags & FIELD_IS_STRING && 3612 + is_printable_array(data + offset, len)) { 3622 3613 trace_seq_printf(s, "%s", (char *)data + offset); 3623 3614 } else { 3624 3615 trace_seq_puts(s, "ARRAY["); ··· 3630 3619 *((unsigned char *)data + offset + i)); 3631 3620 } 3632 3621 trace_seq_putc(s, ']'); 3622 + field->flags &= ~FIELD_IS_STRING; 3633 3623 } 3634 3624 } else { 3635 3625 val = pevent_read_number(event->pevent, data + field->offset,