summaryrefslogtreecommitdiff
path: root/gnu/usr.bin
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2005-02-27 19:03:19 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2005-02-27 19:03:19 +0000
commitcad998c248a34bfed045f3a27347bad3bf8c8c1a (patch)
tree8dd1813f1e4bfb6ae0b57bcbb6cff549e4c033c4 /gnu/usr.bin
parent5df29dba0aaa8b713981d5052ffbdb2842096a9d (diff)
Fix backtraces for kernel core dumps.
Diffstat (limited to 'gnu/usr.bin')
-rw-r--r--gnu/usr.bin/binutils/gdb/i386nbsd-nat.c24
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;
}