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.
class Generator final {
+
public:
Generator(const FileSpec &root);
~Generator();
return g_settings_sp;
}
-class ProcessGDBRemoteProvider
- : public repro::Provider<ProcessGDBRemoteProvider> {
-public:
- struct Info {
- static const char *name;
- static const char *file;
- };
-
- ProcessGDBRemoteProvider(const FileSpec &directory) : Provider(directory) {
- }
-
- raw_ostream *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();
- }
-
- 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<raw_fd_ostream> m_stream_up;
-};
-
-char ProcessGDBRemoteProvider::ID = 0;
-const char *ProcessGDBRemoteProvider::Info::name = "gdb-remote";
-const char *ProcessGDBRemoteProvider::Info::file = "gdb-remote.yaml";
-
} // namespace
// TODO Randomly assigning a port is unsafe. We should get an unused
"async thread did exit");
if (repro::Generator *g = repro::Reproducer::Instance().GetGenerator()) {
- ProcessGDBRemoteProvider &provider =
- g->GetOrCreate<ProcessGDBRemoteProvider>();
+ 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.
return Status("No loader provided.");
// Construct replay history path.
- FileSpec history_file = loader->GetFile<ProcessGDBRemoteProvider::Info>();
+ FileSpec history_file =
+ loader->GetFile<repro::ProcessGDBRemoteProvider::Info>();
if (!history_file)
return Status("No provider for gdb-remote.");
std::error_code EC;
auto strm = std::make_unique<raw_fd_ostream>(index.GetPath(), EC,
- sys::fs::OpenFlags::OF_None);
+ sys::fs::OpenFlags::OF_None);
yaml::Output yout(*strm);
std::vector<std::string> files;
os << m_version << "\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();
+}
+
void ProviderBase::anchor() {}
-char ProviderBase::ID = 0;
char CommandProvider::ID = 0;
char FileProvider::ID = 0;
+char ProcessGDBRemoteProvider::ID = 0;
+char ProviderBase::ID = 0;
char VersionProvider::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 *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";