Download raw body.
lldb: Show consistent stack pointer value with GDB
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)
lldb: Show consistent stack pointer value with GDB