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 this: ksymoops 2.4.8 on i686 2.5.65-mm2. Options used -v /boot/vmlinux (specified) -K (specified) -L (specified) -o /lib/modules/2.5.65-mm2/ (default) -M (specified) No modules in ksyms, skipping objects Mar 18 23:37:08 vmm kernel: <1>Unable to handle kernel NULL pointer dereference at virtual address 00000000 Mar 18 23:37:08 vmm kernel: c014fcdc Mar 18 23:37:08 vmm kernel: *pde = 00000000 Mar 18 23:37:08 vmm kernel: Oops: 0002 [#2] Mar 18 23:37:08 vmm kernel: CPU: 1 Mar 18 23:37:08 vmm kernel: EIP: 0060:[] Not tainted Using defaults from ksymoops -t elf32-i386 -a i386 Mar 18 23:37:08 vmm kernel: EFLAGS: 00010246 VLI Mar 18 23:37:08 vmm kernel: eax: cd20ace0 ebx: fffffffe ecx: c17f3c08 edx: c17f3c18 Mar 18 23:37:08 vmm kernel: esi: fffffffe edi: cc427000 ebp: cc29dfbc esp: cc29dfa8 Mar 18 23:37:08 vmm kernel: ds: 007b es: 007b ss: 0068 Mar 18 23:37:08 vmm kernel: Stack: cffbd908 cc427000 4001020d 00000000 bfffeff0 cc29c000 c0109143 4001020d Mar 18 23:37:08 vmm kernel: 00000000 00000003 00000000 bfffeff0 bfffef08 00000005 0000007b 0000007b Mar 18 23:37:08 vmm kernel: 00000005 4000ef94 00000073 00000206 bfffee58 0000007b Mar 18 23:37:08 vmm kernel: Call Trace: Mar 18 23:37:08 vmm kernel: [] syscall_call+0x7/0xb Mar 18 23:37:08 vmm kernel: Code: 35 89 da 89 f0 e8 51 ff ff ff 57 a1 30 9a 46 c0 50 e8 85 c8 fe ff b8 00 e0 ff ff 21 e0 8b 00 81 b8 e4 01 00 00 0e 27 00 00 75 07 05 00 00 00 00 00 89 f0 eb 0b 89 f0 e8 ca fe ff ff 89 de eb >>EIP; c014fcdc <===== >>eax; cd20ace0 <_end+cd82afc/3fb77d20> >>ebx; fffffffe >>ecx; c17f3c08 <_end+136ba24/3fb77d20> >>edx; c17f3c18 <_end+136ba34/3fb77d20> >>esi; fffffffe >>edi; cc427000 <_end+bf9ee1c/3fb77d20> >>ebp; cc29dfbc <_end+be15dd8/3fb77d20> >>esp; cc29dfa8 <_end+be15dc4/3fb77d20> Trace; c0109143 Code; c014fcb1 00000000 <_EIP>: Code; c014fcb1 0: 35 89 da 89 f0 xor $0xf089da89,%eax Code; c014fcb6 5: e8 51 ff ff ff call ffffff5b <_EIP+0xffffff5b> Code; c014fcbb a: 57 push %edi Code; c014fcbc b: a1 30 9a 46 c0 mov 0xc0469a30,%eax Code; c014fcc1 10: 50 push %eax Code; c014fcc2 11: e8 85 c8 fe ff call fffec89b <_EIP+0xfffec89b> Code; c014fcc7 16: b8 00 e0 ff ff mov $0xffffe000,%eax Code; c014fccc 1b: 21 e0 and %esp,%eax Code; c014fcce 1d: 8b 00 mov (%eax),%eax Code; c014fcd0 1f: 81 b8 e4 01 00 00 0e cmpl $0x270e,0x1e4(%eax) Code; c014fcd7 26: 27 00 00 Code; c014fcda 29: 75 07 jne 32 <_EIP+0x32> Code; c014fcdc <===== 2b: c6 05 00 00 00 00 00 movb $0x0,0x0 <===== Code; c014fce3 32: 89 f0 mov %esi,%eax Code; c014fce5 34: eb 0b jmp 41 <_EIP+0x41> Code; c014fce7 36: 89 f0 mov %esi,%eax Code; c014fce9 38: e8 ca fe ff ff call ffffff07 <_EIP+0xffffff07> Code; c014fcee 3d: 89 de mov %ebx,%esi Code; c014fcf0 3f: eb .byte 0xeb 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-03-18 23:55:58.000000000 -0800 +++ 25-akpm/arch/i386/kernel/traps.c 2003-03-18 23:55:58.000000000 -0800 @@ -186,8 +186,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\nEFLAGS: %08lx VLI\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", @@ -203,23 +204,25 @@ void show_registers(struct pt_regs *regs * time of the fault.. */ if (in_kernel) { + u8 *eip; printk("\nStack: "); show_stack((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"); _