[Lldb-commits] [lldb] r348152 - [Reproducers] Change how reproducers are initialized.

Jonas Devlieghere via lldb-commits lldb-commits at lists.llvm.org
Mon Dec 3 09:28:29 PST 2018


Author: jdevlieghere
Date: Mon Dec  3 09:28:29 2018
New Revision: 348152

URL: http://llvm.org/viewvc/llvm-project?rev=348152&view=rev
Log:
[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

Added:
    lldb/trunk/include/lldb/API/SBInitializerOptions.h
    lldb/trunk/lit/Reproducer/
    lldb/trunk/lit/Reproducer/Inputs/
    lldb/trunk/lit/Reproducer/Inputs/GDBRemoteCapture.in
    lldb/trunk/lit/Reproducer/Inputs/GDBRemoteReplay.in
    lldb/trunk/lit/Reproducer/Inputs/simple.c
    lldb/trunk/lit/Reproducer/TestDriverOptions.test
    lldb/trunk/lit/Reproducer/TestGDBRemoteRepro.test
    lldb/trunk/scripts/interface/SBInitializerOptions.i
    lldb/trunk/source/API/SBInitializerOptions.cpp
Removed:
    lldb/trunk/packages/Python/lldbsuite/test/functionalities/reproducer/gdb-remote/Makefile
    lldb/trunk/packages/Python/lldbsuite/test/functionalities/reproducer/gdb-remote/TestGdbRemoteReproducer.py
Modified:
    lldb/trunk/include/lldb/API/SBDebugger.h
    lldb/trunk/include/lldb/API/SBDefines.h
    lldb/trunk/include/lldb/API/SBFileSpec.h
    lldb/trunk/include/lldb/Core/Debugger.h
    lldb/trunk/include/lldb/Host/HostInfoBase.h
    lldb/trunk/include/lldb/Initialization/SystemInitializer.h
    lldb/trunk/include/lldb/Initialization/SystemInitializerCommon.h
    lldb/trunk/include/lldb/Initialization/SystemLifetimeManager.h
    lldb/trunk/include/lldb/Utility/Reproducer.h
    lldb/trunk/scripts/interface/SBDebugger.i
    lldb/trunk/scripts/lldb.swig
    lldb/trunk/source/API/CMakeLists.txt
    lldb/trunk/source/API/SBDebugger.cpp
    lldb/trunk/source/API/SystemInitializerFull.cpp
    lldb/trunk/source/API/SystemInitializerFull.h
    lldb/trunk/source/Commands/CommandObjectReproducer.cpp
    lldb/trunk/source/Core/Debugger.cpp
    lldb/trunk/source/Host/common/HostInfoBase.cpp
    lldb/trunk/source/Initialization/SystemInitializerCommon.cpp
    lldb/trunk/source/Initialization/SystemLifetimeManager.cpp
    lldb/trunk/source/Utility/Reproducer.cpp
    lldb/trunk/tools/driver/Driver.cpp
    lldb/trunk/tools/driver/Options.td
    lldb/trunk/tools/lldb-server/SystemInitializerLLGS.cpp
    lldb/trunk/tools/lldb-server/SystemInitializerLLGS.h
    lldb/trunk/tools/lldb-server/lldb-server.cpp
    lldb/trunk/tools/lldb-test/SystemInitializerTest.cpp
    lldb/trunk/tools/lldb-test/SystemInitializerTest.h
    lldb/trunk/tools/lldb-test/lldb-test.cpp
    lldb/trunk/unittests/Utility/ReproducerTest.cpp

Modified: lldb/trunk/include/lldb/API/SBDebugger.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBDebugger.h?rev=348152&r1=348151&r2=348152&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBDebugger.h (original)
+++ lldb/trunk/include/lldb/API/SBDebugger.h Mon Dec  3 09:28:29 2018
@@ -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);

Modified: lldb/trunk/include/lldb/API/SBDefines.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBDefines.h?rev=348152&r1=348151&r2=348152&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBDefines.h (original)
+++ lldb/trunk/include/lldb/API/SBDefines.h Mon Dec  3 09:28:29 2018
@@ -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;

Modified: lldb/trunk/include/lldb/API/SBFileSpec.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBFileSpec.h?rev=348152&r1=348151&r2=348152&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBFileSpec.h (original)
+++ lldb/trunk/include/lldb/API/SBFileSpec.h Mon Dec  3 09:28:29 2018
@@ -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);
 

Added: lldb/trunk/include/lldb/API/SBInitializerOptions.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBInitializerOptions.h?rev=348152&view=auto
==============================================================================
--- lldb/trunk/include/lldb/API/SBInitializerOptions.h (added)
+++ lldb/trunk/include/lldb/API/SBInitializerOptions.h Mon Dec  3 09:28:29 2018
@@ -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_

Modified: lldb/trunk/include/lldb/Core/Debugger.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Debugger.h?rev=348152&r1=348151&r2=348152&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/Debugger.h (original)
+++ lldb/trunk/include/lldb/Core/Debugger.h Mon Dec  3 09:28:29 2018
@@ -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);

Modified: lldb/trunk/include/lldb/Host/HostInfoBase.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Host/HostInfoBase.h?rev=348152&r1=348151&r2=348152&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Host/HostInfoBase.h (original)
+++ lldb/trunk/include/lldb/Host/HostInfoBase.h Mon Dec  3 09:28:29 2018
@@ -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);

Modified: lldb/trunk/include/lldb/Initialization/SystemInitializer.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Initialization/SystemInitializer.h?rev=348152&r1=348151&r2=348152&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Initialization/SystemInitializer.h (original)
+++ lldb/trunk/include/lldb/Initialization/SystemInitializer.h Mon Dec  3 09:28:29 2018
@@ -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;
 };
 }

Modified: lldb/trunk/include/lldb/Initialization/SystemInitializerCommon.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Initialization/SystemInitializerCommon.h?rev=348152&r1=348151&r2=348152&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Initialization/SystemInitializerCommon.h (original)
+++ lldb/trunk/include/lldb/Initialization/SystemInitializerCommon.h Mon Dec  3 09:28:29 2018
@@ -28,7 +28,7 @@ public:
   SystemInitializerCommon();
   ~SystemInitializerCommon() override;
 
-  void Initialize() override;
+  llvm::Error Initialize(const InitializerOptions &options) override;
   void Terminate() override;
 };
 

Modified: lldb/trunk/include/lldb/Initialization/SystemLifetimeManager.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Initialization/SystemLifetimeManager.h?rev=348152&r1=348151&r2=348152&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Initialization/SystemLifetimeManager.h (original)
+++ lldb/trunk/include/lldb/Initialization/SystemLifetimeManager.h Mon Dec  3 09:28:29 2018
@@ -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:

Modified: lldb/trunk/include/lldb/Utility/Reproducer.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Utility/Reproducer.h?rev=348152&r1=348151&r2=348152&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Utility/Reproducer.h (original)
+++ lldb/trunk/include/lldb/Utility/Reproducer.h Mon Dec  3 09:28:29 2018
@@ -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;
 

Added: lldb/trunk/lit/Reproducer/Inputs/GDBRemoteCapture.in
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/Reproducer/Inputs/GDBRemoteCapture.in?rev=348152&view=auto
==============================================================================
--- lldb/trunk/lit/Reproducer/Inputs/GDBRemoteCapture.in (added)
+++ lldb/trunk/lit/Reproducer/Inputs/GDBRemoteCapture.in Mon Dec  3 09:28:29 2018
@@ -0,0 +1,6 @@
+breakpoint set -f simple.c -l 13
+run
+bt
+cont
+reproducer status
+reproducer generate

Added: lldb/trunk/lit/Reproducer/Inputs/GDBRemoteReplay.in
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/Reproducer/Inputs/GDBRemoteReplay.in?rev=348152&view=auto
==============================================================================
--- lldb/trunk/lit/Reproducer/Inputs/GDBRemoteReplay.in (added)
+++ lldb/trunk/lit/Reproducer/Inputs/GDBRemoteReplay.in Mon Dec  3 09:28:29 2018
@@ -0,0 +1,5 @@
+reproducer status
+breakpoint set -f simple.c -l 13
+run
+bt
+cont

