Hi Robert, this change introduced a bit of a regression in Mac native lldb.  
It's not easy to spot on a Mac but in other environments it's a problem.


LocateDSYMInVincinityOfExecutable is a function in Host/common/Symbols.cpp.  It 
takes a ModuleSpec (the details about the executable binary -- the filename, 
architecture, UUID, etc) and it looks for a dSYM bundle near that executable.  
It adds things on to the file path and if it finds a likely candidate, 
retrieves the ModuleSpecs for that dSYM (in the case of a multiple-architecture 
universal dSYM binary) and compares them to the original executable binary's 
ModuleSpec.

The problem comes from using ModuleSpec::FindMatchingModuleSpec().  This calls 
ModuleSpec::Matches() and this method, among the things it checks, requires 
that the *filenames* match between the executable and the dSYM.

As a reminder, an executable name might be /tmp/a.out.  Its dSYM would be 
/tmp/a.out.dSYM/Contents/Resources/a.out.

After r235737, LocateDSYMInVincinityOfExecutable() never matches anything.

The only reason it escaped all of our notices is that lldb then asks the 
DebugSymbols framework to find the dSYM -- and it has usually been able to do 
that.

But if the DebugSymbols framework is not available or not working, lldb is 
completely broken for automatically loading a dSYM next to a binary.

The old version of LocateDSYMInVincinityOfExecutable() was written in very Mac 
specific terms, e.g.

                if (dsym_fspec.Exists() && FileAtPathContainsArchAndUUID 
(dsym_fspec, module_spec.GetArchitecturePtr(), module_spec.GetUUIDPtr()))
                {
                    return true;
                }

(and FileAtPathContainsArchAndUUID was very mac-only) so you had a bit of 
rewriting to do there in making it non-mac-specific.  But I think using 
ModuleSpec::FindMatchingModuleSpec() in place of this is not correct.

As a quick workaround I made this patch,

Index: source/Host/common/Symbols.cpp
===================================================================
--- source/Host/common/Symbols.cpp      (revision 237751)
+++ source/Host/common/Symbols.cpp      (working copy)
@@ -76,9 +76,20 @@
 
                 ModuleSpecList module_specs;
                 ModuleSpec matched_module_spec;
+
+                ModuleSpec uuid_match_only_module_spec;
+                const ModuleSpec *module_spec_for_search = &module_spec;
+
+                // If the ModuleSpec includes a UUID, only compare the UUID 
when looking at the
+                // dSYM binary.
+                if (module_spec.GetUUID().IsValid())
+                {
+                    uuid_match_only_module_spec.GetUUID() = 
module_spec.GetUUID();
+                    module_spec_for_search = &uuid_match_only_module_spec;
+                }
                 if (dsym_fspec.Exists() &&
                     ObjectFile::GetModuleSpecifications(dsym_fspec, 0, 0, 
module_specs) &&
-                    module_specs.FindMatchingModuleSpec(module_spec, 
matched_module_spec))
+                    
module_specs.FindMatchingModuleSpec(*module_spec_for_search, 
matched_module_spec))
                 {
                     return true;
                 }
@@ -95,10 +106,20 @@
                             *next_slash = '\0';
                             ::strncat(path, ".dSYM/Contents/Resources/DWARF/", 
sizeof(path) - strlen(path) - 1);
                             ::strncat(path, 
exec_fspec->GetFilename().AsCString(), sizeof(path) - strlen(path) - 1);
+                            module_spec_for_search = &module_spec;
+
+                            // If the ModuleSpec includes a UUID, only compare 
the UUID when looking at the
+                            // dSYM binary.
+                            if (module_spec.GetUUID().IsValid())
+                            {
+                                uuid_match_only_module_spec.GetUUID() = 
module_spec.GetUUID();
+                                module_spec_for_search = 
&uuid_match_only_module_spec;
+                            }
+
                             dsym_fspec.SetFile(path, false);
                             if (dsym_fspec.Exists() &&
                                 
ObjectFile::GetModuleSpecifications(dsym_fspec, 0, 0, module_specs) &&
-                                
module_specs.FindMatchingModuleSpec(module_spec, matched_module_spec))
+                                
module_specs.FindMatchingModuleSpec(*module_spec_for_search, 
matched_module_spec))
                             {
                                 return true;
                             }

