diff options
Diffstat (limited to 'lldb/source/Symbol/LocateSymbolFileMacOSX.cpp')
| -rw-r--r-- | lldb/source/Symbol/LocateSymbolFileMacOSX.cpp | 217 |
1 files changed, 110 insertions, 107 deletions
diff --git a/lldb/source/Symbol/LocateSymbolFileMacOSX.cpp b/lldb/source/Symbol/LocateSymbolFileMacOSX.cpp index a13b4a7a54f2..4dc42cf01716 100644 --- a/lldb/source/Symbol/LocateSymbolFileMacOSX.cpp +++ b/lldb/source/Symbol/LocateSymbolFileMacOSX.cpp @@ -18,16 +18,18 @@ #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" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Endian.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" -#include "lldb/Utility/ReproducerProvider.h" #include "lldb/Utility/StreamString.h" #include "lldb/Utility/Timer.h" #include "lldb/Utility/UUID.h" @@ -39,12 +41,14 @@ using namespace lldb; using namespace lldb_private; -static CFURLRef (*g_dlsym_DBGCopyFullDSYMURLForUUID)(CFUUIDRef uuid, CFURLRef exec_url) = nullptr; -static CFDictionaryRef (*g_dlsym_DBGCopyDSYMPropertyLists)(CFURLRef dsym_url) = nullptr; +static CFURLRef (*g_dlsym_DBGCopyFullDSYMURLForUUID)( + CFUUIDRef uuid, CFURLRef exec_url) = nullptr; +static CFDictionaryRef (*g_dlsym_DBGCopyDSYMPropertyLists)(CFURLRef dsym_url) = + nullptr; int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec, ModuleSpec &return_module_spec) { - Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); + Log *log = GetLog(LLDBLog::Host); if (!ModuleList::GetGlobalModuleListProperties().GetEnableExternalLookup()) { LLDB_LOGF(log, "Spotlight lookup for .dSYM bundles is disabled."); return 0; @@ -57,22 +61,19 @@ int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec, const UUID *uuid = module_spec.GetUUIDPtr(); const ArchSpec *arch = module_spec.GetArchitecturePtr(); - if (repro::Loader *l = repro::Reproducer::Instance().GetLoader()) { - static repro::SymbolFileLoader symbol_file_loader(l); - std::pair<FileSpec, FileSpec> paths = symbol_file_loader.GetPaths(uuid); - return_module_spec.GetFileSpec() = paths.first; - return_module_spec.GetSymbolFileSpec() = paths.second; - return 1; - } - int items_found = 0; if (g_dlsym_DBGCopyFullDSYMURLForUUID == nullptr || g_dlsym_DBGCopyDSYMPropertyLists == nullptr) { - void *handle = dlopen ("/System/Library/PrivateFrameworks/DebugSymbols.framework/DebugSymbols", RTLD_LAZY | RTLD_LOCAL); + void *handle = dlopen( + "/System/Library/PrivateFrameworks/DebugSymbols.framework/DebugSymbols", + RTLD_LAZY | RTLD_LOCAL); if (handle) { - g_dlsym_DBGCopyFullDSYMURLForUUID = (CFURLRef (*)(CFUUIDRef, CFURLRef)) dlsym (handle, "DBGCopyFullDSYMURLForUUID"); - g_dlsym_DBGCopyDSYMPropertyLists = (CFDictionaryRef (*)(CFURLRef)) dlsym (handle, "DBGCopyDSYMPropertyLists"); + g_dlsym_DBGCopyFullDSYMURLForUUID = + (CFURLRef(*)(CFUUIDRef, CFURLRef))dlsym(handle, + "DBGCopyFullDSYMURLForUUID"); + g_dlsym_DBGCopyDSYMPropertyLists = (CFDictionaryRef(*)(CFURLRef))dlsym( + handle, "DBGCopyDSYMPropertyLists"); } } @@ -102,19 +103,17 @@ int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec, FALSE)); } - CFCReleaser<CFURLRef> dsym_url( - g_dlsym_DBGCopyFullDSYMURLForUUID(module_uuid_ref.get(), exec_url.get())); + CFCReleaser<CFURLRef> dsym_url(g_dlsym_DBGCopyFullDSYMURLForUUID( + module_uuid_ref.get(), exec_url.get())); char path[PATH_MAX]; if (dsym_url.get()) { if (::CFURLGetFileSystemRepresentation( dsym_url.get(), true, (UInt8 *)path, sizeof(path) - 1)) { - if (log) { - LLDB_LOGF(log, - "DebugSymbols framework returned dSYM path of %s for " - "UUID %s -- looking for the dSYM", - path, uuid->GetAsString().c_str()); - } + LLDB_LOGF(log, + "DebugSymbols framework returned dSYM path of %s for " + "UUID %s -- looking for the dSYM", + path, uuid->GetAsString().c_str()); FileSpec dsym_filespec(path); if (path[0] == '~') FileSystem::Instance().Resolve(dsym_filespec); @@ -148,16 +147,54 @@ int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec, uuid_dict = static_cast<CFDictionaryRef>( ::CFDictionaryGetValue(dict.get(), uuid_cfstr.get())); } - if (uuid_dict) { + + // Check to see if we have the file on the local filesystem. + if (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(); + 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(); + 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<CFStringRef>(::CFDictionaryGetValue( uuid_dict, CFSTR("DBGSymbolRichExecutable"))); if (exec_cf_path && ::CFStringGetFileSystemRepresentation( exec_cf_path, path, sizeof(path))) { - if (log) { - LLDB_LOGF(log, "plist bundle has exec path of %s for UUID %s", - path, uuid->GetAsString().c_str()); - } + LLDB_LOGF(log, "plist bundle has exec path of %s for UUID %s", + path, uuid->GetAsString().c_str()); ++items_found; FileSpec exec_filespec(path); if (path[0] == '~') @@ -169,20 +206,17 @@ int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec, } } + // 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"); if (dsym_extension_pos) { *dsym_extension_pos = '\0'; - if (log) { - LLDB_LOGF(log, - "Looking for executable binary next to dSYM " - "bundle with name with name %s", - path); - } + LLDB_LOGF(log, + "Looking for executable binary next to dSYM " + "bundle with name with name %s", + path); FileSpec file_spec(path); FileSystem::Instance().Resolve(file_spec); ModuleSpecList module_specs; @@ -209,12 +243,10 @@ int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec, { ++items_found; return_module_spec.GetFileSpec() = bundle_exe_file_spec; - if (log) { - LLDB_LOGF(log, - "Executable binary %s next to dSYM is " - "compatible; using", - path); - } + LLDB_LOGF(log, + "Executable binary %s next to dSYM is " + "compatible; using", + path); } } } @@ -239,12 +271,10 @@ int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec, { ++items_found; return_module_spec.GetFileSpec() = file_spec; - if (log) { - LLDB_LOGF(log, - "Executable binary %s next to dSYM is " - "compatible; using", - path); - } + LLDB_LOGF(log, + "Executable binary %s next to dSYM is " + "compatible; using", + path); } break; } @@ -256,12 +286,6 @@ int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec, } } - if (repro::Generator *g = repro::Reproducer::Instance().GetGenerator()) { - g->GetOrCreate<repro::SymbolFileProvider>().AddSymbolFile( - uuid, return_module_spec.GetFileSpec(), - return_module_spec.GetSymbolFileSpec()); - } - return items_found; } @@ -305,25 +329,32 @@ FileSpec Symbols::FindSymbolFileInBundle(const FileSpec &dsym_bundle_fspec, } static bool GetModuleSpecInfoFromUUIDDictionary(CFDictionaryRef uuid_dict, - ModuleSpec &module_spec) { - Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); + ModuleSpec &module_spec, + Status &error) { + Log *log = GetLog(LLDBLog::Host); bool success = false; if (uuid_dict != NULL && CFGetTypeID(uuid_dict) == CFDictionaryGetTypeID()) { std::string str; CFStringRef cf_str; CFDictionaryRef cf_dict; + cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict, + CFSTR("DBGError")); + if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) { + if (CFCString::FileSystemRepresentation(cf_str, str)) { + error.SetErrorString(str); + } + } + cf_str = (CFStringRef)CFDictionaryGetValue( (CFDictionaryRef)uuid_dict, CFSTR("DBGSymbolRichExecutable")); if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) { if (CFCString::FileSystemRepresentation(cf_str, str)) { module_spec.GetFileSpec().SetFile(str.c_str(), FileSpec::Style::native); FileSystem::Instance().Resolve(module_spec.GetFileSpec()); - if (log) { - LLDB_LOGF(log, - "From dsymForUUID plist: Symbol rich executable is at '%s'", - str.c_str()); - } + LLDB_LOGF(log, + "From dsymForUUID plist: Symbol rich executable is at '%s'", + str.c_str()); } } @@ -335,10 +366,7 @@ static bool GetModuleSpecInfoFromUUIDDictionary(CFDictionaryRef uuid_dict, FileSpec::Style::native); FileSystem::Instance().Resolve(module_spec.GetFileSpec()); success = true; - if (log) { - LLDB_LOGF(log, "From dsymForUUID plist: dSYM is at '%s'", - str.c_str()); - } + LLDB_LOGF(log, "From dsymForUUID plist: dSYM is at '%s'", str.c_str()); } } @@ -464,30 +492,11 @@ static bool GetModuleSpecInfoFromUUIDDictionary(CFDictionaryRef uuid_dict, } bool Symbols::DownloadObjectAndSymbolFile(ModuleSpec &module_spec, - bool force_lookup) { + Status &error, bool force_lookup) { bool success = false; const UUID *uuid_ptr = module_spec.GetUUIDPtr(); const FileSpec *file_spec_ptr = module_spec.GetFileSpecPtr(); - if (repro::Loader *l = repro::Reproducer::Instance().GetLoader()) { - static repro::SymbolFileLoader symbol_file_loader(l); - std::pair<FileSpec, FileSpec> paths = symbol_file_loader.GetPaths(uuid_ptr); - if (paths.first) - module_spec.GetFileSpec() = paths.first; - if (paths.second) - module_spec.GetSymbolFileSpec() = paths.second; - return true; - } - - // Lambda to capture the state of module_spec before returning from this - // function. - auto RecordResult = [&]() { - if (repro::Generator *g = repro::Reproducer::Instance().GetGenerator()) { - g->GetOrCreate<repro::SymbolFileProvider>().AddSymbolFile( - uuid_ptr, module_spec.GetFileSpec(), module_spec.GetSymbolFileSpec()); - } - }; - // It's expensive to check for the DBGShellCommands defaults setting, only do // it once per lldb run and cache the result. static bool g_have_checked_for_dbgshell_command = false; @@ -513,7 +522,6 @@ bool Symbols::DownloadObjectAndSymbolFile(ModuleSpec &module_spec, // When g_dbgshell_command is NULL, the user has not enabled the use of an // external program to find the symbols, don't run it for them. if (!force_lookup && g_dbgshell_command == NULL) { - RecordResult(); return false; } @@ -592,7 +600,7 @@ bool Symbols::DownloadObjectAndSymbolFile(ModuleSpec &module_spec, g_dsym_for_uuid_exe_path, file_path); if (!command.GetString().empty()) { - Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); + Log *log = GetLog(LLDBLog::Host); int exit_status = -1; int signo = -1; std::string command_output; @@ -604,15 +612,15 @@ bool Symbols::DownloadObjectAndSymbolFile(ModuleSpec &module_spec, LLDB_LOGF(log, "Calling %s with file %s to find dSYM", g_dsym_for_uuid_exe_path, file_path); } - Status error = Host::RunShellCommand( + error = Host::RunShellCommand( command.GetData(), FileSpec(), // current working directory &exit_status, // Exit status &signo, // Signal int * &command_output, // Command output std::chrono::seconds( - 640), // Large timeout to allow for long dsym download times - false); // Don't run in a shell (we don't need shell expansion) + 640), // Large timeout to allow for long dsym download times + false); // Don't run in a shell (we don't need shell expansion) if (error.Success() && exit_status == 0 && !command_output.empty()) { CFCData data(CFDataCreateWithBytesNoCopy( NULL, (const UInt8 *)command_output.data(), command_output.size(), @@ -628,8 +636,8 @@ bool Symbols::DownloadObjectAndSymbolFile(ModuleSpec &module_spec, CFCString uuid_cfstr(uuid_str.c_str()); CFDictionaryRef uuid_dict = (CFDictionaryRef)CFDictionaryGetValue( plist.get(), uuid_cfstr.get()); - success = - GetModuleSpecInfoFromUUIDDictionary(uuid_dict, module_spec); + success = GetModuleSpecInfoFromUUIDDictionary(uuid_dict, + module_spec, error); } else { const CFIndex num_values = ::CFDictionaryGetCount(plist.get()); if (num_values > 0) { @@ -638,19 +646,17 @@ bool Symbols::DownloadObjectAndSymbolFile(ModuleSpec &module_spec, ::CFDictionaryGetKeysAndValues(plist.get(), NULL, (const void **)&values[0]); if (num_values == 1) { - success = GetModuleSpecInfoFromUUIDDictionary(values[0], - module_spec); - RecordResult(); + success = GetModuleSpecInfoFromUUIDDictionary( + values[0], module_spec, error); return success; } else { for (CFIndex i = 0; i < num_values; ++i) { ModuleSpec curr_module_spec; - if (GetModuleSpecInfoFromUUIDDictionary(values[i], - curr_module_spec)) { + if (GetModuleSpecInfoFromUUIDDictionary( + values[i], curr_module_spec, error)) { if (module_spec.GetArchitecture().IsCompatibleMatch( curr_module_spec.GetArchitecture())) { module_spec = curr_module_spec; - RecordResult(); return true; } } @@ -660,18 +666,15 @@ bool Symbols::DownloadObjectAndSymbolFile(ModuleSpec &module_spec, } } } else { - if (log) { - if (!uuid_str.empty()) - LLDB_LOGF(log, "Called %s on %s, no matches", - g_dsym_for_uuid_exe_path, uuid_str.c_str()); - else if (file_path[0] != '\0') - LLDB_LOGF(log, "Called %s on %s, no matches", - g_dsym_for_uuid_exe_path, file_path); - } + if (!uuid_str.empty()) + LLDB_LOGF(log, "Called %s on %s, no matches", + g_dsym_for_uuid_exe_path, uuid_str.c_str()); + else if (file_path[0] != '\0') + LLDB_LOGF(log, "Called %s on %s, no matches", + g_dsym_for_uuid_exe_path, file_path); } } } } - RecordResult(); return success; } |
