diff --git a/lldb/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp b/lldb/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp --- a/lldb/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp +++ b/lldb/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp @@ -149,6 +149,12 @@ ObjectFile::FindPlugin(module_sp, &dsym_fspec, 0, FileSystem::Instance().GetByteSize(dsym_fspec), dsym_file_data_sp, dsym_file_data_offset); + // Important to save the dSYM FileSpec so we don't call + // Symbols::LocateExecutableSymbolFile a second time while trying to + // add the symbol ObjectFile to this Module. + if (dsym_objfile_sp.get() && !module_sp->GetSymbolFileFileSpec()) { + module_sp->SetSymbolFileFileSpec(dsym_fspec); + } if (UUIDsMatch(module_sp.get(), dsym_objfile_sp.get(), feedback_strm)) { // We need a XML parser if we hope to parse a plist... if (XMLDocument::XMLEnabled()) { diff --git a/lldb/source/Symbol/LocateSymbolFileMacOSX.cpp b/lldb/source/Symbol/LocateSymbolFileMacOSX.cpp --- a/lldb/source/Symbol/LocateSymbolFileMacOSX.cpp +++ b/lldb/source/Symbol/LocateSymbolFileMacOSX.cpp @@ -18,9 +18,11 @@ #include "Host/macosx/cfcpp/CFCData.h" #include "Host/macosx/cfcpp/CFCReleaser.h" #include "Host/macosx/cfcpp/CFCString.h" +#include "lldb/Core/Module.h" #include "lldb/Core/ModuleList.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Host/Host.h" +#include "lldb/Host/HostInfo.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/DataBuffer.h" @@ -147,7 +149,52 @@ uuid_dict = static_cast( ::CFDictionaryGetValue(dict.get(), uuid_cfstr.get())); } - if (uuid_dict) { + + // Check to see if we have the file on the local filesystem. + if (!module_spec.GetFileSpec().GetPath().empty() && + FileSystem::Instance().Exists(module_spec.GetFileSpec())) { + ModuleSpec exe_spec; + exe_spec.GetFileSpec() = module_spec.GetFileSpec(); + exe_spec.GetUUID() = module_spec.GetUUID(); + ModuleSP module_sp; + module_sp.reset(new Module(exe_spec)); + if (module_sp && module_sp->GetObjectFile() && + module_sp->MatchesModuleSpec(exe_spec)) { + success = true; + return_module_spec.GetFileSpec() = module_spec.GetFileSpec(); + if (log) { + LLDB_LOGF(log, "using original binary filepath %s for UUID %s", + module_spec.GetFileSpec().GetPath().c_str(), + uuid->GetAsString().c_str()); + } + ++items_found; + } + } + + // Check if the requested image is in our shared cache. + if (!success) { + SharedCacheImageInfo image_info = HostInfo::GetSharedCacheImageInfo( + module_spec.GetFileSpec().GetPath()); + + // If we found it and it has the correct UUID, let's proceed with + // creating a module from the memory contents. + if (image_info.uuid && (!module_spec.GetUUID() || + module_spec.GetUUID() == image_info.uuid)) { + success = true; + return_module_spec.GetFileSpec() = module_spec.GetFileSpec(); + if (log) { + LLDB_LOGF(log, + "using binary from shared cache for filepath %s for " + "UUID %s", + module_spec.GetFileSpec().GetPath().c_str(), + uuid->GetAsString().c_str()); + } + ++items_found; + } + } + + // Use the DBGSymbolRichExecutable filepath if present + if (!success && uuid_dict) { CFStringRef exec_cf_path = static_cast(::CFDictionaryGetValue( uuid_dict, CFSTR("DBGSymbolRichExecutable"))); @@ -168,9 +215,8 @@ } } + // Look next to the dSYM for the binary file. if (!success) { - // No dictionary, check near the dSYM bundle for an executable that - // matches... if (::CFURLGetFileSystemRepresentation( dsym_url.get(), true, (UInt8 *)path, sizeof(path) - 1)) { char *dsym_extension_pos = ::strstr(path, ".dSYM");