summaryrefslogtreecommitdiff
path: root/lldb/source/Utility/ProcessInfo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Utility/ProcessInfo.cpp')
-rw-r--r--lldb/source/Utility/ProcessInfo.cpp102
1 files changed, 100 insertions, 2 deletions
diff --git a/lldb/source/Utility/ProcessInfo.cpp b/lldb/source/Utility/ProcessInfo.cpp
index b159e26419737..aae48d6a4872e 100644
--- a/lldb/source/Utility/ProcessInfo.cpp
+++ b/lldb/source/Utility/ProcessInfo.cpp
@@ -1,4 +1,4 @@
-//===-- ProcessInfo.cpp -----------------------------------------*- C++ -*-===//
+//===-- ProcessInfo.cpp ---------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -18,6 +18,7 @@
using namespace lldb;
using namespace lldb_private;
+using namespace lldb_private::repro;
ProcessInfo::ProcessInfo()
: m_executable(), m_arguments(), m_environment(), m_uid(UINT32_MAX),
@@ -75,7 +76,7 @@ void ProcessInfo::SetExecutableFile(const FileSpec &exe_file,
llvm::StringRef ProcessInfo::GetArg0() const { return m_arg0; }
-void ProcessInfo::SetArg0(llvm::StringRef arg) { m_arg0 = arg; }
+void ProcessInfo::SetArg0(llvm::StringRef arg) { m_arg0 = std::string(arg); }
void ProcessInfo::SetArguments(char const **argv,
bool first_arg_is_executable) {
@@ -331,3 +332,100 @@ void ProcessInstanceInfoMatch::Clear() {
m_name_match_type = NameMatch::Ignore;
m_match_all_users = false;
}
+
+void llvm::yaml::MappingTraits<ProcessInstanceInfo>::mapping(
+ IO &io, ProcessInstanceInfo &Info) {
+ io.mapRequired("executable", Info.m_executable);
+ io.mapRequired("arg0", Info.m_arg0);
+ io.mapRequired("args", Info.m_arguments);
+ io.mapRequired("arch", Info.m_arch);
+ io.mapRequired("uid", Info.m_uid);
+ io.mapRequired("gid", Info.m_gid);
+ io.mapRequired("pid", Info.m_pid);
+ io.mapRequired("effective-uid", Info.m_euid);
+ io.mapRequired("effective-gid", Info.m_egid);
+ io.mapRequired("parent-pid", Info.m_parent_pid);
+}
+
+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();
+}
+
+llvm::Optional<ProcessInstanceInfoList>
+repro::GetReplayProcessInstanceInfoList() {
+ static std::unique_ptr<repro::MultiLoader<repro::ProcessInfoProvider>>
+ loader = repro::MultiLoader<repro::ProcessInfoProvider>::Create(
+ repro::Reproducer::Instance().GetLoader());
+
+ if (!loader)
+ return {};
+
+ llvm::Optional<std::string> nextfile = loader->GetNextFile();
+ if (!nextfile)
+ return {};
+
+ auto error_or_file = llvm::MemoryBuffer::getFile(*nextfile);
+ if (std::error_code err = error_or_file.getError())
+ return {};
+
+ ProcessInstanceInfoList infos;
+ llvm::yaml::Input yin((*error_or_file)->getBuffer());
+ yin >> infos;
+
+ if (auto err = yin.error())
+ return {};
+
+ return infos;
+}
+
+char ProcessInfoProvider::ID = 0;
+const char *ProcessInfoProvider::Info::file = "process-info.yaml";
+const char *ProcessInfoProvider::Info::name = "process-info";