On 12/11/2014 06:27 AM, Dave Anderson wrote:
First, please address all of these warnings: $ make warn ... [ cut ] ... cc -c -g -DX86_64 -DLZO -DSNAPPY -DGDB_7_6 netdump.c -Wall -O2 -Wstrict-prototypes -Wmissing-prototypes -fstack-protector -Wformat-security netdump.c: In function 'dump_Elf32_Nhdr': netdump.c:1987:4: warning: format not a string literal and no format arguments [-Wformat-security] netdump.c: In function 'dump_Elf64_Nhdr': netdump.c:2272:4: warning: format not a string literal and no format arguments [-Wformat-security] netdump.c:2303:4: warning: format not a string literal and no format arguments [-Wformat-security] ...
Hello Dave, These warnings have been addressed.
Secondly, for compressed kdumps in diskdump.c, you have this construct: if (dd->machine_type == EM_386) display_note_elf32(dd->nt_prstatus_percpu[i],l_buf); else if (dd->machine_type == EM_X86_64) display_note_elf64(dd->nt_prstatus_percpu[i],l_buf); But for ELF kdumps in netdump.c, display_note_elf32() are display_note_elf64() look to be called unconditionally. What about the other architectures?
I distinguish the architectures by the struct size in display_note(). I wonder if it is needed to add other conditions like machine_type. display_note(void *note_ptr, char *buf, int descsz) { if (descsz == (2 * sizeof(struct x86_64_prstatus))) display_prstatus_elf64(note_ptr, buf); else if (descsz == sizeof(struct x86_prstatus)) display_prstatus_elf32(note_ptr, buf); else if (descsz == (2 * sizeof(QEMUCPUState))) display_qemu_elf64(note_ptr, buf); else if (descsz == sizeof(QEMUCPUState)) display_qemu_elf32(note_ptr, buf); }
Also, are there any dumping facilities that actually utilize any of the nt_prstatus fields besides the registers and maybe the pid?: struct x86_64_prstatus { int si_signo; int si_code; int si_errno; short cursig; unsigned long sigpend; unsigned long sighold; int pid; int ppid; int pgrp; int sid; struct timeval utime; struct timeval stime; struct timeval cutime; struct timeval cstime; struct x86_64_user_regs_struct regs; int fpvalid; }; For example, kdump just does this: memset(&prstatus, 0, sizeof(prstatus)); prstatus.pr_pid = current->pid; elf_core_copy_kernel_regs(&prstatus.pr_reg, regs); So I guess I wonder what is the point of displaying of all the other fields?
These patches are just used to make the original information readable. I'm not sure whether it is a good idea to display only the registers contents here, for help -r can show them well.
Also, can you explain to me the difference between the register contents in the QEMUCPUState structure vs. the register contents in the NT_PRSTATUS note?
They are almost the same except that there are more information in QEMUCPUState.
And related to that question, why doesn't your dump_qemu_elf() function display the rip and rflags registers?
It's my fault that I left them. And they have been added.
Dave -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility
-- Thanks Zhou Wenjian
From d55b7f1102c40d8ee18211c03c1eb74d3f81ba15 Mon Sep 17 00:00:00 2001 From: Zhou Wenjian <zhouwj-fnst@xxxxxxxxxxxxxx> Date: Wed, 10 Dec 2014 10:34:46 +0800 Subject: [PATCH 1/5] Make elf64 note human readable --- netdump.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 97 insertions(+), 0 deletions(-) diff --git a/netdump.c b/netdump.c index 903faa0..c3bd0e3 100644 --- a/netdump.c +++ b/netdump.c @@ -45,6 +45,7 @@ static int proc_kcore_init_64(FILE *fp); static char *get_regs_from_note(char *, ulong *, ulong *); static void kdump_get_osrelease(void); static char *vmcoreinfo_read_string(const char *); +void display_note_elf64(void *note_ptr, char *buf); #define ELFSTORE 1 @@ -2279,6 +2280,12 @@ dump_Elf64_Nhdr(Elf64_Off offset, int store) iptr = (int *)uptr; netdump_print(" %08lx\n", *iptr); } else { + if (nd->ofp) { + char *l_buf = (char *)malloc(2 * BUFSIZE); + display_note_elf64(note,l_buf); + fprintf(fp, "%s", l_buf); + free(l_buf); + } for (i = lf = 0; i < note->n_descsz/sizeof(ulonglong); i++) { if (((i%2)==0)) { netdump_print("%s ", @@ -2543,6 +2550,96 @@ struct x86_64_user_regs_struct { unsigned long ds,es,fs,gs; }; +struct x86_64_prstatus { + int si_signo; + int si_code; + int si_errno; + short cursig; + unsigned long sigpend; + unsigned long sighold; + int pid; + int ppid; + int pgrp; + int sid; + struct timeval utime; + struct timeval stime; + struct timeval cutime; + struct timeval cstime; + struct x86_64_user_regs_struct regs; + int fpvalid; +}; + +static void +display_prstatus_elf64(void *note_ptr, char *buf) +{ + struct x86_64_prstatus *pr; + Elf64_Nhdr *note; + + note = (Elf64_Nhdr *)note_ptr; + pr = (struct x86_64_prstatus *)( + (char *)note + sizeof(Elf64_Nhdr) + note->n_namesz); + pr = (struct x86_64_prstatus *)roundup((ulong)pr, 4); + sprintf(buf, + "\t\tsi.signo: %d, si.code: %d, si.errno: %d, cursig:%d\n" + "\t\tsigpend: %lu\n" + "\t\tsighold: %lu\n" + "\t\tpid: %d, ppid: %d, pgrp: %d, sid:%d\n" + "\t\tutime: %01lld.%06d, stime: %01lld.%06d, cutime: %01lld.%06d, " + "cstime: %01lld.%06d\n" + "\t\tORIG_RAX: %lu, fpvalid: %d\n" + "\t\tR15 : 0x%016lx\tR14 : 0x%016lx\n" + "\t\tR13 : 0x%016lx\tR12 : 0x%016lx\n" + "\t\tRBP : 0x%016lx\tRBX : 0x%016lx\n" + "\t\tR11 : 0x%016lx\tR10 : 0x%016lx\n" + "\t\tR9 : 0x%016lx\tR8 : 0x%016lx\n" + "\t\tRAX : 0x%016lx\tRCX : 0x%016lx\n" + "\t\tRDX : 0x%016lx\tRSI : 0x%016lx\n" + "\t\tRDI : 0x%016lx\tRIP : 0x%016lx\n" + "\t\tRFLAGS : 0x%016lx\tRSP : 0x%016lx\n" + "\t\tFS_BASE: 0x%016lx\tGS_BASE : 0x%016lx\n" + "\t\tCS: 0x%04lx SS: 0x%04lx DS: 0x%04lx ES: 0x%04lx " + "FS: 0x%04lx GS: 0x%04lx\n", + pr->si_signo, pr->si_code, pr->si_errno, pr->cursig, + pr->sigpend, pr->sighold, + pr->pid, pr->ppid, pr->pgrp, pr->sid, + (long long)pr->utime.tv_sec, (int)pr->utime.tv_usec, + (long long)pr->stime.tv_sec, (int)pr->stime.tv_usec, + (long long)pr->cutime.tv_sec, (int)pr->cutime.tv_usec, + (long long)pr->cstime.tv_sec, (int)pr->cstime.tv_usec, + pr->regs.orig_rax, pr->fpvalid, + pr->regs.r15, pr->regs.r14, + pr->regs.r13, pr->regs.r12, + pr->regs.rbp, pr->regs.rbx, + pr->regs.r11, pr->regs.r10, + pr->regs.r9, pr->regs.r8, + pr->regs.rax, pr->regs.rcx, + pr->regs.rdx, pr->regs.rsi, + pr->regs.rdi, pr->regs.rip, + pr->regs.eflags, pr->regs.rsp, + pr->regs.fs_base, pr->regs.gs_base, + pr->regs.cs, pr->regs.ss, + pr->regs.ds, pr->regs.es, + pr->regs.fs, pr->regs.gs + ); +} + +static void +display_note(void *note_ptr, char *buf, int descsz) +{ + if (descsz == (2 * sizeof(struct x86_64_prstatus))) + display_prstatus_elf64(note_ptr, buf); +} + +void +display_note_elf64(void *note_ptr, char *buf) +{ + Elf64_Nhdr *note; + + note = (Elf64_Nhdr *)note_ptr; + + display_note(note_ptr, buf, 2 * (note->n_descsz)); +} + void get_netdump_regs_x86_64(struct bt_info *bt, ulong *ripp, ulong *rspp) { -- 1.7.1
From 263faa8870abe59ea36e42f676045af36d8774e5 Mon Sep 17 00:00:00 2001 From: Zhou Wenjian <zhouwj-fnst@xxxxxxxxxxxxxx> Date: Wed, 10 Dec 2014 10:35:45 +0800 Subject: [PATCH 2/5] Make elf32 note human readable --- netdump.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 89 insertions(+), 0 deletions(-) diff --git a/netdump.c b/netdump.c index c3bd0e3..51403b7 100644 --- a/netdump.c +++ b/netdump.c @@ -46,6 +46,7 @@ static char *get_regs_from_note(char *, ulong *, ulong *); static void kdump_get_osrelease(void); static char *vmcoreinfo_read_string(const char *); void display_note_elf64(void *note_ptr, char *buf); +void display_note_elf32(void *note_ptr, char *buf); #define ELFSTORE 1 @@ -1977,6 +1978,12 @@ dump_Elf32_Nhdr(Elf32_Off offset, int store) } lf = 0; } else { + if (nd->ofp) { + char *l_buf = (char *)malloc(2 * BUFSIZE); + display_note_elf32(note,l_buf); + fprintf(fp, "%s", l_buf); + free(l_buf); + } for (i = lf = 0; i < note->n_descsz/sizeof(ulong); i++) { if (((i%4)==0)) { netdump_print("%s ", @@ -2623,11 +2630,83 @@ display_prstatus_elf64(void *note_ptr, char *buf) ); } +struct x86_user_regs_struct { + unsigned long ebx,ecx,edx,esi,edi,ebp,eax; + unsigned long ds,es,fs,gs,orig_eax; + unsigned long eip,cs,eflags; + unsigned long esp,ss; +}; + +struct x86_prstatus { + int si_signo; + int si_code; + int si_errno; + short cursig; + unsigned long sigpend; + unsigned long sighold; + int pid; + int ppid; + int pgrp; + int sid; + struct timeval utime; + struct timeval stime; + struct timeval cutime; + struct timeval cstime; + struct x86_user_regs_struct regs; + int fpvalid; +}; + +static void +display_prstatus_elf32(void *note_ptr, char *buf) +{ + struct x86_prstatus *pr; + Elf32_Nhdr *note; + + note = (Elf32_Nhdr *)note_ptr; + pr = (struct x86_prstatus *)( + (char *)note + sizeof(Elf32_Nhdr) + note->n_namesz); + pr = (struct x86_prstatus *)roundup((ulong)pr, 4); + + sprintf(buf, + "\t\tsi.signo: %d si.code: %d si.errno: %d cursig: %d\n" + "\t\tsigpend : %lu\n" + "\t\tsighold : %lu\n" + "\t\tpid: %d ppid: %d pgrp: %d sid: %d\n" + "\t\tutime: %01lld.%06d, stime: %01lld.%06d, cutime: %01lld.%06d, " + "cstime: %01lld.%06d\n" + "\t\torig_eax: %lu, fpvalid: %d\n" + "\t\tEBX : 0x%08lx\tECX : 0x%08lx\n" + "\t\tEDX : 0x%08lx\tESI : 0x%08lx\n" + "\t\tEDI : 0x%08lx\tEBP : 0x%08lx\n" + "\t\tEAX : 0x%08lx\tEIP : 0x%08lx\n" + "\t\tEFLAGS : 0x%08lx\tESP : 0x%08lx\n" + "\t\tDS: 0x%04lx ES: 0x%04lx FS: 0x%04lx GS: 0x%04lx " + "CS: 0x%04lx SS: 0x%04lx\n", + pr->si_signo, pr->si_code, pr->si_errno, pr->cursig, + pr->sigpend, pr->sighold, + pr->pid, pr->ppid, pr->pgrp, pr->sid, + (long long)pr->utime.tv_sec, (int)pr->utime.tv_usec, + (long long)pr->stime.tv_sec, (int)pr->stime.tv_usec, + (long long)pr->cutime.tv_sec, (int)pr->cutime.tv_usec, + (long long)pr->cstime.tv_sec, (int)pr->cstime.tv_usec, + pr->regs.orig_eax, pr->fpvalid, + pr->regs.ebx, pr->regs.ecx, + pr->regs.edx, pr->regs.esi, + pr->regs.edi, pr->regs.ebp, + pr->regs.eax, pr->regs.eip, + pr->regs.eflags, pr->regs.esp, + pr->regs.ds, pr->regs.es, pr->regs.fs, + pr->regs.gs, pr->regs.cs, pr->regs.ss + ); +} + static void display_note(void *note_ptr, char *buf, int descsz) { if (descsz == (2 * sizeof(struct x86_64_prstatus))) display_prstatus_elf64(note_ptr, buf); + else if (descsz == sizeof(struct x86_prstatus)) + display_prstatus_elf32(note_ptr, buf); } void @@ -2640,6 +2719,16 @@ display_note_elf64(void *note_ptr, char *buf) display_note(note_ptr, buf, 2 * (note->n_descsz)); } +void +display_note_elf32(void *note_ptr, char *buf) +{ + Elf32_Nhdr *note; + + note = (Elf32_Nhdr *)note_ptr; + + display_note(note_ptr, buf, note->n_descsz); +} + void get_netdump_regs_x86_64(struct bt_info *bt, ulong *ripp, ulong *rspp) { -- 1.7.1
From 99b9a5f5e0668f2f66698481d9ad23da7159287c Mon Sep 17 00:00:00 2001 From: Zhou Wenjian <zhouwj-fnst@xxxxxxxxxxxxxx> Date: Thu, 11 Dec 2014 11:14:47 +0800 Subject: [PATCH 3/5] Show kdump note information when help -D --- diskdump.c | 13 +++++++++++++ 1 files changed, 13 insertions(+), 0 deletions(-) diff --git a/diskdump.c b/diskdump.c index 3d33fdc..e5053f5 100644 --- a/diskdump.c +++ b/diskdump.c @@ -83,6 +83,9 @@ static char *vmcoreinfo_read_string(const char *); static void diskdump_get_osrelease(void); static int valid_note_address(unsigned char *); +void display_note_elf64(void *note_ptr, char *buf); +void display_note_elf32(void *note_ptr, char *buf); + /* For split dumpfile */ static struct diskdump_data **dd_list = NULL; static int num_dd = 0; @@ -1736,10 +1739,20 @@ __diskdump_memory_dump(FILE *fp) dd->num_prstatus_notes); fprintf(fp, " notes_buf: %lx\n", (ulong)dd->notes_buf); + + char *l_buf = (char *)malloc(2 * BUFSIZE); for (i = 0; i < dd->num_prstatus_notes; i++) { fprintf(fp, " notes[%d]: %lx\n", i, (ulong)dd->nt_prstatus_percpu[i]); + + if (dd->machine_type == EM_386) + display_note_elf32(dd->nt_prstatus_percpu[i],l_buf); + else if (dd->machine_type == EM_X86_64) + display_note_elf64(dd->nt_prstatus_percpu[i],l_buf); + fprintf(fp, "%s", l_buf); + memset(l_buf, 0, 2 * BUFSIZE); } + free(l_buf); dump_nt_prstatus_offset(fp); } if (dh->header_version >= 5) { -- 1.7.1
From 0e2b34c4b60df753a700bcdf2cd6c10901f0dcc8 Mon Sep 17 00:00:00 2001 From: Zhou Wenjian <zhouwj-fnst@xxxxxxxxxxxxxx> Date: Wed, 10 Dec 2014 09:38:39 +0800 Subject: [PATCH 4/5] Make qemu64 note human readable --- netdump.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 75 insertions(+), 0 deletions(-) diff --git a/netdump.c b/netdump.c index 51403b7..4bb847f 100644 --- a/netdump.c +++ b/netdump.c @@ -2701,12 +2701,87 @@ display_prstatus_elf32(void *note_ptr, char *buf) } static void +display_qemu_elf(QEMUCPUState *ptr, char *buf, int flags) +{ + int i, size, t=0; + QEMUCPUSegment *seg; + char *seg_names[] = {"CS", "DS", "ES", "FS", "GS", "SS", "LDT", "TR", + "GDT", "IDT"}; + + ptr = (QEMUCPUState *)roundup((ulong)ptr, 4); + seg = &(ptr->cs); + + size = sprintf(buf, + "\t\tversion: 0x%08x\tsize: 0x%08x\n" + "\t\tRAX : 0x%016llx\tRBX : 0x%016llx\n" + "\t\tRCX : 0x%016llx\tRDX : 0x%016llx\n" + "\t\tRSI : 0x%016llx\tRDI : 0x%016llx\n" + "\t\tRSP : 0x%016llx\tRBP : 0x%016llx\n" + "\t\tRIP : 0x%016llx\tRFLAGS: 0x%016llx\n", + ptr->version, ptr->size, + (ulonglong)ptr->rax, (ulonglong)ptr->rbx, (ulonglong)ptr->rcx, + (ulonglong)ptr->rdx, (ulonglong)ptr->rsi, (ulonglong)ptr->rdi, + (ulonglong)ptr->rsp, (ulonglong)ptr->rbp, + (ulonglong)ptr->rip, (ulonglong)ptr->rflags + ); + buf += size; + t+=size; + if (flags == KDUMP_ELF64) { + size = sprintf(buf, + "\t\tR8 : 0x%016llx\tR9 : 0x%016llx\n" + "\t\tR10 : 0x%016llx\tR11 : 0x%016llx\n" + "\t\tR12 : 0x%016llx\tR13 : 0x%016llx\n" + "\t\tR14 : 0x%016llx\tR15 : 0x%016llx\n", + (ulonglong)ptr->r8, (ulonglong)ptr->r9, (ulonglong)ptr->r10, + (ulonglong)ptr->r11, (ulonglong)ptr->r12, (ulonglong)ptr->r13, + (ulonglong)ptr->r14, (ulonglong)ptr->r15 + ); + buf += size; + } + + for(i = 0; i < sizeof(seg_names)/sizeof(seg_names[0]); i++) { + size = sprintf(buf, + "\t\t%s:\n" + "\t\tselector: 0x%08x\tlimit: 0x%08x\tflags: 0x%08x\n" + "\t\tpad : 0x%08x\tbase : 0x%016llx\n", + seg_names[i], + seg->selector, seg->limit, seg->flags, + seg->pad, (ulonglong)seg->base + ); + buf += size; + seg++; + } + + sprintf(buf, + "\t\tcr[0]: %016llx\tcr[1]: %016llx\tcr[2]: %016llx\n" + "\t\tcr[3]: %016llx\tcr[4]: %016llx\n", + (ulonglong)ptr->cr[0], (ulonglong)ptr->cr[1], (ulonglong)ptr->cr[2], + (ulonglong)ptr->cr[3], (ulonglong)ptr->cr[4] + ); +} + +static void +display_qemu_elf64(void *note_ptr, char *buf) +{ + Elf64_Nhdr *note; + QEMUCPUState *ptr; + + note = (Elf64_Nhdr *)note_ptr; + ptr = (QEMUCPUState *)( + (char *)note + sizeof(Elf64_Nhdr) + note->n_namesz); + + display_qemu_elf(ptr, buf, KDUMP_ELF64); +} + +static void display_note(void *note_ptr, char *buf, int descsz) { if (descsz == (2 * sizeof(struct x86_64_prstatus))) display_prstatus_elf64(note_ptr, buf); else if (descsz == sizeof(struct x86_prstatus)) display_prstatus_elf32(note_ptr, buf); + else if (descsz == (2 * sizeof(QEMUCPUState))) + display_qemu_elf64(note_ptr, buf); } void -- 1.7.1
From 4a12205dcc3935815e661713cfb8b9902b086796 Mon Sep 17 00:00:00 2001 From: Zhou Wenjian <zhouwj-fnst@xxxxxxxxxxxxxx> Date: Wed, 10 Dec 2014 09:39:17 +0800 Subject: [PATCH 5/5] Make qemu32 note human readable --- netdump.c | 22 ++++++++++++++++++++++ 1 files changed, 22 insertions(+), 0 deletions(-) diff --git a/netdump.c b/netdump.c index 4bb847f..8bab142 100644 --- a/netdump.c +++ b/netdump.c @@ -2263,6 +2263,13 @@ dump_Elf64_Nhdr(Elf64_Off offset, int store) } if (BITS32() && (xen_core || (note->n_type == NT_PRSTATUS))) { + if (!xen_core && nd->ofp) { + char *l_buf = (char *)malloc(2 * BUFSIZE); + display_note_elf32(note, l_buf); + fprintf(fp, "%s", l_buf); + free(l_buf); + } + iptr = (int *)uptr; for (i = lf = 0; i < note->n_descsz/sizeof(ulong); i++) { if (((i%4)==0)) { @@ -2774,6 +2781,19 @@ display_qemu_elf64(void *note_ptr, char *buf) } static void +display_qemu_elf32(void *note_ptr, char *buf) +{ + Elf32_Nhdr *note; + QEMUCPUState *ptr; + + note = (Elf32_Nhdr *)note_ptr; + ptr = (QEMUCPUState *)( + (char *)note + sizeof(Elf32_Nhdr) + note->n_namesz); + + display_qemu_elf(ptr, buf, KDUMP_ELF32); +} + +static void display_note(void *note_ptr, char *buf, int descsz) { if (descsz == (2 * sizeof(struct x86_64_prstatus))) @@ -2782,6 +2802,8 @@ display_note(void *note_ptr, char *buf, int descsz) display_prstatus_elf32(note_ptr, buf); else if (descsz == (2 * sizeof(QEMUCPUState))) display_qemu_elf64(note_ptr, buf); + else if (descsz == sizeof(QEMUCPUState)) + display_qemu_elf32(note_ptr, buf); } void -- 1.7.1
-- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility