Re: crash can not read ia64 lkcd v9 dump

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello Alan,

* Alan Tyson <atyson@xxxxxx> [2006-12-11 10:10]:
> >But first I'll fix the header format which _is_ different in crash and
> >our SLES9 kernel (and klcdutils), and if it then doesn't work I'll
> >come back to the system maps.
> >
> >Thanks for your help!
> 
> There are two changes rquired to fix up the header format for SLES9.
> One is NR_CPUS and the other is a missing fiels in the dump header.
> This may be of help, it' what I've been using:

Sorry for the late reply ... :)

I hacked a patch that does that dynamically. The issue is that
lkcd's lcrash _doesn't_ have that problem because it reads all offsets
of that structure dynamically from kerntypes (the kernel has the same
structures) while crash does that statically.

However, that patch at least works for both SLES-10 and SLES-9 kernels
on IA-64 (I don't know why the position of dha_kernel_addr was
changed, sorry :)) and is better than recompiling crash. Maybe it also
helps you. It will be included at least in openSUSE 10.3 packages.


Regards,
  Bernhard
Index: crash-4.0-2.33/lkcd_fix_mem.h
===================================================================
--- crash-4.0-2.33.orig/lkcd_fix_mem.h	2006-07-13 20:51:50.000000000 +0200
+++ crash-4.0-2.33/lkcd_fix_mem.h	2007-01-10 15:48:18.000000000 +0100
@@ -285,11 +285,16 @@ typedef struct _dump_header_asm_s {
 	/* smp specific */
 	uint32_t	     dha_smp_num_cpus;
 	uint32_t 	     dha_dumping_cpu;	// v4 changed this
+
+	/* if you change something here, you've to change the logic in fix_addr_v8 */
 	struct pt_regs	     dha_smp_regs[NR_CPUS];
 	uint64_t 	     dha_smp_current_task[NR_CPUS]; // v4 changed this 
 	uint64_t     	     dha_stack[NR_CPUS];  // v4 changed this 
 	uint64_t     	     dha_switch_stack[NR_CPUS]; // v4 changed this 
 
+	/* load address of the kernel (added by sles9 patch) */
+	uint64_t             dha_kernel_addr;
+
 } __attribute__((packed)) dump_header_asm_t;
 
 #endif // IA64
Index: crash-4.0-2.33/lkcd_fix_mem.c
===================================================================
--- crash-4.0-2.33.orig/lkcd_fix_mem.c	2006-07-13 20:51:50.000000000 +0200
+++ crash-4.0-2.33/lkcd_fix_mem.c	2007-01-10 16:04:16.000000000 +0100
@@ -21,19 +21,143 @@
 #define LKCD_COMMON
 #include "defs.h"
 #include "lkcd_fix_mem.h"
+#include <stddef.h>
+#include <stdbool.h>
 
 static int fix_addr(dump_header_asm_t *); 
