14 #include "llvm/Support/FileSystem.h"
15 #include "llvm/Support/Threading.h"
16 #include "llvm/Support/raw_ostream.h"
26 llvm::Optional<FileSpec> root) {
27 lldbassert(!InstanceImpl() &&
"Already initialized.");
28 InstanceImpl().emplace();
33 SmallString<128> repro_dir;
34 auto ec = sys::fs::createUniqueDirectory(
"reproducer", repro_dir);
36 return make_error<StringError>(
37 "unable to create unique reproducer directory", ec);
38 root.emplace(repro_dir);
40 auto ec = sys::fs::create_directory(root->GetPath());
42 return make_error<StringError>(
"unable to create reproducer directory",
45 return Instance().SetCapture(root);
51 return Error::success();
61 lldbassert(InstanceImpl() &&
"Already terminated.");
62 InstanceImpl().reset();
66 static Optional<Reproducer> g_reproducer;
71 std::lock_guard<std::mutex> guard(m_mutex);
73 return &(*m_generator);
78 std::lock_guard<std::mutex> guard(m_mutex);
85 std::lock_guard<std::mutex> guard(m_mutex);
87 return &(*m_generator);
92 std::lock_guard<std::mutex> guard(m_mutex);
99 std::lock_guard<std::mutex> guard(m_mutex);
101 if (root && m_loader)
102 return make_error<StringError>(
103 "cannot generate a reproducer when replay one",
104 inconvertibleErrorCode());
108 return Error::success();
111 m_generator.emplace(*root);
112 return Error::success();
116 if (
auto g = GetGenerator())
118 if (
auto l = GetLoader())
124 SmallString<128> path;
125 file_spec.
GetPath(path,
false);
126 llvm::sys::fs::make_absolute(path);
131 GetOrCreate<repro::WorkingDirectoryProvider>();
132 GetOrCreate<repro::HomeDirectoryProvider>();
147 std::pair<const void *, std::unique_ptr<ProviderBase>> key_value(
148 provider->DynamicClassID(), std::move(provider));
150 return e.first->getSecond().get();
159 provider.second->Keep();
170 provider.second->Discard();
186 auto strm = std::make_unique<raw_fd_ostream>(index.
GetPath(), EC,
187 sys::fs::OpenFlags::OF_None);
188 yaml::Output yout(*strm);
190 std::vector<std::string> files;
193 files.emplace_back(provider.second->GetFile());
200 : m_root(
MakeAbsolute(std::move(root))), m_loaded(false) {}
204 return llvm::Error::success();
208 auto error_or_file = MemoryBuffer::getFile(index.
GetPath());
209 if (
auto err = error_or_file.getError())
210 return make_error<StringError>(
"unable to load reproducer index", err);
212 yaml::Input yin((*error_or_file)->getBuffer());
214 if (
auto err = yin.error())
215 return make_error<StringError>(
"unable to read reproducer index", err);
223 return llvm::Error::success();
228 auto it = std::lower_bound(
m_files.begin(),
m_files.end(), file.str());
229 return (it !=
m_files.end()) && (*it == file);