<div dir="ltr">Thanks for the information! I've put up a patch at <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__reviews.llvm.org_D9896&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=MEqT8U_n7oNfuDW5NRbY3ZV384ZquXIYFPWmprwUdKM&m=pQI1q8oPB53OAzO5NNWwA8O3mqURSzbjYKV3vluonHc&s=I3yfwPIBkb7dmDwcA6SMV2V5wcsKhSJVUEFw2cpmGYo&e=">http://reviews.llvm.org/D9896</a> which should do the right thing, please take a look.</div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, May 20, 2015 at 12:59 AM, Jason Molenda <span dir="ltr"><<a href="mailto:jmolenda@apple.com" target="_blank">jmolenda@apple.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">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.<br>
<br>
<br>
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.<br>
<br>
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.<br>
<br>
As a reminder, an executable name might be /tmp/a.out.  Its dSYM would be /tmp/a.out.dSYM/Contents/Resources/a.out.<br>
<br>
After r235737, LocateDSYMInVincinityOfExecutable() never matches anything.<br>
<br>
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.<br>
<br>
But if the DebugSymbols framework is not available or not working, lldb is completely broken for automatically loading a dSYM next to a binary.<br>
<br>
The old version of LocateDSYMInVincinityOfExecutable() was written in very Mac specific terms, e.g.<br>
<br>
                if (dsym_fspec.Exists() && FileAtPathContainsArchAndUUID (dsym_fspec, module_spec.GetArchitecturePtr(), module_spec.GetUUIDPtr()))<br>
                {<br>
                    return true;<br>
                }<br>
