This teaches the i386 oops dumper to dump opcodes preceding and after the offending EIP. Supporting code against ksymoops has been tested and produces output like the below. Support for this was added to ksymoops-2.4.9. Note that ksymoops will guarantee that the disassembly after the value is always in sync - if the disassembly from the start of the Code: line does not sync up with the EIP address ksymoops will perform the resync. Warning (merge_maps): no symbols in merged map Mar 18 23:47:36 vmm kernel: kernel BUG at fs/open.c:802! Mar 18 23:47:36 vmm kernel: invalid operand: 0000 [#1] Mar 18 23:47:36 vmm kernel: CPU: 0 Mar 18 23:47:36 vmm kernel: EIP: 0060:[] VLI Not tainted Using defaults from ksymoops -t elf32-i386 -a i386 Mar 18 23:47:36 vmm kernel: EFLAGS: 00010246 Mar 18 23:47:36 vmm kernel: eax: ccdfb900 ebx: 4001020d ecx: 00000000 edx: 0000007b Mar 18 23:47:36 vmm kernel: esi: 00000000 edi: bfffdd70 ebp: ccdfdfbc esp: ccdfdfb0 Mar 18 23:47:36 vmm kernel: ds: 007b es: 007b ss: 0068 Mar 18 23:47:36 vmm kernel: Stack: 4001020d 00000000 bfffdd70 ccdfc000 c0109213 4001020d 00000000 00000003 Mar 18 23:47:36 vmm kernel: 00000000 bfffdd70 bfffdc88 00000005 0000007b 0000007b 00000005 4000ef94 Mar 18 23:47:36 vmm kernel: 00000073 00000206 bfffdbd8 0000007b Mar 18 23:47:36 vmm kernel: Call Trace: Mar 18 23:47:36 vmm kernel: [] syscall_call+0x7/0xb Mar 18 23:47:36 vmm kernel: Code: 14 98 f0 81 41 04 00 00 00 01 5b 89 ec 5d c3 90 b8 00 e0 ff ff 21 e0 55 89 e5 57 56 53 8b 00 81 b8 e4 01 00 00 0f 27 00 00 75 08 <0f> 0b 22 03 85 18 2f c0 8b 45 08 50 e8 30 d4 00 00 89 c7 83 c4 >>EIP; c014fedf No symbols available <===== Trace; c0109213 No symbols available This architecture has variable length instructions, decoding before eip is unreliable, take these instructions with a pinch of salt. Code; c014feb4 No symbols available 00000000 <_EIP>: Code; c014feb4 No symbols available 0: 14 98 adc $0x98,%al Code; c014feb6 No symbols available 2: f0 81 41 04 00 00 00 lock addl $0x1000000,0x4(%ecx) Code; c014febd No symbols available 9: 01 Code; c014febe No symbols available a: 5b pop %ebx Code; c014febf No symbols available b: 89 ec mov %ebp,%esp Code; c014fec1 No symbols available d: 5d pop %ebp Code; c014fec2 No symbols available e: c3 ret Code; c014fec3 No symbols available f: 90 nop Code; c014fec4 No symbols available 10: b8 00 e0 ff ff mov $0xffffe000,%eax Code; c014fec9 No symbols available 15: 21 e0 and %esp,%eax Code; c014fecb No symbols available 17: 55 push %ebp Code; c014fecc No symbols available 18: 89 e5 mov %esp,%ebp Code; c014fece No symbols available 1a: 57 push %edi Code; c014fecf No symbols available 1b: 56 push %esi Code; c014fed0 No symbols available 1c: 53 push %ebx Code; c014fed1 No symbols available 1d: 8b 00 mov (%eax),%eax Code; c014fed3 No symbols available 1f: 81 b8 e4 01 00 00 0f cmpl $0x270f,0x1e4(%eax) Code; c014feda No symbols available 26: 27 00 00 Code; c014fedd No symbols available 29: 75 08 jne 33 <_EIP+0x33> c014fee7 No symbols available This decode from eip onwards should be reliable Code; c014fedf No symbols available 00000000 <_EIP>: Code; c014fedf No symbols available <===== 0: 0f 0b ud2a <===== Code; c014fee1 No symbols available 2: 22 03 and (%ebx),%al Code; c014fee3 No symbols available 4: 85 18 test %ebx,(%eax) Code; c014fee5 No symbols available 6: 2f das Code; c014fee6 No symbols available 7: c0 8b 45 08 50 e8 30 rorb $0x30,0xe8500845(%ebx) Code; c014feed No symbols available e: d4 00 aam $0x0 Code; c014feef No symbols available 10: 00 .byte 0x0 Code; c014fef0 No symbols available 11: 89 c7 mov %eax,%edi Code; c014fef2 No symbols available 13: 83 .byte 0x83 Code; c014fef3 No symbols available 14: c4 .byte 0xc4 arch/i386/kernel/traps.c | 21 ++++++++++++--------- 1 files changed, 12 insertions(+), 9 deletions(-) diff -puN arch/i386/kernel/traps.c~oops-dump-preceding-code arch/i386/kernel/traps.c --- 25/arch/i386/kernel/traps.c~oops-dump-preceding-code 2003-09-21 14:01:21.000000000 -0700 +++ 25-akpm/arch/i386/kernel/traps.c 2003-09-21 14:01:21.000000000 -0700 @@ -209,8 +209,9 @@ void show_registers(struct pt_regs *regs ss = regs->xss & 0xffff; } print_modules(); - printk("CPU: %d\nEIP: %04x:[<%08lx>] %s\nEFLAGS: %08lx\n", - smp_processor_id(), 0xffff & regs->xcs, regs->eip, print_tainted(), regs->eflags); + printk("CPU: %d\nEIP: %04x:[<%08lx>] %s VLI\nEFLAGS: %08lx\n", + smp_processor_id(), 0xffff & regs->xcs, + regs->eip, print_tainted(), regs->eflags); print_symbol("EIP is at %s\n", regs->eip); printk("eax: %08lx ebx: %08lx ecx: %08lx edx: %08lx\n", @@ -226,23 +227,25 @@ void show_registers(struct pt_regs *regs * time of the fault.. */ if (in_kernel) { + u8 *eip; printk("\nStack: "); show_stack(NULL, (unsigned long*)esp); printk("Code: "); - if(regs->eip < PAGE_OFFSET) - goto bad; - for(i=0;i<20;i++) - { + eip = (u8 *)regs->eip - 43; + for (i = 0; i < 64; i++, eip++) { unsigned char c; - if(__get_user(c, &((unsigned char*)regs->eip)[i])) { -bad: + + if (eip < (u8 *)PAGE_OFFSET || __get_user(c, eip)) { printk(" Bad EIP value."); break; } - printk("%02x ", c); + if (eip == (u8 *)regs->eip) + printk("<%02x> ", c); + else + printk("%02x ", c); } } printk("\n"); _