mirror of https://gitee.com/openkylin/linux.git
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>
This commit is contained in:
parent
9e69c21082
commit
b25114817a
|
@ -695,13 +695,50 @@ static int __event_process_build_id(struct build_id_event *bev,
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int perf_header__read_build_ids_abi_quirk(struct perf_header *header,
|
||||||
|
int input, u64 offset, u64 size)
|
||||||
|
{
|
||||||
|
struct perf_session *session = container_of(header, struct perf_session, header);
|
||||||
|
struct {
|
||||||
|
struct perf_event_header header;
|
||||||
|
u8 build_id[ALIGN(BUILD_ID_SIZE, sizeof(u64))];
|
||||||
|
char filename[0];
|
||||||
|
} old_bev;
|
||||||
|
struct build_id_event bev;
|
||||||
|
char filename[PATH_MAX];
|
||||||
|
u64 limit = offset + size;
|
||||||
|
|
||||||
|
while (offset < limit) {
|
||||||
|
ssize_t len;
|
||||||
|
|
||||||
|
if (read(input, &old_bev, sizeof(old_bev)) != sizeof(old_bev))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (header->needs_swap)
|
||||||
|
perf_event_header__bswap(&old_bev.header);
|
||||||
|
|
||||||
|
len = old_bev.header.size - sizeof(old_bev);
|
||||||
|
if (read(input, filename, len) != len)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
bev.header = old_bev.header;
|
||||||
|
bev.pid = 0;
|
||||||
|
memcpy(bev.build_id, old_bev.build_id, sizeof(bev.build_id));
|
||||||
|
__event_process_build_id(&bev, filename, session);
|
||||||
|
|
||||||
|
offset += bev.header.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int perf_header__read_build_ids(struct perf_header *header,
|
static int perf_header__read_build_ids(struct perf_header *header,
|
||||||
int input, u64 offset, u64 size)
|
int input, u64 offset, u64 size)
|
||||||
{
|
{
|
||||||
struct perf_session *session = container_of(header, struct perf_session, header);
|
struct perf_session *session = container_of(header, struct perf_session, header);
|
||||||
struct build_id_event bev;
|
struct build_id_event bev;
|
||||||
char filename[PATH_MAX];
|
char filename[PATH_MAX];
|
||||||
u64 limit = offset + size;
|
u64 limit = offset + size, orig_offset = offset;
|
||||||
int err = -1;
|
int err = -1;
|
||||||
|
|
||||||
while (offset < limit) {
|
while (offset < limit) {
|
||||||
|
@ -716,6 +753,24 @@ static int perf_header__read_build_ids(struct perf_header *header,
|
||||||
len = bev.header.size - sizeof(bev);
|
len = bev.header.size - sizeof(bev);
|
||||||
if (read(input, filename, len) != len)
|
if (read(input, filename, len) != len)
|
||||||
goto out;
|
goto out;
|
||||||
|
/*
|
||||||
|
* 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).
|
||||||
|
*/
|
||||||
|
if (memcmp(filename, "nel.kallsyms]", 13) == 0) {
|
||||||
|
if (lseek(input, orig_offset, SEEK_SET) == (off_t)-1)
|
||||||
|
return -1;
|
||||||
|
return perf_header__read_build_ids_abi_quirk(header, input, offset, size);
|
||||||
|
}
|
||||||
|
|
||||||
__event_process_build_id(&bev, filename, session);
|
__event_process_build_id(&bev, filename, session);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue