Don't register mem segments that aren't present in a corefile

A Mach-O corefile has an array of memory segments, representing
the memory of the process at the point of the capture.  Each segment
has a virtual address + size, and a file offset + size.  The file
size may be less than the virtual address size, indicating that
the memory was unavailable. When ProcessMachCore::DoLoadCore scans
this array of memory segments, it builds up a table to translate
virtual addresses to file offsets, for memory read requests.
This lookup table combines contiguous memory segments into a single
entry, to reduce the number of entries (some corefile writers will
emit a separate segement for each virtual meory page).

This contiguous check wasn't taking into account a segment that
isn't present in the corefile, e.g. filesize==0, and every contiguous
memory segment after that point would result in lldb reading the
wrong offset of the file because it didn't account for this.

I'd like to have an error message when someone tries to read memory from
one of these segments, instead of returning all zeroes, so this patch
intentionally leaves these out of the vmaddr -> fileoff table (and
avoids combining them with segments that actually do exist in the
corefile).

I'm a little unsure of writing a test for this one; I'd have to do
a yaml2obj of a corefile with the problem, or add an internal mode
to the Mach-O process save-core where it could write a filesize==0
segment while it was writing one.

rdar://83382487
This commit is contained in:
Jason Molenda 2021-10-06 20:04:49 -07:00
parent 809652c93b
commit 62d9163830
1 changed files with 1 additions and 9 deletions

View File

@ -287,7 +287,7 @@ Status ProcessMachCore::DoLoadCore() {
addr_t vm_addr = 0;
for (uint32_t i = 0; i < num_sections; ++i) {
Section *section = section_list->GetSectionAtIndex(i).get();
if (section) {
if (section && section->GetFileSize() > 0) {
lldb::addr_t section_vm_addr = section->GetFileAddress();
FileRange file_range(section->GetFileOffset(), section->GetFileSize());
VMRangeToFileOffset::Entry range_entry(
@ -297,20 +297,12 @@ Status ProcessMachCore::DoLoadCore() {
ranges_are_sorted = false;
vm_addr = section->GetFileAddress();
VMRangeToFileOffset::Entry *last_entry = m_core_aranges.Back();
// printf ("LC_SEGMENT[%u] arange=[0x%16.16" PRIx64 " -
// 0x%16.16" PRIx64 "), frange=[0x%8.8x - 0x%8.8x)\n",
// i,
// range_entry.GetRangeBase(),
// range_entry.GetRangeEnd(),
// range_entry.data.GetRangeBase(),
// range_entry.data.GetRangeEnd());
if (last_entry &&
last_entry->GetRangeEnd() == range_entry.GetRangeBase() &&
last_entry->data.GetRangeEnd() == range_entry.data.GetRangeBase()) {
last_entry->SetRangeEnd(range_entry.GetRangeEnd());
last_entry->data.SetRangeEnd(range_entry.data.GetRangeEnd());
// puts("combine");
} else {
m_core_aranges.Append(range_entry);
}