[Lldb-commits] [lldb] c9e0b35 - Temporarily revert [lldb] e81268d - [lldb/Reproducers] Support multiple GDB remotes
Eric Christopher via lldb-commits
lldb-commits at lists.llvm.org
Tue Dec 10 12:31:00 PST 2019
Author: Eric Christopher
Date: 2019-12-10T12:29:46-08:00
New Revision: c9e0b354e2749ce7ab553974692cb35c8651a869
URL: https://github.com/llvm/llvm-project/commit/c9e0b354e2749ce7ab553974692cb35c8651a869
DIFF: https://github.com/llvm/llvm-project/commit/c9e0b354e2749ce7ab553974692cb35c8651a869.diff
LOG: Temporarily revert [lldb] e81268d - [lldb/Reproducers] Support multiple GDB remotes
This was causing a crash in opt+assert builds on linux and a follow-up
message was posted.
This reverts commit e81268d03e73aef4f9c7bd8ece8ad02f5b017dcf
Added:
Modified:
lldb/include/lldb/Utility/GDBRemote.h
lldb/include/lldb/Utility/Reproducer.h
lldb/source/API/SBDebugger.cpp
lldb/source/Commands/CommandObjectReproducer.cpp
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h
lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
lldb/source/Utility/GDBRemote.cpp
lldb/source/Utility/Reproducer.cpp
Removed:
lldb/test/Shell/Reproducer/Inputs/MultipleTargetsCapture.in
lldb/test/Shell/Reproducer/TestMultipleTargets.test
################################################################################
diff --git a/lldb/include/lldb/Utility/GDBRemote.h b/lldb/include/lldb/Utility/GDBRemote.h
index 21b2c8cd73cd..b4adeb368524 100644
--- a/lldb/include/lldb/Utility/GDBRemote.h
+++ b/lldb/include/lldb/Utility/GDBRemote.h
@@ -9,8 +9,6 @@
#ifndef liblldb_GDBRemote_h_
#define liblldb_GDBRemote_h_
-#include "lldb/Utility/FileSpec.h"
-#include "lldb/Utility/Reproducer.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/lldb-enumerations.h"
#include "lldb/lldb-public.h"
@@ -71,6 +69,7 @@ struct GDBRemotePacket {
std::string data;
};
+ void Serialize(llvm::raw_ostream &strm) const;
void Dump(Stream &strm) const;
BinaryData packet;
@@ -83,46 +82,6 @@ struct GDBRemotePacket {
llvm::StringRef GetTypeStr() const;
};
-namespace repro {
-class PacketRecorder : public AbstractRecorder {
-public:
- PacketRecorder(const FileSpec &filename, std::error_code &ec)
- : AbstractRecorder(filename, ec) {}
-
- static llvm::Expected<std::unique_ptr<PacketRecorder>>
- Create(const FileSpec &filename);
-
- void Record(const GDBRemotePacket &packet);
-};
-
-class GDBRemoteProvider : public repro::Provider<GDBRemoteProvider> {
-public:
- struct Info {
- static const char *name;
- static const char *file;
- };
-
- GDBRemoteProvider(const FileSpec &directory) : Provider(directory) {}
-
- llvm::raw_ostream *GetHistoryStream();
- PacketRecorder *GetNewPacketRecorder();
-
- void SetCallback(std::function<void()> callback) {
- m_callback = std::move(callback);
- }
-
- void Keep() override;
- void Discard() override;
-
- static char ID;
-
-private:
- std::function<void()> m_callback;
- std::unique_ptr<llvm::raw_fd_ostream> m_stream_up;
- std::vector<std::unique_ptr<PacketRecorder>> m_packet_recorders;
-};
-
-} // namespace repro
} // namespace lldb_private
LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(lldb_private::GDBRemotePacket)
diff --git a/lldb/include/lldb/Utility/Reproducer.h b/lldb/include/lldb/Utility/Reproducer.h
index 0d23fe8571ff..ddb1f45a7219 100644
--- a/lldb/include/lldb/Utility/Reproducer.h
+++ b/lldb/include/lldb/Utility/Reproducer.h
@@ -153,32 +153,11 @@ class WorkingDirectoryProvider : public Provider<WorkingDirectoryProvider> {
static char ID;
};
-class AbstractRecorder {
-protected:
- AbstractRecorder(const FileSpec &filename, std::error_code &ec)
- : m_filename(filename.GetFilename().GetStringRef()),
- m_os(filename.GetPath(), ec, llvm::sys::fs::OF_Text), m_record(true) {}
-
-public:
- const FileSpec &GetFilename() { return m_filename; }
-
- void Stop() {
- assert(m_record);
- m_record = false;
- }
-
-private:
- FileSpec m_filename;
-
-protected:
- llvm::raw_fd_ostream m_os;
- bool m_record;
-};
-
-class DataRecorder : public AbstractRecorder {
+class DataRecorder {
public:
DataRecorder(const FileSpec &filename, std::error_code &ec)
- : AbstractRecorder(filename, ec) {}
+ : m_filename(filename.GetFilename().GetStringRef()),
+ m_os(filename.GetPath(), ec, llvm::sys::fs::OF_Text), m_record(true) {}
static llvm::Expected<std::unique_ptr<DataRecorder>>
Create(const FileSpec &filename);
@@ -191,6 +170,18 @@ class DataRecorder : public AbstractRecorder {
m_os << '\n';
m_os.flush();
}
+
+ const FileSpec &GetFilename() { return m_filename; }
+
+ void Stop() {
+ assert(m_record);
+ m_record = false;
+ }
+
+private:
+ FileSpec m_filename;
+ llvm::raw_fd_ostream m_os;
+ bool m_record;
};
class CommandProvider : public Provider<CommandProvider> {
@@ -213,6 +204,32 @@ class CommandProvider : public Provider<CommandProvider> {
std::vector<std::unique_ptr<DataRecorder>> m_data_recorders;
};
+class ProcessGDBRemoteProvider
+ : public repro::Provider<ProcessGDBRemoteProvider> {
+public:
+ struct Info {
+ static const char *name;
+ static const char *file;
+ };
+
+ ProcessGDBRemoteProvider(const FileSpec &directory) : Provider(directory) {}
+
+ llvm::raw_ostream *GetHistoryStream();
+
+ void SetCallback(std::function<void()> callback) {
+ m_callback = std::move(callback);
+ }
+
+ void Keep() override { m_callback(); }
+ void Discard() override { m_callback(); }
+
+ static char ID;
+
+private:
+ std::function<void()> m_callback;
+ std::unique_ptr<llvm::raw_fd_ostream> m_stream_up;
+};
+
/// The generator is responsible for the logic needed to generate a
/// reproducer. For doing so it relies on providers, who serialize data that
/// is necessary for reproducing a failure.
@@ -342,43 +359,13 @@ class Reproducer {
mutable std::mutex m_mutex;
};
-template <typename T> class MultiLoader {
+/// Helper class for replaying commands through the reproducer.
+class CommandLoader {
public:
- MultiLoader(std::vector<std::string> files) : m_files(files) {}
-
- static std::unique_ptr<MultiLoader> Create(Loader *loader) {
- if (!loader)
- return {};
-
- FileSpec file = loader->GetFile<typename T::Info>();
- if (!file)
- return {};
-
- auto error_or_file = llvm::MemoryBuffer::getFile(file.GetPath());
- if (auto err = error_or_file.getError())
- return {};
+ CommandLoader(std::vector<std::string> files) : m_files(files) {}
- std::vector<std::string> files;
- llvm::yaml::Input yin((*error_or_file)->getBuffer());
- yin >> files;
-
- if (auto err = yin.error())
- return {};
-
- for (auto &file : files) {
- FileSpec absolute_path =
- loader->GetRoot().CopyByAppendingPathComponent(file);
- file = absolute_path.GetPath();
- }
-
- return std::make_unique<MultiLoader<T>>(std::move(files));
- }
-
- llvm::Optional<std::string> GetNextFile() {
- if (m_index >= m_files.size())
- return {};
- return m_files[m_index++];
- }
+ static std::unique_ptr<CommandLoader> Create(Loader *loader);
+ llvm::Optional<std::string> GetNextFile();
private:
std::vector<std::string> m_files;
diff --git a/lldb/source/API/SBDebugger.cpp b/lldb/source/API/SBDebugger.cpp
index d9dd7d423ae0..52d0fd36c1a2 100644
--- a/lldb/source/API/SBDebugger.cpp
+++ b/lldb/source/API/SBDebugger.cpp
@@ -316,9 +316,8 @@ SBError SBDebugger::SetInputFile(SBFile file) {
FileSP file_sp = file.m_opaque_sp;
- static std::unique_ptr<repro::MultiLoader<repro::CommandProvider>> loader =
- repro::MultiLoader<repro::CommandProvider>::Create(
- repro::Reproducer::Instance().GetLoader());
+ static std::unique_ptr<repro::CommandLoader> loader =
+ repro::CommandLoader::Create(repro::Reproducer::Instance().GetLoader());
if (loader) {
llvm::Optional<std::string> nextfile = loader->GetNextFile();
FILE *fh = nextfile ? FileSystem::Instance().Fopen(nextfile->c_str(), "r")
diff --git a/lldb/source/Commands/CommandObjectReproducer.cpp b/lldb/source/Commands/CommandObjectReproducer.cpp
index 0f05c564a0d1..a4c69db492da 100644
--- a/lldb/source/Commands/CommandObjectReproducer.cpp
+++ b/lldb/source/Commands/CommandObjectReproducer.cpp
@@ -407,9 +407,10 @@ class CommandObjectReproducerDump : public CommandObjectParsed {
return true;
}
case eReproducerProviderCommands: {
- std::unique_ptr<repro::MultiLoader<repro::CommandProvider>> multi_loader =
- repro::MultiLoader<repro::CommandProvider>::Create(loader);
- if (!multi_loader) {
+ // Create a new command loader.
+ std::unique_ptr<repro::CommandLoader> command_loader =
+ repro::CommandLoader::Create(loader);
+ if (!command_loader) {
SetError(result,
make_error<StringError>(llvm::inconvertibleErrorCode(),
"Unable to create command loader."));
@@ -417,8 +418,9 @@ class CommandObjectReproducerDump : public CommandObjectParsed {
}
// Iterate over the command files and dump them.
- llvm::Optional<std::string> command_file;
- while ((command_file = multi_loader->GetNextFile())) {
+ while (true) {
+ llvm::Optional<std::string> command_file =
+ command_loader->GetNextFile();
if (!command_file)
break;
@@ -434,29 +436,24 @@ class CommandObjectReproducerDump : public CommandObjectParsed {
return true;
}
case eReproducerProviderGDB: {
- std::unique_ptr<repro::MultiLoader<repro::GDBRemoteProvider>>
- multi_loader =
- repro::MultiLoader<repro::GDBRemoteProvider>::Create(loader);
- 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));
- return false;
- }
+ FileSpec gdb_file = loader->GetFile<ProcessGDBRemoteProvider::Info>();
+ auto error_or_file = MemoryBuffer::getFile(gdb_file.GetPath());
+ if (auto err = error_or_file.getError()) {
+ SetError(result, errorCodeToError(err));
+ return false;
+ }
- std::vector<GDBRemotePacket> packets;
- yaml::Input yin((*error_or_file)->getBuffer());
- yin >> packets;
+ std::vector<GDBRemotePacket> packets;
+ yaml::Input yin((*error_or_file)->getBuffer());
+ yin >> packets;
- if (auto err = yin.error()) {
- SetError(result, errorCodeToError(err));
- return false;
- }
+ if (auto err = yin.error()) {
+ SetError(result, errorCodeToError(err));
+ return false;
+ }
- for (GDBRemotePacket &packet : packets) {
- packet.Dump(result.GetOutputStream());
- }
+ for (GDBRemotePacket &packet : packets) {
+ packet.Dump(result.GetOutputStream());
}
result.SetStatus(eReturnStatusSuccessFinishResult);
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
index 0a98f6a15d75..144ae103faa4 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
@@ -31,7 +31,6 @@
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/RegularExpression.h"
-#include "lldb/Utility/Reproducer.h"
#include "lldb/Utility/StreamString.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/ScopedPrinter.h"
@@ -1244,9 +1243,8 @@ Status GDBRemoteCommunication::StartDebugserverProcess(
void GDBRemoteCommunication::DumpHistory(Stream &strm) { m_history.Dump(strm); }
-void GDBRemoteCommunication::SetPacketRecorder(
- repro::PacketRecorder *recorder) {
- m_history.SetRecorder(recorder);
+void GDBRemoteCommunication::SetHistoryStream(llvm::raw_ostream *strm) {
+ m_history.SetStream(strm);
}
llvm::Error
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
index 0b670018bd69..bb777a5c26a7 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
@@ -27,9 +27,6 @@
#include "lldb/lldb-public.h"
namespace lldb_private {
-namespace repro {
-class PacketRecorder;
-}
namespace process_gdb_remote {
enum GDBStoppointType {
@@ -136,8 +133,7 @@ class GDBRemoteCommunication : public Communication {
// fork/exec to avoid having to connect/accept
void DumpHistory(Stream &strm);
-
- void SetPacketRecorder(repro::PacketRecorder *recorder);
+ void SetHistoryStream(llvm::raw_ostream *strm);
static llvm::Error ConnectLocally(GDBRemoteCommunication &client,
GDBRemoteCommunication &server);
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp
index 9e5646985f87..d2cc32f63f20 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp
@@ -40,8 +40,8 @@ void GDBRemoteCommunicationHistory::AddPacket(char packet_char,
m_packets[idx].bytes_transmitted = bytes_transmitted;
m_packets[idx].packet_idx = m_total_packet_count;
m_packets[idx].tid = llvm::get_threadid();
- if (m_recorder)
- m_recorder->Record(m_packets[idx]);
+ if (m_stream)
+ m_packets[idx].Serialize(*m_stream);
}
void GDBRemoteCommunicationHistory::AddPacket(const std::string &src,
@@ -58,8 +58,8 @@ void GDBRemoteCommunicationHistory::AddPacket(const std::string &src,
m_packets[idx].bytes_transmitted = bytes_transmitted;
m_packets[idx].packet_idx = m_total_packet_count;
m_packets[idx].tid = llvm::get_threadid();
- if (m_recorder)
- m_recorder->Record(m_packets[idx]);
+ if (m_stream)
+ m_packets[idx].Serialize(*m_stream);
}
void GDBRemoteCommunicationHistory::Dump(Stream &strm) const {
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h
index ee265ef86dff..c006fbd34a4b 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h
@@ -13,15 +13,11 @@
#include <vector>
#include "lldb/Utility/GDBRemote.h"
-#include "lldb/Utility/Reproducer.h"
#include "lldb/lldb-public.h"
#include "llvm/Support/YAMLTraits.h"
#include "llvm/Support/raw_ostream.h"
namespace lldb_private {
-namespace repro {
-class PacketRecorder;
-}
namespace process_gdb_remote {
/// The history keeps a circular buffer of GDB remote packets. The history is
@@ -45,7 +41,7 @@ class GDBRemoteCommunicationHistory {
void Dump(Log *log) const;
bool DidDumpToLog() const { return m_dumped_to_log; }
- void SetRecorder(repro::PacketRecorder *recorder) { m_recorder = recorder; }
+ void SetStream(llvm::raw_ostream *strm) { m_stream = strm; }
private:
uint32_t GetFirstSavedPacketIndex() const {
@@ -77,7 +73,7 @@ class GDBRemoteCommunicationHistory {
uint32_t m_curr_idx;
uint32_t m_total_packet_count;
mutable bool m_dumped_to_log;
- repro::PacketRecorder *m_recorder = nullptr;
+ llvm::raw_ostream *m_stream = nullptr;
};
} // namespace process_gdb_remote
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 95f3d1fcc53a..dfef06aa6eaf 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -279,9 +279,12 @@ ProcessGDBRemote::ProcessGDBRemote(lldb::TargetSP target_sp,
"async thread did exit");
if (repro::Generator *g = repro::Reproducer::Instance().GetGenerator()) {
- repro::GDBRemoteProvider &provider =
- g->GetOrCreate<repro::GDBRemoteProvider>();
- m_gdb_comm.SetPacketRecorder(provider.GetNewPacketRecorder());
+ repro::ProcessGDBRemoteProvider &provider =
+ g->GetOrCreate<repro::ProcessGDBRemoteProvider>();
+ // Set the history stream to the stream owned by the provider.
+ m_gdb_comm.SetHistoryStream(provider.GetHistoryStream());
+ // Make sure to clear the stream again when we're finished.
+ provider.SetCallback([&]() { m_gdb_comm.SetHistoryStream(nullptr); });
}
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_ASYNC));
@@ -3359,20 +3362,17 @@ Status ProcessGDBRemote::ConnectToReplayServer(repro::Loader *loader) {
if (!loader)
return Status("No loader provided.");
- static std::unique_ptr<repro::MultiLoader<repro::GDBRemoteProvider>>
- multi_loader = repro::MultiLoader<repro::GDBRemoteProvider>::Create(
- repro::Reproducer::Instance().GetLoader());
-
- if (!multi_loader)
- return Status("No gdb remote provider found.");
-
- llvm::Optional<std::string> history_file = multi_loader->GetNextFile();
+ // Construct replay history path.
+ FileSpec history_file =
+ loader->GetFile<repro::ProcessGDBRemoteProvider::Info>();
if (!history_file)
- return Status("No gdb remote packet log found.");
+ return Status("No provider for gdb-remote.");
+
+ // Enable replay mode.
+ m_replay_mode = true;
// Load replay history.
- if (auto error =
- m_gdb_replay_server.LoadReplayHistory(FileSpec(*history_file)))
+ if (auto error = m_gdb_replay_server.LoadReplayHistory(history_file))
return Status("Unable to load replay history");
// Make a local connection.
@@ -3380,9 +3380,6 @@ Status ProcessGDBRemote::ConnectToReplayServer(repro::Loader *loader) {
m_gdb_replay_server))
return Status("Unable to connect to replay server");
- // Enable replay mode.
- m_replay_mode = true;
-
// Start server thread.
m_gdb_replay_server.StartAsyncThread();
diff --git a/lldb/source/Utility/GDBRemote.cpp b/lldb/source/Utility/GDBRemote.cpp
index 54f3a3cd8a86..85c4bc69a8d1 100644
--- a/lldb/source/Utility/GDBRemote.cpp
+++ b/lldb/source/Utility/GDBRemote.cpp
@@ -14,7 +14,6 @@
#include <stdio.h>
using namespace lldb;
-using namespace lldb_private::repro;
using namespace lldb_private;
using namespace llvm;
@@ -46,6 +45,12 @@ int StreamGDBRemote::PutEscapedBytes(const void *s, size_t src_len) {
return bytes_written;
}
+void GDBRemotePacket::Serialize(raw_ostream &strm) const {
+ yaml::Output yout(strm);
+ yout << const_cast<GDBRemotePacket &>(*this);
+ strm.flush();
+}
+
llvm::StringRef GDBRemotePacket::GetTypeStr() const {
switch (type) {
case GDBRemotePacket::ePacketTypeSend:
@@ -98,66 +103,3 @@ yaml::MappingTraits<GDBRemotePacket>::validate(IO &io,
return {};
}
-
-void GDBRemoteProvider::Keep() {
- std::vector<std::string> files;
- for (auto &recorder : m_packet_recorders) {
- 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;
- yaml::Output yout(os);
- yout << files;
-}
-
-void GDBRemoteProvider::Discard() { m_packet_recorders.clear(); }
-
-llvm::Expected<std::unique_ptr<PacketRecorder>>
-PacketRecorder::Create(const FileSpec &filename) {
- std::error_code ec;
- auto recorder = std::make_unique<PacketRecorder>(std::move(filename), ec);
- if (ec)
- return llvm::errorCodeToError(ec);
- return std::move(recorder);
-}
-
-PacketRecorder *GDBRemoteProvider::GetNewPacketRecorder() {
- std::size_t i = m_packet_recorders.size() + 1;
- std::string filename = (llvm::Twine(Info::name) + llvm::Twine("-") +
- llvm::Twine(i) + llvm::Twine(".yaml"))
- .str();
- auto recorder_or_error =
- PacketRecorder::Create(GetRoot().CopyByAppendingPathComponent(filename));
- if (!recorder_or_error) {
- llvm::consumeError(recorder_or_error.takeError());
- return nullptr;
- }
-
- m_packet_recorders.push_back(std::move(*recorder_or_error));
- return m_packet_recorders.back().get();
-}
-
-void PacketRecorder::Record(const GDBRemotePacket &packet) {
- if (!m_record)
- return;
- yaml::Output yout(m_os);
- yout << const_cast<GDBRemotePacket &>(packet);
- m_os.flush();
-}
-
-llvm::raw_ostream *GDBRemoteProvider::GetHistoryStream() {
- FileSpec history_file = GetRoot().CopyByAppendingPathComponent(Info::file);
-
- std::error_code EC;
- m_stream_up = std::make_unique<raw_fd_ostream>(history_file.GetPath(), EC,
- sys::fs::OpenFlags::OF_Text);
- return m_stream_up.get();
-}
-
-char GDBRemoteProvider::ID = 0;
-const char *GDBRemoteProvider::Info::file = "gdb-remote.yaml";
-const char *GDBRemoteProvider::Info::name = "gdb-remote";
diff --git a/lldb/source/Utility/Reproducer.cpp b/lldb/source/Utility/Reproducer.cpp
index b11e1a577ed2..8a28e9b13675 100644
--- a/lldb/source/Utility/Reproducer.cpp
+++ b/lldb/source/Utility/Reproducer.cpp
@@ -255,7 +255,7 @@ DataRecorder::Create(const FileSpec &filename) {
DataRecorder *CommandProvider::GetNewDataRecorder() {
std::size_t i = m_data_recorders.size() + 1;
std::string filename = (llvm::Twine(Info::name) + llvm::Twine("-") +
- llvm::Twine(i) + llvm::Twine(".yaml"))
+ llvm::Twine(i) + llvm::Twine(".txt"))
.str();
auto recorder_or_error =
DataRecorder::Create(GetRoot().CopyByAppendingPathComponent(filename));
@@ -304,9 +304,53 @@ void WorkingDirectoryProvider::Keep() {
os << m_cwd << "\n";
}
+llvm::raw_ostream *ProcessGDBRemoteProvider::GetHistoryStream() {
+ FileSpec history_file = GetRoot().CopyByAppendingPathComponent(Info::file);
+
+ std::error_code EC;
+ m_stream_up = std::make_unique<raw_fd_ostream>(history_file.GetPath(), EC,
+ sys::fs::OpenFlags::OF_Text);
+ return m_stream_up.get();
+}
+
+std::unique_ptr<CommandLoader> CommandLoader::Create(Loader *loader) {
+ if (!loader)
+ return {};
+
+ FileSpec file = loader->GetFile<repro::CommandProvider::Info>();
+ if (!file)
+ return {};
+
+ auto error_or_file = llvm::MemoryBuffer::getFile(file.GetPath());
+ if (auto err = error_or_file.getError())
+ return {};
+
+ std::vector<std::string> files;
+ llvm::yaml::Input yin((*error_or_file)->getBuffer());
+ yin >> files;
+
+ if (auto err = yin.error())
+ return {};
+
+ for (auto &file : files) {
+ FileSpec absolute_path =
+ loader->GetRoot().CopyByAppendingPathComponent(file);
+ file = absolute_path.GetPath();
+ }
+
+ return std::make_unique<CommandLoader>(std::move(files));
+}
+
+llvm::Optional<std::string> CommandLoader::GetNextFile() {
+ if (m_index >= m_files.size())
+ return {};
+ return m_files[m_index++];
+}
+
void ProviderBase::anchor() {}
char CommandProvider::ID = 0;
char FileProvider::ID = 0;
+char ProcessGDBRemoteProvider::ID = 0;
char ProviderBase::ID = 0;
char VersionProvider::ID = 0;
char WorkingDirectoryProvider::ID = 0;
@@ -314,6 +358,8 @@ 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 *ProcessGDBRemoteProvider::Info::file = "gdb-remote.yaml";
+const char *ProcessGDBRemoteProvider::Info::name = "gdb-remote";
const char *VersionProvider::Info::file = "version.txt";
const char *VersionProvider::Info::name = "version";
const char *WorkingDirectoryProvider::Info::file = "cwd.txt";
diff --git a/lldb/test/Shell/Reproducer/Inputs/MultipleTargetsCapture.in b/lldb/test/Shell/Reproducer/Inputs/MultipleTargetsCapture.in
deleted file mode 100644
index c78d6276c89f..000000000000
--- a/lldb/test/Shell/Reproducer/Inputs/MultipleTargetsCapture.in
+++ /dev/null
@@ -1,12 +0,0 @@
-target select 0
-breakpoint set -f simple.c -l 12
-run
-target select 1
-breakpoint set -f simple.c -l 16
-run
-target select 0
-cont
-target select 1
-cont
-reproducer status
-reproducer generate
diff --git a/lldb/test/Shell/Reproducer/TestMultipleTargets.test b/lldb/test/Shell/Reproducer/TestMultipleTargets.test
deleted file mode 100644
index f36dbf6b5c44..000000000000
--- a/lldb/test/Shell/Reproducer/TestMultipleTargets.test
+++ /dev/null
@@ -1,23 +0,0 @@
-# UNSUPPORTED: system-windows, system-freebsd
-
-# This tests the replaying with multiple targets.
-
-# RUN: %clang_host %S/Inputs/simple.c -g -o %t.out
-
-# RUN: rm -rf %t.repro
-# RUN: %lldb -x -b --capture --capture-path %t.repro -o 'target create %t.out' -o 'target create %t.out' -s %S/Inputs/MultipleTargetsCapture.in | FileCheck %s --check-prefix CHECK --check-prefix CAPTURE
-# RUN: env FOO=BAR %lldb --replay %t.repro | FileCheck %s --check-prefix CHECK --check-prefix REPLAY
-
-# CHECK: Process [[TARGET0:[0-9]+]] stopped
-# CHECK: stop reason = breakpoint 1.1
-# CHECK: simple.c:12:5
-# CHECK: Process [[TARGET1:[0-9]+]] stopped
-# CHECK: stop reason = breakpoint 1.1
-# CHECK: simple.c:16:5
-# CHECK: Process [[TARGET0]] resuming
-# CHECK: Process [[TARGET0]] exited
-# CHECK: Process [[TARGET1]] resuming
-# CHECK: Process [[TARGET1]] exited
-
-# CAPTURE: Reproducer is in capture mode.
-# CAPTURE: Reproducer written
More information about the lldb-commits
mailing list