mirror of
https://github.com/intel/llvm.git
synced 2026-01-21 12:19:23 +08:00
[LLDB][SBSaveCore] Add selectable memory regions to SBSaveCore (#105442)
This patch adds the option to specify specific memory ranges to be included in a given core file. The current implementation lets user specified ranges either be in addition to a certain save style, or independent of them via the newly added custom enum. To achieve being inclusive of save style, I've moved from a std::vector of ranges to a RangeDataVector, and to join overlapping ranges to prevent duplication of memory ranges in the core file. As a non function bonus, when SBSavecore was initially created, the header was included in the lldb-private interfaces, and I've fixed that and moved it the forward declare as an oversight. CC @bulbazord in case we need to include that into swift.
This commit is contained in:
@@ -6517,14 +6517,14 @@ static bool AddDirtyPages(const MemoryRegionInfo ®ion,
|
||||
} else {
|
||||
// Add previous contiguous range and init the new range with the
|
||||
// current dirty page.
|
||||
ranges.push_back({range, lldb_permissions});
|
||||
ranges.Append(range.start(), range.end(), {range, lldb_permissions});
|
||||
range = llvm::AddressRange(page_addr, page_addr + page_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
// The last range
|
||||
if (!range.empty())
|
||||
ranges.push_back({range, lldb_permissions});
|
||||
ranges.Append(range.start(), range.end(), {range, lldb_permissions});
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -6545,7 +6545,10 @@ static void AddRegion(const MemoryRegionInfo ®ion, bool try_dirty_pages,
|
||||
return;
|
||||
if (try_dirty_pages && AddDirtyPages(region, ranges))
|
||||
return;
|
||||
ranges.push_back(CreateCoreFileMemoryRange(region));
|
||||
|
||||
ranges.Append(region.GetRange().GetRangeBase(),
|
||||
region.GetRange().GetByteSize(),
|
||||
CreateCoreFileMemoryRange(region));
|
||||
}
|
||||
|
||||
static void SaveOffRegionsWithStackPointers(
|
||||
@@ -6595,7 +6598,7 @@ static void GetCoreFileSaveRangesFull(Process &process,
|
||||
std::set<addr_t> &stack_ends) {
|
||||
|
||||
// Don't add only dirty pages, add full regions.
|
||||
const bool try_dirty_pages = false;
|
||||
const bool try_dirty_pages = false;
|
||||
for (const auto ®ion : regions)
|
||||
if (stack_ends.count(region.GetRange().GetRangeEnd()) == 0)
|
||||
AddRegion(region, try_dirty_pages, ranges);
|
||||
@@ -6651,6 +6654,48 @@ static void GetCoreFileSaveRangesStackOnly(
|
||||
}
|
||||
}
|
||||
|
||||
static void GetUserSpecifiedCoreFileSaveRanges(
|
||||
Process &process, const MemoryRegionInfos ®ions,
|
||||
const SaveCoreOptions &options, Process::CoreFileMemoryRanges &ranges) {
|
||||
const auto &option_ranges = options.GetCoreFileMemoryRanges();
|
||||
if (option_ranges.IsEmpty())
|
||||
return;
|
||||
|
||||
for (const auto &range : regions) {
|
||||
auto entry = option_ranges.FindEntryThatContains(range.GetRange());
|
||||
if (entry)
|
||||
ranges.Append(range.GetRange().GetRangeBase(),
|
||||
range.GetRange().GetByteSize(),
|
||||
CreateCoreFileMemoryRange(range));
|
||||
}
|
||||
}
|
||||
|
||||
static Status
|
||||
FinalizeCoreFileSaveRanges(Process::CoreFileMemoryRanges &ranges) {
|
||||
Status error;
|
||||
ranges.Sort();
|
||||
for (size_t i = ranges.GetSize() - 1; i > 0; i--) {
|
||||
auto region = ranges.GetMutableEntryAtIndex(i);
|
||||
auto next_region = ranges.GetMutableEntryAtIndex(i - 1);
|
||||
if (next_region->GetRangeEnd() >= region->GetRangeBase() &&
|
||||
region->GetRangeBase() <= next_region->GetRangeEnd() &&
|
||||
region->data.lldb_permissions == next_region->data.lldb_permissions) {
|
||||
const addr_t base =
|
||||
std::min(region->GetRangeBase(), next_region->GetRangeBase());
|
||||
const addr_t byte_size =
|
||||
std::max(region->GetRangeEnd(), next_region->GetRangeEnd()) - base;
|
||||
next_region->SetRangeBase(base);
|
||||
next_region->SetByteSize(byte_size);
|
||||
if (!ranges.Erase(i, i + 1)) {
|
||||
error.SetErrorString("Core file memory ranges mutated outside of "
|
||||
"CalculateCoreFileSaveRanges");
|
||||
return error;
|
||||
}
|
||||
}
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
Status Process::CalculateCoreFileSaveRanges(const SaveCoreOptions &options,
|
||||
CoreFileMemoryRanges &ranges) {
|
||||
lldb_private::MemoryRegionInfos regions;
|
||||
@@ -6664,11 +6709,18 @@ Status Process::CalculateCoreFileSaveRanges(const SaveCoreOptions &options,
|
||||
return Status("callers must set the core_style to something other than "
|
||||
"eSaveCoreUnspecified");
|
||||
|
||||
GetUserSpecifiedCoreFileSaveRanges(*this, regions, options, ranges);
|
||||
|
||||
std::set<addr_t> stack_ends;
|
||||
SaveOffRegionsWithStackPointers(*this, options, regions, ranges, stack_ends);
|
||||
// For fully custom set ups, we don't want to even look at threads if there
|
||||
// are no threads specified.
|
||||
if (core_style != lldb::eSaveCoreCustomOnly || options.HasSpecifiedThreads())
|
||||
SaveOffRegionsWithStackPointers(*this, options, regions, ranges,
|
||||
stack_ends);
|
||||
|
||||
switch (core_style) {
|
||||
case eSaveCoreUnspecified:
|
||||
case eSaveCoreCustomOnly:
|
||||
break;
|
||||
|
||||
case eSaveCoreFull:
|
||||
@@ -6687,10 +6739,10 @@ Status Process::CalculateCoreFileSaveRanges(const SaveCoreOptions &options,
|
||||
if (err.Fail())
|
||||
return err;
|
||||
|
||||
if (ranges.empty())
|
||||
if (ranges.IsEmpty())
|
||||
return Status("no valid address ranges found for core style");
|
||||
|
||||
return Status(); // Success!
|
||||
return FinalizeCoreFileSaveRanges(ranges);
|
||||
}
|
||||
|
||||
std::vector<ThreadSP>
|
||||
|
||||
Reference in New Issue
Block a user