Skip to content

Commit f432d21

Browse files
committed
Add Process code to get the fs_base region and the .tdata sections. Plus a test
1 parent 4123050 commit f432d21

File tree

2 files changed

+100
-4
lines changed

2 files changed

+100
-4
lines changed

lldb/source/Target/Process.cpp

Lines changed: 65 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6528,6 +6528,63 @@ static void AddRegion(const MemoryRegionInfo &region, bool try_dirty_pages,
65286528
CreateCoreFileMemoryRange(region));
65296529
}
65306530

6531+
static void AddRegisterSections(Process &process, ThreadSP &thread_sp, CoreFileMemoryRanges &ranges, lldb::addr_t range_end) {
6532+
lldb::RegisterContextSP reg_ctx = thread_sp->GetRegisterContext();
6533+
if (!reg_ctx)
6534+
return;
6535+
6536+
const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(lldb::RegisterKind::eRegisterKindGeneric, LLDB_REGNUM_GENERIC_TP);
6537+
if (!reg_info)
6538+
return;
6539+
6540+
lldb_private::RegisterValue reg_value;
6541+
bool success = reg_ctx->ReadRegister(reg_info, reg_value);
6542+
if (!success)
6543+
return;
6544+
6545+
const uint64_t fail_value = UINT64_MAX;
6546+
bool readSuccess = true;
6547+
const lldb::addr_t reg_value_addr = reg_value.GetAsUInt64(fail_value, &readSuccess);
6548+
if (!readSuccess || reg_value_addr == fail_value)
6549+
return;
6550+
6551+
MemoryRegionInfo register_region;
6552+
Status err = process.GetMemoryRegionInfo(reg_value_addr, register_region);
6553+
if (err.Fail())
6554+
return;
6555+
6556+
// We already saved off this truncated stack range.
6557+
if (register_region.GetRange().GetRangeEnd() == range_end)
6558+
return;
6559+
6560+
// We don't need to worry about duplication because the CoreFileMemoryRanges
6561+
// will unique them
6562+
AddRegion(register_region, true, ranges);
6563+
}
6564+
6565+
static void AddModuleThreadLocalSections(Process &process, ThreadSP &thread_sp, CoreFileMemoryRanges &ranges, lldb::addr_t range_end) {
6566+
ModuleList &module_list = process.GetTarget().GetImages();
6567+
for (size_t idx = 0; idx < module_list.GetSize(); idx++) {
6568+
ModuleSP module_sp = module_list.GetModuleAtIndex(idx);
6569+
if (!module_sp)
6570+
continue;
6571+
// We want the entire section, so the offset is 0.
6572+
const lldb::addr_t tls_storage_addr = thread_sp->GetThreadLocalData(module_sp, 0);
6573+
if (tls_storage_addr == LLDB_INVALID_ADDRESS)
6574+
continue;
6575+
MemoryRegionInfo tls_storage_region;
6576+
Status err = process.GetMemoryRegionInfo(tls_storage_addr, tls_storage_region);
6577+
if (err.Fail())
6578+
continue;
6579+
6580+
// We already saved off this truncated stack range.
6581+
if (tls_storage_region.GetRange().GetRangeEnd() == range_end)
6582+
continue;
6583+
6584+
AddRegion(tls_storage_region, true, ranges);
6585+
}
6586+
}
6587+
65316588
static void SaveOffRegionsWithStackPointers(Process &process,
65326589
const SaveCoreOptions &core_options,
65336590
const MemoryRegionInfos &regions,
@@ -6559,11 +6616,17 @@ static void SaveOffRegionsWithStackPointers(Process &process,
65596616
// off in other calls
65606617
sp_region.GetRange().SetRangeBase(stack_head);
65616618
sp_region.GetRange().SetByteSize(stack_size);
6562-
stack_ends.insert(sp_region.GetRange().GetRangeEnd());
6619+
const addr_t range_end = sp_region.GetRange().GetRangeEnd();
6620+
stack_ends.insert(range_end);
65636621
// This will return true if the threadlist the user specified is empty,
65646622
// or contains the thread id from thread_sp.
6565-
if (core_options.ShouldThreadBeSaved(thread_sp->GetID()))
6623+
if (core_options.ShouldThreadBeSaved(thread_sp->GetID())) {
65666624
AddRegion(sp_region, try_dirty_pages, ranges);
6625+
// Add the register section if x86_64 and add the module tls data
6626+
// only if the range isn't the same as this truncated stack range.
6627+
AddRegisterSections(process, thread_sp, ranges, range_end);
6628+
AddModuleThreadLocalSections(process, thread_sp, ranges, range_end);
6629+
}
65676630
}
65686631
}
65696632
}

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

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -523,8 +523,10 @@ def minidump_deleted_on_save_failure(self):
523523
finally:
524524
self.assertTrue(self.dbg.DeleteTarget(target))
525525

526-
def minidump_deterministic_difference(self):
527-
"""Test that verifies that two minidumps produced are identical."""
526+
@skipUnlessPlatform(["linux"])
527+
@skipUnlessArch("x86_64")
528+
def minidump_saves_fs_base_region(self):
529+
"""Test that verifies the minidump file saves region for fs_base"""
528530

529531
self.build()
530532
exe = self.getBuildArtifact("a.out")
@@ -534,6 +536,37 @@ def minidump_deterministic_difference(self):
534536
None, None, self.get_process_working_directory()
535537
)
536538
self.assertState(process.GetState(), lldb.eStateStopped)
539+
thread = process.GetThreadAtIndex(0)
540+
custom_file = self.getBuildArtifact("core.reg_region.dmp")
541+
options = lldb.SBSaveCoreOptions()
542+
options.SetOutputFile(lldb.SBFileSpec(custom_file))
543+
options.SetPluginName("minidump")
544+
options.SetStyle(lldb.eSaveCoreCustomOnly)
545+
options.AddThread(thread)
546+
error = process.SaveCore(options)
547+
self.assertTrue(error.Success())
548+
549+
registers = thread.GetFrameAtIndex(0).GetRegisters()
550+
fs_base = registers.GetFirstValueByName("fs_base").GetValueAsUnsigned()
551+
core_target = self.dbg.CreateTarget(None)
552+
core_proc = core_target.LoadCore(one_region_file)
553+
core_region_list = core_proc.GetMemoryRegions()
554+
live_region_list = process.GetMemoryRegions()
555+
live_region = lldb.SBMemoryRegionInfo()
556+
live_region_list.GetMemoryRegionForAddress(fs_base, live_region)
557+
core_region = lldb.SBMemoryRegionInfo()
558+
error = core_region_list.GetMemoryRegionForAddress(fs_base, core_region)
559+
self.assertTrue(error.Success())
560+
self.assertEqual(live_region, core_region)
561+
562+
finally:
563+
self.assertTrue(self.dbg.DeleteTarget(target))
564+
self.assertTrue(self.dbg.DeleteTarget(core_target))
565+
if os.path.isfile(custom_file):
566+
os.unlink(custom_file)
567+
568+
def minidump_deterministic_difference(self):
569+
"""Test that verifies that two minidumps produced are identical."""
537570

538571
core_styles = [
539572
lldb.eSaveCoreStackOnly,

0 commit comments

Comments
 (0)