Skip to content

Commit 2ed510d

Browse files
authored
[LLDB][Minidump] Extend the minidump x86_64 registers to include fs_base and gs_base (#106767)
A follow up to #106473 Minidump wasn't collecting fs or gs_base. This patch extends the x86_64 register context and gated reading it behind an lldb specific flag. Additionally these registers are explicitly checked in the tests.
1 parent 8e28f04 commit 2ed510d

File tree

4 files changed

+31
-2
lines changed

4 files changed

+31
-2
lines changed

lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -473,7 +473,8 @@ GetThreadContext_x86_64(RegisterContext *reg_ctx) {
473473
lldb_private::minidump::MinidumpContext_x86_64_Flags::x86_64_Flag |
474474
lldb_private::minidump::MinidumpContext_x86_64_Flags::Control |
475475
lldb_private::minidump::MinidumpContext_x86_64_Flags::Segments |
476-
lldb_private::minidump::MinidumpContext_x86_64_Flags::Integer);
476+
lldb_private::minidump::MinidumpContext_x86_64_Flags::Integer |
477+
lldb_private::minidump::MinidumpContext_x86_64_Flags::LLDBSpecific);
477478
thread_context.rax = read_register_u64(reg_ctx, "rax");
478479
thread_context.rbx = read_register_u64(reg_ctx, "rbx");
479480
thread_context.rcx = read_register_u64(reg_ctx, "rcx");
@@ -499,6 +500,8 @@ GetThreadContext_x86_64(RegisterContext *reg_ctx) {
499500
thread_context.gs = read_register_u64(reg_ctx, "gs");
500501
thread_context.ss = read_register_u64(reg_ctx, "ss");
501502
thread_context.ds = read_register_u64(reg_ctx, "ds");
503+
thread_context.fs_base = read_register_u64(reg_ctx, "fs_base");
504+
thread_context.gs_base = read_register_u64(reg_ctx, "gs_base");
502505
return thread_context;
503506
}
504507

lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ lldb::DataBufferSP lldb_private::minidump::ConvertMinidumpContext_x86_64(
6767
auto ControlFlag = MinidumpContext_x86_64_Flags::Control;
6868
auto IntegerFlag = MinidumpContext_x86_64_Flags::Integer;
6969
auto SegmentsFlag = MinidumpContext_x86_64_Flags::Segments;
70+
auto LLDBSpecificFlag = MinidumpContext_x86_64_Flags::LLDBSpecific;
7071

7172
if ((context_flags & x86_64_Flag) != x86_64_Flag)
7273
return nullptr;
@@ -104,6 +105,13 @@ lldb::DataBufferSP lldb_private::minidump::ConvertMinidumpContext_x86_64(
104105
writeRegister(&context->r15, result_base, reg_info[lldb_r15_x86_64]);
105106
}
106107

108+
if ((context_flags & LLDBSpecificFlag) == LLDBSpecificFlag) {
109+
writeRegister(&context->fs_base, result_base,
110+
reg_info[x86_64_with_base::lldb_fs_base]);
111+
writeRegister(&context->gs_base, result_base,
112+
reg_info[x86_64_with_base::lldb_gs_base]);
113+
}
114+
107115
// TODO parse the floating point registers
108116

109117
return result_context_buf;

lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,11 @@ struct MinidumpContext_x86_64 {
153153
llvm::support::ulittle64_t last_branch_from_rip;
154154
llvm::support::ulittle64_t last_exception_to_rip;
155155
llvm::support::ulittle64_t last_exception_from_rip;
156+
157+
// LLDB can save core files and save extra information that isn't available
158+
// from Google breakpad, or similar, minidump files.
159+
llvm::support::ulittle64_t fs_base;
160+
llvm::support::ulittle64_t gs_base;
156161
};
157162

158163
// For context_flags. These values indicate the type of
@@ -168,9 +173,10 @@ enum class MinidumpContext_x86_64_Flags : uint32_t {
168173
FloatingPoint = x86_64_Flag | 0x00000008,
169174
DebugRegisters = x86_64_Flag | 0x00000010,
170175
XState = x86_64_Flag | 0x00000040,
176+
LLDBSpecific = x86_64_Flag | 0x80000000,
171177

172178
Full = Control | Integer | FloatingPoint,
173-
All = Full | Segments | DebugRegisters,
179+
All = Full | Segments | DebugRegisters | LLDBSpecific,
174180

175181
LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ All)
176182
};

lldb/test/API/functionalities/process_save_core_minidump/TestProcessSaveCoreMinidump.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,18 @@ def verify_core_file(
6767
self.assertIn(thread_id, stacks_to_registers_map)
6868
register_val_list = stacks_to_registers_map[thread_id]
6969
frame_register_list = frame.GetRegisters()
70+
# explicitly verify we collected fs and gs base for x86_64
71+
explicit_registers = ["fs_base", "gs_base"]
72+
for reg in explicit_registers:
73+
register = frame_register_list.GetFirstValueByName(reg)
74+
self.assertNotEqual(None, register)
75+
self.assertEqual(
76+
register.GetValueAsUnsigned(),
77+
stacks_to_registers_map[thread_id]
78+
.GetFirstValueByName("fs_base")
79+
.GetValueAsUnsigned(),
80+
)
81+
7082
for x in register_val_list:
7183
self.assertEqual(
7284
x.GetValueAsUnsigned(),

0 commit comments

Comments
 (0)