Index | Thread | Search

From:
ASOU Masato <takeasou.masato@gmail.com>
Subject:
Re: lldb: Show consistent stack pointer value with GDB
To:
tech@openbsd.org, "robert@openbsd.org" <robert@openbsd.org>
Cc:
Yuichiro NAITO <naito.yuichiro@gmail.com>
Date:
Sun, 25 May 2025 13:29:16 +0900

Download raw body.

Thread
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 <takeasou.masato@gmail.com> 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 <takeasou.masato@gmail.com> wrote:
> >
> > There are no objections, so I will commit later.
> > --
> > ASOU Masato
> >
> > On Fri, Oct 18, 2024 at 10:35 AM ASOU Masato <takeasou.masato@gmail.com> 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
> > >
> > >     </snip>
> > >
> > >     rbp            0xffff80001cb01ca0       0xffff80001cb01ca0
> > >     rsp            0xffff80001cb01a50       0xffff80001cb01a50
> > >
> > >     </snip>
> > >
> > >     (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 <naito.yuichiro@gmail.com> 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 <dumpsys+1795>
> > > > 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)
> > > >