Added: lldb/trunk/lit/Reproducer/Inputs/simple.c
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/Reproducer/Inputs/simple.c?rev=348152&view=auto
==============================================================================
--- lldb/trunk/lit/Reproducer/Inputs/simple.c (added)
+++ lldb/trunk/lit/Reproducer/Inputs/simple.c Mon Dec  3 09:28:29 2018
@@ -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;
+}

Added: lldb/trunk/lit/Reproducer/TestDriverOptions.test
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/Reproducer/TestDriverOptions.test?rev=348152&view=auto
==============================================================================
--- lldb/trunk/lit/Reproducer/TestDriverOptions.test (added)
+++ lldb/trunk/lit/Reproducer/TestDriverOptions.test Mon Dec  3 09:28:29 2018
@@ -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

Added: lldb/trunk/lit/Reproducer/TestGDBRemoteRepro.test
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/Reproducer/TestGDBRemoteRepro.test?rev=348152&view=auto
==============================================================================
--- lldb/trunk/lit/Reproducer/TestGDBRemoteRepro.test (added)
+++ lldb/trunk/lit/Reproducer/TestGDBRemoteRepro.test Mon Dec  3 09:28:29 2018
@@ -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

Removed: lldb/trunk/packages/Python/lldbsuite/test/functionalities/reproducer/gdb-remote/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/reproducer/gdb-remote/Makefile?rev=348151&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/functionalities/reproducer/gdb-remote/Makefile (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/reproducer/gdb-remote/Makefile (removed)
@@ -1,5 +0,0 @@
-LEVEL = ../../../make
-
-C_SOURCES := main.c
-
-include $(LEVEL)/Makefile.rules

Removed: lldb/trunk/packages/Python/lldbsuite/test/functionalities/reproducer/gdb-remote/TestGdbRemoteReproducer.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/reproducer/gdb-remote/TestGdbRemoteReproducer.py?rev=348151&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/functionalities/reproducer/gdb-remote/TestGdbRemoteReproducer.py (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/reproducer/gdb-remote/TestGdbRemoteReproducer.py (removed)
@@ -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")

Modified: lldb/trunk/scripts/interface/SBDebugger.i
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/interface/SBDebugger.i?rev=348152&r1=348151&r2=348152&view=diff
==============================================================================
--- lldb/trunk/scripts/interface/SBDebugger.i (original)
+++ lldb/trunk/scripts/interface/SBDebugger.i Mon Dec  3 09:28:29 2018
@@ -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;
 

Added: lldb/trunk/scripts/interface/SBInitializerOptions.i
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/interface/SBInitializerOptions.i?rev=348152&view=auto
==============================================================================
--- lldb/trunk/scripts/interface/SBInitializerOptions.i (added)
+++ lldb/trunk/scripts/interface/SBInitializerOptions.i Mon Dec  3 09:28:29 2018
@@ -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

Modified: lldb/trunk/scripts/lldb.swig
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/lldb.swig?rev=348152&r1=348151&r2=348152&view=diff
==============================================================================
--- lldb/trunk/scripts/lldb.swig (original)
+++ lldb/trunk/scripts/lldb.swig Mon Dec  3 09:28:29 2018
@@ -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"

Modified: lldb/trunk/source/API/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/CMakeLists.txt?rev=348152&r1=348151&r2=348152&view=diff
==============================================================================
--- lldb/trunk/source/API/CMakeLists.txt (original)
+++ lldb/trunk/source/API/CMakeLists.txt Mon Dec  3 09:28:29 2018
@@ -29,6 +29,7 @@ add_lldb_library(liblldb SHARED
   SBFrame.cpp
   SBFunction.cpp
   SBHostOS.cpp
+  SBInitializerOptions.cpp
   SBInstruction.cpp
   SBInstructionList.cpp
   SBLanguageRuntime.cpp

Modified: lldb/trunk/source/API/SBDebugger.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBDebugger.cpp?rev=348152&r1=348151&r2=348152&view=diff
==============================================================================
--- lldb/trunk/source/API/SBDebugger.cpp (original)
+++ lldb/trunk/source/API/SBDebugger.cpp Mon Dec  3 09:28:29 2018
@@ -125,13 +125,23 @@ SBDebugger &SBDebugger::operator=(const
 }
 
 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::GetReproducerPat
               : 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);
 }

Added: lldb/trunk/source/API/SBInitializerOptions.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBInitializerOptions.cpp?rev=348152&view=auto
==============================================================================
--- lldb/trunk/source/API/SBInitializerOptions.cpp (added)
+++ lldb/trunk/source/API/SBInitializerOptions.cpp Mon Dec  3 09:28:29 2018
@@ -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());
+}

