This revision was automatically updated to reflect the committed changes. Closed by commit rGa842950b62b6: [lldb] Add a SymbolFileProvider to record and replay calls to dsymForUUID (authored by JDevlieghere). Herald added a project: LLDB.
Changed prior to commit: https://reviews.llvm.org/D86389?vs=287164&id=287508#toc Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D86389/new/ https://reviews.llvm.org/D86389 Files: lldb/include/lldb/Utility/Reproducer.h lldb/include/lldb/Utility/ReproducerProvider.h lldb/source/Commands/CommandObjectReproducer.cpp lldb/source/Symbol/LocateSymbolFile.cpp lldb/source/Symbol/LocateSymbolFileMacOSX.cpp lldb/source/Utility/ReproducerProvider.cpp lldb/test/Shell/Reproducer/Inputs/core lldb/test/Shell/Reproducer/Inputs/dsymforuuid.sh lldb/test/Shell/Reproducer/TestDebugSymbols.test
Index: lldb/test/Shell/Reproducer/TestDebugSymbols.test =================================================================== --- /dev/null +++ lldb/test/Shell/Reproducer/TestDebugSymbols.test @@ -0,0 +1,14 @@ +# REQUIRES: system-darwin + +# RUN: rm -rf %t.repro +# RUN: env LLDB_APPLE_DSYMFORUUID_EXECUTABLE=%S/Inputs/dsymforuuid.sh %lldb --capture --capture-path %t.repro -c %S/Inputs/core -o 'reproducer generate' + +# RUN: cat %t.repro/symbol-files.yaml | FileCheck %s --check-prefix YAML +# YAML: AD52358C-94F8-3796-ADD6-B20FFAC00E5C +# YAML: /path/to/unstripped/executable +# YAML: /path/to/foo.dSYM/Contents/Resources/DWARF/foo + +# RUN: %lldb -b -o 'reproducer dump -p symbol-files -f %t.repro' | FileCheck %s --check-prefix DUMP +# DUMP: uuid: AD52358C-94F8-3796-ADD6-B20FFAC00E5C +# DUMP-NEXT: module path: /path/to/unstripped/executable +# DUMP-NEXT: symbol path: /path/to/foo.dSYM/Contents/Resources/DWARF/foo Index: lldb/test/Shell/Reproducer/Inputs/dsymforuuid.sh =================================================================== --- /dev/null +++ lldb/test/Shell/Reproducer/Inputs/dsymforuuid.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +echo "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//ENhttp://www.apple.com/DTDs/PropertyList-1.0.dtd\">" +echo "<plist version=\"1.0\">" +echo "<dict>" +echo " <key>AD52358C-94F8-3796-ADD6-B20FFAC00E5C</key>" +echo " <dict>" +echo " <key>DBGArchitecture</key>" +echo " <string>x86_64</string>" +echo " <key>DBGBuildSourcePath</key>" +echo " <string>/path/to/build/sources</string>" +echo " <key>DBGSourcePath</key>" +echo " <string>/path/to/actual/sources</string>" +echo " <key>DBGDSYMPath</key>" +echo " <string>/path/to/foo.dSYM/Contents/Resources/DWARF/foo</string>" +echo " <key>DBGSymbolRichExecutable</key>" +echo " <string>/path/to/unstripped/executable</string>" +echo " </dict>" +echo "</dict>" +echo "</plist>" Index: lldb/source/Utility/ReproducerProvider.cpp =================================================================== --- lldb/source/Utility/ReproducerProvider.cpp +++ lldb/source/Utility/ReproducerProvider.cpp @@ -105,6 +105,61 @@ m_os.flush(); } +void SymbolFileProvider::AddSymbolFile(const UUID *uuid, + const FileSpec &module_file, + const FileSpec &symbol_file) { + if (!uuid || (!module_file && !symbol_file)) + return; + m_symbol_files.emplace_back(uuid->GetAsString(), module_file.GetPath(), + symbol_file.GetPath()); +} + +void SymbolFileProvider::Keep() { + FileSpec file = this->GetRoot().CopyByAppendingPathComponent(Info::file); + std::error_code ec; + llvm::raw_fd_ostream os(file.GetPath(), ec, llvm::sys::fs::OF_Text); + if (ec) + return; + + // Remove duplicates. + llvm::sort(m_symbol_files.begin(), m_symbol_files.end()); + m_symbol_files.erase( + std::unique(m_symbol_files.begin(), m_symbol_files.end()), + m_symbol_files.end()); + + llvm::yaml::Output yout(os); + yout << m_symbol_files; +} + +SymbolFileLoader::SymbolFileLoader(Loader *loader) { + if (!loader) + return; + + FileSpec file = loader->GetFile<SymbolFileProvider::Info>(); + if (!file) + return; + + auto error_or_file = llvm::MemoryBuffer::getFile(file.GetPath()); + if (auto err = error_or_file.getError()) + return; + + llvm::yaml::Input yin((*error_or_file)->getBuffer()); + yin >> m_symbol_files; +} + +std::pair<FileSpec, FileSpec> +SymbolFileLoader::GetPaths(const UUID *uuid) const { + if (!uuid) + return {}; + + auto it = std::lower_bound(m_symbol_files.begin(), m_symbol_files.end(), + SymbolFileProvider::Entry(uuid->GetAsString())); + if (it == m_symbol_files.end()) + return {}; + return std::make_pair<FileSpec, FileSpec>(FileSpec(it->module_path), + FileSpec(it->symbol_path)); +} + void ProviderBase::anchor() {} char CommandProvider::ID = 0; char FileProvider::ID = 0; @@ -113,6 +168,7 @@ char WorkingDirectoryProvider::ID = 0; char HomeDirectoryProvider::ID = 0; char ProcessInfoProvider::ID = 0; +char SymbolFileProvider::ID = 0; const char *CommandProvider::Info::file = "command-interpreter.yaml"; const char *CommandProvider::Info::name = "command-interpreter"; const char *FileProvider::Info::file = "files.yaml"; @@ -125,3 +181,5 @@ const char *HomeDirectoryProvider::Info::name = "home"; const char *ProcessInfoProvider::Info::file = "process-info.yaml"; const char *ProcessInfoProvider::Info::name = "process-info"; +const char *SymbolFileProvider::Info::file = "symbol-files.yaml"; +const char *SymbolFileProvider::Info::name = "symbol-files"; Index: lldb/source/Symbol/LocateSymbolFileMacOSX.cpp =================================================================== --- lldb/source/Symbol/LocateSymbolFileMacOSX.cpp +++ lldb/source/Symbol/LocateSymbolFileMacOSX.cpp @@ -27,6 +27,7 @@ #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Endian.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/ReproducerProvider.h" #include "lldb/Utility/StreamString.h" #include "lldb/Utility/Timer.h" #include "lldb/Utility/UUID.h" @@ -53,6 +54,17 @@ return_module_spec.GetFileSpec().Clear(); return_module_spec.GetSymbolFileSpec().Clear(); + const UUID *uuid = module_spec.GetUUIDPtr(); + const ArchSpec *arch = module_spec.GetArchitecturePtr(); + + if (repro::Loader *l = repro::Reproducer::Instance().GetLoader()) { + static repro::SymbolFileLoader symbol_file_loader(l); + std::pair<FileSpec, FileSpec> paths = symbol_file_loader.GetPaths(uuid); + return_module_spec.GetFileSpec() = paths.first; + return_module_spec.GetSymbolFileSpec() = paths.second; + return 1; + } + int items_found = 0; if (g_dlsym_DBGCopyFullDSYMURLForUUID == nullptr || @@ -69,9 +81,6 @@ return items_found; } - const UUID *uuid = module_spec.GetUUIDPtr(); - const ArchSpec *arch = module_spec.GetArchitecturePtr(); - if (uuid && uuid->IsValid()) { // Try and locate the dSYM file using DebugSymbols first llvm::ArrayRef<uint8_t> module_uuid = uuid->GetBytes(); @@ -247,6 +256,12 @@ } } + if (repro::Generator *g = repro::Reproducer::Instance().GetGenerator()) { + g->GetOrCreate<repro::SymbolFileProvider>().AddSymbolFile( + uuid, return_module_spec.GetFileSpec(), + return_module_spec.GetSymbolFileSpec()); + } + return items_found; } @@ -464,6 +479,25 @@ const UUID *uuid_ptr = module_spec.GetUUIDPtr(); const FileSpec *file_spec_ptr = module_spec.GetFileSpecPtr(); + if (repro::Loader *l = repro::Reproducer::Instance().GetLoader()) { + static repro::SymbolFileLoader symbol_file_loader(l); + std::pair<FileSpec, FileSpec> paths = symbol_file_loader.GetPaths(uuid_ptr); + if (paths.first) + module_spec.GetFileSpec() = paths.first; + if (paths.second) + module_spec.GetSymbolFileSpec() = paths.second; + return true; + } + + // Lambda to capture the state of module_spec before returning from this + // function. + auto RecordResult = [&]() { + if (repro::Generator *g = repro::Reproducer::Instance().GetGenerator()) { + g->GetOrCreate<repro::SymbolFileProvider>().AddSymbolFile( + uuid_ptr, module_spec.GetFileSpec(), module_spec.GetSymbolFileSpec()); + } + }; + // It's expensive to check for the DBGShellCommands defaults setting, only do // it once per lldb run and cache the result. static bool g_have_checked_for_dbgshell_command = false; @@ -489,6 +523,7 @@ // When g_dbgshell_command is NULL, the user has not enabled the use of an // external program to find the symbols, don't run it for them. if (!force_lookup && g_dbgshell_command == NULL) { + RecordResult(); return false; } @@ -613,8 +648,10 @@ ::CFDictionaryGetKeysAndValues(plist.get(), NULL, (const void **)&values[0]); if (num_values == 1) { - return GetModuleSpecInfoFromUUIDDictionary(values[0], - module_spec); + success = GetModuleSpecInfoFromUUIDDictionary(values[0], + module_spec); + RecordResult(); + return success; } else { for (CFIndex i = 0; i < num_values; ++i) { ModuleSpec curr_module_spec; @@ -623,6 +660,7 @@ if (module_spec.GetArchitecture().IsCompatibleMatch( curr_module_spec.GetArchitecture())) { module_spec = curr_module_spec; + RecordResult(); return true; } } @@ -644,5 +682,6 @@ } } } + RecordResult(); return success; } Index: lldb/source/Symbol/LocateSymbolFile.cpp =================================================================== --- lldb/source/Symbol/LocateSymbolFile.cpp +++ lldb/source/Symbol/LocateSymbolFile.cpp @@ -16,6 +16,7 @@ #include "lldb/Utility/DataBuffer.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/Reproducer.h" #include "lldb/Utility/StreamString.h" #include "lldb/Utility/Timer.h" #include "lldb/Utility/UUID.h" @@ -225,6 +226,7 @@ } else { dsym_module_spec.GetSymbolFileSpec() = symbol_fspec; } + return dsym_module_spec.GetSymbolFileSpec(); } @@ -248,6 +250,7 @@ } else { LocateMacOSXFilesUsingDebugSymbols(module_spec, result); } + return result; } Index: lldb/source/Commands/CommandObjectReproducer.cpp =================================================================== --- lldb/source/Commands/CommandObjectReproducer.cpp +++ lldb/source/Commands/CommandObjectReproducer.cpp @@ -27,6 +27,7 @@ enum ReproducerProvider { eReproducerProviderCommands, eReproducerProviderFiles, + eReproducerProviderSymbolFiles, eReproducerProviderGDB, eReproducerProviderProcessInfo, eReproducerProviderVersion, @@ -46,6 +47,11 @@ "files", "Files", }, + { + eReproducerProviderSymbolFiles, + "symbol-files", + "Symbol Files", + }, { eReproducerProviderGDB, "gdb", @@ -427,6 +433,29 @@ result.SetStatus(eReturnStatusSuccessFinishResult); return true; } + case eReproducerProviderSymbolFiles: { + Expected<std::string> symbol_files = + loader->LoadBuffer<SymbolFileProvider>(); + if (!symbol_files) { + SetError(result, symbol_files.takeError()); + return false; + } + + std::vector<SymbolFileProvider::Entry> entries; + llvm::yaml::Input yin(*symbol_files); + yin >> entries; + + for (const auto &entry : entries) { + result.AppendMessageWithFormat("- uuid: %s\n", + entry.uuid.c_str()); + result.AppendMessageWithFormat(" module path: %s\n", + entry.module_path.c_str()); + result.AppendMessageWithFormat(" symbol path: %s\n", + entry.symbol_path.c_str()); + } + result.SetStatus(eReturnStatusSuccessFinishResult); + return true; + } case eReproducerProviderVersion: { Expected<std::string> version = loader->LoadBuffer<VersionProvider>(); if (!version) { Index: lldb/include/lldb/Utility/ReproducerProvider.h =================================================================== --- lldb/include/lldb/Utility/ReproducerProvider.h +++ lldb/include/lldb/Utility/ReproducerProvider.h @@ -12,6 +12,7 @@ #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/ProcessInfo.h" #include "lldb/Utility/Reproducer.h" +#include "lldb/Utility/UUID.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Error.h" #include "llvm/Support/FileCollector.h" @@ -205,6 +206,41 @@ static char ID; }; +/// Provider for mapping UUIDs to symbol and executable files. +class SymbolFileProvider : public Provider<SymbolFileProvider> { +public: + SymbolFileProvider(const FileSpec &directory) + : Provider(directory), m_symbol_files() {} + + void AddSymbolFile(const UUID *uuid, const FileSpec &module_path, + const FileSpec &symbol_path); + void Keep() override; + + struct Entry { + Entry() = default; + Entry(std::string uuid) : uuid(std::move(uuid)) {} + Entry(std::string uuid, std::string module_path, std::string symbol_path) + : uuid(std::move(uuid)), module_path(std::move(module_path)), + symbol_path(std::move(symbol_path)) {} + + bool operator==(const Entry &rhs) const { return uuid == rhs.uuid; } + bool operator<(const Entry &rhs) const { return uuid < rhs.uuid; } + + std::string uuid; + std::string module_path; + std::string symbol_path; + }; + + struct Info { + static const char *name; + static const char *file; + }; + static char ID; + +private: + std::vector<Entry> m_symbol_files; +}; + /// The MultiProvider is a provider that hands out recorder which can be used /// to capture data for different instances of the same object. The recorders /// can be passed around or stored as an instance member. @@ -345,6 +381,16 @@ unsigned m_index = 0; }; +class SymbolFileLoader { +public: + SymbolFileLoader(Loader *loader); + std::pair<FileSpec, FileSpec> GetPaths(const UUID *uuid) const; + +private: + // Sorted list of UUID to path mappings. + std::vector<SymbolFileProvider::Entry> m_symbol_files; +}; + /// Helper to read directories written by the DirectoryProvider. template <typename T> llvm::Expected<std::string> GetDirectoryFrom(repro::Loader *loader) { @@ -357,4 +403,20 @@ } // namespace repro } // namespace lldb_private +LLVM_YAML_IS_SEQUENCE_VECTOR(lldb_private::repro::SymbolFileProvider::Entry) + +namespace llvm { +namespace yaml { +template <> +struct MappingTraits<lldb_private::repro::SymbolFileProvider::Entry> { + static void mapping(IO &io, + lldb_private::repro::SymbolFileProvider::Entry &entry) { + io.mapRequired("uuid", entry.uuid); + io.mapRequired("module-path", entry.module_path); + io.mapRequired("symbol-path", entry.symbol_path); + } +}; +} // namespace yaml +} // namespace llvm + #endif // LLDB_UTILITY_REPRODUCER_PROVIDER_H Index: lldb/include/lldb/Utility/Reproducer.h =================================================================== --- lldb/include/lldb/Utility/Reproducer.h +++ lldb/include/lldb/Utility/Reproducer.h @@ -22,6 +22,7 @@ #include <vector> namespace lldb_private { +class UUID; namespace repro { class Reproducer;
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits