summaryrefslogtreecommitdiff
path: root/lldb/source/Commands/CommandObjectReproducer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Commands/CommandObjectReproducer.cpp')
-rw-r--r--lldb/source/Commands/CommandObjectReproducer.cpp99
1 files changed, 81 insertions, 18 deletions
diff --git a/lldb/source/Commands/CommandObjectReproducer.cpp b/lldb/source/Commands/CommandObjectReproducer.cpp
index d15f622314d9..104130b70b2b 100644
--- a/lldb/source/Commands/CommandObjectReproducer.cpp
+++ b/lldb/source/Commands/CommandObjectReproducer.cpp
@@ -1,4 +1,4 @@
-//===-- CommandObjectReproducer.cpp -----------------------------*- C++ -*-===//
+//===-- CommandObjectReproducer.cpp ---------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -8,13 +8,14 @@
#include "CommandObjectReproducer.h"
+#include "lldb/Host/HostInfo.h"
#include "lldb/Host/OptionParser.h"
-#include "lldb/Utility/GDBRemote.h"
-#include "lldb/Utility/Reproducer.h"
-
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/OptionArgParser.h"
+#include "lldb/Utility/GDBRemote.h"
+#include "lldb/Utility/ProcessInfo.h"
+#include "lldb/Utility/Reproducer.h"
#include <csignal>
@@ -27,6 +28,7 @@ enum ReproducerProvider {
eReproducerProviderCommands,
eReproducerProviderFiles,
eReproducerProviderGDB,
+ eReproducerProviderProcessInfo,
eReproducerProviderVersion,
eReproducerProviderWorkingDirectory,
eReproducerProviderNone
@@ -49,6 +51,11 @@ static constexpr OptionEnumValueElement g_reproducer_provider_type[] = {
"GDB Remote Packets",
},
{
+ eReproducerProviderProcessInfo,
+ "processes",
+ "Process Info",
+ },
+ {
eReproducerProviderVersion,
"version",
"Version",
@@ -97,6 +104,24 @@ static constexpr OptionEnumValues ReproducerSignalType() {
#define LLDB_OPTIONS_reproducer_xcrash
#include "CommandOptions.inc"
+template <typename T>
+llvm::Expected<T> static ReadFromYAML(StringRef filename) {
+ auto error_or_file = MemoryBuffer::getFile(filename);
+ if (auto err = error_or_file.getError()) {
+ return errorCodeToError(err);
+ }
+
+ T t;
+ yaml::Input yin((*error_or_file)->getBuffer());
+ yin >> t;
+
+ if (auto err = yin.error()) {
+ return errorCodeToError(err);
+ }
+
+ return t;
+}
+
class CommandObjectReproducerGenerate : public CommandObjectParsed {
public:
CommandObjectReproducerGenerate(CommandInterpreter &interpreter)
@@ -258,6 +283,18 @@ protected:
result.GetOutputStream() << "Reproducer is off.\n";
}
+ if (r.IsCapturing() || r.IsReplaying()) {
+ result.GetOutputStream()
+ << "Path: " << r.GetReproducerPath().GetPath() << '\n';
+ }
+
+ // Auto generate is hidden unless enabled because this is mostly for
+ // development and testing.
+ if (Generator *g = r.GetGenerator()) {
+ if (g->IsAutoGenerate())
+ result.GetOutputStream() << "Auto generate: on\n";
+ }
+
result.SetStatus(eReturnStatusSuccessFinishResult);
return result.Succeeded();
}
@@ -410,8 +447,8 @@ protected:
repro::MultiLoader<repro::CommandProvider>::Create(loader);
if (!multi_loader) {
SetError(result,
- make_error<StringError>(llvm::inconvertibleErrorCode(),
- "Unable to create command loader."));
+ make_error<StringError>("Unable to create command loader.",
+ llvm::inconvertibleErrorCode()));
return false;
}
@@ -436,26 +473,52 @@ protected:
std::unique_ptr<repro::MultiLoader<repro::GDBRemoteProvider>>
multi_loader =
repro::MultiLoader<repro::GDBRemoteProvider>::Create(loader);
+
+ if (!multi_loader) {
+ SetError(result,
+ make_error<StringError>("Unable to create GDB loader.",
+ llvm::inconvertibleErrorCode()));
+ return false;
+ }
+
llvm::Optional<std::string> gdb_file;
while ((gdb_file = multi_loader->GetNextFile())) {
- auto error_or_file = MemoryBuffer::getFile(*gdb_file);
- if (auto err = error_or_file.getError()) {
- SetError(result, errorCodeToError(err));
+ if (llvm::Expected<std::vector<GDBRemotePacket>> packets =
+ ReadFromYAML<std::vector<GDBRemotePacket>>(*gdb_file)) {
+ for (GDBRemotePacket &packet : *packets) {
+ packet.Dump(result.GetOutputStream());
+ }
+ } else {
+ SetError(result, packets.takeError());
return false;
}
+ }
+
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return true;
+ }
+ case eReproducerProviderProcessInfo: {
+ std::unique_ptr<repro::MultiLoader<repro::ProcessInfoProvider>>
+ multi_loader =
+ repro::MultiLoader<repro::ProcessInfoProvider>::Create(loader);
- std::vector<GDBRemotePacket> packets;
- yaml::Input yin((*error_or_file)->getBuffer());
- yin >> packets;
+ if (!multi_loader) {
+ SetError(result, make_error<StringError>(
+ llvm::inconvertibleErrorCode(),
+ "Unable to create process info loader."));
+ return false;
+ }
- if (auto err = yin.error()) {
- SetError(result, errorCodeToError(err));
+ llvm::Optional<std::string> process_file;
+ while ((process_file = multi_loader->GetNextFile())) {
+ if (llvm::Expected<ProcessInstanceInfoList> infos =
+ ReadFromYAML<ProcessInstanceInfoList>(*process_file)) {
+ for (ProcessInstanceInfo info : *infos)
+ info.Dump(result.GetOutputStream(), HostInfo::GetUserIDResolver());
+ } else {
+ SetError(result, infos.takeError());
return false;
}
-
- for (GDBRemotePacket &packet : packets) {
- packet.Dump(result.GetOutputStream());
- }
}
result.SetStatus(eReturnStatusSuccessFinishResult);