Modified: lldb/trunk/source/API/SystemInitializerFull.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SystemInitializerFull.cpp?rev=348152&r1=348151&r2=348152&view=diff
==============================================================================
--- lldb/trunk/source/API/SystemInitializerFull.cpp (original)
+++ lldb/trunk/source/API/SystemInitializerFull.cpp Mon Dec  3 09:28:29 2018
@@ -263,8 +263,10 @@ SystemInitializerFull::SystemInitializer
 
 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() {

Modified: lldb/trunk/source/API/SystemInitializerFull.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SystemInitializerFull.h?rev=348152&r1=348151&r2=348152&view=diff
==============================================================================
--- lldb/trunk/source/API/SystemInitializerFull.h (original)
+++ lldb/trunk/source/API/SystemInitializerFull.h Mon Dec  3 09:28:29 2018
@@ -26,7 +26,7 @@ public:
   SystemInitializerFull();
   ~SystemInitializerFull() override;
 
-  void Initialize() override;
+  llvm::Error Initialize(const InitializerOptions &options) override;
   void Terminate() override;
 
 private:

Modified: lldb/trunk/source/Commands/CommandObjectReproducer.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectReproducer.cpp?rev=348152&r1=348151&r2=348152&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectReproducer.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectReproducer.cpp Mon Dec  3 09:28:29 2018
@@ -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;

Modified: lldb/trunk/source/Core/Debugger.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Debugger.cpp?rev=348152&r1=348151&r2=348152&view=diff
==============================================================================
--- lldb/trunk/source/Core/Debugger.cpp (original)
+++ lldb/trunk/source/Core/Debugger.cpp Mon Dec  3 09:28:29 2018
@@ -418,24 +418,6 @@ llvm::StringRef Debugger::GetReproducerP
   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);

Modified: lldb/trunk/source/Host/common/HostInfoBase.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/common/HostInfoBase.cpp?rev=348152&r1=348151&r2=348152&view=diff
==============================================================================
--- lldb/trunk/source/Host/common/HostInfoBase.cpp (original)
+++ lldb/trunk/source/Host/common/HostInfoBase.cpp Mon Dec  3 09:28:29 2018
@@ -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();
@@ -285,26 +272,6 @@ bool HostInfoBase::ComputeGlobalTempFile
   if (llvm::sys::fs::create_directory(temp_file_spec.GetPath()))
     return false;
 
-  file_spec.GetDirectory().SetCString(temp_file_spec.GetCString());
-  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;
 }

Modified: lldb/trunk/source/Initialization/SystemInitializerCommon.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Initialization/SystemInitializerCommon.cpp?rev=348152&r1=348151&r2=348152&view=diff
==============================================================================
--- lldb/trunk/source/Initialization/SystemInitializerCommon.cpp (original)
+++ lldb/trunk/source/Initialization/SystemInitializerCommon.cpp Mon Dec  3 09:28:29 2018
@@ -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();
 }

Modified: lldb/trunk/source/Initialization/SystemLifetimeManager.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Initialization/SystemLifetimeManager.cpp?rev=348152&r1=348151&r2=348152&view=diff
==============================================================================
--- lldb/trunk/source/Initialization/SystemLifetimeManager.cpp (original)
+++ lldb/trunk/source/Initialization/SystemLifetimeManager.cpp Mon Dec  3 09:28:29 2018
@@ -24,9 +24,9 @@ SystemLifetimeManager::~SystemLifetimeMa
          "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() {

Modified: lldb/trunk/source/Utility/Reproducer.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Utility/Reproducer.cpp?rev=348152&r1=348151&r2=348152&view=diff
==============================================================================
--- lldb/trunk/source/Utility/Reproducer.cpp (original)
+++ lldb/trunk/source/Utility/Reproducer.cpp Mon Dec  3 09:28:29 2018
@@ -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:
         "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::
         "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;

