diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2005-02-27 19:03:19 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2005-02-27 19:03:19 +0000 |
commit | cad998c248a34bfed045f3a27347bad3bf8c8c1a (patch) | |
tree | 8dd1813f1e4bfb6ae0b57bcbb6cff549e4c033c4 /gnu/usr.bin | |
parent | 5df29dba0aaa8b713981d5052ffbdb2842096a9d (diff) |
Fix backtraces for kernel core dumps.
Diffstat (limited to 'gnu/usr.bin')
-rw-r--r-- | gnu/usr.bin/binutils/gdb/i386nbsd-nat.c | 24 |
1 files changed, 19 insertions, 5 deletions
diff --git a/gnu/usr.bin/binutils/gdb/i386nbsd-nat.c b/gnu/usr.bin/binutils/gdb/i386nbsd-nat.c index 22af0117e4e..c1f700de2cb 100644 --- a/gnu/usr.bin/binutils/gdb/i386nbsd-nat.c +++ b/gnu/usr.bin/binutils/gdb/i386nbsd-nat.c @@ -60,14 +60,28 @@ i386nbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb) if (pcb->pcb_esp == 0) return 0; + /* Read the stack frame, and check its validity. We do this by + checking if the saved interrupt priority level in the stack frame + looks reasonable.. */ read_memory (pcb->pcb_esp, (char *) &sf, sizeof sf); - pcb->pcb_esp += sizeof (struct switchframe); - regcache_raw_supply (regcache, I386_EDI_REGNUM, &sf.sf_edi); - regcache_raw_supply (regcache, I386_ESI_REGNUM, &sf.sf_esi); + if ((unsigned int) sf.sf_ppl < 0x100 && (sf.sf_ppl & 0xf) == 0) + { + /* Yes, we have a frame that matches cpu_switch(). */ + pcb->pcb_esp += sizeof (struct switchframe); + regcache_raw_supply (regcache, I386_EDI_REGNUM, &sf.sf_edi); + regcache_raw_supply (regcache, I386_ESI_REGNUM, &sf.sf_esi); + regcache_raw_supply (regcache, I386_EBX_REGNUM, &sf.sf_ebx); + regcache_raw_supply (regcache, I386_EIP_REGNUM, &sf.sf_eip); + } + else + { + /* No, the pcb must have been last updated by savectx(). */ + pcb->pcb_esp += 4; + regcache_raw_supply (regcache, I386_EIP_REGNUM, &sf); + } + regcache_raw_supply (regcache, I386_EBP_REGNUM, &pcb->pcb_ebp); regcache_raw_supply (regcache, I386_ESP_REGNUM, &pcb->pcb_esp); - regcache_raw_supply (regcache, I386_EBX_REGNUM, &sf.sf_ebx); - regcache_raw_supply (regcache, I386_EIP_REGNUM, &sf.sf_eip); return 1; } |