which looks to see if the executable module has a UUID in its ModuleSpec -- and 
if so, it creates a new ModuleSpec with only that one field.  That is always 
enough to disambiguate among a multi-architecture dSYM, and to ensure that we 
have the correct dSYM.  (and on Mac, it's nigh impossible to get a binary that 
doesn't have a UUID in it--you never see them in practice.)

Do you want to take another look at this function?


Thanks!


Jason



> On Apr 24, 2015, at 11:09 AM, Robert Flack <fla...@gmail.com> wrote:
> 
> Author: flackr
> Date: Fri Apr 24 13:09:54 2015
> New Revision: 235737
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=235737&view=rev
> Log:
> Look for both .debug and dsym debugging symbol information for stripped 
> executable.
> 
> Currently Symbols::LocateExecutableSymbolFile on MacOSX only looks for 
> external
> dsym debugging information, however if running on a stripped dwarf executable 
> it
> should also check for a .debug file as well.
> 
> Test Plan:
> ./dotest.py $DOTEST_OPTS -t -p TestSharedLibStrippedSymbols.py
> This test now passes when running a remote Mac -> Linux test, and still passes
> running locally on Mac or locally on Linux.
> 
> Differential Revision: http://reviews.llvm.org/D9174
> 
> Modified:
>    lldb/trunk/source/Host/common/Symbols.cpp
>    lldb/trunk/source/Host/macosx/Symbols.cpp
> 
> Modified: lldb/trunk/source/Host/common/Symbols.cpp
> URL: 
> http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/common/Symbols.cpp?rev=235737&r1=235736&r2=235737&view=diff
> ==============================================================================
> --- lldb/trunk/source/Host/common/Symbols.cpp (original)
> +++ lldb/trunk/source/Host/common/Symbols.cpp Fri Apr 24 13:09:54 2015
> @@ -18,139 +18,253 @@
> #include "lldb/Core/UUID.h"
> #include "lldb/Symbol/ObjectFile.h"
> #include "lldb/Target/Target.h"
> +#include "lldb/Utility/SafeMachO.h"
> 
> #include "llvm/Support/FileSystem.h"
> 
> +// From MacOSX system header "mach/machine.h"
> +typedef int cpu_type_t;
> +typedef int cpu_subtype_t;
> +
> using namespace lldb;
> using namespace lldb_private;
> +using namespace llvm::MachO;
> +
> +#if defined(__APPLE__)
> +
> +// Forward declaration of method defined in source/Host/macosx/Symbols.cpp
> +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
> +);
> +
> +#else
> +
> +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
> +) {
> +    // Cannot find MacOSX files using debug symbols on non MacOSX.
> +    return 0;
> +}
> +
> +#endif
> +
> +static bool
> +LocateDSYMInVincinityOfExecutable (const ModuleSpec &module_spec, FileSpec 
> &dsym_fspec)
> +{
> +    const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();
> +    if (exec_fspec)
> +    {
> +        char path[PATH_MAX];
> +        if (exec_fspec->GetPath(path, sizeof(path)))
> +        {
> +            // Make sure the module isn't already just a dSYM file...
> +            if (strcasestr(path, ".dSYM/Contents/Resources/DWARF") == NULL)
> +            {
> +                size_t obj_file_path_length = strlen(path);
> +                ::strncat(path, ".dSYM/Contents/Resources/DWARF/", 
> sizeof(path) - strlen(path) - 1);
> +                ::strncat(path, exec_fspec->GetFilename().AsCString(), 
> sizeof(path) - strlen(path) - 1);
> +
> +                dsym_fspec.SetFile(path, false);
> +
> +                ModuleSpecList module_specs;
> +                ModuleSpec matched_module_spec;
> +                if (dsym_fspec.Exists() &&
> +                    ObjectFile::GetModuleSpecifications(dsym_fspec, 0, 0, 
> module_specs) &&
> +                    module_specs.FindMatchingModuleSpec(module_spec, 
> matched_module_spec))
> +                {
> +                    return true;
> +                }
> +                else
> +                {
> +                    path[obj_file_path_length] = '\0';
> +
> +                    char *last_dot = strrchr(path, '.');
> +                    while (last_dot != NULL && last_dot[0])
> +                    {
> +                        char *next_slash = strchr(last_dot, '/');
> +                        if (next_slash != NULL)
> +                        {
> +                            *next_slash = '\0';
> +                            ::strncat(path, 
> ".dSYM/Contents/Resources/DWARF/", sizeof(path) - strlen(path) - 1);
> +                            ::strncat(path, 
> exec_fspec->GetFilename().AsCString(), sizeof(path) - strlen(path) - 1);
> +                            dsym_fspec.SetFile(path, false);
> +                            if (dsym_fspec.Exists() &&
> +                                
> ObjectFile::GetModuleSpecifications(dsym_fspec, 0, 0, module_specs) &&
> +                                
> module_specs.FindMatchingModuleSpec(module_spec, matched_module_spec))
> +                            {
> +                                return true;
> +                            }
> +                            else
> +                            {
> +                                *last_dot = '\0';
> +                                char *prev_slash = strrchr(path, '/');
> +                                if (prev_slash != NULL)
> +                                    *prev_slash = '\0';
> +                                else
> +                                    break;
> +                            }
> +                        }
> +                        else
> +                        {
> +                            break;
> +                        }
> +                    }
> +                }
> +            }
> +        }
> +    }
> +    dsym_fspec.Clear();
> +    return false;
> +}
> 
> -#if defined (__linux__) || defined (__FreeBSD__)
> +FileSpec
> +LocateExecutableSymbolFileDsym (const ModuleSpec &module_spec)
> +{
> +    const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();
> +    const ArchSpec *arch = module_spec.GetArchitecturePtr();
> +    const UUID *uuid = module_spec.GetUUIDPtr();
> +
> +    Timer scoped_timer (__PRETTY_FUNCTION__,
> +                        "LocateExecutableSymbolFileDsym (file = %s, arch = 
> %s, uuid = %p)",
> +                        exec_fspec ? exec_fspec->GetFilename().AsCString 
> ("<NULL>") : "<NULL>",
> +                        arch ? arch->GetArchitectureName() : "<NULL>",
> +                        uuid);
> +
> +    FileSpec symbol_fspec;
> +    // 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);
> +    }
> +    return symbol_fspec;
> +}
> 
> FileSpec
> Symbols::LocateExecutableObjectFile (const ModuleSpec &module_spec)
> {
> -    // FIXME
> -    return FileSpec();
> +    const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();
> +    const ArchSpec *arch = module_spec.GetArchitecturePtr();
> +    const UUID *uuid = module_spec.GetUUIDPtr();
> +    Timer scoped_timer (__PRETTY_FUNCTION__,
> +                        "LocateExecutableObjectFile (file = %s, arch = %s, 
> uuid = %p)",
> +                        exec_fspec ? exec_fspec->GetFilename().AsCString 
> ("<NULL>") : "<NULL>",
> +                        arch ? arch->GetArchitectureName() : "<NULL>",
> +                        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;
> +    }
> +    else
> +    {
> +        LocateMacOSXFilesUsingDebugSymbols (module_spec, &objfile_fspec, 
> NULL);
> +    }
> +    return objfile_fspec;
> }
> 
> FileSpec
> Symbols::LocateExecutableSymbolFile (const ModuleSpec &module_spec)
> {
>     const char *symbol_filename = 
> module_spec.GetSymbolFileSpec().GetFilename().AsCString();
> -    if (!symbol_filename || !symbol_filename[0])
> -        return FileSpec();
> -
> -    FileSpecList debug_file_search_paths 
> (Target::GetDefaultDebugFileSearchPaths());
> -
> -    // Add module directory.
> -    const ConstString &file_dir = module_spec.GetFileSpec().GetDirectory();
> -    debug_file_search_paths.AppendIfUnique 
> (FileSpec(file_dir.AsCString("."), true));
> +    if (symbol_filename && symbol_filename[0])
> +    {
> +        FileSpecList debug_file_search_paths 
> (Target::GetDefaultDebugFileSearchPaths());
> 
> -    // Add current working directory.
> -    debug_file_search_paths.AppendIfUnique (FileSpec(".", true));
> +        // Add module directory.
> +        const ConstString &file_dir = 
> module_spec.GetFileSpec().GetDirectory();
> +        debug_file_search_paths.AppendIfUnique 
> (FileSpec(file_dir.AsCString("."), true));
> 
> -    // Add /usr/lib/debug directory.
> -    debug_file_search_paths.AppendIfUnique (FileSpec("/usr/lib/debug", 
> true));
> +        // Add current working directory.
> +        debug_file_search_paths.AppendIfUnique (FileSpec(".", true));
> 
> -    std::string uuid_str;
> -    const UUID &module_uuid = module_spec.GetUUID();
> -    if (module_uuid.IsValid())
> -    {
> -        // Some debug files are stored in the .build-id directory like this:
> -        //   
> /usr/lib/debug/.build-id/ff/e7fe727889ad82bb153de2ad065b2189693315.debug
> -        uuid_str = module_uuid.GetAsString("");
> -        uuid_str.insert (2, 1, '/');
> -        uuid_str = uuid_str + ".debug";
> -    }
> +        // Add /usr/lib/debug directory.
> +        debug_file_search_paths.AppendIfUnique (FileSpec("/usr/lib/debug", 
> true));
> 
> -    // Get directory of our module. Needed to check debug files like this:
> -    //   /usr/lib/debug/usr/lib/library.so.debug
> -    std::string module_directory = 
> module_spec.GetFileSpec().GetDirectory().AsCString();
> +        std::string uuid_str;
> +        const UUID &module_uuid = module_spec.GetUUID();
> +        if (module_uuid.IsValid())
> +        {
> +            // Some debug files are stored in the .build-id directory like 
> this:
> +            //   
> /usr/lib/debug/.build-id/ff/e7fe727889ad82bb153de2ad065b2189693315.debug
> +            uuid_str = module_uuid.GetAsString("");
> +            uuid_str.insert (2, 1, '/');
> +            uuid_str = uuid_str + ".debug";
> +        }
> 
> -    size_t num_directories = debug_file_search_paths.GetSize();
> -    for (size_t idx = 0; idx < num_directories; ++idx)
> -    {
> -        FileSpec dirspec = debug_file_search_paths.GetFileSpecAtIndex (idx);
> -        dirspec.ResolvePath();
> -        if (!dirspec.Exists() || !dirspec.IsDirectory())
> -            continue;
> -
> -        std::vector<std::string> files;
> -        std::string dirname = dirspec.GetPath();
> -
> -        files.push_back (dirname + "/" + symbol_filename);
> -        files.push_back (dirname + "/.debug/" + symbol_filename);
> -        files.push_back (dirname + "/.build-id/" + uuid_str);
> -        files.push_back (dirname + module_directory + "/" + symbol_filename);
> +        // Get directory of our module. Needed to check debug files like 
> this:
> +        //   /usr/lib/debug/usr/lib/library.so.debug
> +        std::string module_directory = 
> module_spec.GetFileSpec().GetDirectory().AsCString();
> 
> -        const uint32_t num_files = files.size();
> -        for (size_t idx_file = 0; idx_file < num_files; ++idx_file)
> +        size_t num_directories = debug_file_search_paths.GetSize();
> +        for (size_t idx = 0; idx < num_directories; ++idx)
>         {
> -            const std::string &filename = files[idx_file];
> -            FileSpec file_spec (filename.c_str(), true);
> -
> -            if (llvm::sys::fs::equivalent (file_spec.GetPath(), 
> module_spec.GetFileSpec().GetPath()))
> +            FileSpec dirspec = debug_file_search_paths.GetFileSpecAtIndex 
> (idx);
> +            dirspec.ResolvePath();
> +            if (!dirspec.Exists() || !dirspec.IsDirectory())
>                 continue;
> 
> -            if (file_spec.Exists())
> +            std::vector<std::string> files;
> +            std::string dirname = dirspec.GetPath();
> +
> +            files.push_back (dirname + "/" + symbol_filename);
> +            files.push_back (dirname + "/.debug/" + symbol_filename);
> +            files.push_back (dirname + "/.build-id/" + uuid_str);
> +            files.push_back (dirname + module_directory + "/" + 
> symbol_filename);
> +
> +            const uint32_t num_files = files.size();
> +            for (size_t idx_file = 0; idx_file < num_files; ++idx_file)
>             {
> -                lldb_private::ModuleSpecList specs;
> -                const size_t num_specs = ObjectFile::GetModuleSpecifications 
> (file_spec, 0, 0, specs);
> -                assert (num_specs <= 1 && "Symbol Vendor supports only a 
> single architecture");
> -                if (num_specs == 1)
> +                const std::string &filename = files[idx_file];
> +                FileSpec file_spec (filename.c_str(), true);
> +
> +                if (llvm::sys::fs::equivalent (file_spec.GetPath(), 
> module_spec.GetFileSpec().GetPath()))
> +                    continue;
> +
> +                if (file_spec.Exists())
>                 {
> -                    ModuleSpec mspec;
> -                    if (specs.GetModuleSpecAtIndex (0, mspec))
> +                    lldb_private::ModuleSpecList specs;
> +                    const size_t num_specs = 
> ObjectFile::GetModuleSpecifications (file_spec, 0, 0, specs);
> +                    assert (num_specs <= 1 && "Symbol Vendor supports only a 
> single architecture");
> +                    if (num_specs == 1)
>                     {
> -                        if (mspec.GetUUID() == module_uuid)
> -                            return file_spec;
> +                        ModuleSpec mspec;
> +                        if (specs.GetModuleSpecAtIndex (0, mspec))
> +                        {
> +                            if (mspec.GetUUID() == module_uuid)
> +                                return file_spec;
> +                        }
>                     }
>                 }
>             }
>         }
>     }
> 
> -    return FileSpec();
> +    return LocateExecutableSymbolFileDsym(module_spec);
> }
> 
> -FileSpec
> -Symbols::FindSymbolFileInBundle (const FileSpec& symfile_bundle,
> -                                 const lldb_private::UUID *uuid,
> -                                 const ArchSpec *arch)
> -{
> -    // FIXME
> -    return FileSpec();
> -}
> -
> -bool
> -Symbols::DownloadObjectAndSymbolFile (ModuleSpec &module_spec, bool 
> force_lookup)
> -{
> -    // Fill in the module_spec.GetFileSpec() for the object file and/or the
> -    // module_spec.GetSymbolFileSpec() for the debug symbols file.
> -    return false;
> -}
> -
> -#elif !defined (__APPLE__)
> -
> -FileSpec
> -Symbols::LocateExecutableObjectFile (const ModuleSpec &module_spec)
> -{
> -    // FIXME
> -    return FileSpec();
> -}
> -
> -FileSpec
> -Symbols::LocateExecutableSymbolFile (const ModuleSpec &module_spec)
> -{
> -    // FIXME
> -    return FileSpec();
> -}
> +#if !defined (__APPLE__)
> 
> FileSpec
> Symbols::FindSymbolFileInBundle (const FileSpec& symfile_bundle,
>                                  const lldb_private::UUID *uuid,
>                                  const ArchSpec *arch)
> {
> +    // FIXME
>     return FileSpec();
> }
> 
> 
> Modified: lldb/trunk/source/Host/macosx/Symbols.cpp
> URL: 
> http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/macosx/Symbols.cpp?rev=235737&r1=235736&r2=235737&view=diff
> ==============================================================================
> --- lldb/trunk/source/Host/macosx/Symbols.cpp (original)
> +++ lldb/trunk/source/Host/macosx/Symbols.cpp Fri Apr 24 13:09:54 2015
> @@ -29,6 +29,7 @@
> #include "lldb/Core/UUID.h"
> #include "lldb/Host/Endian.h"
> #include "lldb/Host/Host.h"
> +#include "lldb/Symbol/ObjectFile.h"
> #include "lldb/Utility/CleanUp.h"
> #include "Host/macosx/cfcpp/CFCBundle.h"
> #include "Host/macosx/cfcpp/CFCData.h"
> @@ -36,7 +37,6 @@
> #include "Host/macosx/cfcpp/CFCString.h"
> #include "mach/machine.h"
> 
> -
> using namespace lldb;
> using namespace lldb_private;
> using namespace llvm::MachO;
> @@ -50,234 +50,7 @@ CFDictionaryRef DBGCopyDSYMPropertyLists
> }
> #endif
> 
> -static bool
> -SkinnyMachOFileContainsArchAndUUID
> -(
> -    const FileSpec &file_spec,
> -    const ArchSpec *arch,
> -    const lldb_private::UUID *uuid,   // the UUID we are looking for
> -    off_t file_offset,
> -    DataExtractor& data,
> -    lldb::offset_t data_offset,
> -    const uint32_t magic
> -)
> -{
> -    assert(magic == MH_MAGIC || magic == MH_CIGAM || magic == MH_MAGIC_64 || 
> magic == MH_CIGAM_64);
> -    if (magic == MH_MAGIC || magic == MH_MAGIC_64)
> -        data.SetByteOrder (lldb::endian::InlHostByteOrder());
> -    else if (lldb::endian::InlHostByteOrder() == eByteOrderBig)
> -        data.SetByteOrder (eByteOrderLittle);
> -    else
> -        data.SetByteOrder (eByteOrderBig);
> -
> -    uint32_t i;
> -    const uint32_t cputype      = data.GetU32(&data_offset);    // cpu 
> specifier
> -    const uint32_t cpusubtype   = data.GetU32(&data_offset);    // machine 
> specifier
> -    data_offset+=4; // Skip mach file type
> -    const uint32_t ncmds        = data.GetU32(&data_offset);    // number of 
> load commands
> -    const uint32_t sizeofcmds   = data.GetU32(&data_offset);    // the size 
> of all the load commands
> -    data_offset+=4; // Skip flags
> -
> -    // Check the architecture if we have a valid arch pointer
> -    if (arch)
> -    {
> -        ArchSpec file_arch(eArchTypeMachO, cputype, cpusubtype);
> -
> -        if (!file_arch.IsCompatibleMatch(*arch))
> -            return false;
> -    }
> -
> -    // The file exists, and if a valid arch pointer was passed in we know
> -    // if already matches, so we can return if we aren't looking for a 
> specific
> -    // UUID
> -    if (uuid == NULL)
> -        return true;
> -
> -    if (magic == MH_CIGAM_64 || magic == MH_MAGIC_64)
> -        data_offset += 4;   // Skip reserved field for in mach_header_64
> -
> -    // Make sure we have enough data for all the load commands
> -    if (magic == MH_CIGAM_64 || magic == MH_MAGIC_64)
> -    {
> -        if (data.GetByteSize() < sizeof(struct mach_header_64) + sizeofcmds)
> -        {
> -            DataBufferSP data_buffer_sp (file_spec.ReadFileContents 
> (file_offset, sizeof(struct mach_header_64) + sizeofcmds));
> -            data.SetData (data_buffer_sp);
> -        }
> -    }
> -    else
> -    {
> -        if (data.GetByteSize() < sizeof(struct mach_header) + sizeofcmds)
> -        {
> -            DataBufferSP data_buffer_sp (file_spec.ReadFileContents 
> (file_offset, sizeof(struct mach_header) + sizeofcmds));
> -            data.SetData (data_buffer_sp);
> -        }
> -    }
> -
> -    for (i=0; i<ncmds; i++)
> -    {
> -        const lldb::offset_t cmd_offset = data_offset;    // Save this 
> data_offset in case parsing of the segment goes awry!
> -        uint32_t cmd        = data.GetU32(&data_offset);
> -        uint32_t cmd_size   = data.GetU32(&data_offset);
> -        if (cmd == LC_UUID)
> -        {
> -            lldb_private::UUID file_uuid (data.GetData(&data_offset, 16), 
> 16);
> -            if (file_uuid == *uuid)
> -                return true;
> -            return false;
> -        }
> -        data_offset = cmd_offset + cmd_size;
> -    }
> -    return false;
> -}
> -
> -bool
> -UniversalMachOFileContainsArchAndUUID
> -(
> -    const FileSpec &file_spec,
> -    const ArchSpec *arch,
> -    const lldb_private::UUID *uuid,
> -    off_t file_offset,
> -    DataExtractor& data,
> -    lldb::offset_t data_offset,
> -    const uint32_t magic
> -)
> -{
> -    assert(magic == FAT_MAGIC || magic == FAT_CIGAM);
> -
> -    // Universal mach-o files always have their headers encoded as BIG endian
> -    data.SetByteOrder(eByteOrderBig);
> -
> -    uint32_t i;
> -    const uint32_t nfat_arch = data.GetU32(&data_offset);   // number of 
> structs that follow
> -    const uint32_t fat_header_and_arch_size = sizeof(struct fat_header) + 
> nfat_arch * sizeof(struct fat_arch);
> -    if (data.GetByteSize() < fat_header_and_arch_size)
> -    {
> -        DataBufferSP data_buffer_sp (file_spec.ReadFileContents 
> (file_offset, fat_header_and_arch_size));
> -        data.SetData (data_buffer_sp);
> -    }
> -
> -    for (i=0; i<nfat_arch; i++)
> -    {
> -        cpu_type_t      arch_cputype        = data.GetU32(&data_offset);    
> // cpu specifier (int)
> -        cpu_subtype_t   arch_cpusubtype     = data.GetU32(&data_offset);    
> // machine specifier (int)
> -        uint32_t        arch_offset         = data.GetU32(&data_offset);    
> // file offset to this object file
> -    //  uint32_t        arch_size           = data.GetU32(&data_offset);    
> // size of this object file
> -    //  uint32_t        arch_align          = data.GetU32(&data_offset);    
> // alignment as a power of 2
> -        data_offset += 8;   // Skip size and align as we don't need those
> -        // Only process this slice if the cpu type/subtype matches
> -        if (arch)
> -        {
> -            ArchSpec fat_arch(eArchTypeMachO, arch_cputype, arch_cpusubtype);
> -            if (!fat_arch.IsExactMatch(*arch))
> -                continue;
> -        }
> -
> -        // Create a buffer with only the arch slice date in it
> -        DataExtractor arch_data;
> -        DataBufferSP data_buffer_sp (file_spec.ReadFileContents (file_offset 
> + arch_offset, 0x1000));
> -        arch_data.SetData(data_buffer_sp);
> -        lldb::offset_t arch_data_offset = 0;
> -        uint32_t arch_magic = arch_data.GetU32(&arch_data_offset);
> -
> -        switch (arch_magic)
> -        {
> -        case MH_MAGIC:
> -        case MH_CIGAM:
> -        case MH_MAGIC_64:
> -        case MH_CIGAM_64:
> -            if (SkinnyMachOFileContainsArchAndUUID (file_spec, arch, uuid, 
> file_offset + arch_offset, arch_data, arch_data_offset, arch_magic))
> -                return true;
> -            break;
> -        }
> -    }
> -    return false;
> -}
> -
> -static bool
> -FileAtPathContainsArchAndUUID
> -(
> -    const FileSpec &file_spec,
> -    const ArchSpec *arch,
> -    const lldb_private::UUID *uuid
> -)
> -{
> -    DataExtractor data;
> -    off_t file_offset = 0;
> -    DataBufferSP data_buffer_sp (file_spec.ReadFileContents (file_offset, 
> 0x1000));
> -
> -    if (data_buffer_sp && data_buffer_sp->GetByteSize() > 0)
> -    {
> -        data.SetData(data_buffer_sp);
> -
> -        lldb::offset_t data_offset = 0;
> -        uint32_t magic = data.GetU32(&data_offset);
> -
> -        switch (magic)
> -        {
> -        // 32 bit mach-o file
> -        case MH_MAGIC:
> -        case MH_CIGAM:
> -        case MH_MAGIC_64:
> -        case MH_CIGAM_64:
> -            return SkinnyMachOFileContainsArchAndUUID (file_spec, arch, 
> uuid, file_offset, data, data_offset, magic);
> -
> -        // fat mach-o file
> -        case FAT_MAGIC:
> -        case FAT_CIGAM:
> -            return UniversalMachOFileContainsArchAndUUID (file_spec, arch, 
> uuid, file_offset, data, data_offset, magic);
> -
> -        default:
> -            break;
> -        }
> -    }
> -    return false;
> -}
> -
> -FileSpec
> -Symbols::FindSymbolFileInBundle (const FileSpec& dsym_bundle_fspec,
> -                                 const lldb_private::UUID *uuid,
> -                                 const ArchSpec *arch)
> -{
> -    char path[PATH_MAX];
> -
> -    FileSpec dsym_fspec;
> -
> -    if (dsym_bundle_fspec.GetPath(path, sizeof(path)))
> -    {
> -        ::strncat (path, "/Contents/Resources/DWARF", sizeof(path) - 
> strlen(path) - 1);
> -
> -        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;
> -
> -                    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);
> -                    if (FileAtPathContainsArchAndUUID (dsym_fspec, arch, 
> uuid))
> -                        return dsym_fspec;
> -                }
> -            }
> -        }
> -    }
> -    dsym_fspec.Clear();
> -    return dsym_fspec;
> -}
> -
> -static int
> +int
> LocateMacOSXFilesUsingDebugSymbols
> (
>     const ModuleSpec &module_spec,
> @@ -415,6 +188,8 @@ LocateMacOSXFilesUsingDebugSymbols
>                                 {
>                                     *dsym_extension_pos = '\0';
>                                     FileSpec file_spec (path, true);
> +                                    ModuleSpecList module_specs;
> +                                    ModuleSpec matched_module_spec;
>                                     switch (file_spec.GetFileType())
>                                     {
>                                         case FileSpec::eFileTypeDirectory:  
> // Bundle directory?
> @@ -426,8 +201,9 @@ LocateMacOSXFilesUsingDebugSymbols
>                                                     if 
> (::CFURLGetFileSystemRepresentation (bundle_exe_url.get(), true, 
> (UInt8*)path, sizeof(path)-1))
>                                                     {
>                                                         FileSpec 
> bundle_exe_file_spec (path, true);
> -                                                        
> -                                                        if 
> (FileAtPathContainsArchAndUUID (bundle_exe_file_spec, arch, uuid))
> +                                                        if 
> (ObjectFile::GetModuleSpecifications(bundle_exe_file_spec, 0, 0, 
> module_specs) &&
> +                                                            
> module_specs.FindMatchingModuleSpec(module_spec, matched_module_spec))
> +
>                                                         {
>                                                             ++items_found;
>                                                             *out_exec_fspec = 
> bundle_exe_file_spec;
> @@ -436,7 +212,7 @@ LocateMacOSXFilesUsingDebugSymbols
>                                                 }
>                                             }
>                                             break;
> -                                            
> +
>                                         case FileSpec::eFileTypePipe:       
> // Forget pipes
>                                         case FileSpec::eFileTypeSocket:     
> // We can't process socket files
>                                         case FileSpec::eFileTypeInvalid:    
> // File doesn't exist...
> @@ -446,7 +222,9 @@ LocateMacOSXFilesUsingDebugSymbols
>                                         case FileSpec::eFileTypeRegular:
>                                         case FileSpec::eFileTypeSymbolicLink:
>                                         case FileSpec::eFileTypeOther:
> -                                            if 
> (FileAtPathContainsArchAndUUID (file_spec, arch, uuid))
> +                                            if 
> (ObjectFile::GetModuleSpecifications(file_spec, 0, 0, module_specs) &&
> +                                                
> module_specs.FindMatchingModuleSpec(module_spec, matched_module_spec))
> +
>                                             {
>                                                 ++items_found;
>                                                 *out_exec_fspec = file_spec;
> @@ -466,112 +244,61 @@ LocateMacOSXFilesUsingDebugSymbols
>     return items_found;
> }
> 
> -static bool
> -LocateDSYMInVincinityOfExecutable (const ModuleSpec &module_spec, FileSpec 
> &dsym_fspec)
> +FileSpec
> +Symbols::FindSymbolFileInBundle (const FileSpec& dsym_bundle_fspec,
> +                                 const lldb_private::UUID *uuid,
> +                                 const ArchSpec *arch)
> {
> -    const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();
> -    if (exec_fspec)
> +    char path[PATH_MAX];
> +
> +    FileSpec dsym_fspec;
> +
> +    if (dsym_bundle_fspec.GetPath(path, sizeof(path)))
>     {
> -        char path[PATH_MAX];
> -        if (exec_fspec->GetPath(path, sizeof(path)))
> +        ::strncat (path, "/Contents/Resources/DWARF", sizeof(path) - 
> strlen(path) - 1);
> +
> +        lldb_utility::CleanUp <DIR *, int> dirp (opendir(path), NULL, 
> closedir);
> +        if (dirp.is_valid())
>         {
> -            // Make sure the module isn't already just a dSYM file...
> -            if (strcasestr(path, ".dSYM/Contents/Resources/DWARF") == NULL)
> +            dsym_fspec.GetDirectory().SetCString(path);
> +            struct dirent* dp;
> +            while ((dp = readdir(dirp.get())) != NULL)
>             {
> -                size_t obj_file_path_length = strlen(path);
> -                strlcat(path, ".dSYM/Contents/Resources/DWARF/", 
> sizeof(path));
> -                strlcat(path, exec_fspec->GetFilename().AsCString(), 
> sizeof(path));
> -
> -                dsym_fspec.SetFile(path, false);
> -
> -                if (dsym_fspec.Exists() && FileAtPathContainsArchAndUUID 
> (dsym_fspec, module_spec.GetArchitecturePtr(), module_spec.GetUUIDPtr()))
> +                // Only search directories
> +                if (dp->d_type == DT_DIR || dp->d_type == DT_UNKNOWN)
>                 {
> -                    return true;
> +                    if (dp->d_namlen == 1 && dp->d_name[0] == '.')
> +                        continue;
> +
> +                    if (dp->d_namlen == 2 && dp->d_name[0] == '.' && 
> dp->d_name[1] == '.')
> +                        continue;
>                 }
> -                else
> -                {
> -                    path[obj_file_path_length] = '\0';
> 
> -                    char *last_dot = strrchr(path, '.');
> -                    while (last_dot != NULL && last_dot[0])
> +                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))
>                     {
> -                        char *next_slash = strchr(last_dot, '/');
> -                        if (next_slash != NULL)
> +                        ModuleSpec spec;
> +                        for (size_t i = 0; i < module_specs.GetSize(); ++i)
>                         {
> -                            *next_slash = '\0';
> -                            strlcat(path, ".dSYM/Contents/Resources/DWARF/", 
> sizeof(path));
> -                            strlcat(path, 
> exec_fspec->GetFilename().AsCString(), sizeof(path));
> -                            dsym_fspec.SetFile(path, false);
> -                            if (dsym_fspec.Exists() && 
> FileAtPathContainsArchAndUUID (dsym_fspec, module_spec.GetArchitecturePtr(), 
> module_spec.GetUUIDPtr()))
> -                                return true;
> -                            else
> +                            assert(module_specs.GetModuleSpecAtIndex(i, 
> spec));
> +                            if ((uuid == NULL || (spec.GetUUIDPtr() && 
> spec.GetUUID() == *uuid)) &&
> +                                (arch == NULL || (spec.GetArchitecturePtr() 
> && spec.GetArchitecture().IsCompatibleMatch(*arch))))
>                             {
> -                                *last_dot = '\0';
> -                                char *prev_slash = strrchr(path, '/');
> -                                if (prev_slash != NULL)
> -                                    *prev_slash = '\0';
> -                                else
> -                                    break;
> +                                return dsym_fspec;
>                             }
>                         }
> -                        else
> -                        {
> -                            break;
> -                        }
>                     }
>                 }
>             }
>         }
>     }
>     dsym_fspec.Clear();
> -    return false;
> -}
> -
> -FileSpec
> -Symbols::LocateExecutableObjectFile (const ModuleSpec &module_spec)
> -{
> -    const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();
> -    const ArchSpec *arch = module_spec.GetArchitecturePtr();
> -    const UUID *uuid = module_spec.GetUUIDPtr();
> -    Timer scoped_timer (__PRETTY_FUNCTION__,
> -                        "LocateExecutableObjectFile (file = %s, arch = %s, 
> uuid = %p)",
> -                        exec_fspec ? exec_fspec->GetFilename().AsCString 
> ("<NULL>") : "<NULL>",
> -                        arch ? arch->GetArchitectureName() : "<NULL>",
> -                        uuid);
> -
> -    FileSpec objfile_fspec;
> -    if (exec_fspec && FileAtPathContainsArchAndUUID (exec_fspec, arch, uuid))
> -        objfile_fspec = exec_fspec;
> -    else
> -        LocateMacOSXFilesUsingDebugSymbols (module_spec, &objfile_fspec, 
> NULL);
> -    return objfile_fspec;
> -}
> -
> -FileSpec
> -Symbols::LocateExecutableSymbolFile (const ModuleSpec &module_spec)
> -{
> -    const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();
> -    const ArchSpec *arch = module_spec.GetArchitecturePtr();
> -    const UUID *uuid = module_spec.GetUUIDPtr();
> -
> -    Timer scoped_timer (__PRETTY_FUNCTION__,
> -                        "LocateExecutableSymbolFile (file = %s, arch = %s, 
> uuid = %p)",
> -                        exec_fspec ? exec_fspec->GetFilename().AsCString 
> ("<NULL>") : "<NULL>",
> -                        arch ? arch->GetArchitectureName() : "<NULL>",
> -                        uuid);
> -
> -    FileSpec symbol_fspec;
> -    // 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);
> -    }
> -    return symbol_fspec;
> +    return dsym_fspec;
> }
> 
> -
> static bool
> GetModuleSpecInfoFromUUIDDictionary (CFDictionaryRef uuid_dict, ModuleSpec 
> &module_spec)
> {
> 
> 
> _______________________________________________
> lldb-commits mailing list
> lldb-commits@cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits

_______________________________________________
lldb-commits mailing list
lldb-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits

Reply via email to