Commit b25114817a73bbd2b84ce9dba02ee1ef8989a947
1 parent
9e69c21082
Exists in
master
and in
4 other branches
perf build-id: Add quirk to deal with perf.data file format breakage
The a1645ce1 changeset: "perf: 'perf kvm' tool for monitoring guest performance from host" Added a field to struct build_id_event that broke the file format. Since the kernel build-id is the first entry, process the table using the old format if the well known '[kernel.kallsyms]' string for the kernel build-id has the first 4 characters chopped off (where the pid_t sits). Reported-by: Han Pingtian <phan@redhat.com> Cc: Avi Kivity <avi@redhat.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Cc: Tom Zanussi <tzanussi@gmail.com> Cc: Zhang Yanmin <yanmin_zhang@linux.intel.com> Cc: stable@kernel.org LKML-Reference: <new-submission> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Showing 1 changed file with 56 additions and 1 deletions Side-by-side Diff
tools/perf/util/header.c
... | ... | @@ -695,13 +695,50 @@ |
695 | 695 | return err; |
696 | 696 | } |
697 | 697 | |
698 | +static int perf_header__read_build_ids_abi_quirk(struct perf_header *header, | |
699 | + int input, u64 offset, u64 size) | |
700 | +{ | |
701 | + struct perf_session *session = container_of(header, struct perf_session, header); | |
702 | + struct { | |
703 | + struct perf_event_header header; | |
704 | + u8 build_id[ALIGN(BUILD_ID_SIZE, sizeof(u64))]; | |
705 | + char filename[0]; | |
706 | + } old_bev; | |
707 | + struct build_id_event bev; | |
708 | + char filename[PATH_MAX]; | |
709 | + u64 limit = offset + size; | |
710 | + | |
711 | + while (offset < limit) { | |
712 | + ssize_t len; | |
713 | + | |
714 | + if (read(input, &old_bev, sizeof(old_bev)) != sizeof(old_bev)) | |
715 | + return -1; | |
716 | + | |
717 | + if (header->needs_swap) | |
718 | + perf_event_header__bswap(&old_bev.header); | |
719 | + | |
720 | + len = old_bev.header.size - sizeof(old_bev); | |
721 | + if (read(input, filename, len) != len) | |
722 | + return -1; | |
723 | + | |
724 | + bev.header = old_bev.header; | |
725 | + bev.pid = 0; | |
726 | + memcpy(bev.build_id, old_bev.build_id, sizeof(bev.build_id)); | |
727 | + __event_process_build_id(&bev, filename, session); | |
728 | + | |
729 | + offset += bev.header.size; | |
730 | + } | |
731 | + | |
732 | + return 0; | |
733 | +} | |
734 | + | |
698 | 735 | static int perf_header__read_build_ids(struct perf_header *header, |
699 | 736 | int input, u64 offset, u64 size) |
700 | 737 | { |
701 | 738 | struct perf_session *session = container_of(header, struct perf_session, header); |
702 | 739 | struct build_id_event bev; |
703 | 740 | char filename[PATH_MAX]; |
704 | - u64 limit = offset + size; | |
741 | + u64 limit = offset + size, orig_offset = offset; | |
705 | 742 | int err = -1; |
706 | 743 | |
707 | 744 | while (offset < limit) { |
... | ... | @@ -716,6 +753,24 @@ |
716 | 753 | len = bev.header.size - sizeof(bev); |
717 | 754 | if (read(input, filename, len) != len) |
718 | 755 | goto out; |
756 | + /* | |
757 | + * The a1645ce1 changeset: | |
758 | + * | |
759 | + * "perf: 'perf kvm' tool for monitoring guest performance from host" | |
760 | + * | |
761 | + * Added a field to struct build_id_event that broke the file | |
762 | + * format. | |
763 | + * | |
764 | + * Since the kernel build-id is the first entry, process the | |
765 | + * table using the old format if the well known | |
766 | + * '[kernel.kallsyms]' string for the kernel build-id has the | |
767 | + * first 4 characters chopped off (where the pid_t sits). | |
768 | + */ | |
769 | + if (memcmp(filename, "nel.kallsyms]", 13) == 0) { | |
770 | + if (lseek(input, orig_offset, SEEK_SET) == (off_t)-1) | |
771 | + return -1; | |
772 | + return perf_header__read_build_ids_abi_quirk(header, input, offset, size); | |
773 | + } | |
719 | 774 | |
720 | 775 | __event_process_build_id(&bev, filename, session); |
721 | 776 |