From: Peter Zijlstra Date: Tue, 26 May 2009 18:51:47 +0000 (+0200) Subject: perf report: More robust error handling X-Git-Tag: v2.6.31-rc1~383^2~194 X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=6142f9ec108a4ddbf0d5904c3daa5fdcaa618792;p=karo-tx-linux.git 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: Peter Zijlstra Cc: Mike Galbraith Cc: Paul Mackerras Cc: Corey Ashford Cc: Marcelo Tosatti Cc: Arnaldo Carvalho de Melo Cc: Thomas Gleixner Cc: John Kacur LKML-Reference: Signed-off-by: Ingo Molnar --- diff --git a/Documentation/perf_counter/builtin-report.c b/Documentation/perf_counter/builtin-report.c index 2d4e4cc655a3..a58be7fee425 100644 --- a/Documentation/perf_counter/builtin-report.c +++ b/Documentation/perf_counter/builtin-report.c @@ -645,6 +645,7 @@ static int __cmd_report(void) char *buf; event_t *event; int ret, rc = EXIT_FAILURE; + uint32_t size; unsigned long total = 0, total_mmap = 0, total_comm = 0, total_unknown = 0; input = open(input_name, O_RDONLY); @@ -680,6 +681,10 @@ remap: more: event = (event_t *)(buf + head); + size = event->header.size; + if (!size) + size = 8; + if (head + event->header.size >= page_size * mmap_window) { unsigned long shift = page_size * (head / page_size); int ret; @@ -692,12 +697,9 @@ more: goto remap; } - - if (!event->header.size) { - fprintf(stderr, "zero-sized event at file offset %ld\n", offset + head); - fprintf(stderr, "skipping %ld bytes of events.\n", stat.st_size - offset - head); - goto done; - } + size = event->header.size; + if (!size) + goto broken_event; if (event->header.misc & PERF_EVENT_MISC_OVERFLOW) { char level; @@ -787,15 +789,26 @@ more: break; } default: { +broken_event: fprintf(stderr, "%p [%p]: skipping unknown header type: %d\n", (void *)(offset + head), (void *)(long)(event->header.size), event->header.type); 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) goto more;