[Crash-utility] [PATCH] bug on get_be_long() and improvement of bt

Hu Tao hutao at cn.fujitsu.com
Tue Oct 19 09:05:46 UTC 2010


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
-------------- next part --------------
>From 007a86417ca1995e2727230851bd4f55dc8eff47 Mon Sep 17 00:00:00 2001
From: Hu Tao <hutao at cn.fujitsu.com>
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

-------------- next part --------------
>From a329c20495c5dae4c0759798b4b954d0b0a45d1a Mon Sep 17 00:00:00 2001
From: Hu Tao <hutao at cn.fujitsu.com>
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

-------------- next part --------------
>From de6809819c06cf8c294a03ad79207b3ac9c2dca8 Mon Sep 17 00:00:00 2001
From: Hu Tao <hutao at cn.fujitsu.com>
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



More information about the Crash-utility mailing list