From 15eacd741faa5ec75ef55d82db3486cbaf91f46f Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Mon, 3 Dec 2018 17:28:29 +0000 Subject: [PATCH] [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 --- lldb/include/lldb/API/SBDebugger.h | 4 +- lldb/include/lldb/API/SBDefines.h | 1 + lldb/include/lldb/API/SBFileSpec.h | 3 +- lldb/include/lldb/API/SBInitializerOptions.h | 43 ++++++ lldb/include/lldb/Core/Debugger.h | 5 - lldb/include/lldb/Host/HostInfoBase.h | 7 - .../lldb/Initialization/SystemInitializer.h | 13 +- .../Initialization/SystemInitializerCommon.h | 2 +- .../Initialization/SystemLifetimeManager.h | 8 +- lldb/include/lldb/Utility/Reproducer.h | 21 ++- .../lit/Reproducer/Inputs/GDBRemoteCapture.in | 6 + lldb/lit/Reproducer/Inputs/GDBRemoteReplay.in | 5 + lldb/lit/Reproducer/Inputs/simple.c | 19 +++ lldb/lit/Reproducer/TestDriverOptions.test | 7 + lldb/lit/Reproducer/TestGDBRemoteRepro.test | 26 ++++ .../reproducer/gdb-remote/Makefile | 5 - .../gdb-remote/TestGdbRemoteReproducer.py | 49 ------- lldb/scripts/interface/SBDebugger.i | 6 +- lldb/scripts/interface/SBInitializerOptions.i | 24 ++++ lldb/scripts/lldb.swig | 1 + lldb/source/API/CMakeLists.txt | 1 + lldb/source/API/SBDebugger.cpp | 25 ++-- lldb/source/API/SBInitializerOptions.cpp | 49 +++++++ lldb/source/API/SystemInitializerFull.cpp | 8 +- lldb/source/API/SystemInitializerFull.h | 2 +- .../Commands/CommandObjectReproducer.cpp | 128 +++--------------- lldb/source/Core/Debugger.cpp | 18 --- lldb/source/Host/common/HostInfoBase.cpp | 33 ----- .../SystemInitializerCommon.cpp | 17 ++- .../Initialization/SystemLifetimeManager.cpp | 10 +- lldb/source/Utility/Reproducer.cpp | 65 +++++++-- lldb/tools/driver/Driver.cpp | 37 ++--- lldb/tools/driver/Options.td | 10 +- .../lldb-server/SystemInitializerLLGS.cpp | 9 +- .../tools/lldb-server/SystemInitializerLLGS.h | 4 +- lldb/tools/lldb-server/lldb-server.cpp | 5 +- .../tools/lldb-test/SystemInitializerTest.cpp | 8 +- lldb/tools/lldb-test/SystemInitializerTest.h | 2 +- lldb/tools/lldb-test/lldb-test.cpp | 9 +- lldb/unittests/Utility/ReproducerTest.cpp | 18 ++- 40 files changed, 402 insertions(+), 311 deletions(-) create mode 100644 lldb/include/lldb/API/SBInitializerOptions.h create mode 100644 lldb/lit/Reproducer/Inputs/GDBRemoteCapture.in create mode 100644 lldb/lit/Reproducer/Inputs/GDBRemoteReplay.in create mode 100644 lldb/lit/Reproducer/Inputs/simple.c create mode 100644 lldb/lit/Reproducer/TestDriverOptions.test create mode 100644 lldb/lit/Reproducer/TestGDBRemoteRepro.test delete mode 100644 lldb/packages/Python/lldbsuite/test/functionalities/reproducer/gdb-remote/Makefile delete mode 100644 lldb/packages/Python/lldbsuite/test/functionalities/reproducer/gdb-remote/TestGdbRemoteReproducer.py create mode 100644 lldb/scripts/interface/SBInitializerOptions.i create mode 100644 lldb/source/API/SBInitializerOptions.cpp diff --git a/lldb/include/lldb/API/SBDebugger.h b/lldb/include/lldb/API/SBDebugger.h index ccb1f6dae0f3..3f31bf16da8d 100644 --- a/lldb/include/lldb/API/SBDebugger.h +++ b/lldb/include/lldb/API/SBDebugger.h @@ -13,6 +13,7 @@ #include #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 166cc2ae129c..c5c9851272f2 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 33e48f5c7c41..9ad1a5df0cfa 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 000000000000..184c82df4f86 --- /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 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 8056b8bf7acf..f7de9ff281ae 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 efc6607a1336..f3e49c8f25d7 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 58bbb44b1f34..b665b9997214 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 + 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 2a9851c6a34c..f33acaf40466 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 0ebd4a50a342..0839856f21e2 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 #include namespace lldb_private { -class SystemInitializer; class SystemLifetimeManager { public: SystemLifetimeManager(); ~SystemLifetimeManager(); - void Initialize(std::unique_ptr initializer, - LoadPluginCallbackType plugin_callback); + llvm::Error Initialize(std::unique_ptr 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 6ad1acfa5ff7..ea315ad771a6 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 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 root); llvm::Error SetReplay(llvm::Optional root); - FileSpec GetReproducerPath() const; - private: + static llvm::Optional &InstanceImpl(); + llvm::Optional m_generator; llvm::Optional m_loader; diff --git a/lldb/lit/Reproducer/Inputs/GDBRemoteCapture.in b/lldb/lit/Reproducer/Inputs/GDBRemoteCapture.in new file mode 100644 index 000000000000..8df7ca42fee0 --- /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 000000000000..1364c7e72764 --- /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 000000000000..a4585b380ca6 --- /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 + +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 000000000000..d7a076841d9b --- /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 000000000000..6a6bdd780a85 --- /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 b09a579159d4..000000000000 --- 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 adbbd1be6456..000000000000 --- 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 18796e80e559..fde3d7b6b88e 100644 --- a/lldb/scripts/interface/SBDebugger.i +++ b/lldb/scripts/interface/SBDebugger.i @@ -123,6 +123,9 @@ public: static void Initialize(); + static void + Initialize(lldb::SBInitializerOptions& options); + static void Terminate(); @@ -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 000000000000..9478642ebd6f --- /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 e920718d3e84..e8553d075d46 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 3c5f4ddb43f6..d2ab24c7c01f 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 a7217964abf3..af343233c90e 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(), - LoadPlugin); + SBError error; + if (auto e = g_debugger_lifetime->Initialize( + llvm::make_unique(), *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 000000000000..8d8ec28190ec --- /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 671077ca0b0c..937604425b42 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 9cfc6896da61..b0cf476e9193 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 03a3e2309802..f393f17d9aec 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; + CommandObjectReproducerStatus(CommandInterpreter &interpreter) + : CommandObjectParsed(interpreter, "reproducer status", + "Show the current reproducer status.", nullptr) {} - // 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); - } - - ~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 []") { - 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 1f12dc4dbd63..6e86519b501f 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 arg = llvm::None; - - if (!p.empty()) - arg = FileSpec(p); - - return repro::Reproducer::Instance().SetReplay(arg); -} - -llvm::Error Debugger::SetReproducerCapture(bool b) { - llvm::Optional 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 e82fec36705f..34c362efc9e0 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 221dc8c58b7a..d1d55fcfde74 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 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 4d271787833d..65431bf6017d 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 initializer, - LoadPluginCallbackType plugin_callback) { + const InitializerOptions &options, LoadPluginCallbackType plugin_callback) { std::lock_guard 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 0048a11970df..a6b5fa849c2c 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 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( + "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("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::InstanceImpl() { + static Optional g_reproducer; return g_reproducer; } @@ -59,11 +98,12 @@ llvm::Error Reproducer::SetCapture(llvm::Optional 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 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("unable to load reproducer index", err); std::vector provider_info; yaml::Input yin((*error_or_file)->getBuffer()); yin >> provider_info; if (auto err = yin.error()) - return errorCodeToError(err); + return make_error("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 637103088b13..cd61cf66833f 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(""); signal(SIGINT, sigint_handler); diff --git a/lldb/tools/driver/Options.td b/lldb/tools/driver/Options.td index 90df963325a2..4a2ddfeefa33 100644 --- a/lldb/tools/driver/Options.td +++ b/lldb/tools/driver/Options.td @@ -209,11 +209,11 @@ def: Flag<["-"], "d">, Alias, HelpText<"Alias for --debug">; -def reproducer: Separate<["--", "-"], "reproducer">, +def capture: Separate<["--", "-"], "capture">, MetaVarName<"">, - HelpText<"Tells the debugger to use the fullpath to as a reproducer.">; -def: Separate<["-"], "z">, - Alias, - HelpText<"Alias for --reproducer">; + HelpText<"Tells the debugger to capture a reproducer to .">; +def replay: Separate<["--", "-"], "replay">, + MetaVarName<"">, + HelpText<"Tells the debugger to replay a reproducer from .">; def REM : R<["--"], "">; diff --git a/lldb/tools/lldb-server/SystemInitializerLLGS.cpp b/lldb/tools/lldb-server/SystemInitializerLLGS.cpp index aeaf382a1dd8..93ef4d9d0761 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 e6460a2cdd39..7feba3fe07bd 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 f05c96cfaa95..c924fa22f310 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(), - nullptr); + if (auto e = g_debugger_lifetime->Initialize( + llvm::make_unique(), {}, 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 750f9c3d5cfd..8f549bcd1d03 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 887d6243765d..5950ff725ff0 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 631e6a5dd1e3..25ee16886e55 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(), - nullptr); + if (auto e = DebuggerLifetime.Initialize( + llvm::make_unique(), {}, 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 29d65e5d29cb..aadb92b21843 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());