* Troy Heber <troy.heber@xxxxxx> [2007-01-17 19:11]: > On 01/17/07 17:46, Bernhard Walle wrote: > > > I think it's too specific (the part that detemines the position of the > > load daddress), but at least I think the LKCD IA64 maintainer should > > take a look at the problem that CONFIG_NR_CPU in kernel must be equal > > to the CPU define in crash and find a solution for this. > > I agree, the patch is to specific. I also like the NR_CPU calculation. > Bernhard, can you workup a patch that just does the NR_CPU calc and > skips the header moves? Attached. The dha_kernel_addr member is now also upstream in http://lkcd.svn.sourceforge.net/svnroot/lkcd/trunk/lkcd/lkcd-8.0.0_rc5_2.6.17.patch Regards, Bernhard
--- lkcd_fix_mem.c | 118 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- lkcd_fix_mem.h | 5 ++ 2 files changed, 121 insertions(+), 2 deletions(-) Index: crash-4.0-3.17/lkcd_fix_mem.h =================================================================== --- crash-4.0-3.17.orig/lkcd_fix_mem.h +++ crash-4.0-3.17/lkcd_fix_mem.h @@ -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-3.17/lkcd_fix_mem.c =================================================================== --- crash-4.0-3.17.orig/lkcd_fix_mem.c +++ crash-4.0-3.17/lkcd_fix_mem.c @@ -21,9 +21,58 @@ #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 \ + (offsetof(dump_header_asm_t, dha_magic_number)) + +#define VERSION_OFFSET \ + (offsetof(dump_header_asm_t, dha_version)) + +#define HEADER_SIZE_OFFSET \ + (offsetof(dump_header_asm_t, dha_header_size)) + +#define PT_REGS_OFFSET \ + (offsetof(dump_header_asm_t, dha_pt_regs)) + +#define REGS_OFFSET \ + (offsetof(dump_header_asm_t, dha_regs)) + +#define RNAT_OFFSET \ + (offsetof(dump_header_asm_t, dha_rnat)) + +#define PFS_OFFSET \ + (offsetof(dump_header_asm_t, dha_pfs)) + +#define BSPSTORE_OFFSET \ + (offsetof(dump_header_asm_t, dha_bspstore)) + +#define SMP_NUM_CPUS_OFFSET \ + (offsetof(dump_header_asm_t, dha_smp_num_cpus)) + +#define DUMPING_CPU_OFFSET \ + (offsetof(dump_header_asm_t, dha_dumping_cpu)) + +#define SMP_REGS_OFFSET \ + (offsetof(dump_header_asm_t, dha_smp_regs)) + +#define CURRENT_TASK_OFFSET(cpun) \ + (SMP_REGS_OFFSET + sizeof(struct pt_regs) * (cpun)) + +#define STACK_OFFSET(cpun) \ + (CURRENT_TASK_OFFSET(cpun) + sizeof(uint64_t) * (cpun)) + +#define SWITCH_STACK_OFFSET(cpun) \ + (STACK_OFFSET(cpun) + sizeof(uint64_t) * (cpun)) + +#define KERNEL_ADDR_OFFSET(cpun) \ + (SWITCH_STACK_OFFSET(cpun) + sizeof(uint64_t) * (cpun)) +#endif + int fix_addr_v8(int fd) { @@ -31,9 +80,74 @@ fix_addr_v8(int fd) dump_header_asm_t *dha; dha = &dump_header_asm_v8; +#ifdef IA64 + int cpu_num = 0; + int cpunum_specific; + size_t size; + unsigned char *buffer; + + /* + * Dynamically load the data from the header. This addresses the problem + * that 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) { + free(buffer); + return -1; + } + if (read(lkcd->fd, buffer, dha->dha_header_size) != dha->dha_header_size) { + free(buffer); + return -1; + } + + /* now try to calculate the number of CPUs */ + cpunum_specific = dha->dha_header_size - SMP_REGS_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, + sizeof(struct pt_regs *)); + memcpy(&dha->dha_regs, buffer + REGS_OFFSET, + sizeof(struct pt_regs)); + memcpy(&dha->dha_rnat, buffer + RNAT_OFFSET, + sizeof(uint64_t)); + memcpy(&dha->dha_pfs, buffer + PFS_OFFSET, + sizeof(uint64_t)); + memcpy(&dha->dha_bspstore, buffer + BSPSTORE_OFFSET, + sizeof(uint64_t)); + memcpy(&dha->dha_smp_num_cpus, buffer + SMP_NUM_CPUS_OFFSET, + sizeof(uint32_t)); + memcpy(&dha->dha_dumping_cpu, buffer + DUMPING_CPU_OFFSET, + sizeof(uint32_t)); + memcpy(&dha->dha_kernel_addr, buffer + KERNEL_ADDR_OFFSET(cpu_num), + sizeof(uint64_t)); + + /* now the CPU number dependent things */ + memcpy(&dha->dha_smp_regs, buffer + SMP_REGS_OFFSET, + sizeof(struct pt_regs) * cpu_num); + memcpy(&dha->dha_smp_current_task, buffer + CURRENT_TASK_OFFSET(cpu_num), + sizeof(uint64_t) * cpu_num); + memcpy(&dha->dha_stack, buffer + STACK_OFFSET(cpu_num), + sizeof(uint64_t) * cpu_num); + memcpy(&dha->dha_switch_stack, buffer + SWITCH_STACK_OFFSET(cpu_num), + sizeof(uint64_t) * cpu_num); + + free(buffer); + +#else if (read(lkcd->fd, dha, sizeof(dump_header_asm_t)) != sizeof(dump_header_asm_t)) return -1; +#endif fix_addr(dha); @@ -61,7 +175,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:
pgpDGxYXC98P9.pgp
Description: PGP signature
-- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility