diff options
Diffstat (limited to 'source/Host/macosx/Symbols.cpp')
| -rw-r--r-- | source/Host/macosx/Symbols.cpp | 184 |
1 files changed, 103 insertions, 81 deletions
diff --git a/source/Host/macosx/Symbols.cpp b/source/Host/macosx/Symbols.cpp index 98c110b1bed67..b01c48e51d900 100644 --- a/source/Host/macosx/Symbols.cpp +++ b/source/Host/macosx/Symbols.cpp @@ -23,7 +23,7 @@ #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/Symbol/ObjectFile.h" @@ -55,6 +55,13 @@ CFDictionaryRef DBGCopyDSYMPropertyLists(CFURLRef dsym_url); int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec, ModuleSpec &return_module_spec) { + Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); + if (!ModuleList::GetGlobalModuleListProperties().GetEnableExternalLookup()) { + if (log) + log->Printf("Spotlight lookup for .dSYM bundles is disabled."); + return 0; + } + return_module_spec = module_spec; return_module_spec.GetFileSpec().Clear(); return_module_spec.GetSymbolFileSpec().Clear(); @@ -69,8 +76,8 @@ int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec, if (uuid && uuid->IsValid()) { // Try and locate the dSYM file using DebugSymbols first - const UInt8 *module_uuid = (const UInt8 *)uuid->GetBytes(); - if (module_uuid != NULL) { + llvm::ArrayRef<uint8_t> module_uuid = uuid->GetBytes(); + if (module_uuid.size() == 16) { CFCReleaser<CFUUIDRef> module_uuid_ref(::CFUUIDCreateWithBytes( NULL, module_uuid[0], module_uuid[1], module_uuid[2], module_uuid[3], module_uuid[4], module_uuid[5], module_uuid[6], module_uuid[7], @@ -80,7 +87,6 @@ int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec, if (module_uuid_ref.get()) { CFCReleaser<CFURLRef> exec_url; const FileSpec *exec_fspec = module_spec.GetFileSpecPtr(); - Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); if (exec_fspec) { char exec_cf_path[PATH_MAX]; if (exec_fspec->GetPath(exec_cf_path, sizeof(exec_cf_path))) @@ -241,52 +247,53 @@ FileSpec Symbols::FindSymbolFileInBundle(const FileSpec &dsym_bundle_fspec, const lldb_private::UUID *uuid, const ArchSpec *arch) { char path[PATH_MAX]; + if (dsym_bundle_fspec.GetPath(path, sizeof(path)) == 0) + return {}; - FileSpec dsym_fspec; + ::strncat(path, "/Contents/Resources/DWARF", sizeof(path) - strlen(path) - 1); - if (dsym_bundle_fspec.GetPath(path, sizeof(path))) { - ::strncat(path, "/Contents/Resources/DWARF", - sizeof(path) - strlen(path) - 1); + DIR *dirp = opendir(path); + if (!dirp) + return {}; - lldb_utility::CleanUp<DIR *, int> dirp(opendir(path), NULL, closedir); - if (dirp.is_valid()) { - dsym_fspec.GetDirectory().SetCString(path); - struct dirent *dp; - while ((dp = readdir(dirp.get())) != NULL) { - // Only search directories - if (dp->d_type == DT_DIR || dp->d_type == DT_UNKNOWN) { - if (dp->d_namlen == 1 && dp->d_name[0] == '.') - continue; + // Make sure we close the directory before exiting this scope. + CleanUp cleanup_dir(closedir, dirp); - if (dp->d_namlen == 2 && dp->d_name[0] == '.' && dp->d_name[1] == '.') - continue; - } + FileSpec dsym_fspec; + dsym_fspec.GetDirectory().SetCString(path); + struct dirent *dp; + while ((dp = readdir(dirp)) != NULL) { + // Only search directories + if (dp->d_type == DT_DIR || dp->d_type == DT_UNKNOWN) { + if (dp->d_namlen == 1 && dp->d_name[0] == '.') + continue; - if (dp->d_type == DT_REG || dp->d_type == DT_UNKNOWN) { - dsym_fspec.GetFilename().SetCString(dp->d_name); - ModuleSpecList module_specs; - if (ObjectFile::GetModuleSpecifications(dsym_fspec, 0, 0, - module_specs)) { - ModuleSpec spec; - for (size_t i = 0; i < module_specs.GetSize(); ++i) { - bool got_spec = module_specs.GetModuleSpecAtIndex(i, spec); - UNUSED_IF_ASSERT_DISABLED(got_spec); - assert(got_spec); - if ((uuid == NULL || - (spec.GetUUIDPtr() && spec.GetUUID() == *uuid)) && - (arch == NULL || - (spec.GetArchitecturePtr() && - spec.GetArchitecture().IsCompatibleMatch(*arch)))) { - return dsym_fspec; - } - } + if (dp->d_namlen == 2 && dp->d_name[0] == '.' && dp->d_name[1] == '.') + continue; + } + + if (dp->d_type == DT_REG || dp->d_type == DT_UNKNOWN) { + dsym_fspec.GetFilename().SetCString(dp->d_name); + ModuleSpecList module_specs; + if (ObjectFile::GetModuleSpecifications(dsym_fspec, 0, 0, module_specs)) { + ModuleSpec spec; + for (size_t i = 0; i < module_specs.GetSize(); ++i) { + bool got_spec = module_specs.GetModuleSpecAtIndex(i, spec); + UNUSED_IF_ASSERT_DISABLED(got_spec); + assert(got_spec); + if ((uuid == NULL || + (spec.GetUUIDPtr() && spec.GetUUID() == *uuid)) && + (arch == NULL || + (spec.GetArchitecturePtr() && + spec.GetArchitecture().IsCompatibleMatch(*arch)))) { + return dsym_fspec; } } } } } - dsym_fspec.Clear(); - return dsym_fspec; + + return {}; } static bool GetModuleSpecInfoFromUUIDDictionary(CFDictionaryRef uuid_dict, @@ -302,7 +309,8 @@ static bool GetModuleSpecInfoFromUUIDDictionary(CFDictionaryRef uuid_dict, (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(), true); + module_spec.GetFileSpec().SetFile(str.c_str(), true, + FileSpec::Style::native); if (log) { log->Printf( "From dsymForUUID plist: Symbol rich executable is at '%s'", @@ -315,7 +323,8 @@ static bool GetModuleSpecInfoFromUUIDDictionary(CFDictionaryRef uuid_dict, CFSTR("DBGDSYMPath")); if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) { if (CFCString::FileSystemRepresentation(cf_str, str)) { - module_spec.GetSymbolFileSpec().SetFile(str.c_str(), true); + module_spec.GetSymbolFileSpec().SetFile(str.c_str(), true, + FileSpec::Style::native); success = true; if (log) { log->Printf("From dsymForUUID plist: dSYM is at '%s'", str.c_str()); @@ -333,28 +342,13 @@ static bool GetModuleSpecInfoFromUUIDDictionary(CFDictionaryRef uuid_dict, std::string DBGBuildSourcePath; std::string DBGSourcePath; - cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict, - CFSTR("DBGBuildSourcePath")); - if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) { - CFCString::FileSystemRepresentation(cf_str, DBGBuildSourcePath); - } - - cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict, - CFSTR("DBGSourcePath")); - if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) { - CFCString::FileSystemRepresentation(cf_str, DBGSourcePath); - } - - if (!DBGBuildSourcePath.empty() && !DBGSourcePath.empty()) { - if (DBGSourcePath[0] == '~') { - FileSpec resolved_source_path(DBGSourcePath.c_str(), true); - DBGSourcePath = resolved_source_path.GetPath(); - } - module_spec.GetSourceMappingList().Append( - ConstString(DBGBuildSourcePath.c_str()), - ConstString(DBGSourcePath.c_str()), true); - } - + // If DBGVersion 1 or DBGVersion missing, ignore DBGSourcePathRemapping. + // If DBGVersion 2, strip last two components of path remappings from + // entries to fix an issue with a specific set of + // DBGSourcePathRemapping entries that lldb worked + // with. + // If DBGVersion 3, trust & use the source path remappings as-is. + // cf_dict = (CFDictionaryRef)CFDictionaryGetValue( (CFDictionaryRef)uuid_dict, CFSTR("DBGSourcePathRemapping")); if (cf_dict && CFGetTypeID(cf_dict) == CFDictionaryGetTypeID()) { @@ -401,10 +395,9 @@ static bool GetModuleSpecInfoFromUUIDDictionary(CFDictionaryRef uuid_dict, } if (!DBGBuildSourcePath.empty() && !DBGSourcePath.empty()) { // In the "old style" DBGSourcePathRemapping dictionary, the - // DBGSourcePath values - // (the "values" half of key-value path pairs) were wrong. Ignore - // them and use the - // universal DBGSourcePath string from earlier. + // DBGSourcePath values (the "values" half of key-value path pairs) + // were wrong. Ignore them and use the universal DBGSourcePath + // string from earlier. if (new_style_source_remapping_dictionary == true && !original_DBGSourcePath_value.empty()) { DBGSourcePath = original_DBGSourcePath_value; @@ -414,9 +407,9 @@ static bool GetModuleSpecInfoFromUUIDDictionary(CFDictionaryRef uuid_dict, DBGSourcePath = resolved_source_path.GetPath(); } // With version 2 of DBGSourcePathRemapping, we can chop off the - // last two filename parts from the source remapping and get a - // more general source remapping that still works. Add this as - // another option in addition to the full source path remap. + // last two filename parts from the source remapping and get a more + // general source remapping that still works. Add this as another + // option in addition to the full source path remap. module_spec.GetSourceMappingList().Append( ConstString(DBGBuildSourcePath.c_str()), ConstString(DBGSourcePath.c_str()), true); @@ -439,6 +432,32 @@ static bool GetModuleSpecInfoFromUUIDDictionary(CFDictionaryRef uuid_dict, free(values); } } + + + // If we have a DBGBuildSourcePath + DBGSourcePath pair, append them to the + // source remappings list. + + cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict, + CFSTR("DBGBuildSourcePath")); + if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) { + CFCString::FileSystemRepresentation(cf_str, DBGBuildSourcePath); + } + + cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict, + CFSTR("DBGSourcePath")); + if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) { + CFCString::FileSystemRepresentation(cf_str, DBGSourcePath); + } + + if (!DBGBuildSourcePath.empty() && !DBGSourcePath.empty()) { + if (DBGSourcePath[0] == '~') { + FileSpec resolved_source_path(DBGSourcePath.c_str(), true); + DBGSourcePath = resolved_source_path.GetPath(); + } + module_spec.GetSourceMappingList().Append( + ConstString(DBGBuildSourcePath.c_str()), + ConstString(DBGSourcePath.c_str()), true); + } } return success; } @@ -450,8 +469,7 @@ bool Symbols::DownloadObjectAndSymbolFile(ModuleSpec &module_spec, const FileSpec *file_spec_ptr = module_spec.GetFileSpecPtr(); // It's expensive to check for the DBGShellCommands defaults setting, only do - // it once per - // lldb run and cache the result. + // it once per lldb run and cache the result. static bool g_have_checked_for_dbgshell_command = false; static const char *g_dbgshell_command = NULL; if (g_have_checked_for_dbgshell_command == false) { @@ -473,8 +491,7 @@ 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. + // external program to find the symbols, don't run it for them. if (force_lookup == false && g_dbgshell_command == NULL) { return false; } @@ -489,12 +506,14 @@ bool Symbols::DownloadObjectAndSymbolFile(ModuleSpec &module_spec, getenv("LLDB_APPLE_DSYMFORUUID_EXECUTABLE"); FileSpec dsym_for_uuid_exe_spec; if (dsym_for_uuid_exe_path_cstr) { - dsym_for_uuid_exe_spec.SetFile(dsym_for_uuid_exe_path_cstr, true); + dsym_for_uuid_exe_spec.SetFile(dsym_for_uuid_exe_path_cstr, true, + FileSpec::Style::native); g_dsym_for_uuid_exe_exists = dsym_for_uuid_exe_spec.Exists(); } if (!g_dsym_for_uuid_exe_exists) { - dsym_for_uuid_exe_spec.SetFile("/usr/local/bin/dsymForUUID", false); + dsym_for_uuid_exe_spec.SetFile("/usr/local/bin/dsymForUUID", false, + FileSpec::Style::native); g_dsym_for_uuid_exe_exists = dsym_for_uuid_exe_spec.Exists(); if (!g_dsym_for_uuid_exe_exists) { long bufsize; @@ -508,14 +527,16 @@ bool Symbols::DownloadObjectAndSymbolFile(ModuleSpec &module_spec, tilde_rc && tilde_rc->pw_dir) { std::string dsymforuuid_path(tilde_rc->pw_dir); dsymforuuid_path += "/bin/dsymForUUID"; - dsym_for_uuid_exe_spec.SetFile(dsymforuuid_path.c_str(), false); + dsym_for_uuid_exe_spec.SetFile(dsymforuuid_path.c_str(), false, + FileSpec::Style::native); g_dsym_for_uuid_exe_exists = dsym_for_uuid_exe_spec.Exists(); } } } } if (!g_dsym_for_uuid_exe_exists && g_dbgshell_command != NULL) { - dsym_for_uuid_exe_spec.SetFile(g_dbgshell_command, true); + dsym_for_uuid_exe_spec.SetFile(g_dbgshell_command, true, + FileSpec::Style::native); g_dsym_for_uuid_exe_exists = dsym_for_uuid_exe_spec.Exists(); } @@ -561,8 +582,9 @@ bool Symbols::DownloadObjectAndSymbolFile(ModuleSpec &module_spec, &exit_status, // Exit status &signo, // Signal int * &command_output, // Command output - 30, // Large timeout to allow for long dsym download times - false); // Don't run in a shell (we don't need shell expansion) + std::chrono::seconds( + 30), // 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(), |
