Thanks for the information! I've put up a patch at http://reviews.llvm.org/D9896 which should do the right thing, please take a look.
On Wed, May 20, 2015 at 12:59 AM, Jason Molenda <jmole...@apple.com> wrote: > 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, > > > > > 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