[Lldb-commits] [lldb] 82ebd33 - [LLDB][Minidumps] Read x64 registers as 64b and handle truncation in the file builder (#106473)
via lldb-commits
lldb-commits at lists.llvm.org
Wed Aug 28 21:15:33 PDT 2024
Author: Jacob Lalonde
Date: 2024-08-28T21:15:30-07:00
New Revision: 82ebd333a889d2372c8445dc3d5d527ec48537db
URL: https://github.com/llvm/llvm-project/commit/82ebd333a889d2372c8445dc3d5d527ec48537db
DIFF: https://github.com/llvm/llvm-project/commit/82ebd333a889d2372c8445dc3d5d527ec48537db.diff
LOG: [LLDB][Minidumps] Read x64 registers as 64b and handle truncation in the file builder (#106473)
This patch addresses a bug where `cs`/`fs` and other segmentation flags
were being identified as having a type of `32b` and `64b` for `rflags`.
In that case the register value was returning the fail value `0xF...`
and this was corrupting some minidumps. Here we just read it as a 64b
value and truncate it.
In addition to that fix, I added comparing the registers from the live
process to the loaded core for the generic minidump test. Prior only
being ARM register tests. This explains why this was not detected
before.
Added:
Modified:
lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp
lldb/test/API/functionalities/process_save_core_minidump/TestProcessSaveCoreMinidump.py
Removed:
################################################################################
diff --git a/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp b/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp
index 689a3fb0e84852..13355afb58dbd1 100644
--- a/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp
+++ b/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp
@@ -491,12 +491,14 @@ GetThreadContext_x86_64(RegisterContext *reg_ctx) {
thread_context.r14 = read_register_u64(reg_ctx, "r14");
thread_context.r15 = read_register_u64(reg_ctx, "r15");
thread_context.rip = read_register_u64(reg_ctx, "rip");
- thread_context.eflags = read_register_u32(reg_ctx, "rflags");
- thread_context.cs = read_register_u16(reg_ctx, "cs");
- thread_context.fs = read_register_u16(reg_ctx, "fs");
- thread_context.gs = read_register_u16(reg_ctx, "gs");
- thread_context.ss = read_register_u16(reg_ctx, "ss");
- thread_context.ds = read_register_u16(reg_ctx, "ds");
+ // To make our code agnostic to whatever type the register value identifies
+ // itself as, we read as a u64 and truncate to u32/u16 ourselves.
+ thread_context.eflags = read_register_u64(reg_ctx, "rflags");
+ thread_context.cs = read_register_u64(reg_ctx, "cs");
+ thread_context.fs = read_register_u64(reg_ctx, "fs");
+ thread_context.gs = read_register_u64(reg_ctx, "gs");
+ thread_context.ss = read_register_u64(reg_ctx, "ss");
+ thread_context.ds = read_register_u64(reg_ctx, "ds");
return thread_context;
}
diff --git a/lldb/test/API/functionalities/process_save_core_minidump/TestProcessSaveCoreMinidump.py b/lldb/test/API/functionalities/process_save_core_minidump/TestProcessSaveCoreMinidump.py
index 5abaa05a90f63e..ea59aef004aff5 100644
--- a/lldb/test/API/functionalities/process_save_core_minidump/TestProcessSaveCoreMinidump.py
+++ b/lldb/test/API/functionalities/process_save_core_minidump/TestProcessSaveCoreMinidump.py
@@ -17,6 +17,7 @@ def verify_core_file(
expected_modules,
expected_threads,
stacks_to_sps_map,
+ stacks_to_registers_map,
):
# To verify, we'll launch with the mini dump
target = self.dbg.CreateTarget(None)
@@ -62,6 +63,17 @@ def verify_core_file(
# Try to read just past the red zone and fail
process.ReadMemory(sp - red_zone - 1, 1, error)
self.assertTrue(error.Fail(), "No failure when reading past the red zone")
+ # Verify the registers are the same
+ self.assertIn(thread_id, stacks_to_registers_map)
+ register_val_list = stacks_to_registers_map[thread_id]
+ frame_register_list = frame.GetRegisters()
+ for x in register_val_list:
+ self.assertEqual(
+ x.GetValueAsUnsigned(),
+ frame_register_list.GetFirstValueByName(
+ x.GetName()
+ ).GetValueAsUnsigned(),
+ )
self.dbg.DeleteTarget(target)
@@ -93,12 +105,16 @@ def test_save_linux_mini_dump(self):
expected_number_of_threads = process.GetNumThreads()
expected_threads = []
stacks_to_sp_map = {}
+ stakcs_to_registers_map = {}
for thread_idx in range(process.GetNumThreads()):
thread = process.GetThreadAtIndex(thread_idx)
thread_id = thread.GetThreadID()
expected_threads.append(thread_id)
stacks_to_sp_map[thread_id] = thread.GetFrameAtIndex(0).GetSP()
+ stakcs_to_registers_map[thread_id] = thread.GetFrameAtIndex(
+ 0
+ ).GetRegisters()
# save core and, kill process and verify corefile existence
base_command = "process save-core --plugin-name=minidump "
@@ -110,6 +126,7 @@ def test_save_linux_mini_dump(self):
expected_modules,
expected_threads,
stacks_to_sp_map,
+ stakcs_to_registers_map,
)
self.runCmd(base_command + " --style=modified-memory '%s'" % (core_dirty))
@@ -120,6 +137,7 @@ def test_save_linux_mini_dump(self):
expected_modules,
expected_threads,
stacks_to_sp_map,
+ stakcs_to_registers_map,
)
self.runCmd(base_command + " --style=full '%s'" % (core_full))
@@ -130,6 +148,7 @@ def test_save_linux_mini_dump(self):
expected_modules,
expected_threads,
stacks_to_sp_map,
+ stakcs_to_registers_map,
)
options = lldb.SBSaveCoreOptions()
@@ -147,6 +166,7 @@ def test_save_linux_mini_dump(self):
expected_modules,
expected_threads,
stacks_to_sp_map,
+ stakcs_to_registers_map,
)
options = lldb.SBSaveCoreOptions()
@@ -163,6 +183,7 @@ def test_save_linux_mini_dump(self):
expected_modules,
expected_threads,
stacks_to_sp_map,
+ stakcs_to_registers_map,
)
# Minidump can now save full core files, but they will be huge and
@@ -181,6 +202,7 @@ def test_save_linux_mini_dump(self):
expected_modules,
expected_threads,
stacks_to_sp_map,
+ stakcs_to_registers_map,
)
self.assertSuccess(process.Kill())
@@ -276,13 +298,16 @@ def test_save_linux_mini_dump_default_options(self):
expected_threads = []
stacks_to_sp_map = {}
expected_pid = process.GetProcessInfo().GetProcessID()
+ stacks_to_registers_map = {}
for thread_idx in range(process.GetNumThreads()):
thread = process.GetThreadAtIndex(thread_idx)
thread_id = thread.GetThreadID()
expected_threads.append(thread_id)
stacks_to_sp_map[thread_id] = thread.GetFrameAtIndex(0).GetSP()
-
+ stacks_to_registers_map[thread_id] = thread.GetFrameAtIndex(
+ 0
+ ).GetRegisters()
# This is almost identical to the single thread test case because
# minidump defaults to stacks only, so we want to see if the
@@ -294,7 +319,14 @@ def test_save_linux_mini_dump_default_options(self):
error = process.SaveCore(options)
self.assertTrue(error.Success())
- self.verify_core_file(default_value_file, expected_pid, expected_modules, expected_threads, stacks_to_sp_map)
+ self.verify_core_file(
+ default_value_file,
+ expected_pid,
+ expected_modules,
+ expected_threads,
+ stacks_to_sp_map,
+ stacks_to_registers_map,
+ )
finally:
self.assertTrue(self.dbg.DeleteTarget(target))
More information about the lldb-commits
mailing list