When a new trap code is added in OpenBSD kernel,
gdb needs to be updated to be taught which symbols are trap frame.
This scenario is just the case of a following patch.

*1: 
https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/gnu/usr.bin/binutils/gdb/amd64obsd-tdep.c.diff?r1=1.13&r2=1.14&f=h

In current ddb, this kind of lookup has been omitted since following commit.

https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/arch/amd64/amd64/db_trace.c.diff?r1=1.38&r2=1.39&f=h

So, I think it is possible that gdb works as same as ddb does.
The frame pointer links in the kernel stack are always kept over a trap frame.
Here is a patch for this idea.

diff --git a/gnu/usr.bin/binutils/gdb/amd64-tdep.c 
b/gnu/usr.bin/binutils/gdb/amd64-tdep.c
index 6892a95d4e1..24a08b763c6 100644
--- a/gnu/usr.bin/binutils/gdb/amd64-tdep.c
+++ b/gnu/usr.bin/binutils/gdb/amd64-tdep.c
@@ -841,21 +841,27 @@ amd64_frame_cache (struct frame_info *next_frame, void 
**this_cache)
   if (cache->frameless_p)
     {
       /* We didn't find a valid frame.  If we're at the start of a
         function, or somewhere half-way its prologue, the function's
         frame probably hasn't been fully setup yet.  Try to
         reconstruct the base address for the stack frame by looking
         at the stack pointer.  For truly "frameless" functions this
         might work too.  */
 
       frame_unwind_register (next_frame, AMD64_RSP_REGNUM, buf);
-      cache->base = extract_unsigned_integer (buf, 8) + cache->sp_offset;
+      CORE_ADDR prev_sp = extract_unsigned_integer (buf, 8) + cache->sp_offset;
+      read_memory (prev_sp - register_size (current_gdbarch, AMD64_RBP_REGNUM),
+                  buf, sizeof(buf));
+      cache->base = extract_unsigned_integer (buf, 8);
+      /* Now we have correct %rbp offset. */
+      cache->saved_regs[AMD64_RBP_REGNUM] = 0;
+      cache->sp_offset += 8;
     }
   else
     {
       frame_unwind_register (next_frame, AMD64_RBP_REGNUM, buf);
       cache->base = extract_unsigned_integer (buf, 8);
     }
 
   /* Now that we have the base address for the stack frame we can
      calculate the value of %rsp in the calling frame.  */
   cache->saved_sp = cache->base + 16;

When gdb analyze trap frame, gdb sets 'frameless_p' false.
In this case, 'frame_unwind_register(..., AMD64_RSP_REGNUM, ...)'
returns stack pointer in the next frame (that means lower frame in the stack).
The frame pointer is always written at 8 bytes lower than it.
Then reads the value to be a base pointer and marks RBP offset and
fix stack pointer offset.
These are normal operations of the frame cache.

I reverted *1 patch and applied my patch for testing.
My gdb shows brack trace over 'alltraps_kern_meltdown' frame.
This sample shows that ddb breaks at `hardclock + 4` and boot dump.

