aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/lldb/source/Utility/ReproducerProvider.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/lldb/source/Utility/ReproducerProvider.cpp')
-rw-r--r--contrib/llvm-project/lldb/source/Utility/ReproducerProvider.cpp221
1 files changed, 221 insertions, 0 deletions
diff --git a/contrib/llvm-project/lldb/source/Utility/ReproducerProvider.cpp b/contrib/llvm-project/lldb/source/Utility/ReproducerProvider.cpp
new file mode 100644
index 000000000000..ed016820db21
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Utility/ReproducerProvider.cpp
@@ -0,0 +1,221 @@
+//===-- Reproducer.cpp ----------------------------------------------------===//
+//
+// 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/ReproducerProvider.h"
+#include "lldb/Utility/ProcessInfo.h"
+#include "llvm/ADT/ScopeExit.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/WithColor.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace lldb_private;
+using namespace lldb_private::repro;
+using namespace llvm;
+using namespace llvm::yaml;
+
+llvm::Expected<std::unique_ptr<DataRecorder>>
+DataRecorder::Create(const FileSpec &filename) {
+ std::error_code ec;
+ auto recorder = std::make_unique<DataRecorder>(std::move(filename), ec);
+ if (ec)
+ return llvm::errorCodeToError(ec);
+ return std::move(recorder);
+}
+
+llvm::Expected<std::unique_ptr<YamlRecorder>>
+YamlRecorder::Create(const FileSpec &filename) {
+ std::error_code ec;
+ auto recorder = std::make_unique<YamlRecorder>(std::move(filename), ec);
+ if (ec)
+ return llvm::errorCodeToError(ec);
+ return std::move(recorder);
+}
+
+void VersionProvider::Keep() {
+ FileSpec file = GetRoot().CopyByAppendingPathComponent(Info::file);
+ std::error_code ec;
+ llvm::raw_fd_ostream os(file.GetPath(), ec, llvm::sys::fs::OF_Text);
+ if (ec)
+ return;
+ os << m_version << "\n";
+}
+
+FlushingFileCollector::FlushingFileCollector(llvm::StringRef files_path,
+ llvm::StringRef dirs_path,
+ std::error_code &ec) {
+ auto clear = llvm::make_scope_exit([this]() {
+ m_files_os.reset();
+ m_dirs_os.reset();
+ });
+ m_files_os.emplace(files_path, ec, llvm::sys::fs::OF_Append);
+ if (ec)
+ return;
+ m_dirs_os.emplace(dirs_path, ec, llvm::sys::fs::OF_Append);
+ if (ec)
+ return;
+ clear.release();
+}
+
+void FlushingFileCollector::addFileImpl(StringRef file) {
+ if (m_files_os) {
+ *m_files_os << file << '\0';
+ m_files_os->flush();
+ }
+}
+
+llvm::vfs::directory_iterator
+FlushingFileCollector::addDirectoryImpl(const Twine &dir,
+ IntrusiveRefCntPtr<vfs::FileSystem> vfs,
+ std::error_code &dir_ec) {
+ if (m_dirs_os) {
+ *m_dirs_os << dir << '\0';
+ m_dirs_os->flush();
+ }
+ return vfs->dir_begin(dir, dir_ec);
+}
+
+void FileProvider::RecordInterestingDirectory(const llvm::Twine &dir) {
+ if (m_collector)
+ m_collector->addFile(dir);
+}
+
+void FileProvider::RecordInterestingDirectoryRecursive(const llvm::Twine &dir) {
+ if (m_collector)
+ m_collector->addDirectory(dir);
+}
+
+llvm::Expected<std::unique_ptr<ProcessInfoRecorder>>
+ProcessInfoRecorder::Create(const FileSpec &filename) {
+ std::error_code ec;
+ auto recorder =
+ std::make_unique<ProcessInfoRecorder>(std::move(filename), ec);
+ if (ec)
+ return llvm::errorCodeToError(ec);
+ return std::move(recorder);
+}
+
+void ProcessInfoProvider::Keep() {
+ std::vector<std::string> files;
+ for (auto &recorder : m_process_info_recorders) {
+ recorder->Stop();
+ files.push_back(recorder->GetFilename().GetPath());
+ }
+
+ FileSpec file = GetRoot().CopyByAppendingPathComponent(Info::file);
+ std::error_code ec;
+ llvm::raw_fd_ostream os(file.GetPath(), ec, llvm::sys::fs::OF_Text);
+ if (ec)
+ return;
+ llvm::yaml::Output yout(os);
+ yout << files;
+}
+
+void ProcessInfoProvider::Discard() { m_process_info_recorders.clear(); }
+
+ProcessInfoRecorder *ProcessInfoProvider::GetNewProcessInfoRecorder() {
+ std::size_t i = m_process_info_recorders.size() + 1;
+ std::string filename = (llvm::Twine(Info::name) + llvm::Twine("-") +
+ llvm::Twine(i) + llvm::Twine(".yaml"))
+ .str();
+ auto recorder_or_error = ProcessInfoRecorder::Create(
+ GetRoot().CopyByAppendingPathComponent(filename));
+ if (!recorder_or_error) {
+ llvm::consumeError(recorder_or_error.takeError());
+ return nullptr;
+ }
+
+ m_process_info_recorders.push_back(std::move(*recorder_or_error));
+ return m_process_info_recorders.back().get();
+}
+
+void ProcessInfoRecorder::Record(const ProcessInstanceInfoList &process_infos) {
+ if (!m_record)
+ return;
+ llvm::yaml::Output yout(m_os);
+ yout << const_cast<ProcessInstanceInfoList &>(process_infos);
+ 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;
+char ProviderBase::ID = 0;
+char VersionProvider::ID = 0;
+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";
+const char *FileProvider::Info::name = "files";
+const char *VersionProvider::Info::file = "version.txt";
+const char *VersionProvider::Info::name = "version";
+const char *WorkingDirectoryProvider::Info::file = "cwd.txt";
+const char *WorkingDirectoryProvider::Info::name = "cwd";
+const char *HomeDirectoryProvider::Info::file = "home.txt";
+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";