Hi Dave, These are updated patches tested with SMP system and panic task. When testing a x86 guest, I found another bug about reading cpu registers from dumpfile. Qemu simulated system is x86_64 (qemu-system-x86_64), guest OS is x86. When crash reads cpu registers from dumpfile, it uses cpu_load_32(), this will read gp registers by get_be_long(fp, 32), that is, treate them as 32bits. But in fact, qemu-system-x86_64 saves 64bits for each of them(although guest OS uses only lower 32 bits). As a result, crash gets wrong cpu gp register values. Is there any way we can know from dumpfile that these gp registers(and those similar registers) are 32bits or 64bits? -- Thanks, Hu Tao
>From 007a86417ca1995e2727230851bd4f55dc8eff47 Mon Sep 17 00:00:00 2001 From: Hu Tao <hutao@xxxxxxxxxxxxxx> Date: Mon, 18 Oct 2010 10:19:47 +0800 Subject: [PATCH 1/3] Return uint64_t for get_be_long() --- qemu-load.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/qemu-load.c b/qemu-load.c index 998b6d4..95eaf97 100644 --- a/qemu-load.c +++ b/qemu-load.c @@ -408,7 +408,7 @@ cpu_common_init_load (struct qemu_device_list *dl, /* CPU loader. */ -static inline int +static inline uint64_t get_be_long (FILE *fp, int size) { uint32_t a = size == 32 ? 0 : get_be32 (fp); -- 1.7.3
>From a329c20495c5dae4c0759798b4b954d0b0a45d1a Mon Sep 17 00:00:00 2001 From: Hu Tao <hutao@xxxxxxxxxxxxxx> Date: Mon, 18 Oct 2010 11:28:04 +0800 Subject: [PATCH 2/3] Add macros for regs --- qemu-load.h | 12 ++++++++++++ 1 files changed, 12 insertions(+), 0 deletions(-) diff --git a/qemu-load.h b/qemu-load.h index 578fedd..0d8db4e 100644 --- a/qemu-load.h +++ b/qemu-load.h @@ -140,6 +140,18 @@ struct qemu_x86_mce { uint64_t mce_banks[10 * 4]; }; +enum CPU_REG { + R_EAX, + R_ECX, + R_EDX, + R_EBX, + R_ESP, + R_EBP, + R_ESI, + R_EDI, + R_GP_MAX, +}; + struct qemu_device_x86 { struct qemu_device dev_base; -- 1.7.3
>From de6809819c06cf8c294a03ad79207b3ac9c2dca8 Mon Sep 17 00:00:00 2001 From: Hu Tao <hutao@xxxxxxxxxxxxxx> Date: Tue, 19 Oct 2010 13:10:12 +0800 Subject: [PATCH 3/3] Use cpu sp/ip to backtrace active task --- defs.h | 8 ++++++++ global_data.c | 3 +++ kvmdump.c | 7 ++++++- qemu-load.c | 8 ++++++-- 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/defs.h b/defs.h index a26150e..f84f9d4 100755 --- a/defs.h +++ b/defs.h @@ -4992,4 +4992,12 @@ extern int have_full_symbols(void); #define XEN_HYPERVISOR_ARCH #endif +struct cpu_info { + uint64_t esp; + uint64_t eip; +}; + +extern struct cpu_info cpu_infos[]; +extern unsigned int n_cpu; + #endif /* !GDB_COMMON */ diff --git a/global_data.c b/global_data.c index 98a5a79..e936ca5 100755 --- a/global_data.c +++ b/global_data.c @@ -134,3 +134,6 @@ struct extension_table *extension_table = NULL; struct offset_table offset_table = { 0 }; struct size_table size_table = { 0 }; struct array_table array_table = { 0 }; + +struct cpu_info cpu_infos[NR_CPUS] = {}; +unsigned int n_cpu = 0; diff --git a/kvmdump.c b/kvmdump.c index 1bf0d9e..4b60551 100644 --- a/kvmdump.c +++ b/kvmdump.c @@ -310,7 +310,12 @@ kvmdump_memory_dump(FILE *ofp) void get_kvmdump_regs(struct bt_info *bt, ulong *pc, ulong *sp) { - machdep->get_stack_frame(bt, pc, sp); + if (is_task_active(bt->task)) { + assert(bt->tc->processor < n_cpu); + *sp = cpu_infos[bt->tc->processor].esp; + *pc = cpu_infos[bt->tc->processor].eip; + } else + machdep->get_stack_frame(bt, pc, sp); } ulong diff --git a/qemu-load.c b/qemu-load.c index 95eaf97..a7beb0b 100644 --- a/qemu-load.c +++ b/qemu-load.c @@ -18,6 +18,7 @@ */ #define _GNU_SOURCE +#include "defs.h" #include "qemu-load.h" #include <stdlib.h> #include <string.h> @@ -609,6 +610,11 @@ cpu_load (struct qemu_device *d, FILE *fp, int size) dx86->kvm.wall_clock_msr = get_be64 (fp); } + assert(d->instance_id == n_cpu); + cpu_infos[n_cpu].eip = dx86->eip; + cpu_infos[n_cpu].esp = dx86->regs[R_ESP]; + n_cpu++; + return QEMU_FEATURE_CPU; } @@ -924,8 +930,6 @@ fail: * crash utility adaptation. */ -#include "defs.h" - int is_qemu_vm_file(char *filename) { -- 1.7.3
-- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility