diff options
author | Jonas Devlieghere <jonas@devlieghere.com> | 2018-12-03 17:28:29 +0000 |
---|---|---|
committer | Jonas Devlieghere <jonas@devlieghere.com> | 2018-12-03 17:28:29 +0000 |
commit | 15eacd741faa5ec75ef55d82db3486cbaf91f46f (patch) | |
tree | 4daa8934087c40d450d390c3fbee9c3b28b36bed /lldb | |
parent | 8918a511a1a53cc568b248428fb75c39b1949001 (diff) | |
download | bcm5719-llvm-15eacd741faa5ec75ef55d82db3486cbaf91f46f.tar.gz bcm5719-llvm-15eacd741faa5ec75ef55d82db3486cbaf91f46f.zip |
[Reproducers] Change how reproducers are initialized.
This patch changes the way the reproducer is initialized. Rather than
making changes at run time we now do everything at initialization time.
To make this happen we had to introduce initializer options and their SB
variant. This allows us to tell the initializer that we're running in
reproducer capture/replay mode.
Because of this change we also had to alter our testing strategy. We
cannot reinitialize LLDB when using the dotest infrastructure. Instead
we use lit and invoke two instances of the driver.
Another consequence is that we can no longer enable capture or replay
through commands. This was bound to go away form the beginning, but I
had something in mind where you could enable/disable specific providers.
However this seems like it adds very little value right now so the
corresponding commands were removed.
Finally this change also means you now have to control this through the
driver, for which I replaced --reproducer with --capture and --replay to
differentiate between the two modes.
Differential revision: https://reviews.llvm.org/D55038
llvm-svn: 348152
Diffstat (limited to 'lldb')
40 files changed, 402 insertions, 311 deletions
diff --git a/lldb/include/lldb/API/SBDebugger.h b/lldb/include/lldb/API/SBDebugger.h index ccb1f6dae0f..3f31bf16da8 100644 --- a/lldb/include/lldb/API/SBDebugger.h +++ b/lldb/include/lldb/API/SBDebugger.h @@ -13,6 +13,7 @@ #include <stdio.h> #include "lldb/API/SBDefines.h" +#include "lldb/API/SBInitializerOptions.h" #include "lldb/API/SBPlatform.h" namespace lldb { @@ -45,6 +46,7 @@ public: lldb::SBDebugger &operator=(const lldb::SBDebugger &rhs); static void Initialize(); + static lldb::SBError Initialize(SBInitializerOptions &options); static void Terminate(); @@ -228,8 +230,6 @@ public: const char *GetReproducerPath() const; - lldb::SBError ReplayReproducer(const char *path); - lldb::ScriptLanguage GetScriptLanguage() const; void SetScriptLanguage(lldb::ScriptLanguage script_lang); diff --git a/lldb/include/lldb/API/SBDefines.h b/lldb/include/lldb/API/SBDefines.h index 166cc2ae129..c5c9851272f 100644 --- a/lldb/include/lldb/API/SBDefines.h +++ b/lldb/include/lldb/API/SBDefines.h @@ -51,6 +51,7 @@ class LLDB_API SBFileSpecList; class LLDB_API SBFrame; class LLDB_API SBFunction; class LLDB_API SBHostOS; +class LLDB_API SBInitializerOptions; class LLDB_API SBInstruction; class LLDB_API SBInstructionList; class LLDB_API SBLanguageRuntime; diff --git a/lldb/include/lldb/API/SBFileSpec.h b/lldb/include/lldb/API/SBFileSpec.h index 33e48f5c7c4..9ad1a5df0cf 100644 --- a/lldb/include/lldb/API/SBFileSpec.h +++ b/lldb/include/lldb/API/SBFileSpec.h @@ -59,6 +59,7 @@ private: friend class SBDeclaration; friend class SBFileSpecList; friend class SBHostOS; + friend class SBInitializerOptions; friend class SBLaunchInfo; friend class SBLineEntry; friend class SBModule; @@ -67,8 +68,8 @@ private: friend class SBProcess; friend class SBProcessInfo; friend class SBSourceManager; - friend class SBThread; friend class SBTarget; + friend class SBThread; SBFileSpec(const lldb_private::FileSpec &fspec); diff --git a/lldb/include/lldb/API/SBInitializerOptions.h b/lldb/include/lldb/API/SBInitializerOptions.h new file mode 100644 index 00000000000..184c82df4f8 --- /dev/null +++ b/lldb/include/lldb/API/SBInitializerOptions.h @@ -0,0 +1,43 @@ +//===-- SBInitializerOptions.h ----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SBInitializerOptuions_h_ +#define LLDB_SBInitializerOptuions_h_ + +#include "lldb/API/SBDefines.h" +#include "lldb/API/SBFileSpec.h" + +namespace lldb_private { +struct InitializerOptions; +} + +namespace lldb { + +class LLDB_API SBInitializerOptions { +public: + SBInitializerOptions(); + SBInitializerOptions(const lldb::SBInitializerOptions &rhs); + ~SBInitializerOptions(); + const SBInitializerOptions &operator=(const lldb::SBInitializerOptions &rhs); + + void SetCaptureReproducer(bool b); + void SetReplayReproducer(bool b); + void SetReproducerPath(const char *path); + + lldb_private::InitializerOptions &ref() const; + +private: + friend class SBDebugger; + + std::unique_ptr<lldb_private::InitializerOptions> m_opaque_up; +}; + +} // namespace lldb + +#endif // LLDB_SBInitializerOptuions_h_ diff --git a/lldb/include/lldb/Core/Debugger.h b/lldb/include/lldb/Core/Debugger.h index 8056b8bf7ac..f7de9ff281a 100644 --- a/lldb/include/lldb/Core/Debugger.h +++ b/lldb/include/lldb/Core/Debugger.h @@ -263,11 +263,6 @@ public: llvm::StringRef GetReproducerPath() const; - llvm::Error SetReproducerReplay(llvm::StringRef p); - llvm::Error SetReproducerReplay(const char *) = delete; - - llvm::Error SetReproducerCapture(bool b); - bool GetUseExternalEditor() const; bool SetUseExternalEditor(bool use_external_editor_p); diff --git a/lldb/include/lldb/Host/HostInfoBase.h b/lldb/include/lldb/Host/HostInfoBase.h index efc6607a133..f3e49c8f25d 100644 --- a/lldb/include/lldb/Host/HostInfoBase.h +++ b/lldb/include/lldb/Host/HostInfoBase.h @@ -93,12 +93,6 @@ public: /// FileSpec is filled in. static FileSpec GetGlobalTempDir(); - /// Returns the reproducer temporary directory. This directory will **not** - /// be automatically cleaned up when this process exits, but might be removed - /// by the reproducer generator. Only the directory member of the FileSpec is - /// filled in. - static FileSpec GetReproducerTempDir(); - //--------------------------------------------------------------------------- /// If the triple does not specify the vendor, os, and environment parts, we /// "augment" these using information from the host and return the resulting @@ -111,7 +105,6 @@ protected: static bool ComputeSupportExeDirectory(FileSpec &file_spec); static bool ComputeProcessTempFileDirectory(FileSpec &file_spec); static bool ComputeGlobalTempFileDirectory(FileSpec &file_spec); - static bool ComputeReproducerTempFileDirectory(FileSpec &file_spec); static bool ComputeTempFileBaseDirectory(FileSpec &file_spec); static bool ComputeHeaderDirectory(FileSpec &file_spec); static bool ComputeSystemPluginsDirectory(FileSpec &file_spec); diff --git a/lldb/include/lldb/Initialization/SystemInitializer.h b/lldb/include/lldb/Initialization/SystemInitializer.h index 58bbb44b1f3..b665b999721 100644 --- a/lldb/include/lldb/Initialization/SystemInitializer.h +++ b/lldb/include/lldb/Initialization/SystemInitializer.h @@ -10,13 +10,24 @@ #ifndef LLDB_INITIALIZATION_SYSTEM_INITIALIZER_H #define LLDB_INITIALIZATION_SYSTEM_INITIALIZER_H +#include "llvm/Support/Error.h" + +#include <string> + namespace lldb_private { + +struct InitializerOptions { + bool reproducer_capture = false; + bool reproducer_replay = false; + std::string reproducer_path; +}; + class SystemInitializer { public: SystemInitializer(); virtual ~SystemInitializer(); - virtual void Initialize() = 0; + virtual llvm::Error Initialize(const InitializerOptions &options) = 0; virtual void Terminate() = 0; }; } diff --git a/lldb/include/lldb/Initialization/SystemInitializerCommon.h b/lldb/include/lldb/Initialization/SystemInitializerCommon.h index 2a9851c6a34..f33acaf4046 100644 --- a/lldb/include/lldb/Initialization/SystemInitializerCommon.h +++ b/lldb/include/lldb/Initialization/SystemInitializerCommon.h @@ -28,7 +28,7 @@ public: SystemInitializerCommon(); ~SystemInitializerCommon() override; - void Initialize() override; + llvm::Error Initialize(const InitializerOptions &options) override; void Terminate() override; }; diff --git a/lldb/include/lldb/Initialization/SystemLifetimeManager.h b/lldb/include/lldb/Initialization/SystemLifetimeManager.h index 0ebd4a50a34..0839856f21e 100644 --- a/lldb/include/lldb/Initialization/SystemLifetimeManager.h +++ b/lldb/include/lldb/Initialization/SystemLifetimeManager.h @@ -10,21 +10,23 @@ #ifndef LLDB_INITIALIZATION_SYSTEM_LIFETIME_MANAGER_H #define LLDB_INITIALIZATION_SYSTEM_LIFETIME_MANAGER_H +#include "lldb/Initialization/SystemInitializer.h" #include "lldb/lldb-private-types.h" +#include "llvm/Support/Error.h" #include <memory> #include <mutex> namespace lldb_private { -class SystemInitializer; class SystemLifetimeManager { public: SystemLifetimeManager(); ~SystemLifetimeManager(); - void Initialize(std::unique_ptr<SystemInitializer> initializer, - LoadPluginCallbackType plugin_callback); + llvm::Error Initialize(std::unique_ptr<SystemInitializer> initializer, + const InitializerOptions &options, + LoadPluginCallbackType plugin_callback); void Terminate(); private: diff --git a/lldb/include/lldb/Utility/Reproducer.h b/lldb/include/lldb/Utility/Reproducer.h index 6ad1acfa5ff..ea315ad771a 100644 --- a/lldb/include/lldb/Utility/Reproducer.h +++ b/lldb/include/lldb/Utility/Reproducer.h @@ -25,6 +25,12 @@ namespace repro { class Reproducer; +enum class ReproducerMode { + Capture, + Replay, + Off, +}; + /// Abstraction for information associated with a provider. This information /// is serialized into an index which is used by the loader. struct ProviderInfo { @@ -159,10 +165,14 @@ private: /// The reproducer enables clients to obtain access to the Generator and /// Loader. -class Reproducer final { - +class Reproducer { public: static Reproducer &Instance(); + static llvm::Error Initialize(ReproducerMode mode, + llvm::Optional<FileSpec> root); + static void Terminate(); + + Reproducer() = default; Generator *GetGenerator(); Loader *GetLoader(); @@ -170,12 +180,15 @@ public: const Generator *GetGenerator() const; const Loader *GetLoader() const; + FileSpec GetReproducerPath() const; + +protected: llvm::Error SetCapture(llvm::Optional<FileSpec> root); llvm::Error SetReplay(llvm::Optional<FileSpec> root); - FileSpec GetReproducerPath() const; - private: + static llvm::Optional<Reproducer> &InstanceImpl(); + llvm::Optional<Generator> m_generator; llvm::Optional<Loader> m_loader; diff --git a/lldb/lit/Reproducer/Inputs/GDBRemoteCapture.in b/lldb/lit/Reproducer/Inputs/GDBRemoteCapture.in new file mode 100644 index 00000000000..8df7ca42fee --- /dev/null +++ b/lldb/lit/Reproducer/Inputs/GDBRemoteCapture.in @@ -0,0 +1,6 @@ +breakpoint set -f simple.c -l 13 +run +bt +cont +reproducer status +reproducer generate diff --git a/lldb/lit/Reproducer/Inputs/GDBRemoteReplay.in b/lldb/lit/Reproducer/Inputs/GDBRemoteReplay.in new file mode 100644 index 00000000000..1364c7e7276 --- /dev/null +++ b/lldb/lit/Reproducer/Inputs/GDBRemoteReplay.in @@ -0,0 +1,5 @@ +reproducer status +breakpoint set -f simple.c -l 13 +run +bt +cont diff --git a/lldb/lit/Reproducer/Inputs/simple.c b/lldb/lit/Reproducer/Inputs/simple.c new file mode 100644 index 00000000000..a4585b380ca --- /dev/null +++ b/lldb/lit/Reproducer/Inputs/simple.c @@ -0,0 +1,19 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include <stdio.h> + +void foo() { + printf("testing\n"); +} + +int main (int argc, char const *argv[]) { + foo(); + return 0; +} diff --git a/lldb/lit/Reproducer/TestDriverOptions.test b/lldb/lit/Reproducer/TestDriverOptions.test new file mode 100644 index 00000000000..d7a076841d9 --- /dev/null +++ b/lldb/lit/Reproducer/TestDriverOptions.test @@ -0,0 +1,7 @@ +# Check that errors are propagated to the driver. + +# RUN: not %lldb --capture /bogus 2>&1 | FileCheck %s --check-prefix CAPTURE +# RUN: not %lldb --replay /bogus 2>&1 | FileCheck %s --check-prefix REPLAY + +# CAPTURE: unable to create reproducer directory +# REPLAY: unable to load reproducer index diff --git a/lldb/lit/Reproducer/TestGDBRemoteRepro.test b/lldb/lit/Reproducer/TestGDBRemoteRepro.test new file mode 100644 index 00000000000..6a6bdd780a8 --- /dev/null +++ b/lldb/lit/Reproducer/TestGDBRemoteRepro.test @@ -0,0 +1,26 @@ +# UNSUPPORTED: system-windows, system-freebsd + +# This tests the replaying of GDB remote packets. +# +# We issue the same commands and ensure the output is identical to the original +# process. To ensure we're not actually running the original binary we check +# that the string "testing" is not printed. + +# RUN: %clang %S/Inputs/simple.c -g -o %t.out +# RUN: %lldb -x -b -s %S/Inputs/GDBRemoteCapture.in --capture %T/reproducer -- %t.out | FileCheck %s --check-prefix CHECK --check-prefix CAPTURE +# RUN: %lldb -x -b -s %S/Inputs/GDBRemoteReplay.in --replay %T/reproducer -- %t.out | FileCheck %s --check-prefix CHECK --check-prefix REPLAY + +# CHECK: Breakpoint 1 +# CHECK: Process {{.*}} stopped +# CHECK: Process {{.*}} launched +# CHECK: thread {{.*}} stop reason = breakpoint +# CHECK: frame {{.*}} simple.c + +# CAPTURE: testing +# REPLAY-NOT: testing + +# CHECK: Process {{.*}} resuming +# CHECK: Process {{.*}} exited + +# CAPTURE: Reproducer is in capture mode. +# CAPTURE: Reproducer written diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/reproducer/gdb-remote/Makefile b/lldb/packages/Python/lldbsuite/test/functionalities/reproducer/gdb-remote/Makefile deleted file mode 100644 index b09a579159d..00000000000 --- a/lldb/packages/Python/lldbsuite/test/functionalities/reproducer/gdb-remote/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -LEVEL = ../../../make - -C_SOURCES := main.c - -include $(LEVEL)/Makefile.rules diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/reproducer/gdb-remote/TestGdbRemoteReproducer.py b/lldb/packages/Python/lldbsuite/test/functionalities/reproducer/gdb-remote/TestGdbRemoteReproducer.py deleted file mode 100644 index adbbd1be645..00000000000 --- a/lldb/packages/Python/lldbsuite/test/functionalities/reproducer/gdb-remote/TestGdbRemoteReproducer.py +++ /dev/null @@ -1,49 +0,0 @@ -""" -Test the GDB remote reproducer. -""" - -from __future__ import print_function - -import os -import lldb -from lldbsuite.test.decorators import * -from lldbsuite.test.lldbtest import * -from lldbsuite.test import lldbutil - - -class TestGdbRemoteReproducer(TestBase): - - mydir = TestBase.compute_mydir(__file__) - NO_DEBUG_INFO_TESTCASE = True - - def test(self): - """Test record and replay of gdb-remote packets.""" - self.build() - - # Create temp directory for the reproducer. - exe = self.getBuildArtifact("a.out") - - # First capture a regular debugging session. - self.runCmd("reproducer capture enable") - - reproducer_path = self.dbg.GetReproducerPath() - - self.runCmd("file {}".format(exe)) - self.runCmd("breakpoint set -f main.c -l 13") - self.runCmd("run") - self.runCmd("bt") - self.runCmd("cont") - - # Generate the reproducer and stop capturing. - self.runCmd("reproducer generate") - self.runCmd("reproducer capture disable") - - # Replay the session from the reproducer. - self.runCmd("reproducer replay {}".format(reproducer_path)) - - # We have to issue the same commands. - self.runCmd("file {}".format(exe)) - self.runCmd("breakpoint set -f main.c -l 13") - self.runCmd("run") - self.runCmd("bt") - self.expect("cont") diff --git a/lldb/scripts/interface/SBDebugger.i b/lldb/scripts/interface/SBDebugger.i index 18796e80e55..fde3d7b6b88 100644 --- a/lldb/scripts/interface/SBDebugger.i +++ b/lldb/scripts/interface/SBDebugger.i @@ -124,6 +124,9 @@ public: Initialize(); static void + Initialize(lldb::SBInitializerOptions& options); + + static void Terminate(); static lldb::SBDebugger @@ -376,9 +379,6 @@ public: const char * GetReproducerPath() const; - lldb::SBError - ReplayReproducer (const char *path); - lldb::ScriptLanguage GetScriptLanguage() const; diff --git a/lldb/scripts/interface/SBInitializerOptions.i b/lldb/scripts/interface/SBInitializerOptions.i new file mode 100644 index 00000000000..9478642ebd6 --- /dev/null +++ b/lldb/scripts/interface/SBInitializerOptions.i @@ -0,0 +1,24 @@ +//===-- SWIG Interface for SBInitializerOptions -----------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +namespace lldb { + +class SBInitializerOptions +{ +public: + SBInitializerOptions (); + SBInitializerOptions (const lldb::SBInitializerOptions &rhs); + ~SBInitializerOptions(); + + void SetCaptureReproducer(bool b); + void SetReplayReproducer(bool b); + void SetReproducerPath(const char* path); +}; + +} // namespace lldb diff --git a/lldb/scripts/lldb.swig b/lldb/scripts/lldb.swig index e920718d3e8..e8553d075d4 100644 --- a/lldb/scripts/lldb.swig +++ b/lldb/scripts/lldb.swig @@ -187,6 +187,7 @@ import six %include "./interface/SBFrame.i" %include "./interface/SBFunction.i" %include "./interface/SBHostOS.i" +%include "./interface/SBInitializerOptions.i" %include "./interface/SBInstruction.i" %include "./interface/SBInstructionList.i" %include "./interface/SBLanguageRuntime.i" diff --git a/lldb/source/API/CMakeLists.txt b/lldb/source/API/CMakeLists.txt index 3c5f4ddb43f..d2ab24c7c01 100644 --- a/lldb/source/API/CMakeLists.txt +++ b/lldb/source/API/CMakeLists.txt @@ -29,6 +29,7 @@ add_lldb_library(liblldb SHARED SBFrame.cpp SBFunction.cpp SBHostOS.cpp + SBInitializerOptions.cpp SBInstruction.cpp SBInstructionList.cpp SBLanguageRuntime.cpp diff --git a/lldb/source/API/SBDebugger.cpp b/lldb/source/API/SBDebugger.cpp index a7217964abf..af343233c90 100644 --- a/lldb/source/API/SBDebugger.cpp +++ b/lldb/source/API/SBDebugger.cpp @@ -125,13 +125,23 @@ SBDebugger &SBDebugger::operator=(const SBDebugger &rhs) { } void SBDebugger::Initialize() { + SBInitializerOptions options; + SBDebugger::Initialize(options); +} + +lldb::SBError SBDebugger::Initialize(SBInitializerOptions &options) { Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); if (log) log->Printf("SBDebugger::Initialize ()"); - g_debugger_lifetime->Initialize(llvm::make_unique<SystemInitializerFull>(), - LoadPlugin); + SBError error; + if (auto e = g_debugger_lifetime->Initialize( + llvm::make_unique<SystemInitializerFull>(), *options.m_opaque_up, + LoadPlugin)) { + error.SetError(Status(std::move(e))); + } + return error; } void SBDebugger::Terminate() { g_debugger_lifetime->Terminate(); } @@ -1057,17 +1067,6 @@ const char *SBDebugger::GetReproducerPath() const { : nullptr); } -SBError SBDebugger::ReplayReproducer(const char *p) { - SBError sb_error; - if (m_opaque_sp) { - auto error = - m_opaque_sp->SetReproducerReplay(llvm::StringRef::withNullAsEmpty(p)); - std::string error_str = llvm::toString(std::move(error)); - sb_error.ref().SetErrorString(error_str); - } - return sb_error; -} - ScriptLanguage SBDebugger::GetScriptLanguage() const { return (m_opaque_sp ? m_opaque_sp->GetScriptLanguage() : eScriptLanguageNone); } diff --git a/lldb/source/API/SBInitializerOptions.cpp b/lldb/source/API/SBInitializerOptions.cpp new file mode 100644 index 00000000000..8d8ec28190e --- /dev/null +++ b/lldb/source/API/SBInitializerOptions.cpp @@ -0,0 +1,49 @@ +//===-- SBInitializerOptions.cpp --------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/API/SBInitializerOptions.h" +#include "lldb/Initialization/SystemInitializer.h" + +using namespace lldb; +using namespace lldb_private; + +SBInitializerOptions::SBInitializerOptions(const SBInitializerOptions &rhs) { + m_opaque_up.reset(new InitializerOptions()); + *(m_opaque_up.get()) = rhs.ref(); +} + +const SBInitializerOptions &SBInitializerOptions:: +operator=(const SBInitializerOptions &rhs) { + if (this != &rhs) { + this->ref() = rhs.ref(); + } + return *this; +} + +SBInitializerOptions::~SBInitializerOptions() {} + +SBInitializerOptions::SBInitializerOptions() { + m_opaque_up.reset(new InitializerOptions()); +} + +void SBInitializerOptions::SetCaptureReproducer(bool b) { + m_opaque_up->reproducer_capture = b; +} + +void SBInitializerOptions::SetReplayReproducer(bool b) { + m_opaque_up->reproducer_replay = b; +} + +void SBInitializerOptions::SetReproducerPath(const char *path) { + m_opaque_up->reproducer_path = path; +} + +InitializerOptions &SBInitializerOptions::ref() const { + return *(m_opaque_up.get()); +} diff --git a/lldb/source/API/SystemInitializerFull.cpp b/lldb/source/API/SystemInitializerFull.cpp index 671077ca0b0..937604425b4 100644 --- a/lldb/source/API/SystemInitializerFull.cpp +++ b/lldb/source/API/SystemInitializerFull.cpp @@ -263,8 +263,10 @@ SystemInitializerFull::SystemInitializerFull() {} SystemInitializerFull::~SystemInitializerFull() {} -void SystemInitializerFull::Initialize() { - SystemInitializerCommon::Initialize(); +llvm::Error +SystemInitializerFull::Initialize(const InitializerOptions &options) { + if (auto e = SystemInitializerCommon::Initialize(options)) + return e; ObjectFileELF::Initialize(); ObjectFileMachO::Initialize(); @@ -396,6 +398,8 @@ void SystemInitializerFull::Initialize() { // AFTER PluginManager::Initialize is called. Debugger::SettingsInitialize(); + + return llvm::Error::success(); } void SystemInitializerFull::InitializeSWIG() { diff --git a/lldb/source/API/SystemInitializerFull.h b/lldb/source/API/SystemInitializerFull.h index 9cfc6896da6..b0cf476e919 100644 --- a/lldb/source/API/SystemInitializerFull.h +++ b/lldb/source/API/SystemInitializerFull.h @@ -26,7 +26,7 @@ public: SystemInitializerFull(); ~SystemInitializerFull() override; - void Initialize() override; + llvm::Error Initialize(const InitializerOptions &options) override; void Terminate() override; private: diff --git a/lldb/source/Commands/CommandObjectReproducer.cpp b/lldb/source/Commands/CommandObjectReproducer.cpp index 03a3e230980..f393f17d9ae 100644 --- a/lldb/source/Commands/CommandObjectReproducer.cpp +++ b/lldb/source/Commands/CommandObjectReproducer.cpp @@ -19,65 +19,6 @@ using namespace lldb; using namespace lldb_private; -static void AppendErrorToResult(llvm::Error e, CommandReturnObject &result) { - std::string error_str = llvm::toString(std::move(e)); - result.AppendErrorWithFormat("%s", error_str.c_str()); -} - -class CommandObjectReproducerCaptureEnable : public CommandObjectParsed { -public: - CommandObjectReproducerCaptureEnable(CommandInterpreter &interpreter) - : CommandObjectParsed(interpreter, "reproducer capture enable", - "Enable gathering information for reproducer", - nullptr) {} - - ~CommandObjectReproducerCaptureEnable() override = default; - -protected: - bool DoExecute(Args &command, CommandReturnObject &result) override { - if (!command.empty()) { - result.AppendErrorWithFormat("'%s' takes no arguments", - m_cmd_name.c_str()); - return false; - } - - if (auto e = m_interpreter.GetDebugger().SetReproducerCapture(true)) { - AppendErrorToResult(std::move(e), result); - return false; - } - - result.SetStatus(eReturnStatusSuccessFinishNoResult); - return result.Succeeded(); - } -}; - -class CommandObjectReproducerCaptureDisable : public CommandObjectParsed { -public: - CommandObjectReproducerCaptureDisable(CommandInterpreter &interpreter) - : CommandObjectParsed(interpreter, "reproducer capture enable", - "Disable gathering information for reproducer", - nullptr) {} - - ~CommandObjectReproducerCaptureDisable() override = default; - -protected: - bool DoExecute(Args &command, CommandReturnObject &result) override { - if (!command.empty()) { - result.AppendErrorWithFormat("'%s' takes no arguments", - m_cmd_name.c_str()); - return false; - } - - if (auto e = m_interpreter.GetDebugger().SetReproducerCapture(false)) { - AppendErrorToResult(std::move(e), result); - return false; - } - - result.SetStatus(eReturnStatusSuccessFinishNoResult); - return result.Succeeded(); - } -}; - class CommandObjectReproducerGenerate : public CommandObjectParsed { public: CommandObjectReproducerGenerate(CommandInterpreter &interpreter) @@ -110,82 +51,47 @@ protected: } }; -class CommandObjectReproducerReplay : public CommandObjectParsed { +class CommandObjectReproducerStatus : public CommandObjectParsed { public: - CommandObjectReproducerReplay(CommandInterpreter &interpreter) - : CommandObjectParsed(interpreter, "reproducer replay", - "Replay a reproducer.", nullptr) { - CommandArgumentEntry arg1; - CommandArgumentData path_arg; - - // Define the first (and only) variant of this arg. - path_arg.arg_type = eArgTypePath; - path_arg.arg_repetition = eArgRepeatPlain; - - // There is only one variant this argument could be; put it into the - // argument entry. - arg1.push_back(path_arg); - - // Push the data for the first argument into the m_arguments vector. - m_arguments.push_back(arg1); - } + CommandObjectReproducerStatus(CommandInterpreter &interpreter) + : CommandObjectParsed(interpreter, "reproducer status", + "Show the current reproducer status.", nullptr) {} - ~CommandObjectReproducerReplay() override = default; + ~CommandObjectReproducerStatus() override = default; protected: bool DoExecute(Args &command, CommandReturnObject &result) override { - if (command.empty()) { - result.AppendErrorWithFormat( - "'%s' takes a single argument: the reproducer path", - m_cmd_name.c_str()); + if (!command.empty()) { + result.AppendErrorWithFormat("'%s' takes no arguments", + m_cmd_name.c_str()); return false; } auto &r = repro::Reproducer::Instance(); + if (auto generator = r.GetGenerator()) { + result.GetOutputStream() << "Reproducer is in capture mode.\n"; + } else if (auto generator = r.GetLoader()) { + result.GetOutputStream() << "Reproducer is in replay mode.\n"; + } else { - const char *repro_path = command.GetArgumentAtIndex(0); - if (auto e = r.SetReplay(FileSpec(repro_path))) { - std::string error_str = llvm::toString(std::move(e)); - result.AppendErrorWithFormat("%s", error_str.c_str()); - return false; + result.GetOutputStream() << "Reproducer is off.\n"; } - result.SetStatus(eReturnStatusSuccessFinishNoResult); + result.SetStatus(eReturnStatusSuccessFinishResult); return result.Succeeded(); } }; -class CommandObjectReproducerCapture : public CommandObjectMultiword { -private: -public: - CommandObjectReproducerCapture(CommandInterpreter &interpreter) - : CommandObjectMultiword( - interpreter, "reproducer capture", - "Manage gathering of information needed to generate a reproducer.", - NULL) { - LoadSubCommand( - "enable", - CommandObjectSP(new CommandObjectReproducerCaptureEnable(interpreter))); - LoadSubCommand("disable", - CommandObjectSP( - new CommandObjectReproducerCaptureDisable(interpreter))); - } - - ~CommandObjectReproducerCapture() {} -}; - CommandObjectReproducer::CommandObjectReproducer( CommandInterpreter &interpreter) : CommandObjectMultiword(interpreter, "reproducer", "Commands controlling LLDB reproducers.", "log <subcommand> [<command-options>]") { - LoadSubCommand("capture", CommandObjectSP(new CommandObjectReproducerCapture( - interpreter))); LoadSubCommand( "generate", CommandObjectSP(new CommandObjectReproducerGenerate(interpreter))); - LoadSubCommand("replay", CommandObjectSP( - new CommandObjectReproducerReplay(interpreter))); + LoadSubCommand("status", CommandObjectSP( + new CommandObjectReproducerStatus(interpreter))); } CommandObjectReproducer::~CommandObjectReproducer() = default; diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp index 1f12dc4dbd6..6e86519b501 100644 --- a/lldb/source/Core/Debugger.cpp +++ b/lldb/source/Core/Debugger.cpp @@ -418,24 +418,6 @@ llvm::StringRef Debugger::GetReproducerPath() const { return r.GetReproducerPath().GetCString(); } -llvm::Error Debugger::SetReproducerReplay(llvm::StringRef p) { - llvm::Optional<FileSpec> arg = llvm::None; - - if (!p.empty()) - arg = FileSpec(p); - - return repro::Reproducer::Instance().SetReplay(arg); -} - -llvm::Error Debugger::SetReproducerCapture(bool b) { - llvm::Optional<FileSpec> arg = llvm::None; - - if (b) - arg = HostInfo::GetReproducerTempDir(); - - return repro::Reproducer::Instance().SetCapture(arg); -} - const FormatEntity::Entry *Debugger::GetThreadFormat() const { const uint32_t idx = ePropertyThreadFormat; return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx); diff --git a/lldb/source/Host/common/HostInfoBase.cpp b/lldb/source/Host/common/HostInfoBase.cpp index e82fec36705..34c362efc9e 100644 --- a/lldb/source/Host/common/HostInfoBase.cpp +++ b/lldb/source/Host/common/HostInfoBase.cpp @@ -194,19 +194,6 @@ FileSpec HostInfoBase::GetGlobalTempDir() { return success ? g_fields->m_lldb_global_tmp_dir : FileSpec(); } -FileSpec HostInfoBase::GetReproducerTempDir() { - static llvm::once_flag g_once_flag; - static bool success = false; - llvm::call_once(g_once_flag, []() { - success = HostInfo::ComputeReproducerTempFileDirectory( - g_fields->m_lldb_global_tmp_dir); - Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); - LLDB_LOG(log, "reproducer temp dir -> `{0}`", - g_fields->m_lldb_global_tmp_dir); - }); - return success ? g_fields->m_lldb_global_tmp_dir : FileSpec(); -} - ArchSpec HostInfoBase::GetAugmentedArchSpec(llvm::StringRef triple) { if (triple.empty()) return ArchSpec(); @@ -289,26 +276,6 @@ bool HostInfoBase::ComputeGlobalTempFileDirectory(FileSpec &file_spec) { return true; } -bool HostInfoBase::ComputeReproducerTempFileDirectory(FileSpec &file_spec) { - file_spec.Clear(); - - FileSpec temp_file_spec; - if (!HostInfo::ComputeTempFileBaseDirectory(temp_file_spec)) - return false; - - temp_file_spec.AppendPathComponent("reproducer"); - if (llvm::sys::fs::create_directory(temp_file_spec.GetPath())) - return false; - - std::string pid_str{llvm::to_string(Host::GetCurrentProcessID())}; - temp_file_spec.AppendPathComponent(pid_str); - if (llvm::sys::fs::create_directory(temp_file_spec.GetPath())) - return false; - - file_spec.GetDirectory().SetCString(temp_file_spec.GetCString()); - return true; -} - bool HostInfoBase::ComputeHeaderDirectory(FileSpec &file_spec) { // TODO(zturner): Figure out how to compute the header directory for all // platforms. diff --git a/lldb/source/Initialization/SystemInitializerCommon.cpp b/lldb/source/Initialization/SystemInitializerCommon.cpp index 221dc8c58b7..d1d55fcfde7 100644 --- a/lldb/source/Initialization/SystemInitializerCommon.cpp +++ b/lldb/source/Initialization/SystemInitializerCommon.cpp @@ -19,6 +19,7 @@ #include "lldb/Host/Host.h" #include "lldb/Host/HostInfo.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/Reproducer.h" #include "lldb/Utility/Timer.h" #if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) @@ -35,12 +36,14 @@ #include <string> using namespace lldb_private; +using namespace lldb_private::repro; SystemInitializerCommon::SystemInitializerCommon() {} SystemInitializerCommon::~SystemInitializerCommon() {} -void SystemInitializerCommon::Initialize() { +llvm::Error +SystemInitializerCommon::Initialize(const InitializerOptions &options) { #if defined(_MSC_VER) const char *disable_crash_dialog_var = getenv("LLDB_DISABLE_CRASH_DIALOG"); if (disable_crash_dialog_var && @@ -63,6 +66,15 @@ void SystemInitializerCommon::Initialize() { } #endif + ReproducerMode mode = ReproducerMode::Off; + if (options.reproducer_capture) + mode = ReproducerMode::Capture; + if (options.reproducer_replay) + mode = ReproducerMode::Replay; + + if (auto e = Reproducer::Initialize(mode, FileSpec(options.reproducer_path))) + return e; + FileSystem::Initialize(); Log::Initialize(); HostInfo::Initialize(); @@ -89,6 +101,8 @@ void SystemInitializerCommon::Initialize() { #if defined(_MSC_VER) ProcessWindowsLog::Initialize(); #endif + + return llvm::Error::success(); } void SystemInitializerCommon::Terminate() { @@ -109,4 +123,5 @@ void SystemInitializerCommon::Terminate() { HostInfo::Terminate(); Log::DisableAllLogChannels(); FileSystem::Terminate(); + Reproducer::Terminate(); } diff --git a/lldb/source/Initialization/SystemLifetimeManager.cpp b/lldb/source/Initialization/SystemLifetimeManager.cpp index 4d271787833..65431bf6017 100644 --- a/lldb/source/Initialization/SystemLifetimeManager.cpp +++ b/lldb/source/Initialization/SystemLifetimeManager.cpp @@ -24,9 +24,9 @@ SystemLifetimeManager::~SystemLifetimeManager() { "SystemLifetimeManager destroyed without calling Terminate!"); } -void SystemLifetimeManager::Initialize( +llvm::Error SystemLifetimeManager::Initialize( std::unique_ptr<SystemInitializer> initializer, - LoadPluginCallbackType plugin_callback) { + const InitializerOptions &options, LoadPluginCallbackType plugin_callback) { std::lock_guard<std::recursive_mutex> guard(m_mutex); if (!m_initialized) { assert(!m_initializer && "Attempting to call " @@ -35,9 +35,13 @@ void SystemLifetimeManager::Initialize( m_initialized = true; m_initializer = std::move(initializer); - m_initializer->Initialize(); + if (auto e = m_initializer->Initialize(options)) + return e; + Debugger::Initialize(plugin_callback); } + + return llvm::Error::success(); } void SystemLifetimeManager::Terminate() { diff --git a/lldb/source/Utility/Reproducer.cpp b/lldb/source/Utility/Reproducer.cpp index 0048a11970d..a6b5fa849c2 100644 --- a/lldb/source/Utility/Reproducer.cpp +++ b/lldb/source/Utility/Reproducer.cpp @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// #include "lldb/Utility/Reproducer.h" +#include "lldb/Utility/LLDBAssert.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Threading.h" @@ -18,8 +19,46 @@ using namespace lldb_private::repro; using namespace llvm; using namespace llvm::yaml; -Reproducer &Reproducer::Instance() { - static Reproducer g_reproducer; +Reproducer &Reproducer::Instance() { return *InstanceImpl(); } + +llvm::Error Reproducer::Initialize(ReproducerMode mode, + llvm::Optional<FileSpec> root) { + lldbassert(!InstanceImpl() && "Already initialized."); + InstanceImpl().emplace(); + + switch (mode) { + case ReproducerMode::Capture: { + if (!root) { + SmallString<128> repro_dir; + auto ec = sys::fs::createUniqueDirectory("reproducer", repro_dir); + if (ec) + return make_error<StringError>( + "unable to create unique reproducer directory", ec); + root.emplace(repro_dir); + } else { + auto ec = sys::fs::create_directories(root->GetPath()); + if (ec) + return make_error<StringError>("unable to create reproducer directory", + ec); + } + return Instance().SetCapture(root); + } break; + case ReproducerMode::Replay: + return Instance().SetReplay(root); + case ReproducerMode::Off: + break; + }; + + return Error::success(); +} + +void Reproducer::Terminate() { + lldbassert(InstanceImpl() && "Already terminated."); + InstanceImpl().reset(); +} + +Optional<Reproducer> &Reproducer::InstanceImpl() { + static Optional<Reproducer> g_reproducer; return g_reproducer; } @@ -59,11 +98,12 @@ llvm::Error Reproducer::SetCapture(llvm::Optional<FileSpec> root) { "cannot generate a reproducer when replay one", inconvertibleErrorCode()); - if (root) - m_generator.emplace(*root); - else + if (!root) { m_generator.reset(); + return Error::success(); + } + m_generator.emplace(*root); return Error::success(); } @@ -75,14 +115,15 @@ llvm::Error Reproducer::SetReplay(llvm::Optional<FileSpec> root) { "cannot replay a reproducer when generating one", inconvertibleErrorCode()); - if (root) { - m_loader.emplace(*root); - if (auto e = m_loader->LoadIndex()) - return e; - } else { + if (!root) { m_loader.reset(); + return Error::success(); } + m_loader.emplace(*root); + if (auto e = m_loader->LoadIndex()) + return e; + return Error::success(); } @@ -153,14 +194,14 @@ llvm::Error Loader::LoadIndex() { auto error_or_file = MemoryBuffer::getFile(index.GetPath()); if (auto err = error_or_file.getError()) - return errorCodeToError(err); + return make_error<StringError>("unable to load reproducer index", err); std::vector<ProviderInfo> provider_info; yaml::Input yin((*error_or_file)->getBuffer()); yin >> provider_info; if (auto err = yin.error()) - return errorCodeToError(err); + return make_error<StringError>("unable to read reproducer index", err); for (auto &info : provider_info) m_provider_info[info.name] = info; diff --git a/lldb/tools/driver/Driver.cpp b/lldb/tools/driver/Driver.cpp index 637103088b1..cd61cf66833 100644 --- a/lldb/tools/driver/Driver.cpp +++ b/lldb/tools/driver/Driver.cpp @@ -367,21 +367,6 @@ SBError Driver::ProcessArgs(const opt::InputArgList &args, bool &exiting) { m_option_data.m_debug_mode = true; } - if (auto *arg = args.getLastArg(OPT_reproducer)) { - auto arg_value = arg->getValue(); - SBFileSpec file(arg_value); - if (file.Exists()) { - SBError repro_error = m_debugger.ReplayReproducer(arg_value); - if (repro_error.Fail()) - return repro_error; - } else { - error.SetErrorStringWithFormat("file specified in --reproducer " - "(-z) option doesn't exist: '%s'", - arg_value); - return error; - } - } - if (args.hasArg(OPT_no_use_colors)) { m_debugger.SetUseColor(false); } @@ -942,7 +927,27 @@ main(int argc, char const *argv[]) << '\n'; } - SBDebugger::Initialize(); + SBInitializerOptions options; + + if (auto *arg = input_args.getLastArg(OPT_capture)) { + auto arg_value = arg->getValue(); + options.SetReproducerPath(arg_value); + options.SetCaptureReproducer(true); + } + + if (auto *arg = input_args.getLastArg(OPT_replay)) { + auto arg_value = arg->getValue(); + options.SetReplayReproducer(true); + options.SetReproducerPath(arg_value); + } + + SBError error = SBDebugger::Initialize(options); + if (error.Fail()) { + WithColor::error() << "initialization failed: " << error.GetCString() + << '\n'; + return 1; + } + SBHostOS::ThreadCreated("<lldb.driver.main-thread>"); signal(SIGINT, sigint_handler); diff --git a/lldb/tools/driver/Options.td b/lldb/tools/driver/Options.td index 90df963325a..4a2ddfeefa3 100644 --- a/lldb/tools/driver/Options.td +++ b/lldb/tools/driver/Options.td @@ -209,11 +209,11 @@ def: Flag<["-"], "d">, Alias<debug>, HelpText<"Alias for --debug">; -def reproducer: Separate<["--", "-"], "reproducer">, +def capture: Separate<["--", "-"], "capture">, MetaVarName<"<filename>">, - HelpText<"Tells the debugger to use the fullpath to <filename> as a reproducer.">; -def: Separate<["-"], "z">, - Alias<file>, - HelpText<"Alias for --reproducer">; + HelpText<"Tells the debugger to capture a reproducer to <filename>.">; +def replay: Separate<["--", "-"], "replay">, + MetaVarName<"<filename>">, + HelpText<"Tells the debugger to replay a reproducer from <filename>.">; def REM : R<["--"], "">; diff --git a/lldb/tools/lldb-server/SystemInitializerLLGS.cpp b/lldb/tools/lldb-server/SystemInitializerLLGS.cpp index aeaf382a1dd..93ef4d9d076 100644 --- a/lldb/tools/lldb-server/SystemInitializerLLGS.cpp +++ b/lldb/tools/lldb-server/SystemInitializerLLGS.cpp @@ -22,9 +22,14 @@ using HostObjectFile = ObjectFileELF; using namespace lldb_private; -void SystemInitializerLLGS::Initialize() { - SystemInitializerCommon::Initialize(); +llvm::Error +SystemInitializerLLGS::Initialize(const InitializerOptions &options) { + if (auto e = SystemInitializerCommon::Initialize(options)) + return e; + HostObjectFile::Initialize(); + + return llvm::Error::success(); } void SystemInitializerLLGS::Terminate() { diff --git a/lldb/tools/lldb-server/SystemInitializerLLGS.h b/lldb/tools/lldb-server/SystemInitializerLLGS.h index e6460a2cdd3..7feba3fe07b 100644 --- a/lldb/tools/lldb-server/SystemInitializerLLGS.h +++ b/lldb/tools/lldb-server/SystemInitializerLLGS.h @@ -10,11 +10,13 @@ #ifndef LLDB_SYSTEMINITIALIZERLLGS_H #define LLDB_SYSTEMINITIALIZERLLGS_H +#include "lldb/Initialization/SystemInitializer.h" #include "lldb/Initialization/SystemInitializerCommon.h" class SystemInitializerLLGS : public lldb_private::SystemInitializerCommon { public: - void Initialize() override; + llvm::Error + Initialize(const lldb_private::InitializerOptions &options) override; void Terminate() override; }; diff --git a/lldb/tools/lldb-server/lldb-server.cpp b/lldb/tools/lldb-server/lldb-server.cpp index f05c96cfaa9..c924fa22f31 100644 --- a/lldb/tools/lldb-server/lldb-server.cpp +++ b/lldb/tools/lldb-server/lldb-server.cpp @@ -38,8 +38,9 @@ int main_gdbserver(int argc, char *argv[]); int main_platform(int argc, char *argv[]); static void initialize() { - g_debugger_lifetime->Initialize(llvm::make_unique<SystemInitializerLLGS>(), - nullptr); + if (auto e = g_debugger_lifetime->Initialize( + llvm::make_unique<SystemInitializerLLGS>(), {}, nullptr)) + llvm::consumeError(std::move(e)); } static void terminate() { g_debugger_lifetime->Terminate(); } diff --git a/lldb/tools/lldb-test/SystemInitializerTest.cpp b/lldb/tools/lldb-test/SystemInitializerTest.cpp index 750f9c3d5cf..8f549bcd1d0 100644 --- a/lldb/tools/lldb-test/SystemInitializerTest.cpp +++ b/lldb/tools/lldb-test/SystemInitializerTest.cpp @@ -111,8 +111,10 @@ SystemInitializerTest::SystemInitializerTest() {} SystemInitializerTest::~SystemInitializerTest() {} -void SystemInitializerTest::Initialize() { - SystemInitializerCommon::Initialize(); +llvm::Error +SystemInitializerTest::Initialize(const InitializerOptions &options) { + if (auto e = SystemInitializerCommon::Initialize(options)) + return e; ObjectFileELF::Initialize(); ObjectFileMachO::Initialize(); @@ -231,6 +233,8 @@ void SystemInitializerTest::Initialize() { // AFTER PluginManager::Initialize is called. Debugger::SettingsInitialize(); + + return llvm::Error::success(); } void SystemInitializerTest::Terminate() { diff --git a/lldb/tools/lldb-test/SystemInitializerTest.h b/lldb/tools/lldb-test/SystemInitializerTest.h index 887d6243765..5950ff725ff 100644 --- a/lldb/tools/lldb-test/SystemInitializerTest.h +++ b/lldb/tools/lldb-test/SystemInitializerTest.h @@ -26,7 +26,7 @@ public: SystemInitializerTest(); ~SystemInitializerTest() override; - void Initialize() override; + llvm::Error Initialize(const InitializerOptions &options) override; void Terminate() override; }; diff --git a/lldb/tools/lldb-test/lldb-test.cpp b/lldb/tools/lldb-test/lldb-test.cpp index 631e6a5dd1e..25ee16886e5 100644 --- a/lldb/tools/lldb-test/lldb-test.cpp +++ b/lldb/tools/lldb-test/lldb-test.cpp @@ -934,8 +934,13 @@ int main(int argc, const char *argv[]) { cl::ParseCommandLineOptions(argc, argv, "LLDB Testing Utility\n"); SystemLifetimeManager DebuggerLifetime; - DebuggerLifetime.Initialize(llvm::make_unique<SystemInitializerTest>(), - nullptr); + if (auto e = DebuggerLifetime.Initialize( + llvm::make_unique<SystemInitializerTest>(), {}, nullptr)) { + WithColor::error() << "initialization failed: " << toString(std::move(e)) + << '\n'; + return 1; + } + CleanUp TerminateDebugger([&] { DebuggerLifetime.Terminate(); }); auto Dbg = lldb_private::Debugger::CreateInstance(); diff --git a/lldb/unittests/Utility/ReproducerTest.cpp b/lldb/unittests/Utility/ReproducerTest.cpp index 29d65e5d29c..aadb92b2184 100644 --- a/lldb/unittests/Utility/ReproducerTest.cpp +++ b/lldb/unittests/Utility/ReproducerTest.cpp @@ -32,10 +32,18 @@ public: static char ID; }; +class DummyReproducer : public Reproducer { +public: + DummyReproducer() : Reproducer(){}; + + using Reproducer::SetCapture; + using Reproducer::SetReplay; +}; + char DummyProvider::ID = 0; TEST(ReproducerTest, SetCapture) { - Reproducer reproducer; + DummyReproducer reproducer; // Initially both generator and loader are unset. EXPECT_EQ(nullptr, reproducer.GetGenerator()); @@ -59,7 +67,7 @@ TEST(ReproducerTest, SetCapture) { } TEST(ReproducerTest, SetReplay) { - Reproducer reproducer; + DummyReproducer reproducer; // Initially both generator and loader are unset. EXPECT_EQ(nullptr, reproducer.GetGenerator()); @@ -80,7 +88,7 @@ TEST(ReproducerTest, SetReplay) { } TEST(GeneratorTest, Create) { - Reproducer reproducer; + DummyReproducer reproducer; EXPECT_THAT_ERROR(reproducer.SetCapture(FileSpec("/bogus/path")), Succeeded()); @@ -95,7 +103,7 @@ TEST(GeneratorTest, Create) { } TEST(GeneratorTest, Get) { - Reproducer reproducer; + DummyReproducer reproducer; EXPECT_THAT_ERROR(reproducer.SetCapture(FileSpec("/bogus/path")), Succeeded()); @@ -109,7 +117,7 @@ TEST(GeneratorTest, Get) { } TEST(GeneratorTest, GetOrCreate) { - Reproducer reproducer; + DummyReproducer reproducer; EXPECT_THAT_ERROR(reproducer.SetCapture(FileSpec("/bogus/path")), Succeeded()); |