summaryrefslogtreecommitdiffstats
path: root/lldb/source
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source')
-rw-r--r--lldb/source/API/CMakeLists.txt1
-rw-r--r--lldb/source/API/SBDebugger.cpp25
-rw-r--r--lldb/source/API/SBInitializerOptions.cpp49
-rw-r--r--lldb/source/API/SystemInitializerFull.cpp8
-rw-r--r--lldb/source/API/SystemInitializerFull.h2
-rw-r--r--lldb/source/Commands/CommandObjectReproducer.cpp128
-rw-r--r--lldb/source/Core/Debugger.cpp18
-rw-r--r--lldb/source/Host/common/HostInfoBase.cpp33
-rw-r--r--lldb/source/Initialization/SystemInitializerCommon.cpp17
-rw-r--r--lldb/source/Initialization/SystemLifetimeManager.cpp10
-rw-r--r--lldb/source/Utility/Reproducer.cpp65
11 files changed, 162 insertions, 194 deletions
diff --git a/lldb/source/API/CMakeLists.txt b/lldb/source/API/CMakeLists.txt
index 3c5f4ddb43f..d2ab24c7c01 100644
--- a/lldb/source/API/CMakeLists.txt
+++ b/lldb/source/API/CMakeLists.txt
@@ -29,6 +29,7 @@ add_lldb_library(liblldb SHARED
SBFrame.cpp
SBFunction.cpp
SBHostOS.cpp
+ SBInitializerOptions.cpp
SBInstruction.cpp
SBInstructionList.cpp
SBLanguageRuntime.cpp
diff --git a/lldb/source/API/SBDebugger.cpp b/lldb/source/API/SBDebugger.cpp
index a7217964abf..af343233c90 100644
--- a/lldb/source/API/SBDebugger.cpp
+++ b/lldb/source/API/SBDebugger.cpp
@@ -125,13 +125,23 @@ SBDebugger &SBDebugger::operator=(const SBDebugger &rhs) {
}
void SBDebugger::Initialize() {
+ SBInitializerOptions options;
+ SBDebugger::Initialize(options);
+}
+
+lldb::SBError SBDebugger::Initialize(SBInitializerOptions &options) {
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
if (log)
log->Printf("SBDebugger::Initialize ()");
- g_debugger_lifetime->Initialize(llvm::make_unique<SystemInitializerFull>(),
- LoadPlugin);
+ SBError error;
+ if (auto e = g_debugger_lifetime->Initialize(
+ llvm::make_unique<SystemInitializerFull>(), *options.m_opaque_up,
+ LoadPlugin)) {
+ error.SetError(Status(std::move(e)));
+ }
+ return error;
}
void SBDebugger::Terminate() { g_debugger_lifetime->Terminate(); }
@@ -1057,17 +1067,6 @@ const char *SBDebugger::GetReproducerPath() const {
: nullptr);
}
-SBError SBDebugger::ReplayReproducer(const char *p) {
- SBError sb_error;
- if (m_opaque_sp) {
- auto error =
- m_opaque_sp->SetReproducerReplay(llvm::StringRef::withNullAsEmpty(p));
- std::string error_str = llvm::toString(std::move(error));
- sb_error.ref().SetErrorString(error_str);
- }
- return sb_error;
-}
-
ScriptLanguage SBDebugger::GetScriptLanguage() const {
return (m_opaque_sp ? m_opaque_sp->GetScriptLanguage() : eScriptLanguageNone);
}
diff --git a/lldb/source/API/SBInitializerOptions.cpp b/lldb/source/API/SBInitializerOptions.cpp
new file mode 100644
index 00000000000..8d8ec28190e
--- /dev/null
+++ b/lldb/source/API/SBInitializerOptions.cpp
@@ -0,0 +1,49 @@
+//===-- SBInitializerOptions.cpp --------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/API/SBInitializerOptions.h"
+#include "lldb/Initialization/SystemInitializer.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+SBInitializerOptions::SBInitializerOptions(const SBInitializerOptions &rhs) {
+ m_opaque_up.reset(new InitializerOptions());
+ *(m_opaque_up.get()) = rhs.ref();
+}
+
+const SBInitializerOptions &SBInitializerOptions::
+operator=(const SBInitializerOptions &rhs) {
+ if (this != &rhs) {
+ this->ref() = rhs.ref();
+ }
+ return *this;
+}
+
+SBInitializerOptions::~SBInitializerOptions() {}
+
+SBInitializerOptions::SBInitializerOptions() {
+ m_opaque_up.reset(new InitializerOptions());
+}
+
+void SBInitializerOptions::SetCaptureReproducer(bool b) {
+ m_opaque_up->reproducer_capture = b;
+}
+
+void SBInitializerOptions::SetReplayReproducer(bool b) {
+ m_opaque_up->reproducer_replay = b;
+}
+
+void SBInitializerOptions::SetReproducerPath(const char *path) {
+ m_opaque_up->reproducer_path = path;
+}
+
+InitializerOptions &SBInitializerOptions::ref() const {
+ return *(m_opaque_up.get());
+}
diff --git a/lldb/source/API/SystemInitializerFull.cpp b/lldb/source/API/SystemInitializerFull.cpp
index 671077ca0b0..937604425b4 100644
--- a/lldb/source/API/SystemInitializerFull.cpp
+++ b/lldb/source/API/SystemInitializerFull.cpp
@@ -263,8 +263,10 @@ SystemInitializerFull::SystemInitializerFull() {}
SystemInitializerFull::~SystemInitializerFull() {}
-void SystemInitializerFull::Initialize() {
- SystemInitializerCommon::Initialize();
+llvm::Error
+SystemInitializerFull::Initialize(const InitializerOptions &options) {
+ if (auto e = SystemInitializerCommon::Initialize(options))
+ return e;
ObjectFileELF::Initialize();
ObjectFileMachO::Initialize();
@@ -396,6 +398,8 @@ void SystemInitializerFull::Initialize() {
// AFTER PluginManager::Initialize is called.
Debugger::SettingsInitialize();
+
+ return llvm::Error::success();
}
void SystemInitializerFull::InitializeSWIG() {
diff --git a/lldb/source/API/SystemInitializerFull.h b/lldb/source/API/SystemInitializerFull.h
index 9cfc6896da6..b0cf476e919 100644
--- a/lldb/source/API/SystemInitializerFull.h
+++ b/lldb/source/API/SystemInitializerFull.h
@@ -26,7 +26,7 @@ public:
SystemInitializerFull();
~SystemInitializerFull() override;
- void Initialize() override;
+ llvm::Error Initialize(const InitializerOptions &options) override;
void Terminate() override;
private:
diff --git a/lldb/source/Commands/CommandObjectReproducer.cpp b/lldb/source/Commands/CommandObjectReproducer.cpp
index 03a3e230980..f393f17d9ae 100644
--- a/lldb/source/Commands/CommandObjectReproducer.cpp
+++ b/lldb/source/Commands/CommandObjectReproducer.cpp
@@ -19,65 +19,6 @@
using namespace lldb;
using namespace lldb_private;
-static void AppendErrorToResult(llvm::Error e, CommandReturnObject &result) {
- std::string error_str = llvm::toString(std::move(e));
- result.AppendErrorWithFormat("%s", error_str.c_str());
-}
-
-class CommandObjectReproducerCaptureEnable : public CommandObjectParsed {
-public:
- CommandObjectReproducerCaptureEnable(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "reproducer capture enable",
- "Enable gathering information for reproducer",
- nullptr) {}
-
- ~CommandObjectReproducerCaptureEnable() override = default;
-
-protected:
- bool DoExecute(Args &command, CommandReturnObject &result) override {
- if (!command.empty()) {
- result.AppendErrorWithFormat("'%s' takes no arguments",
- m_cmd_name.c_str());
- return false;
- }
-
- if (auto e = m_interpreter.GetDebugger().SetReproducerCapture(true)) {
- AppendErrorToResult(std::move(e), result);
- return false;
- }
-
- result.SetStatus(eReturnStatusSuccessFinishNoResult);
- return result.Succeeded();
- }
-};
-
-class CommandObjectReproducerCaptureDisable : public CommandObjectParsed {
-public:
- CommandObjectReproducerCaptureDisable(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "reproducer capture enable",
- "Disable gathering information for reproducer",
- nullptr) {}
-
- ~CommandObjectReproducerCaptureDisable() override = default;
-
-protected:
- bool DoExecute(Args &command, CommandReturnObject &result) override {
- if (!command.empty()) {
- result.AppendErrorWithFormat("'%s' takes no arguments",
- m_cmd_name.c_str());
- return false;
- }
-
- if (auto e = m_interpreter.GetDebugger().SetReproducerCapture(false)) {
- AppendErrorToResult(std::move(e), result);
- return false;
- }
-
- result.SetStatus(eReturnStatusSuccessFinishNoResult);
- return result.Succeeded();
- }
-};
-
class CommandObjectReproducerGenerate : public CommandObjectParsed {
public:
CommandObjectReproducerGenerate(CommandInterpreter &interpreter)
@@ -110,82 +51,47 @@ protected:
}
};
-class CommandObjectReproducerReplay : public CommandObjectParsed {
+class CommandObjectReproducerStatus : public CommandObjectParsed {
public:
- CommandObjectReproducerReplay(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "reproducer replay",
- "Replay a reproducer.", nullptr) {
- CommandArgumentEntry arg1;
- CommandArgumentData path_arg;
-
- // Define the first (and only) variant of this arg.
- path_arg.arg_type = eArgTypePath;
- path_arg.arg_repetition = eArgRepeatPlain;
-
- // There is only one variant this argument could be; put it into the
- // argument entry.
- arg1.push_back(path_arg);
-
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back(arg1);
- }
+ CommandObjectReproducerStatus(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "reproducer status",
+ "Show the current reproducer status.", nullptr) {}
- ~CommandObjectReproducerReplay() override = default;
+ ~CommandObjectReproducerStatus() override = default;
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
- if (command.empty()) {
- result.AppendErrorWithFormat(
- "'%s' takes a single argument: the reproducer path",
- m_cmd_name.c_str());
+ if (!command.empty()) {
+ result.AppendErrorWithFormat("'%s' takes no arguments",
+ m_cmd_name.c_str());
return false;
}
auto &r = repro::Reproducer::Instance();
+ if (auto generator = r.GetGenerator()) {
+ result.GetOutputStream() << "Reproducer is in capture mode.\n";
+ } else if (auto generator = r.GetLoader()) {
+ result.GetOutputStream() << "Reproducer is in replay mode.\n";
+ } else {
- const char *repro_path = command.GetArgumentAtIndex(0);
- if (auto e = r.SetReplay(FileSpec(repro_path))) {
- std::string error_str = llvm::toString(std::move(e));
- result.AppendErrorWithFormat("%s", error_str.c_str());
- return false;
+ result.GetOutputStream() << "Reproducer is off.\n";
}
- result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ result.SetStatus(eReturnStatusSuccessFinishResult);
return result.Succeeded();
}
};
-class CommandObjectReproducerCapture : public CommandObjectMultiword {
-private:
-public:
- CommandObjectReproducerCapture(CommandInterpreter &interpreter)
- : CommandObjectMultiword(
- interpreter, "reproducer capture",
- "Manage gathering of information needed to generate a reproducer.",
- NULL) {
- LoadSubCommand(
- "enable",
- CommandObjectSP(new CommandObjectReproducerCaptureEnable(interpreter)));
- LoadSubCommand("disable",
- CommandObjectSP(
- new CommandObjectReproducerCaptureDisable(interpreter)));
- }
-
- ~CommandObjectReproducerCapture() {}
-};
-
CommandObjectReproducer::CommandObjectReproducer(
CommandInterpreter &interpreter)
: CommandObjectMultiword(interpreter, "reproducer",
"Commands controlling LLDB reproducers.",
"log <subcommand> [<command-options>]") {
- LoadSubCommand("capture", CommandObjectSP(new CommandObjectReproducerCapture(
- interpreter)));
LoadSubCommand(
"generate",
CommandObjectSP(new CommandObjectReproducerGenerate(interpreter)));
- LoadSubCommand("replay", CommandObjectSP(
- new CommandObjectReproducerReplay(interpreter)));
+ LoadSubCommand("status", CommandObjectSP(
+ new CommandObjectReproducerStatus(interpreter)));
}
CommandObjectReproducer::~CommandObjectReproducer() = default;
diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp
index 1f12dc4dbd6..6e86519b501 100644
--- a/lldb/source/Core/Debugger.cpp
+++ b/lldb/source/Core/Debugger.cpp
@@ -418,24 +418,6 @@ llvm::StringRef Debugger::GetReproducerPath() const {
return r.GetReproducerPath().GetCString();
}
-llvm::Error Debugger::SetReproducerReplay(llvm::StringRef p) {
- llvm::Optional<FileSpec> arg = llvm::None;
-
- if (!p.empty())
- arg = FileSpec(p);
-
- return repro::Reproducer::Instance().SetReplay(arg);
-}
-
-llvm::Error Debugger::SetReproducerCapture(bool b) {
- llvm::Optional<FileSpec> arg = llvm::None;
-
- if (b)
- arg = HostInfo::GetReproducerTempDir();
-
- return repro::Reproducer::Instance().SetCapture(arg);
-}
-
const FormatEntity::Entry *Debugger::GetThreadFormat() const {
const uint32_t idx = ePropertyThreadFormat;
return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx);
diff --git a/lldb/source/Host/common/HostInfoBase.cpp b/lldb/source/Host/common/HostInfoBase.cpp
index e82fec36705..34c362efc9e 100644
--- a/lldb/source/Host/common/HostInfoBase.cpp
+++ b/lldb/source/Host/common/HostInfoBase.cpp
@@ -194,19 +194,6 @@ FileSpec HostInfoBase::GetGlobalTempDir() {
return success ? g_fields->m_lldb_global_tmp_dir : FileSpec();
}
-FileSpec HostInfoBase::GetReproducerTempDir() {
- static llvm::once_flag g_once_flag;
- static bool success = false;
- llvm::call_once(g_once_flag, []() {
- success = HostInfo::ComputeReproducerTempFileDirectory(
- g_fields->m_lldb_global_tmp_dir);
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- LLDB_LOG(log, "reproducer temp dir -> `{0}`",
- g_fields->m_lldb_global_tmp_dir);
- });
- return success ? g_fields->m_lldb_global_tmp_dir : FileSpec();
-}
-
ArchSpec HostInfoBase::GetAugmentedArchSpec(llvm::StringRef triple) {
if (triple.empty())
return ArchSpec();
@@ -289,26 +276,6 @@ bool HostInfoBase::ComputeGlobalTempFileDirectory(FileSpec &file_spec) {
return true;
}
-bool HostInfoBase::ComputeReproducerTempFileDirectory(FileSpec &file_spec) {
- file_spec.Clear();
-
- FileSpec temp_file_spec;
- if (!HostInfo::ComputeTempFileBaseDirectory(temp_file_spec))
- return false;
-
- temp_file_spec.AppendPathComponent("reproducer");
- if (llvm::sys::fs::create_directory(temp_file_spec.GetPath()))
- return false;
-
- std::string pid_str{llvm::to_string(Host::GetCurrentProcessID())};
- temp_file_spec.AppendPathComponent(pid_str);
- if (llvm::sys::fs::create_directory(temp_file_spec.GetPath()))
- return false;
-
- file_spec.GetDirectory().SetCString(temp_file_spec.GetCString());
- return true;
-}
-
bool HostInfoBase::ComputeHeaderDirectory(FileSpec &file_spec) {
// TODO(zturner): Figure out how to compute the header directory for all
// platforms.
diff --git a/lldb/source/Initialization/SystemInitializerCommon.cpp b/lldb/source/Initialization/SystemInitializerCommon.cpp
index 221dc8c58b7..d1d55fcfde7 100644
--- a/lldb/source/Initialization/SystemInitializerCommon.cpp
+++ b/lldb/source/Initialization/SystemInitializerCommon.cpp
@@ -19,6 +19,7 @@
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/Reproducer.h"
#include "lldb/Utility/Timer.h"
#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__)
@@ -35,12 +36,14 @@
#include <string>
using namespace lldb_private;
+using namespace lldb_private::repro;
SystemInitializerCommon::SystemInitializerCommon() {}
SystemInitializerCommon::~SystemInitializerCommon() {}
-void SystemInitializerCommon::Initialize() {
+llvm::Error
+SystemInitializerCommon::Initialize(const InitializerOptions &options) {
#if defined(_MSC_VER)
const char *disable_crash_dialog_var = getenv("LLDB_DISABLE_CRASH_DIALOG");
if (disable_crash_dialog_var &&
@@ -63,6 +66,15 @@ void SystemInitializerCommon::Initialize() {
}
#endif
+ ReproducerMode mode = ReproducerMode::Off;
+ if (options.reproducer_capture)
+ mode = ReproducerMode::Capture;
+ if (options.reproducer_replay)
+ mode = ReproducerMode::Replay;
+
+ if (auto e = Reproducer::Initialize(mode, FileSpec(options.reproducer_path)))
+ return e;
+
FileSystem::Initialize();
Log::Initialize();
HostInfo::Initialize();
@@ -89,6 +101,8 @@ void SystemInitializerCommon::Initialize() {
#if defined(_MSC_VER)
ProcessWindowsLog::Initialize();
#endif
+
+ return llvm::Error::success();
}
void SystemInitializerCommon::Terminate() {
@@ -109,4 +123,5 @@ void SystemInitializerCommon::Terminate() {
HostInfo::Terminate();
Log::DisableAllLogChannels();
FileSystem::Terminate();
+ Reproducer::Terminate();
}
diff --git a/lldb/source/Initialization/SystemLifetimeManager.cpp b/lldb/source/Initialization/SystemLifetimeManager.cpp
index 4d271787833..65431bf6017 100644
--- a/lldb/source/Initialization/SystemLifetimeManager.cpp
+++ b/lldb/source/Initialization/SystemLifetimeManager.cpp
@@ -24,9 +24,9 @@ SystemLifetimeManager::~SystemLifetimeManager() {
"SystemLifetimeManager destroyed without calling Terminate!");
}
-void SystemLifetimeManager::Initialize(
+llvm::Error SystemLifetimeManager::Initialize(
std::unique_ptr<SystemInitializer> initializer,
- LoadPluginCallbackType plugin_callback) {
+ const InitializerOptions &options, LoadPluginCallbackType plugin_callback) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (!m_initialized) {
assert(!m_initializer && "Attempting to call "
@@ -35,9 +35,13 @@ void SystemLifetimeManager::Initialize(
m_initialized = true;
m_initializer = std::move(initializer);
- m_initializer->Initialize();
+ if (auto e = m_initializer->Initialize(options))
+ return e;
+
Debugger::Initialize(plugin_callback);
}
+
+ return llvm::Error::success();
}
void SystemLifetimeManager::Terminate() {
diff --git a/lldb/source/Utility/Reproducer.cpp b/lldb/source/Utility/Reproducer.cpp
index 0048a11970d..a6b5fa849c2 100644
--- a/lldb/source/Utility/Reproducer.cpp
+++ b/lldb/source/Utility/Reproducer.cpp
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include "lldb/Utility/Reproducer.h"
+#include "lldb/Utility/LLDBAssert.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Threading.h"
@@ -18,8 +19,46 @@ using namespace lldb_private::repro;
using namespace llvm;
using namespace llvm::yaml;
-Reproducer &Reproducer::Instance() {
- static Reproducer g_reproducer;
+Reproducer &Reproducer::Instance() { return *InstanceImpl(); }
+
+llvm::Error Reproducer::Initialize(ReproducerMode mode,
+ llvm::Optional<FileSpec> root) {
+ lldbassert(!InstanceImpl() && "Already initialized.");
+ InstanceImpl().emplace();
+
+ switch (mode) {
+ case ReproducerMode::Capture: {
+ if (!root) {
+ SmallString<128> repro_dir;
+ auto ec = sys::fs::createUniqueDirectory("reproducer", repro_dir);
+ if (ec)
+ return make_error<StringError>(
+ "unable to create unique reproducer directory", ec);
+ root.emplace(repro_dir);
+ } else {
+ auto ec = sys::fs::create_directories(root->GetPath());
+ if (ec)
+ return make_error<StringError>("unable to create reproducer directory",
+ ec);
+ }
+ return Instance().SetCapture(root);
+ } break;
+ case ReproducerMode::Replay:
+ return Instance().SetReplay(root);
+ case ReproducerMode::Off:
+ break;
+ };
+
+ return Error::success();
+}
+
+void Reproducer::Terminate() {
+ lldbassert(InstanceImpl() && "Already terminated.");
+ InstanceImpl().reset();
+}
+
+Optional<Reproducer> &Reproducer::InstanceImpl() {
+ static Optional<Reproducer> g_reproducer;
return g_reproducer;
}
@@ -59,11 +98,12 @@ llvm::Error Reproducer::SetCapture(llvm::Optional<FileSpec> root) {
"cannot generate a reproducer when replay one",
inconvertibleErrorCode());
- if (root)
- m_generator.emplace(*root);
- else
+ if (!root) {
m_generator.reset();
+ return Error::success();
+ }
+ m_generator.emplace(*root);
return Error::success();
}
@@ -75,14 +115,15 @@ llvm::Error Reproducer::SetReplay(llvm::Optional<FileSpec> root) {
"cannot replay a reproducer when generating one",
inconvertibleErrorCode());
- if (root) {
- m_loader.emplace(*root);
- if (auto e = m_loader->LoadIndex())
- return e;
- } else {
+ if (!root) {
m_loader.reset();
+ return Error::success();
}
+ m_loader.emplace(*root);
+ if (auto e = m_loader->LoadIndex())
+ return e;
+
return Error::success();
}
@@ -153,14 +194,14 @@ llvm::Error Loader::LoadIndex() {
auto error_or_file = MemoryBuffer::getFile(index.GetPath());
if (auto err = error_or_file.getError())
- return errorCodeToError(err);
+ return make_error<StringError>("unable to load reproducer index", err);
std::vector<ProviderInfo> provider_info;
yaml::Input yin((*error_or_file)->getBuffer());
yin >> provider_info;
if (auto err = yin.error())
- return errorCodeToError(err);
+ return make_error<StringError>("unable to read reproducer index", err);
for (auto &info : provider_info)
m_provider_info[info.name] = info;
OpenPOWER on IntegriCloud