JDevlieghere created this revision. JDevlieghere added reviewers: labath, arphaman, aprantl. JDevlieghere added a project: LLDB. Herald added subscribers: teemperor, abidh, dexonsmith, hiraditya, mgorny. JDevlieghere added a parent revision: D76671: [FileCollector] Add a method to add a whole directory and it contents..
The FileCollector in LLDB collects every files that's used during a debug session when capture is enabled. This ensures that the reproducer only contains the files necessary to reproduce. This approach is not a good fit for the dSYM bundle, which is a directory on disk, but should be treated as a single unit. On macOS LLDB have automatically find the matching dSYM for a binary by its UUID. Having a incomplete dSYM in a reproducer can break debugging even when reproducers are disabled. This patch adds a custom FileCollector to LLDB that is aware of dSYM. When it encounters a dSYM bundle, it iterates over everything inside it and adds it to the reproducer. While this might seem like overkill right now, having custom FileCollector is going to be inevitable as soon as we want to be smarter in what we include in the reproducer. For example, to keep its size small, we might want to skip system libraries in the future. Repository: rLLDB LLDB https://reviews.llvm.org/D76672 Files: lldb/include/lldb/Host/FileSystem.h lldb/include/lldb/Utility/FileCollector.h lldb/include/lldb/Utility/Reproducer.h lldb/source/Utility/CMakeLists.txt lldb/source/Utility/FileCollector.cpp lldb/test/Shell/Reproducer/TestDSYM.test llvm/include/llvm/Support/FileCollector.h llvm/lib/Support/FileCollector.cpp
Index: llvm/lib/Support/FileCollector.cpp =================================================================== --- llvm/lib/Support/FileCollector.cpp +++ llvm/lib/Support/FileCollector.cpp @@ -61,26 +61,25 @@ return true; } -void FileCollector::addFile(const Twine &file) { - std::lock_guard<std::mutex> lock(Mutex); - std::string FileStr = file.str(); - if (markAsSeen(FileStr)) - addFileImpl(FileStr); -} +void FileCollector::addFile(const Twine &file) { addFileImpl(file.str()); } void FileCollector::addDirectory(const Twine &dir) { assert(sys::fs::is_directory(dir)); std::error_code EC; sys::fs::recursive_directory_iterator Iter(dir, EC); sys::fs::recursive_directory_iterator End; - addFile(dir); // Add the directory in case it's empty. + addFileImpl(dir.str()); // Add the directory in case it's empty. for (; Iter != End && !EC; Iter.increment(EC)) { if (sys::fs::is_regular_file(Iter->path())) - addFile(Iter->path()); + addFileImpl(Iter->path()); } } void FileCollector::addFileImpl(StringRef SrcPath) { + std::lock_guard<std::mutex> lock(Mutex); + if (!markAsSeen(SrcPath)) + return; + // We need an absolute src path to append to the root. SmallString<256> AbsoluteSrc = SrcPath; sys::fs::make_absolute(AbsoluteSrc); Index: llvm/include/llvm/Support/FileCollector.h =================================================================== --- llvm/include/llvm/Support/FileCollector.h +++ llvm/include/llvm/Support/FileCollector.h @@ -45,7 +45,7 @@ createCollectorVFS(IntrusiveRefCntPtr<vfs::FileSystem> BaseFS, std::shared_ptr<FileCollector> Collector); -private: +protected: void addFileImpl(StringRef SrcPath); bool markAsSeen(StringRef Path) { @@ -60,7 +60,6 @@ VFSWriter.addFileMapping(VirtualPath, RealPath); } -protected: /// Synchronizes adding files. std::mutex Mutex; Index: lldb/test/Shell/Reproducer/TestDSYM.test =================================================================== --- /dev/null +++ lldb/test/Shell/Reproducer/TestDSYM.test @@ -0,0 +1,11 @@ +# REQUIRES: system-darwin +# Ensure that the reproducers captures the whole dSYM bundle. + +# RUN: rm -rf %t.repro +# RUN: %clang_host %S/Inputs/simple.c -g -o %t.out +# RUN: touch %t.out.dSYM/foo.bar + +# RUN: %lldb -x -b --capture --capture-path %t.repro %t.out -o 'b main' -o 'run' -o 'reproducer generate' + +# RUN: %lldb -b -o 'reproducer dump -p files -f %t.repro' | FileCheck %s --check-prefix FILES +# FILES: foo.bar Index: lldb/source/Utility/FileCollector.cpp =================================================================== --- /dev/null +++ lldb/source/Utility/FileCollector.cpp @@ -0,0 +1,43 @@ +//===-- FileCollector.cpp ---------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "lldb/Utility/FileCollector.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/Path.h" +#include "llvm/Support/Process.h" + +using namespace lldb_private; + +void FileCollector::addFile(const llvm::Twine &file) { + // Add dSYM bundle if applicable. + if (addDSYM(file)) + return; + + // Add the file. + addFileImpl(file.str()); +} + +bool FileCollector::addDSYM(const llvm::Twine &file) { + auto begin = llvm::sys::path::begin(file.str()); + auto end = llvm::sys::path::end(file.str()); + llvm::SmallString<128> bundle; + for (auto it = begin; it != end; ++it) { + if (llvm::sys::path::extension(*it).lower() == ".dsym") { + llvm::sys::path::append(bundle, begin, ++it); + break; + } + } + + // If bundle is empty the path is not a dSYM. + if (bundle.empty()) + return false; + + llvm::FileCollector::addDirectory(bundle.str()); + return true; +} Index: lldb/source/Utility/CMakeLists.txt =================================================================== --- lldb/source/Utility/CMakeLists.txt +++ lldb/source/Utility/CMakeLists.txt @@ -24,6 +24,7 @@ DataExtractor.cpp Environment.cpp Event.cpp + FileCollector.cpp FileSpec.cpp GDBRemote.cpp IOObject.cpp Index: lldb/include/lldb/Utility/Reproducer.h =================================================================== --- lldb/include/lldb/Utility/Reproducer.h +++ lldb/include/lldb/Utility/Reproducer.h @@ -9,10 +9,10 @@ #ifndef LLDB_UTILITY_REPRODUCER_H #define LLDB_UTILITY_REPRODUCER_H +#include "lldb/Utility/FileCollector.h" #include "lldb/Utility/FileSpec.h" #include "llvm/ADT/DenseMap.h" #include "llvm/Support/Error.h" -#include "llvm/Support/FileCollector.h" #include "llvm/Support/YAMLTraits.h" #include <mutex> @@ -90,13 +90,11 @@ FileProvider(const FileSpec &directory) : Provider(directory), - m_collector(std::make_shared<llvm::FileCollector>( + m_collector(std::make_shared<FileCollector>( directory.CopyByAppendingPathComponent("root").GetPath(), directory.GetPath())) {} - std::shared_ptr<llvm::FileCollector> GetFileCollector() { - return m_collector; - } + std::shared_ptr<FileCollector> GetFileCollector() { return m_collector; } void Keep() override { auto mapping = GetRoot().CopyByAppendingPathComponent(Info::file); @@ -109,7 +107,7 @@ static char ID; private: - std::shared_ptr<llvm::FileCollector> m_collector; + std::shared_ptr<FileCollector> m_collector; }; /// Provider for the LLDB version number. Index: lldb/include/lldb/Utility/FileCollector.h =================================================================== --- /dev/null +++ lldb/include/lldb/Utility/FileCollector.h @@ -0,0 +1,31 @@ +//===-- FileCollector.h -----------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDD_SUPPORT_FILE_COLLECTOR_H +#define LLDD_SUPPORT_FILE_COLLECTOR_H + +#include "llvm/Support/FileCollector.h" + +#include <mutex> + +namespace lldb_private { + +class FileCollector : public llvm::FileCollector { +public: + FileCollector(std::string Root, std::string OverlayRoot) + : llvm::FileCollector(Root, OverlayRoot) {} + + void addFile(const llvm::Twine &file) override; + +private: + bool addDSYM(const llvm::Twine &file); +}; + +} // namespace lldb_private + +#endif // LLVM_SUPPORT_FILE_COLLECTOR_H Index: lldb/include/lldb/Host/FileSystem.h =================================================================== --- lldb/include/lldb/Host/FileSystem.h +++ lldb/include/lldb/Host/FileSystem.h @@ -11,12 +11,12 @@ #include "lldb/Host/File.h" #include "lldb/Utility/DataBufferLLVM.h" +#include "lldb/Utility/FileCollector.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/Status.h" #include "llvm/ADT/Optional.h" #include "llvm/Support/Chrono.h" -#include "llvm/Support/FileCollector.h" #include "llvm/Support/VirtualFileSystem.h" #include "lldb/lldb-types.h" @@ -34,7 +34,7 @@ FileSystem() : m_fs(llvm::vfs::getRealFileSystem()), m_collector(nullptr), m_mapped(false) {} - FileSystem(std::shared_ptr<llvm::FileCollector> collector) + FileSystem(std::shared_ptr<FileCollector> collector) : m_fs(llvm::vfs::getRealFileSystem()), m_collector(collector), m_mapped(false) {} FileSystem(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> fs, @@ -47,7 +47,7 @@ static FileSystem &Instance(); static void Initialize(); - static void Initialize(std::shared_ptr<llvm::FileCollector> collector); + static void Initialize(std::shared_ptr<FileCollector> collector); static llvm::Error Initialize(const FileSpec &mapping); static void Initialize(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> fs); static void Terminate(); @@ -190,7 +190,7 @@ void AddFile(const llvm::Twine &file); static llvm::Optional<FileSystem> &InstanceImpl(); llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> m_fs; - std::shared_ptr<llvm::FileCollector> m_collector; + std::shared_ptr<FileCollector> m_collector; bool m_mapped; }; } // namespace lldb_private
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits