diff --git a/src/coreclr/debug/createdump/crashinfo.h b/src/coreclr/debug/createdump/crashinfo.h index 50c0cca3eec723..7e46c65552ae6f 100644 --- a/src/coreclr/debug/createdump/crashinfo.h +++ b/src/coreclr/debug/createdump/crashinfo.h @@ -142,7 +142,6 @@ class CrashInfo : public ICLRDataEnumMemoryRegionsCallback, public ICLRDataLoggi #ifdef __APPLE__ bool EnumerateMemoryRegions(); void InitializeOtherMappings(); - bool TryFindDyLinker(mach_vm_address_t address, mach_vm_size_t size, bool* found); void VisitModule(MachOModule& module); void VisitSegment(MachOModule& module, const segment_command_64& segment); void VisitSection(MachOModule& module, const section_64& section); diff --git a/src/coreclr/debug/createdump/crashinfomac.cpp b/src/coreclr/debug/createdump/crashinfomac.cpp index f1f91ff4a55ca2..21ec72ff234170 100644 --- a/src/coreclr/debug/createdump/crashinfomac.cpp +++ b/src/coreclr/debug/createdump/crashinfomac.cpp @@ -148,18 +148,23 @@ CrashInfo::EnumerateMemoryRegions() } } - // Now find all the modules and add them to the module list - for (const MemoryRegion& region : m_allMemoryRegions) + // Get the dylinker info and enumerate all the modules + struct task_dyld_info dyld_info; + mach_msg_type_number_t count = TASK_DYLD_INFO_COUNT; + kern_return_t result = ::task_info(Task(), TASK_DYLD_INFO, (task_info_t)&dyld_info, &count); + if (result != KERN_SUCCESS) { - bool found; - if (!TryFindDyLinker(region.StartAddress(), region.Size(), &found)) { - return false; - } - if (found) { - break; - } + TRACE("EnumerateMemoryRegions: task_info(TASK_DYLD_INFO) FAILED %x %s\n", result, mach_error_string(result)); + return false; + } + + // Enumerate all the modules in dyld's image cache. VisitModule is called for every module found. + if (!EnumerateModules(dyld_info.all_image_info_addr)) + { + return false; } - TRACE("AllMemoryRegions %06llx native ModuleMappings %06llx\n", cbAllMemoryRegions / PAGE_SIZE, m_cbModuleMappings / PAGE_SIZE); + + TRACE("EnumerateMemoryRegions: cbAllMemoryRegions %06llx native cbModuleMappings %06llx\n", cbAllMemoryRegions / PAGE_SIZE, m_cbModuleMappings / PAGE_SIZE); return true; } @@ -216,46 +221,6 @@ CrashInfo::InitializeOtherMappings() TRACE("OtherMappings: %06llx\n", cbOtherMappings / PAGE_SIZE); } -bool -CrashInfo::TryFindDyLinker(mach_vm_address_t address, mach_vm_size_t size, bool* found) -{ - bool result = true; - *found = false; - - if (size > sizeof(mach_header_64)) - { - mach_header_64 header; - size_t read = 0; - if (ReadProcessMemory((void*)address, &header, sizeof(mach_header_64), &read)) - { - if (header.magic == MH_MAGIC_64) - { - TRACE("TryFindDyLinker: found module header at %016llx %08llx ncmds %d sizeofcmds %08x type %02x\n", - address, - size, - header.ncmds, - header.sizeofcmds, - header.filetype); - - if (header.filetype == MH_DYLINKER) - { - TRACE("TryFindDyLinker: found dylinker\n"); - *found = true; - - // Enumerate all the modules in dyld's image cache. VisitModule is called for every module found. - result = EnumerateModules(address, &header); - } - } - } - else - { - TRACE("TryFindDyLinker: ReadProcessMemory header at %p %d FAILED\n", address, read); - } - } - - return result; -} - void CrashInfo::VisitModule(MachOModule& module) { AddModuleInfo(false, module.BaseAddress(), nullptr, module.Name()); diff --git a/src/coreclr/debug/dbgutil/machoreader.cpp b/src/coreclr/debug/dbgutil/machoreader.cpp index 7fef34e1afb16d..07528e1d176cbf 100644 --- a/src/coreclr/debug/dbgutil/machoreader.cpp +++ b/src/coreclr/debug/dbgutil/machoreader.cpp @@ -75,7 +75,7 @@ TryGetSymbol(ICorDebugDataTarget* dataTarget, uint64_t baseAddress, const char* // MachO module //-------------------------------------------------------------------- -MachOModule::MachOModule(MachOReader& reader, mach_vm_address_t baseAddress, mach_header_64* header, std::string* name) : +MachOModule::MachOModule(MachOReader& reader, mach_vm_address_t baseAddress, std::string* name) : m_reader(reader), m_baseAddress(baseAddress), m_loadBias(0), @@ -84,9 +84,6 @@ MachOModule::MachOModule(MachOReader& reader, mach_vm_address_t baseAddress, mac m_nlists(nullptr), m_strtabAddress(0) { - if (header != nullptr) { - m_header = *header; - } if (name != nullptr) { m_name = *name; } @@ -363,43 +360,25 @@ MachOReader::MachOReader() } bool -MachOReader::EnumerateModules(mach_vm_address_t address, mach_header_64* header) +MachOReader::EnumerateModules(mach_vm_address_t dyldInfoAddress) { - _ASSERTE(header->magic == MH_MAGIC_64); - _ASSERTE(header->filetype == MH_DYLINKER); - - MachOModule dylinker(*this, address, header); - - // Search for symbol for the dyld image info cache - uint64_t dyldInfoAddress = 0; - if (!dylinker.TryLookupSymbol("dyld_all_image_infos", &dyldInfoAddress)) - { - Trace("ERROR: Can not find the _dyld_all_image_infos symbol\n"); - return false; - } - // Read the all image info from the dylinker image dyld_all_image_infos dyldInfo; - if (!ReadMemory((void*)dyldInfoAddress, &dyldInfo, sizeof(dyld_all_image_infos))) { Trace("ERROR: Failed to read dyld_all_image_infos at %p\n", (void*)dyldInfoAddress); return false; } - std::string dylinkerPath; - if (!ReadString(dyldInfo.dyldPath, dylinkerPath)) + Trace("MOD: infoArray %p infoArrayCount %d\n", dyldInfo.infoArray, dyldInfo.infoArrayCount); + + // Create the dyld module info + if (!TryRegisterModule(dyldInfo.dyldImageLoadAddress, dyldInfo.dyldPath, true)) { - Trace("ERROR: Failed to read name at %p\n", dyldInfo.dyldPath); + Trace("ERROR: Failed to read dyld header at %p\n", dyldInfo.dyldImageLoadAddress); return false; } - dylinker.SetName(dylinkerPath); - Trace("MOD: %016llx %08x %s\n", dylinker.BaseAddress(), dylinker.Header().flags, dylinker.Name().c_str()); - VisitModule(dylinker); - void* imageInfosAddress = (void*)dyldInfo.infoArray; size_t imageInfosSize = dyldInfo.infoArrayCount * sizeof(dyld_image_info); - Trace("MOD: infoArray %p infoArrayCount %d\n", dyldInfo.infoArray, dyldInfo.infoArrayCount); - ArrayHolder imageInfos = new (std::nothrow) dyld_image_info[dyldInfo.infoArrayCount]; if (imageInfos == nullptr) { @@ -413,22 +392,38 @@ MachOReader::EnumerateModules(mach_vm_address_t address, mach_header_64* header) } for (int i = 0; i < dyldInfo.infoArrayCount; i++) { - mach_vm_address_t imageAddress = (mach_vm_address_t)imageInfos[i].imageLoadAddress; - const char* imageFilePathAddress = imageInfos[i].imageFilePath; + // Ignore any errors and continue to next module + TryRegisterModule(imageInfos[i].imageLoadAddress, imageInfos[i].imageFilePath, false); + } + return true; +} - std::string imagePath; - if (!ReadString(imageFilePathAddress, imagePath)) - { - Trace("ERROR: Failed to read image name at %p\n", imageFilePathAddress); - continue; - } - MachOModule module(*this, imageAddress, nullptr, &imagePath); - if (!module.ReadHeader()) +bool +MachOReader::TryRegisterModule(const struct mach_header* imageAddress, const char* imageFilePathAddress, bool dylinker) +{ + std::string imagePath; + if (!ReadString(imageFilePathAddress, imagePath)) + { + return false; + } + MachOModule module(*this, (mach_vm_address_t)imageAddress, &imagePath); + if (!module.ReadHeader()) + { + return false; + } + Trace("MOD: %016llx %08x %s\n", imageAddress, module.Header().flags, imagePath.c_str()); + VisitModule(module); + if (dylinker) + { + // Make sure the memory for the symbol and string tables are in the core dump for our + // dump readers which still use this symbol to enumerate modules. + uint64_t dyldInfoAddress = 0; + if (!module.TryLookupSymbol("dyld_all_image_infos", &dyldInfoAddress)) { - continue; + Trace("ERROR: Can not find the _dyld_all_image_infos symbol\n"); + return false; } - Trace("MOD: %016llx %08x %s\n", imageAddress, module.Header().flags, imagePath.c_str()); - VisitModule(module); + Trace("MOD: dyldInfoAddress %016llx\n", dyldInfoAddress); } return true; } diff --git a/src/coreclr/debug/dbgutil/machoreader.h b/src/coreclr/debug/dbgutil/machoreader.h index a5f458b17ff2d5..19630e624f61c6 100644 --- a/src/coreclr/debug/dbgutil/machoreader.h +++ b/src/coreclr/debug/dbgutil/machoreader.h @@ -27,7 +27,7 @@ class MachOModule uint64_t m_strtabAddress; public: - MachOModule(MachOReader& reader, mach_vm_address_t baseAddress, mach_header_64* header = nullptr, std::string* name = nullptr); + MachOModule(MachOReader& reader, mach_vm_address_t baseAddress, std::string* name = nullptr); ~MachOModule(); inline mach_vm_address_t BaseAddress() const { return m_baseAddress; } @@ -41,8 +41,6 @@ class MachOModule bool EnumerateSegments(); private: - inline void SetName(std::string& name) { m_name = name; } - bool ReadLoadCommands(); bool ReadSymbolTable(); uint64_t GetAddressFromFileOffset(uint32_t offset); @@ -54,9 +52,10 @@ class MachOReader friend MachOModule; public: MachOReader(); - bool EnumerateModules(mach_vm_address_t address, mach_header_64* header); + bool EnumerateModules(mach_vm_address_t dyldInfoAddress); private: + bool TryRegisterModule(const struct mach_header* imageAddress, const char* imageFilePathAddress, bool dylinker); bool ReadString(const char* address, std::string& str); virtual void VisitModule(MachOModule& module) { }; virtual void VisitSegment(MachOModule& module, const segment_command_64& segment) { };