diff options
| author | Jason Molenda <jmolenda@apple.com> | 2013-09-14 05:20:02 +0000 |
|---|---|---|
| committer | Jason Molenda <jmolenda@apple.com> | 2013-09-14 05:20:02 +0000 |
| commit | 7e50d9135fffc8edcdaeb43932d447b3d1cfa0ce (patch) | |
| tree | 84eb34da62971bc20e678b5a11b268fec130c957 | |
| parent | 2e5f5b2e78729ce724073314423cf726f92c10da (diff) | |
| download | bcm5719-llvm-7e50d9135fffc8edcdaeb43932d447b3d1cfa0ce.tar.gz bcm5719-llvm-7e50d9135fffc8edcdaeb43932d447b3d1cfa0ce.zip | |
Change ProcessMachCore to search for both a user-process dyld binary
and a mach kernel in all the pages of the core file. If it finds
a user-process dyld binary, assume this is a user process that had
a copy of the mach kernel in memory when it crashed (e.g. lldb doing
kernel debugging) even though we found the kernel binary first.
Also, change the error messages about sections extending past the end
of the file to be warnings and make the messages sound less severe.
Most user process core files have one section that isn't included in
the file and there's no reason to worry people about that.
<rdar://problem/14473235>
llvm-svn: 190741
3 files changed, 42 insertions, 33 deletions
diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp index 2ef69469286..87020cedb21 100644 --- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp +++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp @@ -1040,7 +1040,7 @@ ObjectFileMachO::CreateSections (SectionList &unified_section_list) // is null out the SectionList vector and if a process has been set up, dump a message // to stdout. The most common case here is core file debugging with a truncated file. const char *lc_segment_name = load_cmd.cmd == LC_SEGMENT_64 ? "LC_SEGMENT_64" : "LC_SEGMENT"; - module_sp->ReportError("is a corrupt mach-o file: load command %u %s has a fileoff (0x%" PRIx64 ") that extends beyond the end of the file (0x%" PRIx64 ")", + module_sp->ReportWarning("load command %u %s has a fileoff (0x%" PRIx64 ") that extends beyond the end of the file (0x%" PRIx64 "), ignoring this section", i, lc_segment_name, load_cmd.fileoff, @@ -1058,7 +1058,7 @@ ObjectFileMachO::CreateSections (SectionList &unified_section_list) // is null out the SectionList vector and if a process has been set up, dump a message // to stdout. The most common case here is core file debugging with a truncated file. const char *lc_segment_name = load_cmd.cmd == LC_SEGMENT_64 ? "LC_SEGMENT_64" : "LC_SEGMENT"; - GetModule()->ReportError("is a corrupt mach-o file: load command %u %s has a fileoff + filesize (0x%" PRIx64 ") that extends beyond the end of the file (0x%" PRIx64 "), the segment will be truncated", + GetModule()->ReportWarning("load command %u %s has a fileoff + filesize (0x%" PRIx64 ") that extends beyond the end of the file (0x%" PRIx64 "), the segment will be truncated to match", i, lc_segment_name, load_cmd.fileoff + load_cmd.filesize, diff --git a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp index ba8f74d8be9..faf6a856d92 100644 --- a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp +++ b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp @@ -107,6 +107,7 @@ ProcessMachCore::ProcessMachCore(Target& target, Listener &listener, const FileS m_core_module_sp (), m_core_file (core_file), m_dyld_addr (LLDB_INVALID_ADDRESS), + m_mach_kernel_addr (LLDB_INVALID_ADDRESS), m_dyld_plugin_name () { } @@ -173,7 +174,10 @@ ProcessMachCore::GetDynamicLoaderAddress (lldb::addr_t addr) case llvm::MachO::MH_DYLINKER: //printf("0x%16.16" PRIx64 ": file_type = MH_DYLINKER\n", vaddr); // Address of dyld "struct mach_header" in the core file - m_dyld_plugin_name = DynamicLoaderMacOSXDYLD::GetPluginNameStatic(); + if (m_dyld_addr != LLDB_INVALID_ADDRESS) + { + assert (!"already had user process dyld"); + } m_dyld_addr = addr; return true; @@ -183,9 +187,8 @@ ProcessMachCore::GetDynamicLoaderAddress (lldb::addr_t addr) // is NOT set. If it isn't, then we have a mach_kernel. if ((header.flags & llvm::MachO::MH_DYLDLINK) == 0) { - m_dyld_plugin_name = DynamicLoaderDarwinKernel::GetPluginNameStatic(); // Address of the mach kernel "struct mach_header" in the core file. - m_dyld_addr = addr; + m_mach_kernel_addr = addr; return true; } break; @@ -278,13 +281,6 @@ ProcessMachCore::DoLoadCore () { m_core_aranges.Append(range_entry); } - - // After we have added this section to our m_core_aranges map, - // we can check the start of the section to see if it might - // contain dyld for user space apps, or the mach kernel file - // for kernel cores. - if (m_dyld_addr == LLDB_INVALID_ADDRESS) - GetDynamicLoaderAddress (section_vm_addr); } } if (!ranges_are_sorted) @@ -292,40 +288,50 @@ ProcessMachCore::DoLoadCore () m_core_aranges.Sort(); } - // Even if the architecture is set in the target, we need to override - // it to match the core file which is always single arch. - ArchSpec arch (m_core_module_sp->GetArchitecture()); - if (arch.GetCore() == ArchSpec::eCore_x86_32_i486) - { - arch.SetTriple ("i386", m_target.GetPlatform().get()); - } - if (arch.IsValid()) - m_target.SetArchitecture(arch); - - if (m_dyld_addr == LLDB_INVALID_ADDRESS) + if (m_dyld_addr == LLDB_INVALID_ADDRESS || m_mach_kernel_addr == LLDB_INVALID_ADDRESS) { // We need to locate the main executable in the memory ranges - // we have in the core file. We already checked the first address - // in each memory zone above, so we just need to check each page - // except the first page in each range and stop once we have found - // our main executable + // we have in the core file. We need to search for both a user-process dyld binary + // and a kernel binary in memory; we must look at all the pages in the binary so + // we don't miss one or the other. If we find a user-process dyld binary, stop + // searching -- that's the one we'll prefer over the mach kernel. const size_t num_core_aranges = m_core_aranges.GetSize(); for (size_t i=0; i<num_core_aranges && m_dyld_addr == LLDB_INVALID_ADDRESS; ++i) { const VMRangeToFileOffset::Entry *entry = m_core_aranges.GetEntryAtIndex(i); lldb::addr_t section_vm_addr_start = entry->GetRangeBase(); lldb::addr_t section_vm_addr_end = entry->GetRangeEnd(); - for (lldb::addr_t section_vm_addr = section_vm_addr_start + 0x1000; + for (lldb::addr_t section_vm_addr = section_vm_addr_start; section_vm_addr < section_vm_addr_end; section_vm_addr += 0x1000) { - if (GetDynamicLoaderAddress (section_vm_addr)) - { - break; - } + GetDynamicLoaderAddress (section_vm_addr); } } } + + // If we find both a user process dyld and a mach kernel, prefer the + // user process dyld. We may be looking at an lldb debug session were they were debugging + // a mach kernel when lldb coredumped. + if (m_dyld_addr != LLDB_INVALID_ADDRESS) + { + m_dyld_plugin_name = DynamicLoaderMacOSXDYLD::GetPluginNameStatic(); + } + else if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS) + { + m_dyld_plugin_name = DynamicLoaderDarwinKernel::GetPluginNameStatic(); + } + + // Even if the architecture is set in the target, we need to override + // it to match the core file which is always single arch. + ArchSpec arch (m_core_module_sp->GetArchitecture()); + if (arch.GetCore() == ArchSpec::eCore_x86_32_i486) + { + arch.SetTriple ("i386", m_target.GetPlatform().get()); + } + if (arch.IsValid()) + m_target.SetArchitecture(arch); + return error; } @@ -455,7 +461,9 @@ ProcessMachCore::Initialize() addr_t ProcessMachCore::GetImageInfoAddress() { - return m_dyld_addr; + if (m_dyld_addr != LLDB_INVALID_ADDRESS) + return m_dyld_addr; + return m_mach_kernel_addr; } diff --git a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h index 2aa208185ef..1f4af97a75b 100644 --- a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h +++ b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h @@ -137,6 +137,7 @@ private: lldb::ModuleSP m_core_module_sp; lldb_private::FileSpec m_core_file; lldb::addr_t m_dyld_addr; + lldb::addr_t m_mach_kernel_addr; lldb_private::ConstString m_dyld_plugin_name; DISALLOW_COPY_AND_ASSIGN (ProcessMachCore); |