Modified: lldb/trunk/tools/driver/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/driver/Driver.cpp?rev=348152&r1=348151&r2=348152&view=diff
==============================================================================
--- lldb/trunk/tools/driver/Driver.cpp (original)
+++ lldb/trunk/tools/driver/Driver.cpp Mon Dec  3 09:28:29 2018
@@ -367,21 +367,6 @@ SBError Driver::ProcessArgs(const opt::I
     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);

Modified: lldb/trunk/tools/driver/Options.td
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/driver/Options.td?rev=348152&r1=348151&r2=348152&view=diff
==============================================================================
--- lldb/trunk/tools/driver/Options.td (original)
+++ lldb/trunk/tools/driver/Options.td Mon Dec  3 09:28:29 2018
@@ -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<["--"], "">;

Modified: lldb/trunk/tools/lldb-server/SystemInitializerLLGS.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-server/SystemInitializerLLGS.cpp?rev=348152&r1=348151&r2=348152&view=diff
==============================================================================
--- lldb/trunk/tools/lldb-server/SystemInitializerLLGS.cpp (original)
+++ lldb/trunk/tools/lldb-server/SystemInitializerLLGS.cpp Mon Dec  3 09:28:29 2018
@@ -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() {

Modified: lldb/trunk/tools/lldb-server/SystemInitializerLLGS.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-server/SystemInitializerLLGS.h?rev=348152&r1=348151&r2=348152&view=diff
==============================================================================
--- lldb/trunk/tools/lldb-server/SystemInitializerLLGS.h (original)
+++ lldb/trunk/tools/lldb-server/SystemInitializerLLGS.h Mon Dec  3 09:28:29 2018
@@ -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;
 };
 

Modified: lldb/trunk/tools/lldb-server/lldb-server.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-server/lldb-server.cpp?rev=348152&r1=348151&r2=348152&view=diff
==============================================================================
--- lldb/trunk/tools/lldb-server/lldb-server.cpp (original)
+++ lldb/trunk/tools/lldb-server/lldb-server.cpp Mon Dec  3 09:28:29 2018
@@ -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(); }

Modified: lldb/trunk/tools/lldb-test/SystemInitializerTest.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-test/SystemInitializerTest.cpp?rev=348152&r1=348151&r2=348152&view=diff
==============================================================================
--- lldb/trunk/tools/lldb-test/SystemInitializerTest.cpp (original)
+++ lldb/trunk/tools/lldb-test/SystemInitializerTest.cpp Mon Dec  3 09:28:29 2018
@@ -111,8 +111,10 @@ SystemInitializerTest::SystemInitializer
 
 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() {

Modified: lldb/trunk/tools/lldb-test/SystemInitializerTest.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-test/SystemInitializerTest.h?rev=348152&r1=348151&r2=348152&view=diff
==============================================================================
--- lldb/trunk/tools/lldb-test/SystemInitializerTest.h (original)
+++ lldb/trunk/tools/lldb-test/SystemInitializerTest.h Mon Dec  3 09:28:29 2018
@@ -26,7 +26,7 @@ public:
   SystemInitializerTest();
   ~SystemInitializerTest() override;
 
-  void Initialize() override;
+  llvm::Error Initialize(const InitializerOptions &options) override;
   void Terminate() override;
 };
 

Modified: lldb/trunk/tools/lldb-test/lldb-test.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-test/lldb-test.cpp?rev=348152&r1=348151&r2=348152&view=diff
==============================================================================
--- lldb/trunk/tools/lldb-test/lldb-test.cpp (original)
+++ lldb/trunk/tools/lldb-test/lldb-test.cpp Mon Dec  3 09:28:29 2018
@@ -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();

Modified: lldb/trunk/unittests/Utility/ReproducerTest.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/Utility/ReproducerTest.cpp?rev=348152&r1=348151&r2=348152&view=diff
==============================================================================
--- lldb/trunk/unittests/Utility/ReproducerTest.cpp (original)
+++ lldb/trunk/unittests/Utility/ReproducerTest.cpp Mon Dec  3 09:28:29 2018
@@ -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());




More information about the lldb-commits mailing list