mirror of
https://github.com/crash-utility/crash
synced 2025-02-19 15:06:48 +00:00
Fix for the handling of ARM and ARM64 QEMU-generated ELF dumpfiles
and compressed kdump clones. The patch utilizes the NT_PRSTATUS notes in the dumpfile headers instead of reading them from the kernel's "crash_notes", which are not initialized when QEMU generates a dumpfile. Without the patch, these warning messages are displayed during session initialization: WARNING: invalid note (n_type != NT_PRSTATUS) WARNING: cannot retrieve registers for active tasks and running "bt" on an active task causes a segmentation violation. (drjones@redhat.com)
This commit is contained in:
parent
2d8895c36a
commit
b2d8f20407
22
arm.c
22
arm.c
@ -597,6 +597,28 @@ arm_get_crash_notes(void)
|
||||
note = (Elf32_Nhdr *)buf;
|
||||
p = buf + sizeof(Elf32_Nhdr);
|
||||
|
||||
/*
|
||||
* dumpfiles created with qemu won't have crash_notes, but there will
|
||||
* be elf notes.
|
||||
*/
|
||||
if (note->n_namesz == 0 && (DISKDUMP_DUMPFILE() || KDUMP_DUMPFILE())) {
|
||||
if (DISKDUMP_DUMPFILE())
|
||||
note = diskdump_get_prstatus_percpu(i);
|
||||
else if (KDUMP_DUMPFILE())
|
||||
note = netdump_get_prstatus_percpu(i);
|
||||
if (note) {
|
||||
/*
|
||||
* SIZE(note_buf) accounts for a "final note", which is a
|
||||
* trailing empty elf note header.
|
||||
*/
|
||||
long notesz = SIZE(note_buf) - sizeof(Elf32_Nhdr);
|
||||
|
||||
if (sizeof(Elf32_Nhdr) + roundup(note->n_namesz, 4) +
|
||||
note->n_descsz == notesz)
|
||||
BCOPY((char *)note, buf, notesz);
|
||||
}
|
||||
}
|
||||
|
||||
if (note->n_type != NT_PRSTATUS) {
|
||||
error(WARNING, "invalid note (n_type != NT_PRSTATUS)\n");
|
||||
goto fail;
|
||||
|
22
arm64.c
22
arm64.c
@ -1828,6 +1828,28 @@ arm64_get_crash_notes(void)
|
||||
note = (Elf64_Nhdr *)buf;
|
||||
p = buf + sizeof(Elf64_Nhdr);
|
||||
|
||||
/*
|
||||
* dumpfiles created with qemu won't have crash_notes, but there will
|
||||
* be elf notes.
|
||||
*/
|
||||
if (note->n_namesz == 0 && (DISKDUMP_DUMPFILE() || KDUMP_DUMPFILE())) {
|
||||
if (DISKDUMP_DUMPFILE())
|
||||
note = diskdump_get_prstatus_percpu(i);
|
||||
else if (KDUMP_DUMPFILE())
|
||||
note = netdump_get_prstatus_percpu(i);
|
||||
if (note) {
|
||||
/*
|
||||
* SIZE(note_buf) accounts for a "final note", which is a
|
||||
* trailing empty elf note header.
|
||||
*/
|
||||
long notesz = SIZE(note_buf) - sizeof(Elf64_Nhdr);
|
||||
|
||||
if (sizeof(Elf64_Nhdr) + roundup(note->n_namesz, 4) +
|
||||
note->n_descsz == notesz)
|
||||
BCOPY((char *)note, buf, notesz);
|
||||
}
|
||||
}
|
||||
|
||||
if (note->n_type != NT_PRSTATUS) {
|
||||
error(WARNING, "invalid note (n_type != NT_PRSTATUS)\n");
|
||||
goto fail;
|
||||
|
1
defs.h
1
defs.h
@ -5721,6 +5721,7 @@ void dump_registers_for_qemu_mem_dump(void);
|
||||
void kdump_backup_region_init(void);
|
||||
void display_regs_from_elf_notes(int, FILE *);
|
||||
void display_ELF_note(int, int, void *, FILE *);
|
||||
void *netdump_get_prstatus_percpu(int);
|
||||
#define PRSTATUS_NOTE (1)
|
||||
#define QEMU_NOTE (2)
|
||||
|
||||
|
21
netdump.c
21
netdump.c
@ -2345,6 +2345,27 @@ dump_Elf64_Nhdr(Elf64_Off offset, int store)
|
||||
return len;
|
||||
}
|
||||
|
||||
void *
|
||||
netdump_get_prstatus_percpu(int cpu)
|
||||
{
|
||||
int online;
|
||||
|
||||
if ((cpu < 0) || (cpu >= nd->num_prstatus_notes))
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* If no cpu mapping was done, then there must be
|
||||
* a one-to-one relationship between the number
|
||||
* of online cpus and the number of notes.
|
||||
*/
|
||||
if ((online = get_cpus_online()) &&
|
||||
(online == kt->cpus) &&
|
||||
(online != nd->num_prstatus_notes))
|
||||
return NULL;
|
||||
|
||||
return nd->nt_prstatus_percpu[cpu];
|
||||
}
|
||||
|
||||
/*
|
||||
* Send the request to the proper architecture hander.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user