Index: lldb/trunk/include/lldb/Utility/FileCollector.h =================================================================== --- lldb/trunk/include/lldb/Utility/FileCollector.h +++ lldb/trunk/include/lldb/Utility/FileCollector.h @@ -25,7 +25,7 @@ /// the VFS. class FileCollector { public: - FileCollector(const FileSpec &root); + FileCollector(const FileSpec &root, const FileSpec &overlay); void AddFile(const llvm::Twine &file); void AddFile(const FileSpec &file) { return AddFile(file.GetPath()); } @@ -59,6 +59,9 @@ /// The root directory where files are copied. FileSpec m_root; + /// The root directory where the VFS overlay lives. + FileSpec m_overlay_root; + /// Tracks already seen files so they can be skipped. llvm::StringSet<> m_seen; Index: lldb/trunk/include/lldb/Utility/Reproducer.h =================================================================== --- lldb/trunk/include/lldb/Utility/Reproducer.h +++ lldb/trunk/include/lldb/Utility/Reproducer.h @@ -91,7 +91,8 @@ FileProvider(const FileSpec &directory) : Provider(directory), - m_collector(directory.CopyByAppendingPathComponent("root")) {} + m_collector(directory.CopyByAppendingPathComponent("root"), directory) { + } FileCollector &GetFileCollector() { return m_collector; } @@ -132,8 +133,8 @@ class DataRecorder { public: DataRecorder(const FileSpec &filename, std::error_code &ec) - : m_filename(std::move(filename)), - m_os(m_filename.GetPath(), ec, llvm::sys::fs::F_Text), m_record(true) {} + : m_filename(filename.GetFilename().GetStringRef()), + m_os(filename.GetPath(), ec, llvm::sys::fs::F_Text), m_record(true) {} static llvm::Expected> Create(const FileSpec &filename); Index: lldb/trunk/lit/Reproducer/TestReuseDirectory.test =================================================================== --- lldb/trunk/lit/Reproducer/TestReuseDirectory.test +++ lldb/trunk/lit/Reproducer/TestReuseDirectory.test @@ -8,3 +8,10 @@ # RUN: %lldb -x -b -s %S/Inputs/GDBRemoteCapture.in --capture --capture-path %t.repro %t.out | FileCheck %S/TestGDBRemoteRepro.test --check-prefix CHECK --check-prefix CAPTURE # RUN: %lldb -x -b -s %S/Inputs/GDBRemoteCapture.in --capture --capture-path %t.repro %t.out | FileCheck %S/TestGDBRemoteRepro.test --check-prefix CHECK --check-prefix CAPTURE # RUN: %lldb --replay %t.repro | FileCheck %S/TestGDBRemoteRepro.test --check-prefix CHECK --check-prefix REPLAY + +# Test that we can replay from a different location, i.e. that the reproducer +# is relocatable. + +# RUN: rm -rf %t.repro_moved +# RUN: mv %t.repro %t.repro_moved +# RUN: %lldb --replay %t.repro_moved | FileCheck %S/TestGDBRemoteRepro.test --check-prefix CHECK --check-prefix REPLAY Index: lldb/trunk/source/API/SBDebugger.cpp =================================================================== --- lldb/trunk/source/API/SBDebugger.cpp +++ lldb/trunk/source/API/SBDebugger.cpp @@ -82,6 +82,12 @@ if (auto err = yin.error()) return {}; + for (auto &file : files) { + FileSpec absolute_path = + loader->GetRoot().CopyByAppendingPathComponent(file); + file = absolute_path.GetPath(); + } + return llvm::make_unique(std::move(files)); } Index: lldb/trunk/source/Host/common/FileSystem.cpp =================================================================== --- lldb/trunk/source/Host/common/FileSystem.cpp +++ lldb/trunk/source/Host/common/FileSystem.cpp @@ -63,8 +63,9 @@ if (!buffer) return llvm::errorCodeToError(buffer.getError()); - InstanceImpl().emplace( - llvm::vfs::getVFSFromYAML(std::move(buffer.get()), nullptr, ""), true); + InstanceImpl().emplace(llvm::vfs::getVFSFromYAML(std::move(buffer.get()), + nullptr, mapping.GetPath()), + true); return llvm::Error::success(); } Index: lldb/trunk/source/Utility/FileCollector.cpp =================================================================== --- lldb/trunk/source/Utility/FileCollector.cpp +++ lldb/trunk/source/Utility/FileCollector.cpp @@ -33,7 +33,8 @@ return true; } -FileCollector::FileCollector(const FileSpec &root) : m_root(root) { +FileCollector::FileCollector(const FileSpec &root, const FileSpec &overlay_root) + : m_root(root), m_overlay_root(overlay_root) { sys::fs::create_directories(m_root.GetPath(), true); } @@ -133,7 +134,9 @@ std::error_code FileCollector::WriteMapping(const FileSpec &mapping_file) { std::lock_guard lock(m_mutex); - const std::string root = m_root.GetPath(); + llvm::StringRef root = m_overlay_root.GetPath(); + + m_vfs_writer.setOverlayDir(root); m_vfs_writer.setCaseSensitivity(IsCaseSensitivePath(root)); m_vfs_writer.setUseExternalNames(false); Index: lldb/trunk/unittests/Utility/FileCollectorTest.cpp =================================================================== --- lldb/trunk/unittests/Utility/FileCollectorTest.cpp +++ lldb/trunk/unittests/Utility/FileCollectorTest.cpp @@ -105,7 +105,7 @@ TEST(FileCollectorTest, AddFile) { ScopedDir root("add_file_root", true); FileSpec root_fs(root.Path); - TestingFileCollector file_collector(root_fs); + TestingFileCollector file_collector(root_fs, root_fs); file_collector.AddFile(FileSpec("/path/to/a")); file_collector.AddFile(FileSpec("/path/to/b")); @@ -132,7 +132,7 @@ // Create file collector and add files. ScopedDir root("copy_files_root", true); FileSpec root_fs(root.Path); - TestingFileCollector file_collector(root_fs); + TestingFileCollector file_collector(root_fs, root_fs); file_collector.AddFile(a.Path); file_collector.AddFile(b.Path); file_collector.AddFile(c.Path); @@ -174,7 +174,7 @@ // Root where files are copied to. ScopedDir reproducer_root("reproducer_root", true); FileSpec root_fs(reproducer_root.Path); - TestingFileCollector file_collector(root_fs); + TestingFileCollector file_collector(root_fs, root_fs); // Add all the files to the collector. file_collector.AddFile(a.Path);