I have investigated the kernel core with gdb and found that the
backtrace command does not work correctly.

$ doas /usr/bin/gdb /usr/obj/sys/arch/amd64/compile/GENERIC.MP/bsd.gdb
doas (a...@asou-kernelcore-tmp.soum.co.jp) password: 
GNU gdb 6.3
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "amd64-unknown-openbsd6.9"...
(gdb) target kvm /var/crash/bsd.0.core
#0  dumpsys () at /usr/src/sys/arch/amd64/amd64/machdep.c:1055
1055                            if (error)
Current language:  auto; currently minimal
(gdb) backtrace
#0  dumpsys () at /usr/src/sys/arch/amd64/amd64/machdep.c:1055
#1  0xffffffff8127c360 in boot (howto=18692) at 
/usr/src/sys/arch/amd64/amd64/machdep.c:847
#2  0xffffffff814fa1fb in reboot (howto=Variable "howto" is not available.
) at /usr/src/sys/kern/kern_xxx.c:74
#3  0xffffffff819e0022 in db_reboot (howto=Variable "howto" is not available.
) at /usr/src/sys/ddb/db_command.c:763
#4  0xffffffff819dfa72 in db_boot_crash_cmd () at 
/usr/src/sys/ddb/db_command.c:775
#5  0xffffffff819df21e in db_command (last_cmdp=0x4904, cmd_table=Variable 
"cmd_table" is not available.
) at /usr/src/sys/ddb/db_command.c:285
#6  0xffffffff819dfef8 in db_command_loop () at 
/usr/src/sys/ddb/db_command.c:680
#7  0xffffffff8178ba95 in db_trap (type=Variable "type" is not available.
) at /usr/src/sys/ddb/db_trap.c:92
#8  0xffffffff819d1782 in db_ktrap (type=0, code=-2112772192, regs=0x0) at 
/usr/src/sys/arch/amd64/amd64/db_interface.c:148
#9  0xffffffff81230cd2 in kerntrap (frame=0x0) at 
/usr/src/sys/arch/amd64/amd64/trap.c:312
#10 0xffffffff81dbc1ce in alltraps_kern_meltdown ()
#11 0xffffffff819d2210 in db_enter () at cpufunc.h:390
#12 0xffffffff8175916a in panic (fmt=0xffffffff81df285d "intr_handler") at 
/usr/src/sys/kern/subr_prf.c:214
#13 0xffffffff811d0158 in intr_handler (frame=Variable "frame" is not available.
) at /usr/src/sys/arch/amd64/amd64/intr.c:528
#14 0xffffffff814c25cf in Xintr_ioapic_edge18_untramp ()
#15 0xffffffff81106e79 in Xspllower ()
#16 0x92dfda64d26a8da4 in ?? ()
#17 0xffff800014e07400 in ?? ()
#18 0xffffffff81734881 in acpicpu_idle () at 
/usr/src/sys/dev/acpi/acpicpu.c:1206
Previous frame inner to this frame (corrupt stack?)
(gdb) 

This core was not created by a bug in the kernel.  I modified
sys/arch/amd64/amd64/intr.c to call panic() in intr_handler().


I made a patch to correct this problem.  The following are the results
of running the patched gdb.

$ doas /usr/obj/gnu/usr.bin/binutils/gdb/gdb 
/usr/obj/sys/arch/amd64/compile/GENERIC.MP/bsd.gdb 
doas (a...@asou-kernelcore-tmp.soum.co.jp) password: 
GNU gdb 6.3
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "amd64-unknown-openbsd6.9"...
(gdb) target kvm /var/crash/bsd.0.core
#0  dumpsys () at /usr/src/sys/arch/amd64/amd64/machdep.c:1055
1055                            if (error)
Current language:  auto; currently minimal
(gdb) backtrace
#0  dumpsys () at /usr/src/sys/arch/amd64/amd64/machdep.c:1055
#1  0xffffffff8127c360 in boot (howto=18692) at 
/usr/src/sys/arch/amd64/amd64/machdep.c:847
#2  0xffffffff814fa1fb in reboot (howto=Variable "howto" is not available.
) at /usr/src/sys/kern/kern_xxx.c:74
#3  0xffffffff819e0022 in db_reboot (howto=Variable "howto" is not available.
) at /usr/src/sys/ddb/db_command.c:763
#4  0xffffffff819dfa72 in db_boot_crash_cmd () at 
/usr/src/sys/ddb/db_command.c:775
#5  0xffffffff819df21e in db_command (last_cmdp=0x4904, cmd_table=Variable 
"cmd_table" is not available.
) at /usr/src/sys/ddb/db_command.c:285
#6  0xffffffff819dfef8 in db_command_loop () at 
/usr/src/sys/ddb/db_command.c:680
#7  0xffffffff8178ba95 in db_trap (type=Variable "type" is not available.
) at /usr/src/sys/ddb/db_trap.c:92
#8  0xffffffff819d1782 in db_ktrap (type=0, code=-2112772192, regs=0x0) at 
/usr/src/sys/arch/amd64/amd64/db_interface.c:148
#9  0xffffffff81230cd2 in kerntrap (frame=0x0) at 
/usr/src/sys/arch/amd64/amd64/trap.c:312
#10 0xffffffff81dbc1ce in alltraps_kern_meltdown ()
#11 0xffffffff819d2210 in db_enter () at cpufunc.h:390
#12 0xffffffff8175916a in panic (fmt=0xffffffff81df285d "intr_handler") at 
/usr/src/sys/kern/subr_prf.c:214
#13 0xffffffff811d0158 in intr_handler (frame=Variable "frame" is not available.
) at /usr/src/sys/arch/amd64/amd64/intr.c:528
#14 0xffffffff814c25cf in Xintr_ioapic_edge18_untramp ()
#15 0xffffffff81106e79 in Xspllower ()
#16 0xffffffff811d04b4 in spllower (nlevel=Variable "nlevel" is not available.
) at /usr/src/sys/arch/amd64/amd64/intr.c:733
#17 0xffffffff812949cc in softintr_dispatch (which=Variable "which" is not 
available.
) at /usr/src/sys/arch/amd64/amd64/softintr.c:101
#18 0xffffffff814d89ff in Xsoftclock ()
#19 0xffffffff81734881 in acpicpu_idle () at 
/usr/src/sys/dev/acpi/acpicpu.c:1206
#20 0xffffffff812fdf8e in sched_idle (v=0xffffffff820daff0) at 
/usr/src/sys/kern/kern_sched.c:190
#21 0xffffffff815dd42c in proc_trampoline ()
#22 0x0000000000000000 in ?? ()
(gdb) 


