From: ASOU Masato Subject: Re: lldb: Show consistent stack pointer value with GDB To: tech@openbsd.org, "robert@openbsd.org" Cc: Yuichiro NAITO Date: Sun, 25 May 2025 13:29:16 +0900 ping I was tested this patch on following OpenBSD 7.7-current: $ sysctl -n kern.version OpenBSD 7.7-current (GENERIC.MP) #0: Sat May 24 17:12:34 JST 2025 asou@obsd-lldb.soum.co.jp:/usr/src/sys/arch/amd64/compile/GENERIC.MP $ -- ASOU@j2k25 On Fri, Nov 22, 2024 at 12:46 PM ASOU Masato wrote: > > I made a mistake when applying Naito's patch. > Broken lldb: > > $ doas lldb bsd.0 -c bsd.0.core > doas (asou@asou-lldb-kernel.soum.co.jp) password: > (lldb) target create "bsd.0" --core "bsd.0.core" > Core file '/var/crash/bsd.0.core' (x86_64) was loaded. > (lldb) register read > General Purpose Registers: > rbp = 0xffff80001cb01ca0 > rsp = 0xffff80001cb01a50 > rip = 0xffff80001cb01cd0 > ^^^^^^^^^^^^^^^^^^ This is stack area. > 21 registers were unavailable. > > (lldb) bt > * thread #1, name = 'Crashed Thread' > * frame #0: 0xffff80001cb01cd0 > frame #1: 0xffffffff8188f51c bsd.0`boot + 268 > frame #2: 0xffffffff81750548 bsd.0`reboot + 104 > frame #3: 0xffffffff817504da bsd.0`sys_reboot + 154 > frame #4: 0xffffffff81597807 bsd.0`syscall + 1511 > frame #5: 0xffffffff82312134 bsd.0`Xsyscall_meltdown + 308 > frame #6: 0xffffffff82312055 bsd.0`Xsyscall_meltdown + 85 > frame #7: 0xffff80001cb01e00 > frame #8: 0x0000083fba322fab > (lldb) > > > And I corrected mistake. > Corrected lldb: > > $ doas lldb bsd.0 -c bsd.0.core > doas (asou@asou-lldb-kernel.soum.co.jp) password: > (lldb) target create "bsd.0" --core "bsd.0.core" > Core file '/var/crash/bsd.0.core' (x86_64) was loaded. > (lldb) register read > General Purpose Registers: > rbp = 0xffff80001cb01ca0 > rsp = 0xffff80001cb01a50 > rip = 0xffffffff8188fda3 bsd.0`dumpsys + 1795 > ^^^^^^^^^^^^^^^^^^ This is instruction area. > 21 registers were unavailable. > > (lldb) bt > * thread #1, name = 'Crashed Thread' > * frame #0: 0xffffffff8188fda3 bsd.0`dumpsys + 1795 > frame #1: 0xffffffff8188f51c bsd.0`boot + 268 > frame #2: 0xffffffff81750548 bsd.0`reboot + 104 > frame #3: 0xffffffff817504da bsd.0`sys_reboot + 154 > frame #4: 0xffffffff81597807 bsd.0`syscall + 1511 > frame #5: 0xffffffff82312134 bsd.0`Xsyscall_meltdown + 308 > frame #6: 0xffffffff82312055 bsd.0`Xsyscall_meltdown + 85 > frame #7: 0xffff80001cb01e00 > frame #8: 0x0000083fba322fab > (lldb) > > ok, comments? > -- > ASOU Masato > > Index: gnu/llvm/lldb/source/Plugins/Process/OpenBSDKernel/RegisterContextOpenBSDKernel_i386.cpp > =================================================================== > RCS file: /cvs/src/gnu/llvm/lldb/source/Plugins/Process/OpenBSDKernel/RegisterContextOpenBSDKernel_i386.cpp,v > diff -u -p -r1.2 RegisterContextOpenBSDKernel_i386.cpp > --- gnu/llvm/lldb/source/Plugins/Process/OpenBSDKernel/RegisterContextOpenBSDKernel_i386.cpp > 31 Oct 2024 07:37:35 -0000 1.2 > +++ gnu/llvm/lldb/source/Plugins/Process/OpenBSDKernel/RegisterContextOpenBSDKernel_i386.cpp > 22 Nov 2024 03:43:08 -0000 > @@ -62,12 +62,12 @@ bool RegisterContextOpenBSDKernel_i386:: > if ((pcb.pcb_flags & PCB_SAVECTX) != 0) { > uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB]; > switch (reg) { > - return true; > case lldb_esp_i386: > value = (u_int32_t)pcb.pcb_ebp; > return true; > case lldb_ebp_i386: > value = m_thread.GetProcess()->ReadPointerFromMemory(pcb.pcb_ebp, error); > + return true; > case lldb_eip_i386: > value = m_thread.GetProcess()->ReadPointerFromMemory(pcb.pcb_ebp + 4, > error); > @@ -88,21 +88,21 @@ bool RegisterContextOpenBSDKernel_i386:: > > uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB]; > switch (reg) { > -#define PCBREG(x, offset) \ > - case lldb_##x##_i386: \ > - value = (u_int32_t)(pcb.pcb_##x + (offset)); \ > +#define PCBREG(x, offset) \ > + case lldb_##x##_i386: \ > + value = (u_int32_t)(pcb.pcb_##x + (offset)); \ > return true; > #define SFREG(x) \ > case lldb_##x##_i386: \ > - value = sf.sf_##x; \ > + value = (u_int32_t)sf.sf_##x; \ > return true; > > SFREG(edi); > SFREG(esi); > SFREG(ebx); > SFREG(eip); > - PCBREG(ebp); > - PCBREG(esp); > + PCBREG(ebp, 0); > + PCBREG(esp, sizeof(sf)); > } > #endif > return false; > Index: gnu/llvm/lldb/source/Plugins/Process/OpenBSDKernel/RegisterContextOpenBSDKernel_x86_64.cpp > =================================================================== > RCS file: /cvs/src/gnu/llvm/lldb/source/Plugins/Process/OpenBSDKernel/RegisterContextOpenBSDKernel_x86_64.cpp,v > diff -u -p -r1.2 RegisterContextOpenBSDKernel_x86_64.cpp > --- gnu/llvm/lldb/source/Plugins/Process/OpenBSDKernel/RegisterContextOpenBSDKernel_x86_64.cpp > 31 Oct 2024 07:37:35 -0000 1.2 > +++ gnu/llvm/lldb/source/Plugins/Process/OpenBSDKernel/RegisterContextOpenBSDKernel_x86_64.cpp > 22 Nov 2024 03:43:08 -0000 > @@ -96,7 +96,7 @@ bool RegisterContextOpenBSDKernel_x86_64 > PCBREG(rbp, 0); > PCBREG(rsp, 8); > case lldb_rip_x86_64: > - value = m_thread.GetProcess()->ReadPointerFromMemory(pcb.pcb_rbp, error); > + value = m_thread.GetProcess()->ReadPointerFromMemory(pcb.pcb_rsp, error); > return true; > } > } > > On Thu, Oct 31, 2024 at 8:13 AM ASOU Masato wrote: > > > > There are no objections, so I will commit later. > > -- > > ASOU Masato > > > > On Fri, Oct 18, 2024 at 10:35 AM ASOU Masato wrote: > > > > > > Hi robert and list. > > > > > > I was tested this patch on amd64 box and work fine for me. > > > ok asou@ > > > > > > Can I commit this patch ok? > > > > > > Before apply patch: > > > $ cd /var/crash > > > $ doas gdb bsd.0 > > > 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-openbsd7.6"...(no > > > debugging symbols found) > > > > > > (gdb) target kvm bsd.0.core > > > #0 0xffffffff8188fda3 in dumpsys () > > > (gdb) info register > > > > > > > > > > > > rbp 0xffff80001cb01ca0 0xffff80001cb01ca0 > > > rsp 0xffff80001cb01a50 0xffff80001cb01a50 > > > > > > > > > > > > (gdb) quit > > > $ doas lldb bsd.0 -c bsd.0.core > > > (lldb) target create "bsd.0" --core "bsd.0.core" > > > Core file '/var/crash/bsd.0.core' (x86_64) was loaded. > > > (lldb) bt > > > * thread #1, name = 'Crashed Thread' > > > * frame #0: 0xffffffff8188f51c bsd.0`boot + 268 > > > frame #1: 0xffffffff8188f51c bsd.0`boot + 268 > > > frame #2: 0xffffffff81750548 bsd.0`reboot + 104 > > > frame #3: 0xffffffff817504da bsd.0`sys_reboot + 154 > > > frame #4: 0xffffffff81597807 bsd.0`syscall + 1511 > > > frame #5: 0xffffffff82312134 bsd.0`Xsyscall_meltdown + 308 > > > frame #6: 0xffffffff82312055 bsd.0`Xsyscall_meltdown + 85 > > > frame #7: 0xffff80001cb01e00 > > > frame #8: 0x0000083fba322fab > > > (lldb) register read > > > General Purpose Registers: > > > rbp = 0xffff80001cb01ca0 > > > rsp = 0xffff80001cb01a48 > > > rip = 0xffffffff8188f51c bsd.0`boot + 268 > > > 21 registers were unavailable. > > > > > > (lldb) quit > > > > > > After applay patch: > > > $ doas lldb bsd.0 -c bsd.0.core > > > doas (asou@asou-lldb-kernel.soum.co.jp) password: > > > (lldb) target create "bsd.0" --core "bsd.0.core" > > > Core file '/var/crash/bsd.0.core' (x86_64) was loaded. > > > (lldb) bt > > > * thread #1, name = 'Crashed Thread' > > > * frame #0: 0xffff80001cb01cd0 > > > frame #1: 0xffffffff8188f51c bsd.0`boot + 268 > > > frame #2: 0xffffffff81750548 bsd.0`reboot + 104 > > > frame #3: 0xffffffff817504da bsd.0`sys_reboot + 154 > > > frame #4: 0xffffffff81597807 bsd.0`syscall + 1511 > > > frame #5: 0xffffffff82312134 bsd.0`Xsyscall_meltdown + 308 > > > frame #6: 0xffffffff82312055 bsd.0`Xsyscall_meltdown + 85 > > > frame #7: 0xffff80001cb01e00 > > > frame #8: 0x0000083fba322fab > > > (lldb) register read > > > General Purpose Registers: > > > rbp = 0xffff80001cb01ca0 > > > rsp = 0xffff80001cb01a50 > > > rip = 0xffff80001cb01cd0 > > > 21 registers were unavailable. > > > > > > (lldb) > > > -- > > > ASOU Masato > > > > > > On Fri, Aug 30, 2024 at 6:22 PM Yuichiro NAITO wrote: > > > > > > > > While I see the top of the backtrace frame in the kernel core file, > > > > the stack register value is differs from what GDB shows. > > > > > > > > For example, the kernel core file that is written by ddb, the stack pointer > > > > of the crashed thread is saved by the 'savectx' function. GDB rollbacks > > > > the pointer to the position when the beginning of the 'savectx' function is > > > > called. The lldb in my code won't. > > > > > > > > The lldb shows as follows. > > > > > > > > ``` > > > > (lldb) register read > > > > General Purpose Registers: > > > > rbp = 0xffff80001c9e2460 > > > > rsp = 0xffff80001c9e2208 > > > > rip = 0xffffffff81adbc0c bsd.0`db_fncall + 1052 > > > > 21 registers were unavailable. > > > > ``` > > > > > > > > Gdb shows as follows. > > > > > > > > ``` > > > > (gdb) info registers > > > > rax 0x0 0 > > > > rbx 0x0 0 > > > > rcx 0x0 0 > > > > rdx 0x0 0 > > > > rsi 0x0 0 > > > > rdi 0x0 0 > > > > rbp 0xffff80001c9e2460 0xffff80001c9e2460 > > > > rsp 0xffff80001c9e2210 0xffff80001c9e2210 > > > > r8 0x0 0 > > > > r9 0x0 0 > > > > r10 0x0 0 > > > > r11 0x0 0 > > > > r12 0x0 0 > > > > r13 0x0 0 > > > > r14 0x0 0 > > > > r15 0x0 0 > > > > rip 0xffffffff819f8723 0xffffffff819f8723 > > > > eflags 0x0 0 > > > > cs 0x0 0 > > > > ss 0x0 0 > > > > ds 0x0 0 > > > > es 0x0 0 > > > > fs 0x0 0 > > > > gs 0x0 0 > > > > ``` > > > > > > > > In this case, the lldb `rsp` value is 8 bytes smaller than what of gdb. > > > > These 8 bytes are the return address from the 'savectx' function. > > > > And `rip` is also different. It is my fault way to read it from `struct pcb`. > > > > The 'savectx' function is called from the 'dumpsys' function so the GDB shows > > > > the right pointer. > > > > > > > > In the other case, `struct pcb` is written by the 'cpu_switchto' function and > > > > the same thing happens. I fixed these cases to be consistent with GDB > > > > on amd64, i386, and arm64 architectures. > > > > OK? > > > > > > > > diff --git a/gnu/llvm/lldb/source/Plugins/Process/OpenBSDKernel/RegisterContextOpenBSDKernel_arm64.cpp b/gnu/llvm/lldb/source/Plugins/Process/OpenBSDKernel/RegisterContextOpenBSDKernel_arm64.cpp > > > > index 1ebfc6a799f..34fc8067203 100644 > > > > --- a/gnu/llvm/lldb/source/Plugins/Process/OpenBSDKernel/RegisterContextOpenBSDKernel_arm64.cpp > > > > +++ b/gnu/llvm/lldb/source/Plugins/Process/OpenBSDKernel/RegisterContextOpenBSDKernel_arm64.cpp > > > > @@ -91,7 +91,7 @@ bool RegisterContextOpenBSDKernel_arm64::ReadRegister( > > > > value = (u_int64_t)sf.sf_x29; > > > > return true; > > > > case gpr_sp_arm64: > > > > - value = (u_int64_t)pcb.pcb_sp; > > > > + value = (u_int64_t)(pcb.pcb_sp + sizeof(sf)); > > > > return true; > > > > case gpr_pc_arm64: > > > > value = (u_int64_t)sf.sf_lr; > > > > diff --git a/gnu/llvm/lldb/source/Plugins/Process/OpenBSDKernel/RegisterContextOpenBSDKernel_i386.cpp b/gnu/llvm/lldb/source/Plugins/Process/OpenBSDKernel/RegisterContextOpenBSDKernel_i386.cpp > > > > index 9a909a4e07d..fcbe6d9000a 100644 > > > > --- a/gnu/llvm/lldb/source/Plugins/Process/OpenBSDKernel/RegisterContextOpenBSDKernel_i386.cpp > > > > +++ b/gnu/llvm/lldb/source/Plugins/Process/OpenBSDKernel/RegisterContextOpenBSDKernel_i386.cpp > > > > @@ -62,12 +62,13 @@ bool RegisterContextOpenBSDKernel_i386::ReadRegister( > > > > if ((pcb.pcb_flags & PCB_SAVECTX) != 0) { > > > > uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB]; > > > > switch (reg) { > > > > -#define PCBREG(x) \ > > > > - case lldb_##x##_i386: \ > > > > - value = pcb.pcb_##x; \ > > > > + case lldb_esp_i386: > > > > + value = (u_int32_t)pcb.pcb_ebp; > > > > + return true; > > > > + case lldb_ebp_i386: > > > > + value = m_thread.GetProcess()->ReadPointerFromMemory(pcb.pcb_ebp, > > > > + error); > > > > return true; > > > > - PCBREG(ebp); > > > > - PCBREG(esp); > > > > case lldb_eip_i386: > > > > value = m_thread.GetProcess()->ReadPointerFromMemory(pcb.pcb_ebp + 4, > > > > error); > > > > @@ -88,17 +89,21 @@ bool RegisterContextOpenBSDKernel_i386::ReadRegister( > > > > > > > > uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB]; > > > > switch (reg) { > > > > +#define PCBREG(x, offset) \ > > > > + case lldb_##x##_i386: \ > > > > + value = (u_int32_t)(pcb.pcb_##x + (offset)); \ > > > > + return true; > > > > #define SFREG(x) \ > > > > case lldb_##x##_i386: \ > > > > - value = sf.sf_##x; \ > > > > + value = (u_int32_t)sf.sf_##x; \ > > > > return true; > > > > > > > > SFREG(edi); > > > > SFREG(esi); > > > > SFREG(ebx); > > > > SFREG(eip); > > > > - PCBREG(ebp); > > > > - PCBREG(esp); > > > > + PCBREG(ebp, 0); > > > > + PCBREG(esp, sizeof(sf)); > > > > } > > > > #endif > > > > return false; > > > > diff --git a/gnu/llvm/lldb/source/Plugins/Process/OpenBSDKernel/RegisterContextOpenBSDKernel_x86_64.cpp b/gnu/llvm/lldb/source/Plugins/Process/OpenBSDKernel/RegisterContextOpenBSDKernel_x86_64.cpp > > > > index 501fa858a92..a5eff4f42cf 100644 > > > > --- a/gnu/llvm/lldb/source/Plugins/Process/OpenBSDKernel/RegisterContextOpenBSDKernel_x86_64.cpp > > > > +++ b/gnu/llvm/lldb/source/Plugins/Process/OpenBSDKernel/RegisterContextOpenBSDKernel_x86_64.cpp > > > > @@ -77,9 +77,9 @@ bool RegisterContextOpenBSDKernel_x86_64::ReadRegister( > > > > case lldb_##x##_x86_64: \ > > > > value = (u_int64_t)sf.sf_##x; \ > > > > return true; > > > > -#define PCBREG(x) \ > > > > +#define PCBREG(x, offset) \ > > > > case lldb_##x##_x86_64: \ > > > > - value = pcb.pcb_##x; \ > > > > + value = pcb.pcb_##x + (offset); \ > > > > return true; > > > > switch (reg) { > > > > SFREG(r15); > > > > @@ -89,14 +89,14 @@ bool RegisterContextOpenBSDKernel_x86_64::ReadRegister( > > > > SFREG(rbp); > > > > SFREG(rbx); > > > > SFREG(rip); > > > > - PCBREG(rsp); > > > > + PCBREG(rsp, sizeof(sf)); > > > > } > > > > } else { > > > > switch (reg) { > > > > - PCBREG(rbp); > > > > - PCBREG(rsp); > > > > + PCBREG(rbp, 0); > > > > + PCBREG(rsp, 8); > > > > case lldb_rip_x86_64: > > > > - value = m_thread.GetProcess()->ReadPointerFromMemory(pcb.pcb_rbp + 8, > > > > + value = m_thread.GetProcess()->ReadPointerFromMemory(pcb.pcb_rsp, > > > > error); > > > > return true; > > > > } > > > > > > > > -- > > > > Yuichiro NAITO (naito.yuichiro@gmail.com) > > > >