-    
+
+#ifdef IA64
+#define MAGIC_NUMBER_OFFSET(x)  \
+	(offsetof(dump_header_asm_t, dha_magic_number) + (x))
+
+#define VERSION_OFFSET(x) \
+	(offsetof(dump_header_asm_t, dha_version) + (x))
+
+#define HEADER_SIZE_OFFSET(x) \
+	(offsetof(dump_header_asm_t, dha_header_size) + (x))
+
+#define PT_REGS_OFFSET(x) \
+	(offsetof(dump_header_asm_t, dha_pt_regs) + (x))
+
+#define REGS_OFFSET(x) \
+	(offsetof(dump_header_asm_t, dha_regs) + (x))
+
+#define RNAT_OFFSET(x) \
+	(offsetof(dump_header_asm_t, dha_rnat) + (x))
+
+#define PFS_OFFSET(x) \
+	(offsetof(dump_header_asm_t, dha_pfs) + (x))
+
+#define BSPSTORE_OFFSET(x) \
+	(offsetof(dump_header_asm_t, dha_bspstore) + (x))
+
+#define SMP_NUM_CPUS_OFFSET(x) \
+	(offsetof(dump_header_asm_t, dha_smp_num_cpus) + (x))
+
+#define DUMPING_CPU_OFFSET(x) \
+	(offsetof(dump_header_asm_t, dha_dumping_cpu) + (x))
+
+#define SMP_REGS_OFFSET(x) \
+	(offsetof(dump_header_asm_t, dha_smp_regs) + (x))
+
+#define CURRENT_TASK_OFFSET(x, cpun) \
+	(SMP_REGS_OFFSET(x) + sizeof(struct pt_regs) * (cpun))
+
+#define STACK_OFFSET(x, cpun) \
+	(CURRENT_TASK_OFFSET(x, cpun) + sizeof(uint64_t) * (cpun))
+
+#define SWITCH_STACK_OFFSET(x, cpun) \
+	(STACK_OFFSET(x, cpun) + sizeof(uint64_t) * (cpun))
+
+#define KERNEL_ADDR_OFFSET(x, cpun) \
+	(SWITCH_STACK_OFFSET(x, cpun) + sizeof(uint64_t) * (cpun))
+#endif
+
 int
 fix_addr_v8(int fd)
 {
     static dump_header_asm_t dump_header_asm_v8 = { 0 };
     dump_header_asm_t *dha;
     dha = &dump_header_asm_v8;
-    
+
+#ifdef IA64
+    int cpu_num = 0;
+    int cpunum_specific;
+    size_t size;
+    bool dha_kernel_addr_end = false;
+    unsigned char *buffer;
+    int offset = 0;
+
+    /* 
+     * Dynamically load the data from the header. This addresses two 
+     * problems:
+     * 
+     *  o support both the SLES10 and the SLES9 kernel. The difference is the
+     *    position of the dha_kernel_addr field (SLES9: after dha_header_size,
+     *    SLES10: at the and as in crash)
+     *
+     *  o NR_CPUS should be only the MAXIMUM number of CPUs supported by crash,
+     *    not necessarily the same as CONFIG_NR_CPUS
+     */
+    size = HEADER_SIZE_OFFSET(sizeof(uint32_t));
+    if (read(lkcd->fd, dha, size) != size)
+        return -1;
+
+    /* read again the whole header */
+    buffer = (unsigned char *)malloc(dha->dha_header_size);
+    if (!buffer)
+        return -1;
+    if (lseek(lkcd->fd, -size, SEEK_CUR) == -1)
+        return -1;
+    if (read(lkcd->fd, buffer, dha->dha_header_size) != dha->dha_header_size)
+        return -1;
+
+    /* check if the dha_kernel_addr is at the end */
+    if ( ((dump_header_asm_t *)buffer)->dha_smp_num_cpus <= NR_CPUS &&
+            ((dump_header_asm_t *)buffer)->dha_dumping_cpu <
+            ((dump_header_asm_t *)buffer)->dha_smp_num_cpus)
+        dha_kernel_addr_end = true;
+    else
+        offset = sizeof(uint64_t);
+
+    /* now try to calculate the number of CPUs */
+    cpunum_specific = dha->dha_header_size - SMP_REGS_OFFSET(offset)
+        + sizeof(uint64_t);
+    cpu_num = cpunum_specific / (sizeof(struct pt_regs) + 3*sizeof(uint64_t));
+
+    /* fill the other CPU number independent members */
+    memcpy(&dha->dha_pt_regs, buffer + PT_REGS_OFFSET(offset),
+            sizeof(struct pt_regs *));
+    memcpy(&dha->dha_regs, buffer + REGS_OFFSET(offset),
+            sizeof(struct pt_regs));
+    memcpy(&dha->dha_rnat, buffer + RNAT_OFFSET(offset),
+            sizeof(uint64_t));
+    memcpy(&dha->dha_pfs, buffer + PFS_OFFSET(offset),
+            sizeof(uint64_t));
+    memcpy(&dha->dha_bspstore, buffer + BSPSTORE_OFFSET(offset),
+            sizeof(uint64_t));
+    memcpy(&dha->dha_smp_num_cpus, buffer + SMP_NUM_CPUS_OFFSET(offset),
+            sizeof(uint32_t));
+    memcpy(&dha->dha_dumping_cpu, buffer + DUMPING_CPU_OFFSET(offset),
+            sizeof(uint32_t));
+    memcpy(&dha->dha_kernel_addr, buffer + KERNEL_ADDR_OFFSET(offset, cpu_num),
+            sizeof(uint64_t));
+
+    /* now the CPU number dependent things */
+    memcpy(&dha->dha_smp_regs, buffer + SMP_REGS_OFFSET(offset),
+            sizeof(struct pt_regs) * cpu_num);
+    memcpy(&dha->dha_smp_current_task, buffer + CURRENT_TASK_OFFSET(offset, cpu_num),
+            sizeof(uint64_t) * cpu_num);
+    memcpy(&dha->dha_stack, buffer + STACK_OFFSET(offset, cpu_num),
+            sizeof(uint64_t) * cpu_num);
+    memcpy(&dha->dha_switch_stack, buffer + SWITCH_STACK_OFFSET(offset, cpu_num),
+            sizeof(uint64_t) * cpu_num);
+
+#else
     if (read(lkcd->fd, dha, sizeof(dump_header_asm_t)) !=
 	    sizeof(dump_header_asm_t))
 	return -1;
+#endif
     
     fix_addr(dha);
 
@@ -61,7 +185,7 @@ fix_addr(dump_header_asm_t *dha)  
 {
     
 
-    if (dha->dha_header_size != sizeof(dump_header_asm_t)) {
+    if (dha->dha_header_size > sizeof(dump_header_asm_t)) {
 	error(INFO, "LKCD machine specific dump header doesn't match crash version\n");
 	error(INFO, "traceback of currently executing threads may not work\n\n");
     }

Attachment: pgpgOdcZJbMaC.pgp
Description: PGP signature

--
Crash-utility mailing list
Crash-utility@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/crash-utility

[Index of Archives]     [Fedora Development]     [Fedora Desktop]     [Fedora SELinux]     [Yosemite News]     [KDE Users]     [Fedora Tools]

 

Powered by Linux