summaryrefslogtreecommitdiff
path: root/source/Host/macosx/Symbols.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/Host/macosx/Symbols.cpp')
-rw-r--r--source/Host/macosx/Symbols.cpp184
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(),