[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