Commit 6142f9ec authored by Peter Zijlstra's avatar Peter Zijlstra Committed by Ingo Molnar

perf report: More robust error handling

Don't let funny events confuse us, stick to what we know and
try to find sensible data again.

If we find an unknown event, check we're still u64 aligned, and
increment by one u64. This ensures we're bound to happen upon a
valid event soon.
Signed-off-by: default avatarPeter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Marcelo Tosatti <mtosatti@redhat.com>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: John Kacur <jkacur@redhat.com>
LKML-Reference: <new-submission>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent f49515b1
...@@ -645,6 +645,7 @@ static int __cmd_report(void) ...@@ -645,6 +645,7 @@ static int __cmd_report(void)
char *buf; char *buf;
event_t *event; event_t *event;
int ret, rc = EXIT_FAILURE; int ret, rc = EXIT_FAILURE;
uint32_t size;
unsigned long total = 0, total_mmap = 0, total_comm = 0, total_unknown = 0; unsigned long total = 0, total_mmap = 0, total_comm = 0, total_unknown = 0;
input = open(input_name, O_RDONLY); input = open(input_name, O_RDONLY);
...@@ -680,6 +681,10 @@ static int __cmd_report(void) ...@@ -680,6 +681,10 @@ static int __cmd_report(void)
more: more:
event = (event_t *)(buf + head); event = (event_t *)(buf + head);
size = event->header.size;
if (!size)
size = 8;
if (head + event->header.size >= page_size * mmap_window) { if (head + event->header.size >= page_size * mmap_window) {
unsigned long shift = page_size * (head / page_size); unsigned long shift = page_size * (head / page_size);
int ret; int ret;
...@@ -692,12 +697,9 @@ static int __cmd_report(void) ...@@ -692,12 +697,9 @@ static int __cmd_report(void)
goto remap; goto remap;
} }
size = event->header.size;
if (!event->header.size) { if (!size)
fprintf(stderr, "zero-sized event at file offset %ld\n", offset + head); goto broken_event;
fprintf(stderr, "skipping %ld bytes of events.\n", stat.st_size - offset - head);
goto done;
}
if (event->header.misc & PERF_EVENT_MISC_OVERFLOW) { if (event->header.misc & PERF_EVENT_MISC_OVERFLOW) {
char level; char level;
...@@ -787,15 +789,26 @@ static int __cmd_report(void) ...@@ -787,15 +789,26 @@ static int __cmd_report(void)
break; break;
} }
default: { default: {
broken_event:
fprintf(stderr, "%p [%p]: skipping unknown header type: %d\n", fprintf(stderr, "%p [%p]: skipping unknown header type: %d\n",
(void *)(offset + head), (void *)(offset + head),
(void *)(long)(event->header.size), (void *)(long)(event->header.size),
event->header.type); event->header.type);
total_unknown++; total_unknown++;
/*
* assume we lost track of the stream, check alignment, and
* increment a single u64 in the hope to catch on again 'soon'.
*/
if (unlikely(head & 7))
head &= ~7ULL;
size = 8;
} }
} }
head += event->header.size; head += size;
if (offset + head < stat.st_size) if (offset + head < stat.st_size)
goto more; goto more;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment