diff options
author | Namhyung Kim <namhyung.kim@lge.com> | 2012-06-22 04:10:15 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2012-06-29 12:28:12 -0400 |
commit | 600da3cfe19496485c5d8d52ff703590a0bd53f6 (patch) | |
tree | 6c5dd5f1e4ce2d85b247024cbecfc75e3d3e606a /tools/lib/traceevent | |
parent | 860df5833e461beba4bf9f3304a7919da98fd789 (diff) |
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>
Diffstat (limited to 'tools/lib/traceevent')
-rw-r--r-- | tools/lib/traceevent/event-parse.c | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c index 554828219c33..b203a50c0f22 100644 --- a/tools/lib/traceevent/event-parse.c +++ b/tools/lib/traceevent/event-parse.c | |||
@@ -3589,6 +3589,16 @@ static void print_mac_arg(struct trace_seq *s, int mac, void *data, int size, | |||
3589 | trace_seq_printf(s, fmt, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]); | 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 | static void print_event_fields(struct trace_seq *s, void *data, int size, | 3602 | static void print_event_fields(struct trace_seq *s, void *data, int size, |
3593 | struct event_format *event) | 3603 | struct event_format *event) |
3594 | { | 3604 | { |
@@ -3608,7 +3618,8 @@ static void print_event_fields(struct trace_seq *s, void *data, int size, | |||
3608 | len = offset >> 16; | 3618 | len = offset >> 16; |
3609 | offset &= 0xffff; | 3619 | offset &= 0xffff; |
3610 | } | 3620 | } |
3611 | if (field->flags & FIELD_IS_STRING) { | 3621 | if (field->flags & FIELD_IS_STRING && |
3622 | is_printable_array(data + offset, len)) { | ||
3612 | trace_seq_printf(s, "%s", (char *)data + offset); | 3623 | trace_seq_printf(s, "%s", (char *)data + offset); |
3613 | } else { | 3624 | } else { |
3614 | trace_seq_puts(s, "ARRAY["); | 3625 | trace_seq_puts(s, "ARRAY["); |
@@ -3619,6 +3630,7 @@ static void print_event_fields(struct trace_seq *s, void *data, int size, | |||
3619 | *((unsigned char *)data + offset + i)); | 3630 | *((unsigned char *)data + offset + i)); |
3620 | } | 3631 | } |
3621 | trace_seq_putc(s, ']'); | 3632 | trace_seq_putc(s, ']'); |
3633 | field->flags &= ~FIELD_IS_STRING; | ||
3622 | } | 3634 | } |
3623 | } else { | 3635 | } else { |
3624 | val = pevent_read_number(event->pevent, data + field->offset, | 3636 | val = pevent_read_number(event->pevent, data + field->offset, |