```
#0  dumpsys () at /usr/src/sys/arch/amd64/amd64/machdep.c:1055
#1  0xffffffff8118d5e7 in boot (howto=18688) at 
/usr/src/sys/arch/amd64/amd64/machdep.c:847
#2  0xffffffff8174dd32 in reboot (howto=Variable "howto" is not available.
) at /usr/src/sys/kern/kern_xxx.c:74
#3  0xffffffff81b59eb0 in db_reboot (howto=Variable "howto" is not available.
) at /usr/src/sys/ddb/db_command.c:769
#4  0xffffffff81b59922 in db_boot_dump_cmd () at 
/usr/src/sys/ddb/db_command.c:787
#5  0xffffffff81b5900e in db_command (last_cmdp=0x4900, cmd_table=Variable 
"cmd_table" is not available.
) at /usr/src/sys/ddb/db_command.c:285
#6  0xffffffff81b59de4 in db_command_loop () at 
/usr/src/sys/ddb/db_command.c:686
#7  0xffffffff81a60185 in db_trap (type=Unhandled dwarf expression opcode 0xa3
) at /usr/src/sys/ddb/db_trap.c:92
#8  0xffffffff81b600d8 in db_ktrap (type=1, code=0, regs=0xffff8000214ef570)
 at /usr/src/sys/arch/amd64/amd64/db_interface.c:149
#9  0xffffffff8119d44c in kerntrap (frame=0x0) at 
/usr/src/sys/arch/amd64/amd64/trap.c:309
#10 0xffffffff81dfe1ce in alltraps_kern_meltdown ()
#11 0xffffffff814046d5 in hardclock (frame=0x0) at 
/usr/src/sys/kern/kern_clock.c:139
#12 0xffffffff810ea0d1 in lapic_clockintr (arg=Unhandled dwarf expression 
opcode 0xa3
) at /usr/src/sys/arch/amd64/amd64/lapic.c:453
#13 0xffffffff812f09e6 in Xresume_lapic_ltimer ()
#14 0xffffffff817b8179 in Xspllower ()
#15 0xffffffff81c03018 in spllower (nlevel=Unhandled dwarf expression opcode 
0xa3
) at /usr/src/sys/arch/amd64/amd64/intr.c:724
#16 0xffffffff81b600ed in db_ktrap (type=1, code=0, regs=0x0)
  at /usr/src/sys/arch/amd64/amd64/db_interface.c:152
#17 0xffffffff8119d44c in kerntrap (frame=0x0) at 
/usr/src/sys/arch/amd64/amd64/trap.c:309
#18 0xffffffff81dfe1ce in alltraps_kern_meltdown ()
#19 0xffffffff81b601e0 in db_enter () at cpufunc.h:390
#20 0xffffffff81512b2d in ddb_sysctl (name=Variable "name" is not available.
) at /usr/src/sys/ddb/db_usrreq.c:81
#21 0xffffffff81949474 in sys_sysctl (p=0x1, v=0x7f7ffffd2990, retval=Variable 
"retval" is not available.
) at /usr/src/sys/kern/kern_sysctl.c:250
#22 0xffffffff8119db89 in syscall (frame=0xbff5d1c299b74ff0) at 
sys/syscall_mi.h:102
#23 0xffffffff81dff134 in Xsyscall ()
```

Without my patch, gdb doesn't show the back trace after 
`alltraps_kern_meltdown`.

```
#0  dumpsys () at /usr/src/sys/arch/amd64/amd64/machdep.c:1055
#1  0xffffffff8118d5e7 in boot (howto=18688) at 
/usr/src/sys/archa/amd64/amd64/machdep.c:847
#2  0xffffffff8174dd32 in reboot (howto=Variable "howto" is not available.
) at /usr/src/sys/kern/kern_xxx.c:74
#3  0xffffffff81b59eb0 in db_reboot (howto=Variable "howto" is not available.
) at /usr/src/sys/ddb/db_command.c:769
#4  0xffffffff81b59922 in db_boot_dump_cmd () at 
/usr/src/sys/ddb/db_command.c:787
#5  0xffffffff81b5900e in db_command (last_cmdp=0x4900, cmd_table=Variable 
"cmd_table" is not available.
) at /usr/src/sys/ddb/db_command.c:285
#6  0xffffffff81b59de4 in db_command_loop () at 
/usr/src/sys/ddb/db_command.c:686
#7  0xffffffff81a60185 in db_trap (type=Unhandled dwarf expression opcode 0xa3
) at /usr/src/sys/ddb/db_trap.c:92
#8  0xffffffff81b600d8 in db_ktrap (type=1, code=0, regs=0xffff8000214ef570)
at /usr/src/sys/arch/amd64/amd64/db_interface.c:149
#9  0xffffffff8119d44c in kerntrap (frame=0x0) at 
/usr/src/sys/arch/amd64/amd64/trap.c:309
#10 0xffffffff81dfe1ce in alltraps_kern_meltdown ()
#11 0xffff8000214ef660 in ?? ()
#12 0xffffffff822774a8 in x86_soft_intrs ()
#13 0x0000000000009095 in ?? ()
#14 0x0000000000000000 in ?? ()
```

-- 
Yuichiro NAITO (naito.yuic...@gmail.com)

Reply via email to