comment, ok?
--
ASOU Masato

Index: gnu/usr.bin/binutils/gdb/amd64obsd-tdep.c
===================================================================
RCS file: /cvs/src/gnu/usr.bin/binutils/gdb/amd64obsd-tdep.c,v
retrieving revision 1.14
diff -u -p -r1.14 amd64obsd-tdep.c
--- gnu/usr.bin/binutils/gdb/amd64obsd-tdep.c   23 Dec 2019 02:18:51 -0000      
1.14
+++ gnu/usr.bin/binutils/gdb/amd64obsd-tdep.c   26 Apr 2021 11:42:22 -0000
@@ -382,14 +382,47 @@ static int amd64obsd_tf_reg_offset[] =
   21 * 8,                      /* %ss */
 };
 
+static int amd64obsd_fromspllower_reg_offset[] =
+{
+  -1,                          /* %rax */
+  2 * 8,                       /* %rbx */
+  -1,                          /* %rcx */
+  -1,                          /* %rdx */
+  -1,                          /* %rsi */
+  -1,                          /* %rdi */
+  -1,                          /* %rbp */
+  -1,                          /* %rsp */
+  -1,                          /* %r8 ... */
+  -1,
+  -1,
+  0 * 8,
+  -1,
+  1 * 8,
+  -1,
+  -1,                          /* ... %r15 */
+  3 * 8,                       /* %rip */
+  -1,                          /* %rflags */
+  -1,                          /* %cs */
+  -1,                          /* %ss */
+};
+
+/* from trad-frame.c */
+struct trad_frame_cache
+{
+  struct frame_info *next_frame;
+  CORE_ADDR this_base;
+  struct trad_frame_saved_reg *prev_regs;
+  struct frame_id this_id;
+};
 
 static struct trad_frame_cache *
 amd64obsd_trapframe_cache(struct frame_info *next_frame, void **this_cache)
 {
   struct trad_frame_cache *cache;
-  CORE_ADDR func, sp, addr;
+  CORE_ADDR func, sp, addr, trapcheck;
   ULONGEST cs;
   int i;
+  char *name = NULL;
 
   if (*this_cache)
     return *this_cache;
@@ -401,6 +434,29 @@ amd64obsd_trapframe_cache(struct frame_i
   sp = frame_unwind_register_unsigned (next_frame, AMD64_RSP_REGNUM);
   addr = sp;
 
+  /* adhoc check: from trap/intr? or from spllower()? */
+  /* Xspllower() pushes %rbx, %r13, %r11.
+     so, if *(sp+(8*3)) == spllower(),
+     this frame may not be trapframe, but a frame created by Xspllower(). */
+  trapcheck = read_memory_unsigned_integer (sp+(8*3), 8);
+  find_pc_partial_function (trapcheck, &name, NULL, NULL);
+
+  if (name != NULL && (strcmp (name, "spllower") == 0)) {
+    /* from spllower(). */
+
+    for (i = 0; i < ARRAY_SIZE (amd64obsd_fromspllower_reg_offset); i++)
+      if (amd64obsd_fromspllower_reg_offset[i] != -1)
+        trad_frame_set_reg_addr (cache, i, addr + 
amd64obsd_fromspllower_reg_offset[i]);
+
+    /* skip rbx,r13,r11(pushed by Xspllower()), rip(pushd by spllower()). */
+    trad_frame_set_value (cache->prev_regs, AMD64_RSP_REGNUM, addr+(8*4));
+
+    /* Construct the frame ID using the function start.  */
+    trad_frame_set_id (cache, frame_id_build (sp + (8*4), func));
+
+  } else {
+    /* from trap/intr. */
+
   for (i = 0; i < ARRAY_SIZE (amd64obsd_tf_reg_offset); i++)
     if (amd64obsd_tf_reg_offset[i] != -1)
       trad_frame_set_reg_addr (cache, i, addr + amd64obsd_tf_reg_offset[i]);
@@ -418,6 +474,8 @@ amd64obsd_trapframe_cache(struct frame_i
       /* Construct the frame ID using the function start.  */
       trad_frame_set_id (cache, frame_id_build (sp + 16, func));
     }
+
+  }
 
   return cache;
 }

Reply via email to