<br>
(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.<br>
<br>
As a quick workaround I made this patch,<br>
<br>
<br><br>
<br>
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.)<br>
<br>
Do you want to take another look at this function?<br>
<br>
<br>
Thanks!<br>
<br>
<br>
Jason<br>
<br>
<br>
<br>
> On Apr 24, 2015, at 11:09 AM, Robert Flack <<a href="mailto:flackr@gmail.com">flackr@gmail.com</a>> wrote:<br>
><br>
> Author: flackr<br>
> Date: Fri Apr 24 13:09:54 2015<br>
> New Revision: 235737<br>
><br>
> URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject-3Frev-3D235737-26view-3Drev&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=MEqT8U_n7oNfuDW5NRbY3ZV384ZquXIYFPWmprwUdKM&m=pQI1q8oPB53OAzO5NNWwA8O3mqURSzbjYKV3vluonHc&s=1MsOzAhnTEfIXKvBQExZ_3DJ6ajqZ6ENl3YuCREQ2cQ&e=" target="_blank">http://llvm.org/viewvc/llvm-project?rev=235737&view=rev</a><br>
> Log:<br>
> Look for both .debug and dsym debugging symbol information for stripped executable.<br>
><br>
> Currently Symbols::LocateExecutableSymbolFile on MacOSX only looks for external<br>
> dsym debugging information, however if running on a stripped dwarf executable it<br>
> should also check for a .debug file as well.<br>
><br>
> Test Plan:<br>
> ./dotest.py $DOTEST_OPTS -t -p TestSharedLibStrippedSymbols.py<br>
> This test now passes when running a remote Mac -> Linux test, and still passes<br>
> running locally on Mac or locally on Linux.<br>
><br>
> Differential Revision: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__reviews.llvm.org_D9174&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=MEqT8U_n7oNfuDW5NRbY3ZV384ZquXIYFPWmprwUdKM&m=pQI1q8oPB53OAzO5NNWwA8O3mqURSzbjYKV3vluonHc&s=QMB9MgHfJkkm6XEhW0tF2IPCOjM787cFFLDk3tf-qBg&e=" target="_blank">http://reviews.llvm.org/D9174</a><br>
><br>
> Modified:<br>
>    lldb/trunk/source/Host/common/Symbols.cpp<br>
>    lldb/trunk/source/Host/macosx/Symbols.cpp<br>
><br>
> Modified: lldb/trunk/source/Host/common/Symbols.cpp<br>
> URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_lldb_trunk_source_Host_common_Symbols.cpp-3Frev-3D235737-26r1-3D235736-26r2-3D235737-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=MEqT8U_n7oNfuDW5NRbY3ZV384ZquXIYFPWmprwUdKM&m=pQI1q8oPB53OAzO5NNWwA8O3mqURSzbjYKV3vluonHc&s=ath0mkTd7WhA6QOnhlgX-mnCfPs4giVEdTXfAFwfG9k&e=" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/common/Symbols.cpp?rev=235737&r1=235736&r2=235737&view=diff</a><br>
> ==============================================================================<br>
> --- lldb/trunk/source/Host/common/Symbols.cpp (original)<br>
> +++ lldb/trunk/source/Host/common/Symbols.cpp Fri Apr 24 13:09:54 2015<br>
> @@ -18,139 +18,253 @@<br>
> #include "lldb/Core/UUID.h"<br>
> #include "lldb/Symbol/ObjectFile.h"<br>
> #include "lldb/Target/Target.h"<br>
> +#include "lldb/Utility/SafeMachO.h"<br>
><br>
> #include "llvm/Support/FileSystem.h"<br>
><br>
> +// From MacOSX system header "mach/machine.h"<br>
> +typedef int cpu_type_t;<br>
> +typedef int cpu_subtype_t;<br>
> +<br>
> using namespace lldb;<br>
> using namespace lldb_private;<br>
> +using namespace llvm::MachO;<br>
> +<br>
> +#if defined(__APPLE__)<br>
> +<br>
> +// Forward declaration of method defined in source/Host/macosx/Symbols.cpp<br>
> +int<br>
> +LocateMacOSXFilesUsingDebugSymbols<br>
> +(<br>
> +    const ModuleSpec &module_spec,<br>
> +    FileSpec *out_exec_fspec,   // If non-NULL, try and find the executable<br>
> +    FileSpec *out_dsym_fspec    // If non-NULL try and find the debug symbol file<br>
> +);<br>
> +<br>
> +#else<br>
> +<br>
> +int<br>
> +LocateMacOSXFilesUsingDebugSymbols<br>
> +(<br>
> +    const ModuleSpec &module_spec,<br>
> +    FileSpec *out_exec_fspec,   // If non-NULL, try and find the executable<br>
> +    FileSpec *out_dsym_fspec    // If non-NULL try and find the debug symbol file<br>
> +) {<br>
> +    // Cannot find MacOSX files using debug symbols on non MacOSX.<br>
> +    return 0;<br>
> +}<br>
> +<br>
> +#endif<br>
> +<br>
> +static bool<br>
> +LocateDSYMInVincinityOfExecutable (const ModuleSpec &module_spec, FileSpec &dsym_fspec)<br>
> +{<br>
> +    const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();<br>
> +    if (exec_fspec)<br>
> +    {<br>
> +        char path[PATH_MAX];<br>
> +        if (exec_fspec->GetPath(path, sizeof(path)))<br>
> +        {<br>
> +            // Make sure the module isn't already just a dSYM file...<br>
> +            if (strcasestr(path, ".dSYM/Contents/Resources/DWARF") == NULL)<br>
> +            {<br>
> +                size_t obj_file_path_length = strlen(path);<br>
> +                ::strncat(path, ".dSYM/Contents/Resources/DWARF/", sizeof(path) - strlen(path) - 1);<br>
> +                ::strncat(path, exec_fspec->GetFilename().AsCString(), sizeof(path) - strlen(path) - 1);<br>
> +<br>
> +                dsym_fspec.SetFile(path, false);<br>
> +<br>
> +                ModuleSpecList module_specs;<br>
> +                ModuleSpec matched_module_spec;<br>
> +                if (dsym_fspec.Exists() &&<br>
> +                    ObjectFile::GetModuleSpecifications(dsym_fspec, 0, 0, module_specs) &&<br>
> +                    module_specs.FindMatchingModuleSpec(module_spec, matched_module_spec))<br>
> +                {<br>
> +                    return true;<br>
> +                }<br>
> +                else<br>
> +                {<br>
> +                    path[obj_file_path_length] = '\0';<br>
> +<br>
> +                    char *last_dot = strrchr(path, '.');<br>
> +                    while (last_dot != NULL && last_dot[0])<br>
> +                    {<br>
> +                        char *next_slash = strchr(last_dot, '/');<br>
> +                        if (next_slash != NULL)<br>
> +                        {<br>
> +                            *next_slash = '\0';<br>
> +                            ::strncat(path, ".dSYM/Contents/Resources/DWARF/", sizeof(path) - strlen(path) - 1);<br>
> +                            ::strncat(path, exec_fspec->GetFilename().AsCString(), sizeof(path) - strlen(path) - 1);<br>
> +                            dsym_fspec.SetFile(path, false);<br>
> +                            if (dsym_fspec.Exists() &&<br>
> +                                ObjectFile::GetModuleSpecifications(dsym_fspec, 0, 0, module_specs) &&<br>
> +                                module_specs.FindMatchingModuleSpec(module_spec, matched_module_spec))<br>
> +                            {<br>
> +                                return true;<br>
> +                            }<br>
> +                            else<br>
> +                            {<br>
> +                                *last_dot = '\0';<br>
> +                                char *prev_slash = strrchr(path, '/');<br>
> +                                if (prev_slash != NULL)<br>
> +                                    *prev_slash = '\0';<br>
> +                                else<br>
> +                                    break;<br>
> +                            }<br>
> +                        }<br>
> +                        else<br>
> +                        {<br>
> +                            break;<br>
> +                        }<br>
> +                    }<br>
> +                }<br>
> +            }<br>
> +        }<br>
> +    }<br>
> +    dsym_fspec.Clear();<br>
> +    return false;<br>
> +}<br>
><br>
> -#if defined (__linux__) || defined (__FreeBSD__)<br>
> +FileSpec<br>
> +LocateExecutableSymbolFileDsym (const ModuleSpec &module_spec)<br>
> +{<br>
> +    const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();<br>
> +    const ArchSpec *arch = module_spec.GetArchitecturePtr();<br>
> +    const UUID *uuid = module_spec.GetUUIDPtr();<br>
> +<br>
> +    Timer scoped_timer (__PRETTY_FUNCTION__,<br>
> +                        "LocateExecutableSymbolFileDsym (file = %s, arch = %s, uuid = %p)",<br>
> +                        exec_fspec ? exec_fspec->GetFilename().AsCString ("<NULL>") : "<NULL>",<br>
> +                        arch ? arch->GetArchitectureName() : "<NULL>",<br>
> +                        uuid);<br>
> +<br>
> +    FileSpec symbol_fspec;<br>
> +    // First try and find the dSYM in the same directory as the executable or in<br>
> +    // an appropriate parent directory<br>
> +    if (LocateDSYMInVincinityOfExecutable (module_spec, symbol_fspec) == false)<br>
> +    {<br>
> +        // We failed to easily find the dSYM above, so use DebugSymbols<br>
> +        LocateMacOSXFilesUsingDebugSymbols (module_spec, NULL, &symbol_fspec);<br>
> +    }<br>
> +    return symbol_fspec;<br>
> +}<br>
><br>
> FileSpec<br>
> Symbols::LocateExecutableObjectFile (const ModuleSpec &module_spec)<br>
> {<br>
> -    // FIXME<br>
> -    return FileSpec();<br>
> +    const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();<br>
> +    const ArchSpec *arch = module_spec.GetArchitecturePtr();<br>
> +    const UUID *uuid = module_spec.GetUUIDPtr();<br>
> +    Timer scoped_timer (__PRETTY_FUNCTION__,<br>
> +                        "LocateExecutableObjectFile (file = %s, arch = %s, uuid = %p)",<br>
> +                        exec_fspec ? exec_fspec->GetFilename().AsCString ("<NULL>") : "<NULL>",<br>
> +                        arch ? arch->GetArchitectureName() : "<NULL>",<br>
> +                        uuid);<br>
> +<br>
> +    FileSpec objfile_fspec;<br>
> +    ModuleSpecList module_specs;<br>
> +    ModuleSpec matched_module_spec;<br>
> +    if (exec_fspec &&<br>
> +        ObjectFile::GetModuleSpecifications(*exec_fspec, 0, 0, module_specs) &&<br>
> +        module_specs.FindMatchingModuleSpec(module_spec, matched_module_spec))<br>
> +    {<br>
> +        objfile_fspec = exec_fspec;<br>
> +    }<br>
> +    else<br>
> +    {<br>
> +        LocateMacOSXFilesUsingDebugSymbols (module_spec, &objfile_fspec, NULL);<br>
> +    }<br>
> +    return objfile_fspec;<br>
> }<br>
><br>
> FileSpec<br>
> Symbols::LocateExecutableSymbolFile (const ModuleSpec &module_spec)<br>
> {<br>
>     const char *symbol_filename = module_spec.GetSymbolFileSpec().GetFilename().AsCString();<br>
> -    if (!symbol_filename || !symbol_filename[0])<br>
> -        return FileSpec();<br>
> -<br>
> -    FileSpecList debug_file_search_paths (Target::GetDefaultDebugFileSearchPaths());<br>
> -<br>
> -    // Add module directory.<br>
> -    const ConstString &file_dir = module_spec.GetFileSpec().GetDirectory();<br>
> -    debug_file_search_paths.AppendIfUnique (FileSpec(file_dir.AsCString("."), true));<br>
> +    if (symbol_filename && symbol_filename[0])<br>
> +    {<br>
> +        FileSpecList debug_file_search_paths (Target::GetDefaultDebugFileSearchPaths());<br>
><br>
> -    // Add current working directory.<br>
> -    debug_file_search_paths.AppendIfUnique (FileSpec(".", true));<br>
> +        // Add module directory.<br>
> +        const ConstString &file_dir = module_spec.GetFileSpec().GetDirectory();<br>
> +        debug_file_search_paths.AppendIfUnique (FileSpec(file_dir.AsCString("."), true));<br>
><br>
> -    // Add /usr/lib/debug directory.<br>
> -    debug_file_search_paths.AppendIfUnique (FileSpec("/usr/lib/debug", true));<br>
> +        // Add current working directory.<br>
> +        debug_file_search_paths.AppendIfUnique (FileSpec(".", true));<br>
><br>
> -    std::string uuid_str;<br>
> -    const UUID &module_uuid = module_spec.GetUUID();<br>
> -    if (module_uuid.IsValid())<br>
> -    {<br>
> -        // Some debug files are stored in the .build-id directory like this:<br>
> -        //   /usr/lib/debug/.build-id/ff/e7fe727889ad82bb153de2ad065b2189693315.debug<br>
> -        uuid_str = module_uuid.GetAsString("");<br>
> -        uuid_str.insert (2, 1, '/');<br>
> -        uuid_str = uuid_str + ".debug";<br>
> -    }<br>
> +        // Add /usr/lib/debug directory.<br>
> +        debug_file_search_paths.AppendIfUnique (FileSpec("/usr/lib/debug", true));<br>
><br>
> -    // Get directory of our module. Needed to check debug files like this:<br>
> -    //   /usr/lib/debug/usr/lib/library.so.debug<br>
> -    std::string module_directory = module_spec.GetFileSpec().GetDirectory().AsCString();<br>
> +        std::string uuid_str;<br>
> +        const UUID &module_uuid = module_spec.GetUUID();<br>
> +        if (module_uuid.IsValid())<br>
> +        {<br>
> +            // Some debug files are stored in the .build-id directory like this:<br>
> +            //   /usr/lib/debug/.build-id/ff/e7fe727889ad82bb153de2ad065b2189693315.debug<br>
> +            uuid_str = module_uuid.GetAsString("");<br>
> +            uuid_str.insert (2, 1, '/');<br>
> +            uuid_str = uuid_str + ".debug";<br>
> +        }<br>
><br>
> -    size_t num_directories = debug_file_search_paths.GetSize();<br>
> -    for (size_t idx = 0; idx < num_directories; ++idx)<br>
> -    {<br>
> -        FileSpec dirspec = debug_file_search_paths.GetFileSpecAtIndex (idx);<br>
> -        dirspec.ResolvePath();<br>
> -        if (!dirspec.Exists() || !dirspec.IsDirectory())<br>
> -            continue;<br>
> -<br>
> -        std::vector<std::string> files;<br>
> -        std::string dirname = dirspec.GetPath();<br>
> -<br>
> -        files.push_back (dirname + "/" + symbol_filename);<br>
> -        files.push_back (dirname + "/.debug/" + symbol_filename);<br>
> -        files.push_back (dirname + "/.build-id/" + uuid_str);<br>
> -        files.push_back (dirname + module_directory + "/" + symbol_filename);<br>
> +        // Get directory of our module. Needed to check debug files like this:<br>
> +        //   /usr/lib/debug/usr/lib/library.so.debug<br>
> +        std::string module_directory = module_spec.GetFileSpec().GetDirectory().AsCString();<br>
><br>
> -        const uint32_t num_files = files.size();<br>
> -        for (size_t idx_file = 0; idx_file < num_files; ++idx_file)<br>
> +        size_t num_directories = debug_file_search_paths.GetSize();<br>
> +        for (size_t idx = 0; idx < num_directories; ++idx)<br>
>         {<br>
> -            const std::string &filename = files[idx_file];<br>
> -            FileSpec file_spec (filename.c_str(), true);<br>
> -<br>
> -            if (llvm::sys::fs::equivalent (file_spec.GetPath(), module_spec.GetFileSpec().GetPath()))<br>
> +            FileSpec dirspec = debug_file_search_paths.GetFileSpecAtIndex (idx);<br>
> +            dirspec.ResolvePath();<br>
> +            if (!dirspec.Exists() || !dirspec.IsDirectory())<br>
>                 continue;<br>
><br>
> -            if (file_spec.Exists())<br>
> +            std::vector<std::string> files;<br>
> +            std::string dirname = dirspec.GetPath();<br>
> +<br>
> +            files.push_back (dirname + "/" + symbol_filename);<br>
> +            files.push_back (dirname + "/.debug/" + symbol_filename);<br>
> +            files.push_back (dirname + "/.build-id/" + uuid_str);<br>
> +            files.push_back (dirname + module_directory + "/" + symbol_filename);<br>
> +<br>
> +            const uint32_t num_files = files.size();<br>
> +            for (size_t idx_file = 0; idx_file < num_files; ++idx_file)<br>
>             {<br>
> -                lldb_private::ModuleSpecList specs;<br>
> -                const size_t num_specs = ObjectFile::GetModuleSpecifications (file_spec, 0, 0, specs);<br>
> -                assert (num_specs <= 1 && "Symbol Vendor supports only a single architecture");<br>
> -                if (num_specs == 1)<br>
> +                const std::string &filename = files[idx_file];<br>
> +                FileSpec file_spec (filename.c_str(), true);<br>
> +<br>
> +                if (llvm::sys::fs::equivalent (file_spec.GetPath(), module_spec.GetFileSpec().GetPath()))<br>
> +                    continue;<br>
> +<br>
> +                if (file_spec.Exists())<br>
>                 {<br>
> -                    ModuleSpec mspec;<br>
> -                    if (specs.GetModuleSpecAtIndex (0, mspec))<br>
> +                    lldb_private::ModuleSpecList specs;<br>
> +                    const size_t num_specs = ObjectFile::GetModuleSpecifications (file_spec, 0, 0, specs);<br>
> +                    assert (num_specs <= 1 && "Symbol Vendor supports only a single architecture");<br>
> +                    if (num_specs == 1)<br>
>                     {<br>
> -                        if (mspec.GetUUID() == module_uuid)<br>
> -                            return file_spec;<br>
> +                        ModuleSpec mspec;<br>
> +                        if (specs.GetModuleSpecAtIndex (0, mspec))<br>
> +                        {<br>
> +                            if (mspec.GetUUID() == module_uuid)<br>
> +                                return file_spec;<br>
> +                        }<br>
>                     }<br>
>                 }<br>
>             }<br>
>         }<br>
>     }<br>
><br>
> -    return FileSpec();<br>
> +    return LocateExecutableSymbolFileDsym(module_spec);<br>
> }<br>
><br>
> -FileSpec<br>
> -Symbols::FindSymbolFileInBundle (const FileSpec& symfile_bundle,<br>
> -                                 const lldb_private::UUID *uuid,<br>
> -                                 const ArchSpec *arch)<br>
> -{<br>
> -    // FIXME<br>
> -    return FileSpec();<br>
> -}<br>
> -<br>
> -bool<br>
> -Symbols::DownloadObjectAndSymbolFile (ModuleSpec &module_spec, bool force_lookup)<br>
> -{<br>
> -    // Fill in the module_spec.GetFileSpec() for the object file and/or the<br>
> -    // module_spec.GetSymbolFileSpec() for the debug symbols file.<br>
> -    return false;<br>
> -}<br>
> -<br>
> -#elif !defined (__APPLE__)<br>
> -<br>
> -FileSpec<br>
> -Symbols::LocateExecutableObjectFile (const ModuleSpec &module_spec)<br>
> -{<br>
> -    // FIXME<br>
> -    return FileSpec();<br>
> -}<br>
> -<br>
> -FileSpec<br>
> -Symbols::LocateExecutableSymbolFile (const ModuleSpec &module_spec)<br>
> -{<br>
> -    // FIXME<br>
> -    return FileSpec();<br>
> -}<br>
> +#if !defined (__APPLE__)<br>
><br>
> FileSpec<br>
> Symbols::FindSymbolFileInBundle (const FileSpec& symfile_bundle,<br>
>                                  const lldb_private::UUID *uuid,<br>
>                                  const ArchSpec *arch)<br>
> {<br>
> +    // FIXME<br>
>     return FileSpec();<br>
> }<br>
><br>
><br>
> Modified: lldb/trunk/source/Host/macosx/Symbols.cpp<br>
> URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_lldb_trunk_source_Host_macosx_Symbols.cpp-3Frev-3D235737-26r1-3D235736-26r2-3D235737-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=MEqT8U_n7oNfuDW5NRbY3ZV384ZquXIYFPWmprwUdKM&m=pQI1q8oPB53OAzO5NNWwA8O3mqURSzbjYKV3vluonHc&s=BWLLt89j7V2ESr7J_zo8UyamLcyaY72gx1NPVniAgiI&e=" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/macosx/Symbols.cpp?rev=235737&r1=235736&r2=235737&view=diff</a><br>
> ==============================================================================<br>
> --- lldb/trunk/source/Host/macosx/Symbols.cpp (original)<br>
> +++ lldb/trunk/source/Host/macosx/Symbols.cpp Fri Apr 24 13:09:54 2015<br>
> @@ -29,6 +29,7 @@<br>
> #include "lldb/Core/UUID.h"<br>
> #include "lldb/Host/Endian.h"<br>
> #include "lldb/Host/Host.h"<br>
> +#include "lldb/Symbol/ObjectFile.h"<br>
> #include "lldb/Utility/CleanUp.h"<br>
> #include "Host/macosx/cfcpp/CFCBundle.h"<br>
> #include "Host/macosx/cfcpp/CFCData.h"<br>
> @@ -36,7 +37,6 @@<br>
> #include "Host/macosx/cfcpp/CFCString.h"<br>
> #include "mach/machine.h"<br>
><br>
> -<br>
> using namespace lldb;<br>
> using namespace lldb_private;<br>
> using namespace llvm::MachO;<br>
> @@ -50,234 +50,7 @@ CFDictionaryRef DBGCopyDSYMPropertyLists<br>
> }<br>
> #endif<br>
><br>
> -static bool<br>
> -SkinnyMachOFileContainsArchAndUUID<br>
> -(<br>
> -    const FileSpec &file_spec,<br>
> -    const ArchSpec *arch,<br>
> -    const lldb_private::UUID *uuid,   // the UUID we are looking for<br>
> -    off_t file_offset,<br>
> -    DataExtractor& data,<br>
> -    lldb::offset_t data_offset,<br>
> -    const uint32_t magic<br>
> -)<br>
> -{<br>
> -    assert(magic == MH_MAGIC || magic == MH_CIGAM || magic == MH_MAGIC_64 || magic == MH_CIGAM_64);<br>
> -    if (magic == MH_MAGIC || magic == MH_MAGIC_64)<br>
> -        data.SetByteOrder (lldb::endian::InlHostByteOrder());<br>
> -    else if (lldb::endian::InlHostByteOrder() == eByteOrderBig)<br>
> -        data.SetByteOrder (eByteOrderLittle);<br>
> -    else<br>
> -        data.SetByteOrder (eByteOrderBig);<br>
> -<br>
> -    uint32_t i;<br>
> -    const uint32_t cputype      = data.GetU32(&data_offset);    // cpu specifier<br>
> -    const uint32_t cpusubtype   = data.GetU32(&data_offset);    // machine specifier<br>
> -    data_offset+=4; // Skip mach file type<br>
> -    const uint32_t ncmds        = data.GetU32(&data_offset);    // number of load commands<br>
> -    const uint32_t sizeofcmds   = data.GetU32(&data_offset);    // the size of all the load commands<br>
> -    data_offset+=4; // Skip flags<br>
> -<br>
> -    // Check the architecture if we have a valid arch pointer<br>
> -    if (arch)<br>
> -    {<br>
> -        ArchSpec file_arch(eArchTypeMachO, cputype, cpusubtype);<br>
> -<br>
> -        if (!file_arch.IsCompatibleMatch(*arch))<br>
> -            return false;<br>
> -    }<br>
> -<br>
> -    // The file exists, and if a valid arch pointer was passed in we know<br>
> -    // if already matches, so we can return if we aren't looking for a specific<br>
> -    // UUID<br>
> -    if (uuid == NULL)<br>
> -        return true;<br>
> -<br>
> -    if (magic == MH_CIGAM_64 || magic == MH_MAGIC_64)<br>
> -        data_offset += 4;   // Skip reserved field for in mach_header_64<br>
> -<br>
> -    // Make sure we have enough data for all the load commands<br>
> -    if (magic == MH_CIGAM_64 || magic == MH_MAGIC_64)<br>
> -    {<br>
> -        if (data.GetByteSize() < sizeof(struct mach_header_64) + sizeofcmds)<br>
> -        {<br>
> -            DataBufferSP data_buffer_sp (file_spec.ReadFileContents (file_offset, sizeof(struct mach_header_64) + sizeofcmds));<br>
> -            data.SetData (data_buffer_sp);<br>
> -        }<br>
> -    }<br>
> -    else<br>
> -    {<br>
> -        if (data.GetByteSize() < sizeof(struct mach_header) + sizeofcmds)<br>
> -        {<br>
> -            DataBufferSP data_buffer_sp (file_spec.ReadFileContents (file_offset, sizeof(struct mach_header) + sizeofcmds));<br>
> -            data.SetData (data_buffer_sp);<br>
> -        }<br>
> -    }<br>
> -<br>
> -    for (i=0; i<ncmds; i++)<br>
> -    {<br>
> -        const lldb::offset_t cmd_offset = data_offset;    // Save this data_offset in case parsing of the segment goes awry!<br>
> -        uint32_t cmd        = data.GetU32(&data_offset);<br>
> -        uint32_t cmd_size   = data.GetU32(&data_offset);<br>
> -        if (cmd == LC_UUID)<br>
> -        {<br>
> -            lldb_private::UUID file_uuid (data.GetData(&data_offset, 16), 16);<br>
> -            if (file_uuid == *uuid)<br>
> -                return true;<br>
> -            return false;<br>
> -        }<br>
> -        data_offset = cmd_offset + cmd_size;<br>
> -    }<br>
> -    return false;<br>
> -}<br>
> -<br>
> -bool<br>
> -UniversalMachOFileContainsArchAndUUID<br>
> -(<br>
> -    const FileSpec &file_spec,<br>
> -    const ArchSpec *arch,<br>
> -    const lldb_private::UUID *uuid,<br>
> -    off_t file_offset,<br>
> -    DataExtractor& data,<br>
> -    lldb::offset_t data_offset,<br>
> -    const uint32_t magic<br>
> -)<br>
> -{<br>
> -    assert(magic == FAT_MAGIC || magic == FAT_CIGAM);<br>
> -<br>
> -    // Universal mach-o files always have their headers encoded as BIG endian<br>
> -    data.SetByteOrder(eByteOrderBig);<br>
> -<br>
> -    uint32_t i;<br>
> -    const uint32_t nfat_arch = data.GetU32(&data_offset);   // number of structs that follow<br>
> -    const uint32_t fat_header_and_arch_size = sizeof(struct fat_header) + nfat_arch * sizeof(struct fat_arch);<br>
> -    if (data.GetByteSize() < fat_header_and_arch_size)<br>
> -    {<br>
> -        DataBufferSP data_buffer_sp (file_spec.ReadFileContents (file_offset, fat_header_and_arch_size));<br>
> -        data.SetData (data_buffer_sp);<br>
> -    }<br>
> -<br>
> -    for (i=0; i<nfat_arch; i++)<br>
> -    {<br>
> -        cpu_type_t      arch_cputype        = data.GetU32(&data_offset);    // cpu specifier (int)<br>
> -        cpu_subtype_t   arch_cpusubtype     = data.GetU32(&data_offset);    // machine specifier (int)<br>
> -        uint32_t        arch_offset         = data.GetU32(&data_offset);    // file offset to this object file<br>
> -    //  uint32_t        arch_size           = data.GetU32(&data_offset);    // size of this object file<br>
> -    //  uint32_t        arch_align          = data.GetU32(&data_offset);    // alignment as a power of 2<br>
> -        data_offset += 8;   // Skip size and align as we don't need those<br>
> -        // Only process this slice if the cpu type/subtype matches<br>
> -        if (arch)<br>
> -        {<br>
> -            ArchSpec fat_arch(eArchTypeMachO, arch_cputype, arch_cpusubtype);<br>
> -            if (!fat_arch.IsExactMatch(*arch))<br>
> -                continue;<br>
> -        }<br>
> -<br>
> -        // Create a buffer with only the arch slice date in it<br>
> -        DataExtractor arch_data;<br>
> -        DataBufferSP data_buffer_sp (file_spec.ReadFileContents (file_offset + arch_offset, 0x1000));<br>
> -        arch_data.SetData(data_buffer_sp);<br>
> -        lldb::offset_t arch_data_offset = 0;<br>
> -        uint32_t arch_magic = arch_data.GetU32(&arch_data_offset);<br>
> -<br>
> -        switch (arch_magic)<br>
> -        {<br>
> -        case MH_MAGIC:<br>
> -        case MH_CIGAM:<br>
> -        case MH_MAGIC_64:<br>
> -        case MH_CIGAM_64:<br>
> -            if (SkinnyMachOFileContainsArchAndUUID (file_spec, arch, uuid, file_offset + arch_offset, arch_data, arch_data_offset, arch_magic))<br>
> -                return true;<br>
> -            break;<br>
> -        }<br>
> -    }<br>
> -    return false;<br>
> -}<br>
> -<br>
> -static bool<br>
> -FileAtPathContainsArchAndUUID<br>
> -(<br>
> -    const FileSpec &file_spec,<br>
> -    const ArchSpec *arch,<br>
> -    const lldb_private::UUID *uuid<br>
> -)<br>
> -{<br>
> -    DataExtractor data;<br>
> -    off_t file_offset = 0;<br>
> -    DataBufferSP data_buffer_sp (file_spec.ReadFileContents (file_offset, 0x1000));<br>
> -<br>
> -    if (data_buffer_sp && data_buffer_sp->GetByteSize() > 0)<br>
> -    {<br>
> -        data.SetData(data_buffer_sp);<br>
> -<br>
> -        lldb::offset_t data_offset = 0;<br>
> -        uint32_t magic = data.GetU32(&data_offset);<br>
> -<br>
> -        switch (magic)<br>
> -        {<br>
> -        // 32 bit mach-o file<br>
> -        case MH_MAGIC:<br>
> -        case MH_CIGAM:<br>
> -        case MH_MAGIC_64:<br>
> -        case MH_CIGAM_64:<br>
> -            return SkinnyMachOFileContainsArchAndUUID (file_spec, arch, uuid, file_offset, data, data_offset, magic);<br>
> -<br>
> -        // fat mach-o file<br>
> -        case FAT_MAGIC:<br>
> -        case FAT_CIGAM:<br>
> -            return UniversalMachOFileContainsArchAndUUID (file_spec, arch, uuid, file_offset, data, data_offset, magic);<br>
> -<br>
> -        default:<br>
> -            break;<br>
> -        }<br>
> -    }<br>
> -    return false;<br>
> -}<br>
> -<br>
> -FileSpec<br>
> -Symbols::FindSymbolFileInBundle (const FileSpec& dsym_bundle_fspec,<br>
> -                                 const lldb_private::UUID *uuid,<br>
> -                                 const ArchSpec *arch)<br>
> -{<br>
> -    char path[PATH_MAX];<br>
> -<br>
> -    FileSpec dsym_fspec;<br>
> -<br>
> -    if (dsym_bundle_fspec.GetPath(path, sizeof(path)))<br>
> -    {<br>
> -        ::strncat (path, "/Contents/Resources/DWARF", sizeof(path) - strlen(path) - 1);<br>
> -<br>
> -        lldb_utility::CleanUp <DIR *, int> dirp (opendir(path), NULL, closedir);<br>
> -        if (dirp.is_valid())<br>
> -        {<br>
> -            dsym_fspec.GetDirectory().SetCString(path);<br>
> -            struct dirent* dp;<br>
> -            while ((dp = readdir(dirp.get())) != NULL)<br>
> -            {<br>
> -                // Only search directories<br>
> -                if (dp->d_type == DT_DIR || dp->d_type == DT_UNKNOWN)<br>
> -                {<br>
> -                    if (dp->d_namlen == 1 && dp->d_name[0] == '.')<br>
> -                        continue;<br>
> -<br>
> -                    if (dp->d_namlen == 2 && dp->d_name[0] == '.' && dp->d_name[1] == '.')<br>
> -                        continue;<br>
> -                }<br>
> -<br>
> -                if (dp->d_type == DT_REG || dp->d_type == DT_UNKNOWN)<br>
> -                {<br>
> -                    dsym_fspec.GetFilename().SetCString(dp->d_name);<br>
> -                    if (FileAtPathContainsArchAndUUID (dsym_fspec, arch, uuid))<br>
> -                        return dsym_fspec;<br>
> -                }<br>
> -            }<br>
> -        }<br>
> -    }<br>
> -    dsym_fspec.Clear();<br>
> -    return dsym_fspec;<br>
> -}<br>
> -<br>
> -static int<br>
> +int<br>
> LocateMacOSXFilesUsingDebugSymbols<br>
> (<br>
>     const ModuleSpec &module_spec,<br>
> @@ -415,6 +188,8 @@ LocateMacOSXFilesUsingDebugSymbols<br>
>                                 {<br>
>                                     *dsym_extension_pos = '\0';<br>
>                                     FileSpec file_spec (path, true);<br>
> +                                    ModuleSpecList module_specs;<br>
> +                                    ModuleSpec matched_module_spec;<br>
>                                     switch (file_spec.GetFileType())<br>
>                                     {<br>
>                                         case FileSpec::eFileTypeDirectory:  // Bundle directory?<br>
> @@ -426,8 +201,9 @@ LocateMacOSXFilesUsingDebugSymbols<br>
>                                                     if (::CFURLGetFileSystemRepresentation (bundle_exe_url.get(), true, (UInt8*)path, sizeof(path)-1))<br>
>                                                     {<br>
>                                                         FileSpec bundle_exe_file_spec (path, true);<br>
> -<br>
> -                                                        if (FileAtPathContainsArchAndUUID (bundle_exe_file_spec, arch, uuid))<br>
> +                                                        if (ObjectFile::GetModuleSpecifications(bundle_exe_file_spec, 0, 0, module_specs) &&<br>
> +                                                            module_specs.FindMatchingModuleSpec(module_spec, matched_module_spec))<br>
> +<br>
>                                                         {<br>
>                                                             ++items_found;<br>
>                                                             *out_exec_fspec = bundle_exe_file_spec;<br>
> @@ -436,7 +212,7 @@ LocateMacOSXFilesUsingDebugSymbols<br>
>                                                 }<br>
>                                             }<br>
>                                             break;<br>
> -<br>
> +<br>
>                                         case FileSpec::eFileTypePipe:       // Forget pipes<br>
>                                         case FileSpec::eFileTypeSocket:     // We can't process socket files<br>
>                                         case FileSpec::eFileTypeInvalid:    // File doesn't exist...<br>
> @@ -446,7 +222,9 @@ LocateMacOSXFilesUsingDebugSymbols<br>
>                                         case FileSpec::eFileTypeRegular:<br>
>                                         case FileSpec::eFileTypeSymbolicLink:<br>
>                                         case FileSpec::eFileTypeOther:<br>
> -                                            if (FileAtPathContainsArchAndUUID (file_spec, arch, uuid))<br>
> +                                            if (ObjectFile::GetModuleSpecifications(file_spec, 0, 0, module_specs) &&<br>
> +                                                module_specs.FindMatchingModuleSpec(module_spec, matched_module_spec))<br>
> +<br>
>                                             {<br>
>                                                 ++items_found;<br>
>                                                 *out_exec_fspec = file_spec;<br>
> @@ -466,112 +244,61 @@ LocateMacOSXFilesUsingDebugSymbols<br>
>     return items_found;<br>
> }<br>
><br>
> -static bool<br>
> -LocateDSYMInVincinityOfExecutable (const ModuleSpec &module_spec, FileSpec &dsym_fspec)<br>
> +FileSpec<br>
> +Symbols::FindSymbolFileInBundle (const FileSpec& dsym_bundle_fspec,<br>
> +                                 const lldb_private::UUID *uuid,<br>
> +                                 const ArchSpec *arch)<br>
> {<br>
> -    const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();<br>
> -    if (exec_fspec)<br>
> +    char path[PATH_MAX];<br>
> +<br>
> +    FileSpec dsym_fspec;<br>
> +<br>
> +    if (dsym_bundle_fspec.GetPath(path, sizeof(path)))<br>
>     {<br>
> -        char path[PATH_MAX];<br>
> -        if (exec_fspec->GetPath(path, sizeof(path)))<br>
> +        ::strncat (path, "/Contents/Resources/DWARF", sizeof(path) - strlen(path) - 1);<br>
> +<br>
> +        lldb_utility::CleanUp <DIR *, int> dirp (opendir(path), NULL, closedir);<br>
> +        if (dirp.is_valid())<br>
>         {<br>
> -            // Make sure the module isn't already just a dSYM file...<br>
> -            if (strcasestr(path, ".dSYM/Contents/Resources/DWARF") == NULL)<br>
> +            dsym_fspec.GetDirectory().SetCString(path);<br>
> +            struct dirent* dp;<br>
> +            while ((dp = readdir(dirp.get())) != NULL)<br>
>             {<br>
> -                size_t obj_file_path_length = strlen(path);<br>
> -                strlcat(path, ".dSYM/Contents/Resources/DWARF/", sizeof(path));<br>
> -                strlcat(path, exec_fspec->GetFilename().AsCString(), sizeof(path));<br>
> -<br>
> -                dsym_fspec.SetFile(path, false);<br>
> -<br>
> -                if (dsym_fspec.Exists() && FileAtPathContainsArchAndUUID (dsym_fspec, module_spec.GetArchitecturePtr(), module_spec.GetUUIDPtr()))<br>
> +                // Only search directories<br>
> +                if (dp->d_type == DT_DIR || dp->d_type == DT_UNKNOWN)<br>
>                 {<br>
> -                    return true;<br>
> +                    if (dp->d_namlen == 1 && dp->d_name[0] == '.')<br>
> +                        continue;<br>
> +<br>
> +                    if (dp->d_namlen == 2 && dp->d_name[0] == '.' && dp->d_name[1] == '.')<br>
> +                        continue;<br>
>                 }<br>
> -                else<br>
> -                {<br>
> -                    path[obj_file_path_length] = '\0';<br>
><br>
> -                    char *last_dot = strrchr(path, '.');<br>
> -                    while (last_dot != NULL && last_dot[0])<br>
> +                if (dp->d_type == DT_REG || dp->d_type == DT_UNKNOWN)<br>
> +                {<br>
> +                    dsym_fspec.GetFilename().SetCString(dp->d_name);<br>
> +                    ModuleSpecList module_specs;<br>
> +                    if (ObjectFile::GetModuleSpecifications(dsym_fspec, 0, 0, module_specs))<br>
>                     {<br>
> -                        char *next_slash = strchr(last_dot, '/');<br>
> -                        if (next_slash != NULL)<br>
> +                        ModuleSpec spec;<br>
> +                        for (size_t i = 0; i < module_specs.GetSize(); ++i)<br>
>                         {<br>
> -                            *next_slash = '\0';<br>
> -                            strlcat(path, ".dSYM/Contents/Resources/DWARF/", sizeof(path));<br>
> -                            strlcat(path, exec_fspec->GetFilename().AsCString(), sizeof(path));<br>
> -                            dsym_fspec.SetFile(path, false);<br>
> -                            if (dsym_fspec.Exists() && FileAtPathContainsArchAndUUID (dsym_fspec, module_spec.GetArchitecturePtr(), module_spec.GetUUIDPtr()))<br>
> -                                return true;<br>
> -                            else<br>
> +                            assert(module_specs.GetModuleSpecAtIndex(i, spec));<br>
> +                            if ((uuid == NULL || (spec.GetUUIDPtr() && spec.GetUUID() == *uuid)) &&<br>
> +                                (arch == NULL || (spec.GetArchitecturePtr() && spec.GetArchitecture().IsCompatibleMatch(*arch))))<br>
>                             {<br>
> -                                *last_dot = '\0';<br>
> -                                char *prev_slash = strrchr(path, '/');<br>
> -                                if (prev_slash != NULL)<br>
> -                                    *prev_slash = '\0';<br>
> -                                else<br>
> -                                    break;<br>
> +                                return dsym_fspec;<br>
>                             }<br>
>                         }<br>
> -                        else<br>
> -                        {<br>
> -                            break;<br>
> -                        }<br>
>                     }<br>
>                 }<br>
>             }<br>
>         }<br>
>     }<br>
>     dsym_fspec.Clear();<br>
> -    return false;<br>
> -}<br>
> -<br>
> -FileSpec<br>
> -Symbols::LocateExecutableObjectFile (const ModuleSpec &module_spec)<br>
> -{<br>
> -    const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();<br>
> -    const ArchSpec *arch = module_spec.GetArchitecturePtr();<br>
> -    const UUID *uuid = module_spec.GetUUIDPtr();<br>
> -    Timer scoped_timer (__PRETTY_FUNCTION__,<br>
> -                        "LocateExecutableObjectFile (file = %s, arch = %s, uuid = %p)",<br>
> -                        exec_fspec ? exec_fspec->GetFilename().AsCString ("<NULL>") : "<NULL>",<br>
> -                        arch ? arch->GetArchitectureName() : "<NULL>",<br>
> -                        uuid);<br>
> -<br>
> -    FileSpec objfile_fspec;<br>
> -    if (exec_fspec && FileAtPathContainsArchAndUUID (exec_fspec, arch, uuid))<br>
> -        objfile_fspec = exec_fspec;<br>
> -    else<br>
> -        LocateMacOSXFilesUsingDebugSymbols (module_spec, &objfile_fspec, NULL);<br>
> -    return objfile_fspec;<br>
> -}<br>
> -<br>
> -FileSpec<br>
> -Symbols::LocateExecutableSymbolFile (const ModuleSpec &module_spec)<br>
> -{<br>
> -    const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();<br>
> -    const ArchSpec *arch = module_spec.GetArchitecturePtr();<br>
> -    const UUID *uuid = module_spec.GetUUIDPtr();<br>
> -<br>
> -    Timer scoped_timer (__PRETTY_FUNCTION__,<br>
> -                        "LocateExecutableSymbolFile (file = %s, arch = %s, uuid = %p)",<br>
> -                        exec_fspec ? exec_fspec->GetFilename().AsCString ("<NULL>") : "<NULL>",<br>
> -                        arch ? arch->GetArchitectureName() : "<NULL>",<br>
> -                        uuid);<br>
> -<br>
> -    FileSpec symbol_fspec;<br>
> -    // First try and find the dSYM in the same directory as the executable or in<br>
> -    // an appropriate parent directory<br>
> -    if (LocateDSYMInVincinityOfExecutable (module_spec, symbol_fspec) == false)<br>
> -    {<br>
> -        // We failed to easily find the dSYM above, so use DebugSymbols<br>
> -        LocateMacOSXFilesUsingDebugSymbols (module_spec, NULL, &symbol_fspec);<br>
> -    }<br>
> -    return symbol_fspec;<br>
> +    return dsym_fspec;<br>
> }<br>
><br>
> -<br>
> static bool<br>
> GetModuleSpecInfoFromUUIDDictionary (CFDictionaryRef uuid_dict, ModuleSpec &module_spec)<br>
> {<br>
><br>
><br>
> _______________________________________________<br>
> lldb-commits mailing list<br>
> <a href="mailto:lldb-commits@cs.uiuc.edu">lldb-commits@cs.uiuc.edu</a><br>
> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits</a><br>
<br>
<br></blockquote></div><br></div>