llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
29.43k stars 12.16k forks source link

[lldb]freebsd kernel unwinding unaware of trap frames #67665

Open emaste opened 1 year ago

emaste commented 1 year ago

While testing #67106 I experimented with a kernel module that generates a fault (using #ud2). The module loading from #67106 works correctly, but unwinding is not aware of the FreeBSD trap frame, and we report an incorrect address (frame 6):

(lldb) bt
* thread #1, name = '(pid 1860) sysctl (crashed)'
  * frame #0: 0xffffffff80b42bbe kernel`doadump + 46
    frame #1: 0xffffffff80b42947 kernel`kern_reboot + 1495
    frame #2: 0xffffffff80b42e1f kernel`vpanic + 415
    frame #3: 0xffffffff80b42c73 kernel`panic + 67
    frame #4: 0xffffffff8100b81c kernel`trap_fatal + 1036
    frame #5: 0xffffffff80fe2378 kernel`calltrap + 8
    frame #6: 0xfffffe013627cbc4
    frame #7: 0xffffffff80b54590 kernel`sysctl_root_handler_locked + 144
    frame #8: 0xffffffff80b539c1 kernel`sysctl_root + 577
    frame #9: 0xffffffff80b54046 kernel`userland_sysctl + 374
    frame #10: 0xffffffff80b53e8c kernel`sys___sysctl + 92
    frame #11: 0xffffffff8100c0d9 kernel`amd64_syscall + 265
    frame #12: 0xffffffff80fe2c8b kernel`fast_syscall_common + 248

gdb, by contrast, is able to parse the trap frame, and the address in frame 7 below is correct (although gdb wasn't able to load the module debug data):

(kgdb) bt
#0  __curthread () at /usr/src/sys/amd64/include/pcpu_aux.h:57
#1  doadump (textdump=<optimized out>) at /usr/src/sys/kern/kern_shutdown.c:405
#2  0xffffffff80b42947 in kern_reboot (howto=260) at /usr/src/sys/kern/kern_shutdown.c:526
#3  0xffffffff80b42e1f in vpanic (fmt=0xffffffff81134c30 "%s", ap=ap@entry=0xfffffe013627ca70) at /usr/src/sys/kern/kern_shutdown.c:970
#4  0xffffffff80b42c73 in panic (fmt=<unavailable>) at /usr/src/sys/kern/kern_shutdown.c:894
#5  0xffffffff8100b81c in trap_fatal (frame=0xfffffe013627cb00, eva=0) at /usr/src/sys/amd64/amd64/trap.c:952
#6  <signal handler called>
#7  0xffffffff8262f27d in ?? ()
#8  0x0000000100000000 in ?? ()
#9  0xffffffff82631270 in ?? ()
#10 0xfffffe013627cc20 in ?? ()
#11 0xffffffff80b54590 in sysctl_root_handler_locked (oid=0xfffffe013627ccc0, arg1=0x0, arg2=0, req=0xfffffe013627ccc0, tracker=0xffffffff8262f27d) at /usr/src/sys/kern/kern_sysctl.c:185
Backtrace stopped: frame did not save the PC
emaste commented 1 year ago

FreeBSD kernel GDB support is in the FreeBSD GDB port (not yet upstream): https://cgit.freebsd.org/ports/tree/devel/gdb/files/kgdb

The files are BSD licensed.

llvmbot commented 1 year ago

@llvm/issue-subscribers-lldb

While testing #67106 I experimented with a kernel module that generates a fault (using #ud2). The module loading from #67106 works correctly, but unwinding is not aware of the FreeBSD trap frame, and we report an incorrect address (frame 6): ``` (lldb) bt * thread #1, name = '(pid 1860) sysctl (crashed)' * frame #0: 0xffffffff80b42bbe kernel`doadump + 46 frame #1: 0xffffffff80b42947 kernel`kern_reboot + 1495 frame #2: 0xffffffff80b42e1f kernel`vpanic + 415 frame #3: 0xffffffff80b42c73 kernel`panic + 67 frame #4: 0xffffffff8100b81c kernel`trap_fatal + 1036 frame #5: 0xffffffff80fe2378 kernel`calltrap + 8 frame #6: 0xfffffe013627cbc4 frame #7: 0xffffffff80b54590 kernel`sysctl_root_handler_locked + 144 frame #8: 0xffffffff80b539c1 kernel`sysctl_root + 577 frame #9: 0xffffffff80b54046 kernel`userland_sysctl + 374 frame #10: 0xffffffff80b53e8c kernel`sys___sysctl + 92 frame #11: 0xffffffff8100c0d9 kernel`amd64_syscall + 265 frame #12: 0xffffffff80fe2c8b kernel`fast_syscall_common + 248 ``` gdb, by contrast, is able to parse the trap frame, and the address in frame 7 below is correct (although gdb wasn't able to load the module debug data): ``` (kgdb) bt #0 __curthread () at /usr/src/sys/amd64/include/pcpu_aux.h:57 #1 doadump (textdump=<optimized out>) at /usr/src/sys/kern/kern_shutdown.c:405 #2 0xffffffff80b42947 in kern_reboot (howto=260) at /usr/src/sys/kern/kern_shutdown.c:526 #3 0xffffffff80b42e1f in vpanic (fmt=0xffffffff81134c30 "%s", ap=ap@entry=0xfffffe013627ca70) at /usr/src/sys/kern/kern_shutdown.c:970 #4 0xffffffff80b42c73 in panic (fmt=<unavailable>) at /usr/src/sys/kern/kern_shutdown.c:894 #5 0xffffffff8100b81c in trap_fatal (frame=0xfffffe013627cb00, eva=0) at /usr/src/sys/amd64/amd64/trap.c:952 #6 <signal handler called> #7 0xffffffff8262f27d in ?? () #8 0x0000000100000000 in ?? () #9 0xffffffff82631270 in ?? () #10 0xfffffe013627cc20 in ?? () #11 0xffffffff80b54590 in sysctl_root_handler_locked (oid=0xfffffe013627ccc0, arg1=0x0, arg2=0, req=0xfffffe013627ccc0, tracker=0xffffffff8262f27d) at /usr/src/sys/kern/kern_sysctl.c:185 Backtrace stopped: frame did not save the PC ```