[Lldb-commits] [lldb] r248985 - Fixing a subtle issue on Mac OS X systems with dSYMs (possibly
Jason Molenda via lldb-commits
lldb-commits at lists.llvm.org
Wed Sep 30 22:37:22 PDT 2015
Author: jmolenda
Date: Thu Oct 1 00:37:22 2015
New Revision: 248985
URL: http://llvm.org/viewvc/llvm-project?rev=248985&view=rev
Log:
Fixing a subtle issue on Mac OS X systems with dSYMs (possibly
introduced by r235737 but I didn't look into it too closely).
A dSYM can have a per-UUID plist in it which tells lldb where
to find an executable binary for the dSYM (DBGSymbolRichExecutable)
- other information can be included in this plist, like how to
remap the source file paths from their build pathnames to their
long-term storage pathnames.
This per-UUID plist is a unusual; it is used probably exclusively
inside apple with our build system. It is not created by default
in normal dSYMs.
The problem was like this:
1. lldb wants to find an executable, given only a UUID
(this happens when lldb is doing cross-host debugging
and doesn't have a copy of the target system's binaries)
2. It eventually calls LocateMacOSXFilesUsingDebugSymbols
which does a spotlight search for the dSYM on the local
system, and failing that, tries the DBGShellCommands
command to find the dSYM.
3. It gets a dSYM. It reads the per-UUID plist in the dSYM.
The dSYM has a DBGSymbolRichExecutable kv pair pointing to
the binary on a network filesystem.
4. Using the binary on the network filesystem, lldb now goes
to find the dSYM.
5. It starts by looking for a dSYM next to the binary it found.
6. lldb is now reading the dSYM over a network filesystem,
ignoring the one it found on its local filesystem earlier.
Everything still *works* but it's much slower.
This would be a tricky one to write up in a testsuite case;
you really need the binary to not exist on the local system.
And LocateMacOSXFilesUsingDebugSymbols will only compile on
Mac OS X - even if I found a way to write up a test case, it
would not run anywhere but on a mac.
One change Greg wanted while I was touching this code was to
have LocateMacOSXFilesUsingDebugSymbols (which could be asked
to find a binary OR find a dSYM) to instead return a ModuleSpec
with the sum total of everything it could find. This
change of passing around a ModuleSpec instead of a FileSpec
was percolated up into ModuleList::GetSharedModule.
The changes to LocateMacOSXFilesUsingDebugSymbols look larger
than they really are - there's a lot of simple whitespace changes
in there.
I ran the testsuites on mac, no new regressions introduced
<rdar://problem/21993813>
Modified:
lldb/trunk/include/lldb/Host/Symbols.h
lldb/trunk/source/Core/ModuleList.cpp
lldb/trunk/source/Host/common/Symbols.cpp
lldb/trunk/source/Host/macosx/Symbols.cpp
lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
Modified: lldb/trunk/include/lldb/Host/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Host/Symbols.h?rev=248985&r1=248984&r2=248985&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Host/Symbols.h (original)
+++ lldb/trunk/include/lldb/Host/Symbols.h Thu Oct 1 00:37:22 2015
@@ -29,7 +29,7 @@ public:
// Locating the file should happen only on the local computer or using
// the current computers global settings.
//----------------------------------------------------------------------
- static FileSpec
+ static ModuleSpec
LocateExecutableObjectFile (const ModuleSpec &module_spec);
//----------------------------------------------------------------------
Modified: lldb/trunk/source/Core/ModuleList.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ModuleList.cpp?rev=248985&r1=248984&r2=248985&view=diff
==============================================================================
--- lldb/trunk/source/Core/ModuleList.cpp (original)
+++ lldb/trunk/source/Core/ModuleList.cpp Thu Oct 1 00:37:22 2015
@@ -1045,19 +1045,19 @@ ModuleList::GetSharedModule
// Fixup the incoming path in case the path points to a valid file, yet
// the arch or UUID (if one was passed in) don't match.
- FileSpec file_spec = Symbols::LocateExecutableObjectFile (module_spec);
+ ModuleSpec located_binary_modulespec = Symbols::LocateExecutableObjectFile (module_spec);
// Don't look for the file if it appears to be the same one we already
// checked for above...
- if (file_spec != module_file_spec)
+ if (located_binary_modulespec.GetFileSpec() != module_file_spec)
{
- if (!file_spec.Exists())
+ if (!located_binary_modulespec.GetFileSpec().Exists())
{
- file_spec.GetPath(path, sizeof(path));
+ located_binary_modulespec.GetFileSpec().GetPath(path, sizeof(path));
if (path[0] == '\0')
module_file_spec.GetPath(path, sizeof(path));
// How can this check ever be true? This branch it is false, and we haven't modified file_spec.
- if (file_spec.Exists())
+ if (located_binary_modulespec.GetFileSpec().Exists())
{
std::string uuid_str;
if (uuid_ptr && uuid_ptr->IsValid())
@@ -1084,9 +1084,8 @@ ModuleList::GetSharedModule
// Make sure no one else can try and get or create a module while this
// function is actively working on it by doing an extra lock on the
// global mutex list.
- ModuleSpec platform_module_spec(module_spec);
- platform_module_spec.GetFileSpec() = file_spec;
- platform_module_spec.GetPlatformFileSpec() = file_spec;
+ ModuleSpec platform_module_spec(located_binary_modulespec);
+ platform_module_spec.GetPlatformFileSpec() = located_binary_modulespec.GetFileSpec();
ModuleList matching_module_list;
if (shared_module_list.FindModules (platform_module_spec, matching_module_list) > 0)
{
@@ -1096,7 +1095,7 @@ ModuleList::GetSharedModule
// then we should make sure the modification time hasn't changed!
if (platform_module_spec.GetUUIDPtr() == NULL)
{
- TimeValue file_spec_mod_time(file_spec.GetModificationTime());
+ TimeValue file_spec_mod_time(located_binary_modulespec.GetFileSpec().GetModificationTime());
if (file_spec_mod_time.IsValid())
{
if (file_spec_mod_time != module_sp->GetModificationTime())
@@ -1125,9 +1124,9 @@ ModuleList::GetSharedModule
}
else
{
- file_spec.GetPath(path, sizeof(path));
+ located_binary_modulespec.GetFileSpec().GetPath(path, sizeof(path));
- if (file_spec)
+ if (located_binary_modulespec.GetFileSpec())
{
if (arch.IsValid())
error.SetErrorStringWithFormat("unable to open %s architecture in '%s'", arch.GetArchitectureName(), path);
Modified: lldb/trunk/source/Host/common/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/common/Symbols.cpp?rev=248985&r1=248984&r2=248985&view=diff
==============================================================================
--- lldb/trunk/source/Host/common/Symbols.cpp (original)
+++ lldb/trunk/source/Host/common/Symbols.cpp Thu Oct 1 00:37:22 2015
@@ -38,8 +38,7 @@ int
LocateMacOSXFilesUsingDebugSymbols
(
const ModuleSpec &module_spec,
- FileSpec *out_exec_fspec, // If non-NULL, try and find the executable
- FileSpec *out_dsym_fspec // If non-NULL try and find the debug symbol file
+ ModuleSpec &return_module_spec
);
#else
@@ -48,8 +47,7 @@ int
LocateMacOSXFilesUsingDebugSymbols
(
const ModuleSpec &module_spec,
- FileSpec *out_exec_fspec, // If non-NULL, try and find the executable
- FileSpec *out_dsym_fspec // If non-NULL try and find the debug symbol file
+ ModuleSpec &return_module_spec
) {
// Cannot find MacOSX files using debug symbols on non MacOSX.
return 0;
@@ -178,19 +176,25 @@ LocateExecutableSymbolFileDsym (const Mo
(const void*)uuid);
FileSpec symbol_fspec;
+ ModuleSpec dsym_module_spec;
// First try and find the dSYM in the same directory as the executable or in
// an appropriate parent directory
if (LocateDSYMInVincinityOfExecutable (module_spec, symbol_fspec) == false)
{
// We failed to easily find the dSYM above, so use DebugSymbols
- LocateMacOSXFilesUsingDebugSymbols (module_spec, NULL, &symbol_fspec);
+ LocateMacOSXFilesUsingDebugSymbols (module_spec, dsym_module_spec);
}
- return symbol_fspec;
+ else
+ {
+ dsym_module_spec.GetSymbolFileSpec() = symbol_fspec;
+ }
+ return dsym_module_spec.GetSymbolFileSpec();
}
-FileSpec
+ModuleSpec
Symbols::LocateExecutableObjectFile (const ModuleSpec &module_spec)
{
+ ModuleSpec result = module_spec;
const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();
const ArchSpec *arch = module_spec.GetArchitecturePtr();
const UUID *uuid = module_spec.GetUUIDPtr();
@@ -200,20 +204,19 @@ Symbols::LocateExecutableObjectFile (con
arch ? arch->GetArchitectureName() : "<NULL>",
(const void*)uuid);
- FileSpec objfile_fspec;
ModuleSpecList module_specs;
ModuleSpec matched_module_spec;
if (exec_fspec &&
ObjectFile::GetModuleSpecifications(*exec_fspec, 0, 0, module_specs) &&
module_specs.FindMatchingModuleSpec(module_spec, matched_module_spec))
{
- objfile_fspec = exec_fspec;
+ result.GetFileSpec() = exec_fspec;
}
else
{
- LocateMacOSXFilesUsingDebugSymbols (module_spec, &objfile_fspec, NULL);
+ LocateMacOSXFilesUsingDebugSymbols (module_spec, result);
}
- return objfile_fspec;
+ return result;
}
FileSpec
Modified: lldb/trunk/source/Host/macosx/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/macosx/Symbols.cpp?rev=248985&r1=248984&r2=248985&view=diff
==============================================================================
--- lldb/trunk/source/Host/macosx/Symbols.cpp (original)
+++ lldb/trunk/source/Host/macosx/Symbols.cpp Thu Oct 1 00:37:22 2015
@@ -55,17 +55,14 @@ int
LocateMacOSXFilesUsingDebugSymbols
(
const ModuleSpec &module_spec,
- FileSpec *out_exec_fspec, // If non-NULL, try and find the executable
- FileSpec *out_dsym_fspec // If non-NULL try and find the debug symbol file
+ ModuleSpec &return_module_spec
)
{
- int items_found = 0;
-
- if (out_exec_fspec)
- out_exec_fspec->Clear();
+ return_module_spec = module_spec;
+ return_module_spec.GetFileSpec().Clear();
+ return_module_spec.GetSymbolFileSpec().Clear();
- if (out_dsym_fspec)
- out_dsym_fspec->Clear();
+ int items_found = 0;
#if !defined (__arm__) && !defined (__arm64__) && !defined (__aarch64__) // No DebugSymbols on the iOS devices
@@ -110,151 +107,132 @@ LocateMacOSXFilesUsingDebugSymbols
strlen(exec_cf_path),
FALSE));
}
- if (log)
- {
- std::string searching_for;
- if (out_exec_fspec && out_dsym_fspec)
- {
- searching_for = "executable binary and dSYM";
- }
- else if (out_exec_fspec)
- {
- searching_for = "executable binary";
- }
- else
- {
- searching_for = "dSYM bundle";
- }
- log->Printf ("Calling DebugSymbols framework to locate dSYM bundle for UUID %s, searching for %s", uuid->GetAsString().c_str(), searching_for.c_str());
- }
CFCReleaser<CFURLRef> dsym_url (::DBGCopyFullDSYMURLForUUID(module_uuid_ref.get(), exec_url.get()));
char path[PATH_MAX];
if (dsym_url.get())
{
- if (out_dsym_fspec)
+ if (::CFURLGetFileSystemRepresentation (dsym_url.get(), true, (UInt8*)path, sizeof(path)-1))
+ {
+ if (log)
+ {
+ log->Printf ("DebugSymbols framework returned dSYM path of %s for UUID %s -- looking for the dSYM", path, uuid->GetAsString().c_str());
+ }
+ FileSpec dsym_filespec(path, path[0] == '~');
+
+ if (dsym_filespec.GetFileType () == FileSpec::eFileTypeDirectory)
+ {
+ dsym_filespec = Symbols::FindSymbolFileInBundle (dsym_filespec, uuid, arch);
+ ++items_found;
+ }
+ else
+ {
+ ++items_found;
+ }
+ return_module_spec.GetSymbolFileSpec() = dsym_filespec;
+ }
+
+ bool success = false;
+ if (log)
{
if (::CFURLGetFileSystemRepresentation (dsym_url.get(), true, (UInt8*)path, sizeof(path)-1))
{
- if (log)
- {
- log->Printf ("DebugSymbols framework returned dSYM path of %s for UUID %s -- looking for the dSYM", path, uuid->GetAsString().c_str());
- }
- out_dsym_fspec->SetFile(path, path[0] == '~');
+ log->Printf ("DebugSymbols framework returned dSYM path of %s for UUID %s -- looking for an exec file", path, uuid->GetAsString().c_str());
+ }
- if (out_dsym_fspec->GetFileType () == FileSpec::eFileTypeDirectory)
+ }
+
+ CFCReleaser<CFDictionaryRef> dict(::DBGCopyDSYMPropertyLists (dsym_url.get()));
+ CFDictionaryRef uuid_dict = NULL;
+ if (dict.get())
+ {
+ CFCString uuid_cfstr (uuid->GetAsString().c_str());
+ uuid_dict = static_cast<CFDictionaryRef>(::CFDictionaryGetValue (dict.get(), uuid_cfstr.get()));
+ }
+ if (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)
{
- *out_dsym_fspec = Symbols::FindSymbolFileInBundle (*out_dsym_fspec, uuid, arch);
- if (*out_dsym_fspec)
- ++items_found;
+ log->Printf ("plist bundle has exec path of %s for UUID %s", path, uuid->GetAsString().c_str());
}
- else
+ ++items_found;
+ FileSpec exec_filespec (path, path[0] == '~');
+ if (exec_filespec.Exists())
{
- ++items_found;
+ success = true;
+ return_module_spec.GetFileSpec() = exec_filespec;
}
}
}
- if (out_exec_fspec)
+ if (!success)
{
- bool success = false;
- if (log)
- {
- if (::CFURLGetFileSystemRepresentation (dsym_url.get(), true, (UInt8*)path, sizeof(path)-1))
- {
- log->Printf ("DebugSymbols framework returned dSYM path of %s for UUID %s -- looking for an exec file", path, uuid->GetAsString().c_str());
- }
-
- }
- CFCReleaser<CFDictionaryRef> dict(::DBGCopyDSYMPropertyLists (dsym_url.get()));
- CFDictionaryRef uuid_dict = NULL;
- if (dict.get())
- {
- CFCString uuid_cfstr (uuid->GetAsString().c_str());
- uuid_dict = static_cast<CFDictionaryRef>(::CFDictionaryGetValue (dict.get(), uuid_cfstr.get()));
- }
- if (uuid_dict)
+ // No dictionary, check near the dSYM bundle for an executable that matches...
+ if (::CFURLGetFileSystemRepresentation (dsym_url.get(), true, (UInt8*)path, sizeof(path)-1))
{
- CFStringRef exec_cf_path = static_cast<CFStringRef>(::CFDictionaryGetValue (uuid_dict, CFSTR("DBGSymbolRichExecutable")));
- if (exec_cf_path && ::CFStringGetFileSystemRepresentation (exec_cf_path, path, sizeof(path)))
+ char *dsym_extension_pos = ::strstr (path, ".dSYM");
+ if (dsym_extension_pos)
{
+ *dsym_extension_pos = '\0';
if (log)
{
- log->Printf ("plist bundle has exec path of %s for UUID %s", path, uuid->GetAsString().c_str());
+ log->Printf ("Looking for executable binary next to dSYM bundle with name with name %s", path);
}
- ++items_found;
- out_exec_fspec->SetFile(path, path[0] == '~');
- if (out_exec_fspec->Exists())
- success = true;
- }
- }
-
- 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)
+ FileSpec file_spec (path, true);
+ ModuleSpecList module_specs;
+ ModuleSpec matched_module_spec;
+ switch (file_spec.GetFileType())
{
- *dsym_extension_pos = '\0';
- if (log)
- {
- log->Printf ("Looking for executable binary next to dSYM bundle with name with name %s", path);
- }
- FileSpec file_spec (path, true);
- ModuleSpecList module_specs;
- ModuleSpec matched_module_spec;
- switch (file_spec.GetFileType())
- {
- case FileSpec::eFileTypeDirectory: // Bundle directory?
+ case FileSpec::eFileTypeDirectory: // Bundle directory?
+ {
+ CFCBundle bundle (path);
+ CFCReleaser<CFURLRef> bundle_exe_url (bundle.CopyExecutableURL ());
+ if (bundle_exe_url.get())
{
- CFCBundle bundle (path);
- CFCReleaser<CFURLRef> bundle_exe_url (bundle.CopyExecutableURL ());
- if (bundle_exe_url.get())
+ if (::CFURLGetFileSystemRepresentation (bundle_exe_url.get(), true, (UInt8*)path, sizeof(path)-1))
{
- if (::CFURLGetFileSystemRepresentation (bundle_exe_url.get(), true, (UInt8*)path, sizeof(path)-1))
- {
- FileSpec bundle_exe_file_spec (path, true);
- if (ObjectFile::GetModuleSpecifications(bundle_exe_file_spec, 0, 0, module_specs) &&
- module_specs.FindMatchingModuleSpec(module_spec, matched_module_spec))
+ FileSpec bundle_exe_file_spec (path, true);
+ if (ObjectFile::GetModuleSpecifications(bundle_exe_file_spec, 0, 0, module_specs) &&
+ module_specs.FindMatchingModuleSpec(module_spec, matched_module_spec))
+ {
+ ++items_found;
+ return_module_spec.GetFileSpec() = bundle_exe_file_spec;
+ if (log)
{
- ++items_found;
- *out_exec_fspec = bundle_exe_file_spec;
- if (log)
- {
- log->Printf ("Executable binary %s next to dSYM is compatible; using", path);
- }
+ log->Printf ("Executable binary %s next to dSYM is compatible; using", path);
}
}
}
}
- break;
-
- case FileSpec::eFileTypePipe: // Forget pipes
- case FileSpec::eFileTypeSocket: // We can't process socket files
- case FileSpec::eFileTypeInvalid: // File doesn't exist...
- break;
-
- case FileSpec::eFileTypeUnknown:
- case FileSpec::eFileTypeRegular:
- case FileSpec::eFileTypeSymbolicLink:
- case FileSpec::eFileTypeOther:
- if (ObjectFile::GetModuleSpecifications(file_spec, 0, 0, module_specs) &&
- module_specs.FindMatchingModuleSpec(module_spec, matched_module_spec))
+ }
+ break;
+ case FileSpec::eFileTypePipe: // Forget pipes
+ case FileSpec::eFileTypeSocket: // We can't process socket files
+ case FileSpec::eFileTypeInvalid: // File doesn't exist...
+ break;
+
+ case FileSpec::eFileTypeUnknown:
+ case FileSpec::eFileTypeRegular:
+ case FileSpec::eFileTypeSymbolicLink:
+ case FileSpec::eFileTypeOther:
+ if (ObjectFile::GetModuleSpecifications(file_spec, 0, 0, module_specs) &&
+ module_specs.FindMatchingModuleSpec(module_spec, matched_module_spec))
+
+ {
+ ++items_found;
+ return_module_spec.GetFileSpec() = file_spec;
+ if (log)
{
- ++items_found;
- *out_exec_fspec = file_spec;
- if (log)
- {
- log->Printf ("Executable binary %s next to dSYM is compatible; using", path);
- }
+ log->Printf ("Executable binary %s next to dSYM is compatible; using", path);
}
- break;
- }
+ }
+ break;
}
}
}
Modified: lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp?rev=248985&r1=248984&r2=248985&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp (original)
+++ lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp Thu Oct 1 00:37:22 2015
@@ -321,7 +321,13 @@ ProcessKDP::DoConnectRemote (Stream *str
// Lookup UUID locally, before attempting dsymForUUID like action
module_spec.GetSymbolFileSpec() = Symbols::LocateExecutableSymbolFile(module_spec);
if (module_spec.GetSymbolFileSpec())
- module_spec.GetFileSpec() = Symbols::LocateExecutableObjectFile (module_spec);
+ {
+ ModuleSpec executable_module_spec = Symbols::LocateExecutableObjectFile (module_spec);
+ if (executable_module_spec.GetFileSpec().Exists())
+ {
+ module_spec.GetFileSpec() = executable_module_spec.GetFileSpec();
+ }
+ }
if (!module_spec.GetSymbolFileSpec() || !module_spec.GetSymbolFileSpec())
Symbols::DownloadObjectAndSymbolFile (module_spec, true);
More information about the lldb-commits
mailing list