[Crash-utility] [PATCH] Using crash with newer xen versions fails

Dietmar Hahn dietmar.hahn at ts.fujitsu.com
Fri Jan 18 10:01:29 UTC 2019


Hi Dave,

when trying to debug the xen hypervisor on a vmcore file it doesn't work for me.
xen_version: 4.11.0_08-1

...
This GDB was configured as "x86_64-unknown-linux-gnu"...

crash: invalid kernel virtual address: bf45ffa0001ef8  type:
"fill_pcpu_struct"
WARNING: cannot fill pcpu_struct.

crash: cannot read cpu_info.

I had a look at this and found a change in the struct tss_struct when trying
to read the rsp0. The change in the xen-git-tree was done with commit 98dffb05ce4.
Old:
struct tss_struct {
    unsigned short      back_link,__blh;
    union { u64 rsp0, esp0; };
    ...
New:
struct __packed __cacheline_aligned tss_struct {
    uint32_t :32;
    uint64_t rsp0, rsp1, rsp2;

After fixing this in the crash command I got:
...
This GDB was configured as "x86_64-unknown-linux-gnu"...

   KERNEL: xen-syms
 DUMPFILE: vmcore
     CPUS: 4
  DOMAINS: 3
   UPTIME: --:--:--
  MACHINE: Intel(R) Xeon(R) CPU           E5520  @ 2.27GHz  (2266 Mhz)
   MEMORY: 12 GB
Segmentation fault (core dumped)

It seems that the commit 4e1dca21 in xen_hyper.c isn't sufficient
anymore.
Because reading the symbol "dom0" is successful but the address is zero.
My suggestion now is simply to switch the if statement.
First ask for the symbol "hardware_domain" (introduced in xen version 4.5.0)
and if it isn't found use the symbol "dom0".

This works for me with vmcore's with xen-4.4.4.

Dietmar.

---

 x86_64.c    | 6 +++++-
 xen_hyper.c | 8 ++++----
 2 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/x86_64.c b/x86_64.c
index 0f6c584..26eb286 100644
--- a/x86_64.c
+++ b/x86_64.c
@@ -7903,7 +7903,11 @@ x86_64_init_hyper(int when)
 	case POST_GDB:
 		XEN_HYPER_STRUCT_SIZE_INIT(cpuinfo_x86, "cpuinfo_x86");
 		XEN_HYPER_STRUCT_SIZE_INIT(tss_struct, "tss_struct");
-		XEN_HYPER_ASSIGN_OFFSET(tss_struct_rsp0) = MEMBER_OFFSET("tss_struct", "__blh") + sizeof(short unsigned int);
+		if (MEMBER_EXISTS("tss_struct", "__blh")) {
+			XEN_HYPER_ASSIGN_OFFSET(tss_struct_rsp0) = MEMBER_OFFSET("tss_struct", "__blh") + sizeof(short unsigned int);
+		} else {
+			XEN_HYPER_ASSIGN_OFFSET(tss_struct_rsp0) = MEMBER_OFFSET("tss_struct", "rsp0");
+		}
 		XEN_HYPER_MEMBER_OFFSET_INIT(tss_struct_ist, "tss_struct", "ist");
 		if (symbol_exists("cpu_data")) {
 			xht->cpu_data_address = symbol_value("cpu_data");
diff --git a/xen_hyper.c b/xen_hyper.c
index 20072e9..f2f00e6 100644
--- a/xen_hyper.c
+++ b/xen_hyper.c
@@ -1060,8 +1060,8 @@ xen_hyper_get_domains(void)
 	long domain_next_in_list;
 	int i, j;
 
-	if (!try_get_symbol_data("dom0", sizeof(void *), &domain))
-		get_symbol_data("hardware_domain", sizeof(void *), &domain);
+	if (!try_get_symbol_data("hardware_domain", sizeof(void *), &domain))
+		get_symbol_data("dom0", sizeof(void *), &domain);
 
 	domain_next_in_list = MEMBER_OFFSET("domain", "next_in_list");
 	i = 0;
@@ -1103,8 +1103,8 @@ xen_hyper_get_domain_next(int mod, ulong *next)
 		if (xhdt->dom0) {
 			*next = xhdt->dom0->domain;
 		} else {
-			if (!try_get_symbol_data("dom0", sizeof(void *), next))
-				get_symbol_data("hardware_domain", sizeof(void *), next);
+			if (!try_get_symbol_data("hardware_domain", sizeof(void *), next))
+				get_symbol_data("dom0", sizeof(void *), next);
 		}
 		return xhdt->domain_struct;
 		break;
-- 
2.12.3




More information about the Crash-utility mailing list