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

Hu Tao hutao at cn.fujitsu.com
Wed Oct 20 07:51:09 UTC 2010


And one more patch adding command `cpu' to show cpu registers.

-- 
Thanks,
Hu Tao
-------------- next part --------------
>From 3d737a7ea51261eb3d39febbcbf93cce02b458c1 Mon Sep 17 00:00:00 2001
From: Hu Tao <hutao at cn.fujitsu.com>
Date: Wed, 20 Oct 2010 15:40:07 +0800
Subject: [PATCH 4/4] Add a command cpu to show cpu registers

---
 defs.h        |   18 +++++++++++++++++-
 global_data.c |    1 +
 help.c        |   14 +-------------
 kernel.c      |   10 ++++++++++
 kvmdump.c     |    2 +-
 qemu-load.c   |    3 ++-
 qemu-load.h   |   12 ------------
 x86.c         |   20 ++++++++++++++++++++
 x86_64.c      |   28 ++++++++++++++++++++++++++++
 9 files changed, 80 insertions(+), 28 deletions(-)

diff --git a/defs.h b/defs.h
index f84f9d4..1e8f2f9 100755
--- a/defs.h
+++ b/defs.h
@@ -807,6 +807,7 @@ struct machdep_table {
 	int (*xen_kdump_p2m_create)(struct xen_kdump_data *);
 	int (*in_alternate_stack)(int, ulong);
 	void (*dumpfile_init)(int, void *);
+	void (*show_cpu)(void);
 };
 
 /*
@@ -3357,6 +3358,7 @@ void cmd_sys(void);          /* kernel.c */
 void cmd_irq(void);          /* kernel.c */
 void cmd_timer(void);        /* kernel.c */
 void cmd_waitq(void);        /* kernel.c */
+void cmd_cpu(void);          /* kernel.c */
 void cmd_sym(void);          /* symbols.c */
 void cmd_struct(void);       /* symbols.c */
 void cmd_union(void);        /* symbols.c */
@@ -3821,6 +3823,7 @@ extern char *help_union[];
 extern char *help_vm[];
 extern char *help_vtop[];
 extern char *help_waitq[];
+extern char *help_cpu[];
 extern char *help_whatis[];
 extern char *help_wr[];
 #if defined(S390) || defined(S390X)
@@ -4992,9 +4995,22 @@ extern int have_full_symbols(void);
 #define XEN_HYPERVISOR_ARCH 
 #endif
 
+enum CPU_REG {
+	R_EAX,
+	R_ECX,
+	R_EDX,
+	R_EBX,
+	R_ESP,
+	R_EBP,
+	R_ESI,
+	R_EDI,
+	R_GP_MAX,
+};
+
 struct cpu_info {
-	uint64_t	esp;
+	uint64_t	regs[16];
 	uint64_t	eip;
+	uint64_t	eflags;
 };
 
 extern struct cpu_info cpu_infos[];
diff --git a/global_data.c b/global_data.c
index e936ca5..20539fb 100755
--- a/global_data.c
+++ b/global_data.c
@@ -118,6 +118,7 @@ struct command_table_entry linux_command_table[] = {
 	{"waitq",   cmd_waitq,   help_waitq,   REFRESH_TASK_TABLE},
 	{"whatis",  cmd_whatis,  help_whatis,  0},
 	{"wr",      cmd_wr,      help_wr,      0},
+	{"cpu",     cmd_cpu,     help_cpu,     0},
 #if defined(S390) || defined(S390X)
         {"s390dbf", cmd_s390dbf, help_s390dbf, 0},
 #endif
diff --git a/help.c b/help.c
index 94402f9..6fb6846 100755
--- a/help.c
+++ b/help.c
@@ -2248,19 +2248,7 @@ NULL
 
 char *help_cpu[] = {
 "cpu",
-"set context to the active task on a cpu",
-"[cpu]",
-"  This command sets the current context to the active task on a cpu.  If no",
-"  argument is given, the current context is displayed.\n",
-"    cpu   a valid cpu number\n",
-"  This command is not allowable on live systems.",
-"\nEXAMPLES",
-"    %s> cpu 1",
-"         PID: 286",
-"     COMMAND: \"in.rlogind\"",
-"        TASK: c0b3a000 ",
-"         CPU: 1 ",
-"       STATE: TASK_RUNNING (ACTIVE)",
+"Show cpu registers",
 NULL               
 };
 
diff --git a/kernel.c b/kernel.c
index e399099..1d04e68 100755
--- a/kernel.c
+++ b/kernel.c
@@ -6070,6 +6070,16 @@ cmd_waitq(void)
 	}
 }
 
+void
+cmd_cpu(void)
+{
+	if (machdep->show_cpu)
+		machdep->show_cpu();
+	else
+		printf("This command is not supported on %s.\n", MACHINE_TYPE);
+}
+
+
 static void
 dump_waitq(ulong wq, char *wq_name)
 {
diff --git a/kvmdump.c b/kvmdump.c
index 4b60551..6205892 100644
--- a/kvmdump.c
+++ b/kvmdump.c
@@ -312,7 +312,7 @@ get_kvmdump_regs(struct bt_info *bt, ulong *pc, ulong *sp)
 {
 	if (is_task_active(bt->task)) {
 		assert(bt->tc->processor < n_cpu);
-		*sp = cpu_infos[bt->tc->processor].esp;
+		*sp = cpu_infos[bt->tc->processor].regs[R_ESP];
 		*pc = cpu_infos[bt->tc->processor].eip;
 	} else
 		machdep->get_stack_frame(bt, pc, sp);
diff --git a/qemu-load.c b/qemu-load.c
index a7beb0b..303ed94 100644
--- a/qemu-load.c
+++ b/qemu-load.c
@@ -611,8 +611,9 @@ cpu_load (struct qemu_device *d, FILE *fp, int size)
 	}
 
 	assert(d->instance_id == n_cpu);
+	memcpy(cpu_infos[n_cpu].regs, dx86->regs, sizeof(cpu_infos[n_cpu].regs));
 	cpu_infos[n_cpu].eip = dx86->eip;
-	cpu_infos[n_cpu].esp = dx86->regs[R_ESP];
+	cpu_infos[n_cpu].eflags = dx86->eflags;
 	n_cpu++;
 
 	return QEMU_FEATURE_CPU;
diff --git a/qemu-load.h b/qemu-load.h
index 0d8db4e..578fedd 100644
--- a/qemu-load.h
+++ b/qemu-load.h
@@ -140,18 +140,6 @@ 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;
 
diff --git a/x86.c b/x86.c
index 4121e28..4ab0677 100755
--- a/x86.c
+++ b/x86.c
@@ -1673,6 +1673,25 @@ x86_user_eframe(struct bt_info *bt)
 
 }
 
+static void
+show_cpu(void)
+{
+	unsigned int i;
+
+	for (i = 0; i < n_cpu; i++) {
+		printf("CPU %d:\n", i);
+
+		printf("  eax %08llx ebx %08llx ecx %08llx edx %08llx\n"
+			"  esi %08llx edi %08llx esp %08llx ebp %08llx\n",
+			cpu_infos[i].regs[R_EAX], cpu_infos[i].regs[R_EBX],
+			cpu_infos[i].regs[R_ECX], cpu_infos[i].regs[R_EDX],
+			cpu_infos[i].regs[R_ESI], cpu_infos[i].regs[R_EDI],
+			cpu_infos[i].regs[R_ESP], cpu_infos[i].regs[R_EBP]);
+
+		printf("  eip %08llx\n", cpu_infos[i].eip);
+	}
+}
+
 /*
  *  Do all necessary machine-specific setup here.  This is called three times,
  *  during symbol table initialization, and before and after GDB has been 
@@ -1717,6 +1736,7 @@ x86_init(int when)
 		machdep->last_ptbl_read = 0;
 		machdep->machspec = &x86_machine_specific;
 		machdep->verify_paddr = generic_verify_paddr;
+		machdep->show_cpu = show_cpu;
 		break;
 
 	case PRE_GDB:
diff --git a/x86_64.c b/x86_64.c
index be81247..5a500ee 100755
--- a/x86_64.c
+++ b/x86_64.c
@@ -102,6 +102,7 @@ static ulong x86_64_get_framepointer(struct bt_info *, ulong);
 static int x86_64_get_framesize(struct bt_info *, ulong, ulong);
 static void x86_64_framesize_debug(struct bt_info *);
 static void x86_64_get_active_set(void);
+static void show_cpu(void);
 
 struct machine_specific x86_64_machine_specific = { 0 };
 
@@ -154,6 +155,7 @@ x86_64_init(int when)
 		machdep->machspec->irq_eframe_link = UNINITIALIZED;
                 if (machdep->cmdline_args[0])
                         parse_cmdline_args();
+		machdep->show_cpu = show_cpu;
 		break;
 
 	case PRE_GDB:
@@ -6850,4 +6852,30 @@ x86_64_get_active_set(void)
 	}
 }
 
+static void
+show_cpu(void)
+{
+	unsigned int i;
+
+	for (i = 0; i < n_cpu; i++) {
+		printf("CPU %d:\n", i);
+
+		printf("  rax %016llx rbx %016llx rcx %016llx rdx %016llx\n"
+			"  rsi %016llx rdi %016llx rsp %016llx rbp %016llx\n",
+			cpu_infos[i].regs[R_EAX], cpu_infos[i].regs[R_EBX],
+			cpu_infos[i].regs[R_ECX], cpu_infos[i].regs[R_EDX],
+			cpu_infos[i].regs[R_ESI], cpu_infos[i].regs[R_EDI],
+			cpu_infos[i].regs[R_ESP], cpu_infos[i].regs[R_EBP]);
+
+		printf("   r8 %016llx  r9 %016llx r10 %016llx r11 %016llx\n"
+			"  r12 %016llx r13 %016llx r14 %016llx r15 %016llx\n",
+			cpu_infos[i].regs[8], cpu_infos[i].regs[9],
+			cpu_infos[i].regs[10], cpu_infos[i].regs[11],
+			cpu_infos[i].regs[12], cpu_infos[i].regs[13],
+			cpu_infos[i].regs[14], cpu_infos[i].regs[15]);
+
+		printf("  rip %16llx\n", cpu_infos[i].eip);
+	}
+}
+
 #endif  /* X86_64 */ 
-- 
1.7.3



More information about the Crash-utility mailing list