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 collector) + FileSystem(std::shared_ptr collector) : m_fs(llvm::vfs::getRealFileSystem()), m_collector(collector), m_mapped(false) {} FileSystem(llvm::IntrusiveRefCntPtr fs, @@ -47,7 +47,7 @@ static FileSystem &Instance(); static void Initialize(); - static void Initialize(std::shared_ptr collector); + static void Initialize(std::shared_ptr collector); static llvm::Error Initialize(const FileSpec &mapping); static void Initialize(llvm::IntrusiveRefCntPtr fs); static void Terminate(); @@ -190,7 +190,7 @@ void AddFile(const llvm::Twine &file); static llvm::Optional &InstanceImpl(); llvm::IntrusiveRefCntPtr m_fs; - std::shared_ptr m_collector; + std::shared_ptr m_collector; bool m_mapped; }; } // namespace lldb_private 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 + +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/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 @@ -90,13 +90,11 @@ FileProvider(const FileSpec &directory) : Provider(directory), - m_collector(std::make_shared( + m_collector(std::make_shared( directory.CopyByAppendingPathComponent("root").GetPath(), directory.GetPath())) {} - std::shared_ptr GetFileCollector() { - return m_collector; - } + std::shared_ptr GetFileCollector() { return m_collector; } void Keep() override { auto mapping = GetRoot().CopyByAppendingPathComponent(Info::file); @@ -109,7 +107,7 @@ static char ID; private: - std::shared_ptr m_collector; + std::shared_ptr m_collector; }; /// Provider for the LLDB version number. 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/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/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: llvm/include/llvm/Support/FileCollector.h =================================================================== --- llvm/include/llvm/Support/FileCollector.h +++ llvm/include/llvm/Support/FileCollector.h @@ -45,7 +45,7 @@ createCollectorVFS(IntrusiveRefCntPtr BaseFS, std::shared_ptr 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: 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 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 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);