aboutsummaryrefslogtreecommitdiffstats
path: root/Documentation/perf_counter/builtin-report.c
diff options
context:
space:
mode:
authorPeter Zijlstra <a.p.zijlstra@chello.nl>2009-05-26 14:51:47 -0400
committerIngo Molnar <mingo@elte.hu>2009-05-26 14:17:46 -0400
commit6142f9ec108a4ddbf0d5904c3daa5fdcaa618792 (patch)
tree49bd3b00fa337832d85f9629b8671aa6f036ad6b /Documentation/perf_counter/builtin-report.c
parentf49515b157e2d3ca3633eb0664fc46c42f6cb37e (diff)
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 <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: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'Documentation/perf_counter/builtin-report.c')
-rw-r--r--Documentation/perf_counter/builtin-report.c27
1 files changed, 20 insertions, 7 deletions
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)
645 char *buf; 645 char *buf;
646 event_t *event; 646 event_t *event;
647 int ret, rc = EXIT_FAILURE; 647 int ret, rc = EXIT_FAILURE;
648 uint32_t size;
648 unsigned long total = 0, total_mmap = 0, total_comm = 0, total_unknown = 0; 649 unsigned long total = 0, total_mmap = 0, total_comm = 0, total_unknown = 0;
649 650
650 input = open(input_name, O_RDONLY); 651 input = open(input_name, O_RDONLY);
@@ -680,6 +681,10 @@ remap:
680more: 681more:
681 event = (event_t *)(buf + head); 682 event = (event_t *)(buf + head);
682 683
684 size = event->header.size;
685 if (!size)
686 size = 8;
687
683 if (head + event->header.size >= page_size * mmap_window) { 688 if (head + event->header.size >= page_size * mmap_window) {
684 unsigned long shift = page_size * (head / page_size); 689 unsigned long shift = page_size * (head / page_size);
685 int ret; 690 int ret;
@@ -692,12 +697,9 @@ more:
692 goto remap; 697 goto remap;
693 } 698 }
694 699
695 700 size = event->header.size;
696 if (!event->header.size) { 701 if (!size)
697 fprintf(stderr, "zero-sized event at file offset %ld\n", offset + head); 702 goto broken_event;
698 fprintf(stderr, "skipping %ld bytes of events.\n", stat.st_size - offset - head);
699 goto done;
700 }
701 703
702 if (event->header.misc & PERF_EVENT_MISC_OVERFLOW) { 704 if (event->header.misc & PERF_EVENT_MISC_OVERFLOW) {
703 char level; 705 char level;
@@ -787,15 +789,26 @@ more:
787 break; 789 break;
788 } 790 }
789 default: { 791 default: {
792broken_event:
790 fprintf(stderr, "%p [%p]: skipping unknown header type: %d\n", 793 fprintf(stderr, "%p [%p]: skipping unknown header type: %d\n",
791 (void *)(offset + head), 794 (void *)(offset + head),
792 (void *)(long)(event->header.size), 795 (void *)(long)(event->header.size),
793 event->header.type); 796 event->header.type);
794 total_unknown++; 797 total_unknown++;
798
799 /*
800 * assume we lost track of the stream, check alignment, and
801 * increment a single u64 in the hope to catch on again 'soon'.
802 */
803
804 if (unlikely(head & 7))
805 head &= ~7ULL;
806
807 size = 8;
795 } 808 }
796 } 809 }
797 810
798 head += event->header.size; 811 head += size;
799 812
800 if (offset + head < stat.st_size) 813 if (offset + head < stat.st_size)
801 goto more; 814 goto more;