diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2019-12-20 19:53:05 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2019-12-20 19:53:05 +0000 |
commit | 0b57cec536236d46e3dba9bd041533462f33dbb7 (patch) | |
tree | 56229dbdbbf76d18580f72f789003db17246c8d9 /contrib/llvm-project/lldb/source/API/SBDebugger.cpp | |
parent | 718ef55ec7785aae63f98f8ca05dc07ed399c16d (diff) |
Notes
Diffstat (limited to 'contrib/llvm-project/lldb/source/API/SBDebugger.cpp')
-rw-r--r-- | contrib/llvm-project/lldb/source/API/SBDebugger.cpp | 1730 |
1 files changed, 1730 insertions, 0 deletions
diff --git a/contrib/llvm-project/lldb/source/API/SBDebugger.cpp b/contrib/llvm-project/lldb/source/API/SBDebugger.cpp new file mode 100644 index 000000000000..634c4a929595 --- /dev/null +++ b/contrib/llvm-project/lldb/source/API/SBDebugger.cpp @@ -0,0 +1,1730 @@ +//===-- SBDebugger.cpp ------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "SBReproducerPrivate.h" +#include "SystemInitializerFull.h" + +#include "lldb/API/SBDebugger.h" + +#include "lldb/lldb-private.h" + +#include "lldb/API/SBBroadcaster.h" +#include "lldb/API/SBCommandInterpreter.h" +#include "lldb/API/SBCommandReturnObject.h" +#include "lldb/API/SBError.h" +#include "lldb/API/SBEvent.h" +#include "lldb/API/SBFrame.h" +#include "lldb/API/SBListener.h" +#include "lldb/API/SBProcess.h" +#include "lldb/API/SBSourceManager.h" +#include "lldb/API/SBStream.h" +#include "lldb/API/SBStringList.h" +#include "lldb/API/SBStructuredData.h" +#include "lldb/API/SBTarget.h" +#include "lldb/API/SBThread.h" +#include "lldb/API/SBTypeCategory.h" +#include "lldb/API/SBTypeFilter.h" +#include "lldb/API/SBTypeFormat.h" +#include "lldb/API/SBTypeNameSpecifier.h" +#include "lldb/API/SBTypeSummary.h" +#include "lldb/API/SBTypeSynthetic.h" + +#include "lldb/Core/Debugger.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Core/StreamFile.h" +#include "lldb/Core/StructuredDataImpl.h" +#include "lldb/DataFormatters/DataVisualization.h" +#include "lldb/Host/XML.h" +#include "lldb/Initialization/SystemLifetimeManager.h" +#include "lldb/Interpreter/CommandInterpreter.h" +#include "lldb/Interpreter/OptionArgParser.h" +#include "lldb/Interpreter/OptionGroupPlatform.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/TargetList.h" +#include "lldb/Utility/Args.h" +#include "lldb/Utility/State.h" + +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/DynamicLibrary.h" +#include "llvm/Support/ManagedStatic.h" + +using namespace lldb; +using namespace lldb_private; + +/// Helper class for replaying commands through the reproducer. +class CommandLoader { +public: + CommandLoader(std::vector<std::string> files) : m_files(files) {} + + static std::unique_ptr<CommandLoader> Create() { + repro::Loader *loader = repro::Reproducer::Instance().GetLoader(); + if (!loader) + return {}; + + FileSpec file = loader->GetFile<repro::CommandProvider::Info>(); + if (!file) + return {}; + + auto error_or_file = llvm::MemoryBuffer::getFile(file.GetPath()); + if (auto err = error_or_file.getError()) + return {}; + + std::vector<std::string> files; + llvm::yaml::Input yin((*error_or_file)->getBuffer()); + yin >> files; + + if (auto err = yin.error()) + return {}; + + for (auto &file : files) { + FileSpec absolute_path = + loader->GetRoot().CopyByAppendingPathComponent(file); + file = absolute_path.GetPath(); + } + + return llvm::make_unique<CommandLoader>(std::move(files)); + } + + FILE *GetNextFile() { + if (m_index >= m_files.size()) + return nullptr; + return FileSystem::Instance().Fopen(m_files[m_index++].c_str(), "r"); + } + +private: + std::vector<std::string> m_files; + unsigned m_index = 0; +}; + +static llvm::sys::DynamicLibrary LoadPlugin(const lldb::DebuggerSP &debugger_sp, + const FileSpec &spec, + Status &error) { + llvm::sys::DynamicLibrary dynlib = + llvm::sys::DynamicLibrary::getPermanentLibrary(spec.GetPath().c_str()); + if (dynlib.isValid()) { + typedef bool (*LLDBCommandPluginInit)(lldb::SBDebugger & debugger); + + lldb::SBDebugger debugger_sb(debugger_sp); + // This calls the bool lldb::PluginInitialize(lldb::SBDebugger debugger) + // function. + // TODO: mangle this differently for your system - on OSX, the first + // underscore needs to be removed and the second one stays + LLDBCommandPluginInit init_func = + (LLDBCommandPluginInit)(uintptr_t)dynlib.getAddressOfSymbol( + "_ZN4lldb16PluginInitializeENS_10SBDebuggerE"); + if (init_func) { + if (init_func(debugger_sb)) + return dynlib; + else + error.SetErrorString("plug-in refused to load " + "(lldb::PluginInitialize(lldb::SBDebugger) " + "returned false)"); + } else { + error.SetErrorString("plug-in is missing the required initialization: " + "lldb::PluginInitialize(lldb::SBDebugger)"); + } + } else { + if (FileSystem::Instance().Exists(spec)) + error.SetErrorString("this file does not represent a loadable dylib"); + else + error.SetErrorString("no such file"); + } + return llvm::sys::DynamicLibrary(); +} + +static llvm::ManagedStatic<SystemLifetimeManager> g_debugger_lifetime; + +SBError SBInputReader::Initialize( + lldb::SBDebugger &sb_debugger, + unsigned long (*callback)(void *, lldb::SBInputReader *, + lldb::InputReaderAction, char const *, + unsigned long), + void *a, lldb::InputReaderGranularity b, char const *c, char const *d, + bool e) { + LLDB_RECORD_DUMMY( + lldb::SBError, SBInputReader, Initialize, + (lldb::SBDebugger &, + unsigned long (*)(void *, lldb::SBInputReader *, lldb::InputReaderAction, + const char *, unsigned long), + void *, lldb::InputReaderGranularity, const char *, const char *, bool), + sb_debugger, callback, a, b, c, d, e); + + return SBError(); +} + +void SBInputReader::SetIsDone(bool b) { + LLDB_RECORD_METHOD(void, SBInputReader, SetIsDone, (bool), b); +} + +bool SBInputReader::IsActive() const { + LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBInputReader, IsActive); + + return false; +} + +SBDebugger::SBDebugger() { LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBDebugger); } + +SBDebugger::SBDebugger(const lldb::DebuggerSP &debugger_sp) + : m_opaque_sp(debugger_sp) { + LLDB_RECORD_CONSTRUCTOR(SBDebugger, (const lldb::DebuggerSP &), debugger_sp); +} + +SBDebugger::SBDebugger(const SBDebugger &rhs) : m_opaque_sp(rhs.m_opaque_sp) { + LLDB_RECORD_CONSTRUCTOR(SBDebugger, (const lldb::SBDebugger &), rhs); +} + +SBDebugger::~SBDebugger() = default; + +SBDebugger &SBDebugger::operator=(const SBDebugger &rhs) { + LLDB_RECORD_METHOD(lldb::SBDebugger &, + SBDebugger, operator=,(const lldb::SBDebugger &), rhs); + + if (this != &rhs) { + m_opaque_sp = rhs.m_opaque_sp; + } + return LLDB_RECORD_RESULT(*this); +} + +void SBDebugger::Initialize() { + LLDB_RECORD_STATIC_METHOD_NO_ARGS(void, SBDebugger, Initialize); + SBError ignored = SBDebugger::InitializeWithErrorHandling(); +} + +lldb::SBError SBDebugger::InitializeWithErrorHandling() { + LLDB_RECORD_STATIC_METHOD_NO_ARGS(lldb::SBError, SBDebugger, + InitializeWithErrorHandling); + + + + SBError error; + if (auto e = g_debugger_lifetime->Initialize( + llvm::make_unique<SystemInitializerFull>(), LoadPlugin)) { + error.SetError(Status(std::move(e))); + } + return LLDB_RECORD_RESULT(error); +} + +void SBDebugger::Terminate() { + LLDB_RECORD_STATIC_METHOD_NO_ARGS(void, SBDebugger, Terminate); + + g_debugger_lifetime->Terminate(); +} + +void SBDebugger::Clear() { + LLDB_RECORD_METHOD_NO_ARGS(void, SBDebugger, Clear); + + + if (m_opaque_sp) + m_opaque_sp->ClearIOHandlers(); + + m_opaque_sp.reset(); +} + +SBDebugger SBDebugger::Create() { + LLDB_RECORD_STATIC_METHOD_NO_ARGS(lldb::SBDebugger, SBDebugger, Create); + + return LLDB_RECORD_RESULT(SBDebugger::Create(false, nullptr, nullptr)); +} + +SBDebugger SBDebugger::Create(bool source_init_files) { + LLDB_RECORD_STATIC_METHOD(lldb::SBDebugger, SBDebugger, Create, (bool), + source_init_files); + + return LLDB_RECORD_RESULT( + SBDebugger::Create(source_init_files, nullptr, nullptr)); +} + +SBDebugger SBDebugger::Create(bool source_init_files, + lldb::LogOutputCallback callback, void *baton) + +{ + LLDB_RECORD_DUMMY(lldb::SBDebugger, SBDebugger, Create, + (bool, lldb::LogOutputCallback, void *), source_init_files, + callback, baton); + + SBDebugger debugger; + + // Currently we have issues if this function is called simultaneously on two + // different threads. The issues mainly revolve around the fact that the + // lldb_private::FormatManager uses global collections and having two threads + // parsing the .lldbinit files can cause mayhem. So to get around this for + // now we need to use a mutex to prevent bad things from happening. + static std::recursive_mutex g_mutex; + std::lock_guard<std::recursive_mutex> guard(g_mutex); + + debugger.reset(Debugger::CreateInstance(callback, baton)); + + + SBCommandInterpreter interp = debugger.GetCommandInterpreter(); + if (source_init_files) { + interp.get()->SkipLLDBInitFiles(false); + interp.get()->SkipAppInitFiles(false); + SBCommandReturnObject result; + interp.SourceInitFileInHomeDirectory(result); + } else { + interp.get()->SkipLLDBInitFiles(true); + interp.get()->SkipAppInitFiles(true); + } + return debugger; +} + +void SBDebugger::Destroy(SBDebugger &debugger) { + LLDB_RECORD_STATIC_METHOD(void, SBDebugger, Destroy, (lldb::SBDebugger &), + debugger); + + + Debugger::Destroy(debugger.m_opaque_sp); + + if (debugger.m_opaque_sp.get() != nullptr) + debugger.m_opaque_sp.reset(); +} + +void SBDebugger::MemoryPressureDetected() { + LLDB_RECORD_STATIC_METHOD_NO_ARGS(void, SBDebugger, MemoryPressureDetected); + + // Since this function can be call asynchronously, we allow it to be non- + // mandatory. We have seen deadlocks with this function when called so we + // need to safeguard against this until we can determine what is causing the + // deadlocks. + + const bool mandatory = false; + + ModuleList::RemoveOrphanSharedModules(mandatory); +} + +bool SBDebugger::IsValid() const { + LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBDebugger, IsValid); + return this->operator bool(); +} +SBDebugger::operator bool() const { + LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBDebugger, operator bool); + + return m_opaque_sp.get() != nullptr; +} + +void SBDebugger::SetAsync(bool b) { + LLDB_RECORD_METHOD(void, SBDebugger, SetAsync, (bool), b); + + if (m_opaque_sp) + m_opaque_sp->SetAsyncExecution(b); +} + +bool SBDebugger::GetAsync() { + LLDB_RECORD_METHOD_NO_ARGS(bool, SBDebugger, GetAsync); + + return (m_opaque_sp ? m_opaque_sp->GetAsyncExecution() : false); +} + +void SBDebugger::SkipLLDBInitFiles(bool b) { + LLDB_RECORD_METHOD(void, SBDebugger, SkipLLDBInitFiles, (bool), b); + + if (m_opaque_sp) + m_opaque_sp->GetCommandInterpreter().SkipLLDBInitFiles(b); +} + +void SBDebugger::SkipAppInitFiles(bool b) { + LLDB_RECORD_METHOD(void, SBDebugger, SkipAppInitFiles, (bool), b); + + if (m_opaque_sp) + m_opaque_sp->GetCommandInterpreter().SkipAppInitFiles(b); +} + +// Shouldn't really be settable after initialization as this could cause lots +// of problems; don't want users trying to switch modes in the middle of a +// debugging session. +void SBDebugger::SetInputFileHandle(FILE *fh, bool transfer_ownership) { + LLDB_RECORD_METHOD(void, SBDebugger, SetInputFileHandle, (FILE *, bool), fh, + transfer_ownership); + + if (!m_opaque_sp) + return; + + repro::DataRecorder *recorder = nullptr; + if (repro::Generator *g = repro::Reproducer::Instance().GetGenerator()) + recorder = g->GetOrCreate<repro::CommandProvider>().GetNewDataRecorder(); + + static std::unique_ptr<CommandLoader> loader = CommandLoader::Create(); + if (loader) + fh = loader->GetNextFile(); + + m_opaque_sp->SetInputFileHandle(fh, transfer_ownership, recorder); +} + +void SBDebugger::SetOutputFileHandle(FILE *fh, bool transfer_ownership) { + LLDB_RECORD_METHOD(void, SBDebugger, SetOutputFileHandle, (FILE *, bool), fh, + transfer_ownership); + + if (m_opaque_sp) + m_opaque_sp->SetOutputFileHandle(fh, transfer_ownership); +} + +void SBDebugger::SetErrorFileHandle(FILE *fh, bool transfer_ownership) { + LLDB_RECORD_METHOD(void, SBDebugger, SetErrorFileHandle, (FILE *, bool), fh, + transfer_ownership); + + + if (m_opaque_sp) + m_opaque_sp->SetErrorFileHandle(fh, transfer_ownership); +} + +FILE *SBDebugger::GetInputFileHandle() { + LLDB_RECORD_METHOD_NO_ARGS(FILE *, SBDebugger, GetInputFileHandle); + + if (m_opaque_sp) { + StreamFileSP stream_file_sp(m_opaque_sp->GetInputFile()); + if (stream_file_sp) + return LLDB_RECORD_RESULT(stream_file_sp->GetFile().GetStream()); + } + return nullptr; +} + +FILE *SBDebugger::GetOutputFileHandle() { + LLDB_RECORD_METHOD_NO_ARGS(FILE *, SBDebugger, GetOutputFileHandle); + + if (m_opaque_sp) { + StreamFileSP stream_file_sp(m_opaque_sp->GetOutputFile()); + if (stream_file_sp) + return LLDB_RECORD_RESULT(stream_file_sp->GetFile().GetStream()); + } + return nullptr; +} + +FILE *SBDebugger::GetErrorFileHandle() { + LLDB_RECORD_METHOD_NO_ARGS(FILE *, SBDebugger, GetErrorFileHandle); + + if (m_opaque_sp) { + StreamFileSP stream_file_sp(m_opaque_sp->GetErrorFile()); + if (stream_file_sp) + return LLDB_RECORD_RESULT(stream_file_sp->GetFile().GetStream()); + } + return nullptr; +} + +void SBDebugger::SaveInputTerminalState() { + LLDB_RECORD_METHOD_NO_ARGS(void, SBDebugger, SaveInputTerminalState); + + if (m_opaque_sp) + m_opaque_sp->SaveInputTerminalState(); +} + +void SBDebugger::RestoreInputTerminalState() { + LLDB_RECORD_METHOD_NO_ARGS(void, SBDebugger, RestoreInputTerminalState); + + if (m_opaque_sp) + m_opaque_sp->RestoreInputTerminalState(); +} +SBCommandInterpreter SBDebugger::GetCommandInterpreter() { + LLDB_RECORD_METHOD_NO_ARGS(lldb::SBCommandInterpreter, SBDebugger, + GetCommandInterpreter); + + + SBCommandInterpreter sb_interpreter; + if (m_opaque_sp) + sb_interpreter.reset(&m_opaque_sp->GetCommandInterpreter()); + + + return LLDB_RECORD_RESULT(sb_interpreter); +} + +void SBDebugger::HandleCommand(const char *command) { + LLDB_RECORD_METHOD(void, SBDebugger, HandleCommand, (const char *), command); + + if (m_opaque_sp) { + TargetSP target_sp(m_opaque_sp->GetSelectedTarget()); + std::unique_lock<std::recursive_mutex> lock; + if (target_sp) + lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex()); + + SBCommandInterpreter sb_interpreter(GetCommandInterpreter()); + SBCommandReturnObject result; + + sb_interpreter.HandleCommand(command, result, false); + + if (GetErrorFileHandle() != nullptr) + result.PutError(GetErrorFileHandle()); + if (GetOutputFileHandle() != nullptr) + result.PutOutput(GetOutputFileHandle()); + + if (!m_opaque_sp->GetAsyncExecution()) { + SBProcess process(GetCommandInterpreter().GetProcess()); + ProcessSP process_sp(process.GetSP()); + if (process_sp) { + EventSP event_sp; + ListenerSP lldb_listener_sp = m_opaque_sp->GetListener(); + while (lldb_listener_sp->GetEventForBroadcaster( + process_sp.get(), event_sp, std::chrono::seconds(0))) { + SBEvent event(event_sp); + HandleProcessEvent(process, event, GetOutputFileHandle(), + GetErrorFileHandle()); + } + } + } + } +} + +SBListener SBDebugger::GetListener() { + LLDB_RECORD_METHOD_NO_ARGS(lldb::SBListener, SBDebugger, GetListener); + + + SBListener sb_listener; + if (m_opaque_sp) + sb_listener.reset(m_opaque_sp->GetListener()); + + + return LLDB_RECORD_RESULT(sb_listener); +} + +void SBDebugger::HandleProcessEvent(const SBProcess &process, + const SBEvent &event, FILE *out, + FILE *err) { + LLDB_RECORD_METHOD( + void, SBDebugger, HandleProcessEvent, + (const lldb::SBProcess &, const lldb::SBEvent &, FILE *, FILE *), process, + event, out, err); + + if (!process.IsValid()) + return; + + TargetSP target_sp(process.GetTarget().GetSP()); + if (!target_sp) + return; + + const uint32_t event_type = event.GetType(); + char stdio_buffer[1024]; + size_t len; + + std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex()); + + if (event_type & + (Process::eBroadcastBitSTDOUT | Process::eBroadcastBitStateChanged)) { + // Drain stdout when we stop just in case we have any bytes + while ((len = process.GetSTDOUT(stdio_buffer, sizeof(stdio_buffer))) > 0) + if (out != nullptr) + ::fwrite(stdio_buffer, 1, len, out); + } + + if (event_type & + (Process::eBroadcastBitSTDERR | Process::eBroadcastBitStateChanged)) { + // Drain stderr when we stop just in case we have any bytes + while ((len = process.GetSTDERR(stdio_buffer, sizeof(stdio_buffer))) > 0) + if (err != nullptr) + ::fwrite(stdio_buffer, 1, len, err); + } + + if (event_type & Process::eBroadcastBitStateChanged) { + StateType event_state = SBProcess::GetStateFromEvent(event); + + if (event_state == eStateInvalid) + return; + + bool is_stopped = StateIsStoppedState(event_state); + if (!is_stopped) + process.ReportEventState(event, out); + } +} + +SBSourceManager SBDebugger::GetSourceManager() { + LLDB_RECORD_METHOD_NO_ARGS(lldb::SBSourceManager, SBDebugger, + GetSourceManager); + + SBSourceManager sb_source_manager(*this); + return LLDB_RECORD_RESULT(sb_source_manager); +} + +bool SBDebugger::GetDefaultArchitecture(char *arch_name, size_t arch_name_len) { + LLDB_RECORD_STATIC_METHOD(bool, SBDebugger, GetDefaultArchitecture, + (char *, size_t), "", arch_name_len); + + if (arch_name && arch_name_len) { + ArchSpec default_arch = Target::GetDefaultArchitecture(); + + if (default_arch.IsValid()) { + const std::string &triple_str = default_arch.GetTriple().str(); + if (!triple_str.empty()) + ::snprintf(arch_name, arch_name_len, "%s", triple_str.c_str()); + else + ::snprintf(arch_name, arch_name_len, "%s", + default_arch.GetArchitectureName()); + return true; + } + } + if (arch_name && arch_name_len) + arch_name[0] = '\0'; + return false; +} + +bool SBDebugger::SetDefaultArchitecture(const char *arch_name) { + LLDB_RECORD_STATIC_METHOD(bool, SBDebugger, SetDefaultArchitecture, + (const char *), arch_name); + + if (arch_name) { + ArchSpec arch(arch_name); + if (arch.IsValid()) { + Target::SetDefaultArchitecture(arch); + return true; + } + } + return false; +} + +ScriptLanguage +SBDebugger::GetScriptingLanguage(const char *script_language_name) { + LLDB_RECORD_METHOD(lldb::ScriptLanguage, SBDebugger, GetScriptingLanguage, + (const char *), script_language_name); + + if (!script_language_name) return eScriptLanguageDefault; + return OptionArgParser::ToScriptLanguage( + llvm::StringRef(script_language_name), eScriptLanguageDefault, nullptr); +} + +const char *SBDebugger::GetVersionString() { + LLDB_RECORD_STATIC_METHOD_NO_ARGS(const char *, SBDebugger, GetVersionString); + + return lldb_private::GetVersion(); +} + +const char *SBDebugger::StateAsCString(StateType state) { + LLDB_RECORD_STATIC_METHOD(const char *, SBDebugger, StateAsCString, + (lldb::StateType), state); + + return lldb_private::StateAsCString(state); +} + +static void AddBoolConfigEntry(StructuredData::Dictionary &dict, + llvm::StringRef name, bool value, + llvm::StringRef description) { + auto entry_up = llvm::make_unique<StructuredData::Dictionary>(); + entry_up->AddBooleanItem("value", value); + entry_up->AddStringItem("description", description); + dict.AddItem(name, std::move(entry_up)); +} + +static void AddLLVMTargets(StructuredData::Dictionary &dict) { + auto array_up = llvm::make_unique<StructuredData::Array>(); +#define LLVM_TARGET(target) \ + array_up->AddItem(llvm::make_unique<StructuredData::String>(#target)); +#include "llvm/Config/Targets.def" + auto entry_up = llvm::make_unique<StructuredData::Dictionary>(); + entry_up->AddItem("value", std::move(array_up)); + entry_up->AddStringItem("description", "A list of configured LLVM targets."); + dict.AddItem("targets", std::move(entry_up)); +} + +SBStructuredData SBDebugger::GetBuildConfiguration() { + LLDB_RECORD_STATIC_METHOD_NO_ARGS(lldb::SBStructuredData, SBDebugger, + GetBuildConfiguration); + + auto config_up = llvm::make_unique<StructuredData::Dictionary>(); + AddBoolConfigEntry( + *config_up, "xml", XMLDocument::XMLEnabled(), + "A boolean value that indicates if XML support is enabled in LLDB"); + AddLLVMTargets(*config_up); + + SBStructuredData data; + data.m_impl_up->SetObjectSP(std::move(config_up)); + return LLDB_RECORD_RESULT(data); +} + +bool SBDebugger::StateIsRunningState(StateType state) { + LLDB_RECORD_STATIC_METHOD(bool, SBDebugger, StateIsRunningState, + (lldb::StateType), state); + + + const bool result = lldb_private::StateIsRunningState(state); + + return result; +} + +bool SBDebugger::StateIsStoppedState(StateType state) { + LLDB_RECORD_STATIC_METHOD(bool, SBDebugger, StateIsStoppedState, + (lldb::StateType), state); + + + const bool result = lldb_private::StateIsStoppedState(state, false); + + return result; +} + +lldb::SBTarget SBDebugger::CreateTarget(const char *filename, + const char *target_triple, + const char *platform_name, + bool add_dependent_modules, + lldb::SBError &sb_error) { + LLDB_RECORD_METHOD( + lldb::SBTarget, SBDebugger, CreateTarget, + (const char *, const char *, const char *, bool, lldb::SBError &), + filename, target_triple, platform_name, add_dependent_modules, sb_error); + + SBTarget sb_target; + TargetSP target_sp; + if (m_opaque_sp) { + sb_error.Clear(); + OptionGroupPlatform platform_options(false); + platform_options.SetPlatformName(platform_name); + + sb_error.ref() = m_opaque_sp->GetTargetList().CreateTarget( + *m_opaque_sp, filename, target_triple, + add_dependent_modules ? eLoadDependentsYes : eLoadDependentsNo, + &platform_options, target_sp); + + if (sb_error.Success()) + sb_target.SetSP(target_sp); + } else { + sb_error.SetErrorString("invalid debugger"); + } + + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); + if (log) + log->Printf("SBDebugger(%p)::CreateTarget (filename=\"%s\", triple=%s, " + "platform_name=%s, add_dependent_modules=%u, error=%s) => " + "SBTarget(%p)", + static_cast<void *>(m_opaque_sp.get()), filename, target_triple, + platform_name, add_dependent_modules, sb_error.GetCString(), + static_cast<void *>(target_sp.get())); + + return LLDB_RECORD_RESULT(sb_target); +} + +SBTarget +SBDebugger::CreateTargetWithFileAndTargetTriple(const char *filename, + const char *target_triple) { + LLDB_RECORD_METHOD(lldb::SBTarget, SBDebugger, + CreateTargetWithFileAndTargetTriple, + (const char *, const char *), filename, target_triple); + + SBTarget sb_target; + TargetSP target_sp; + if (m_opaque_sp) { + const bool add_dependent_modules = true; + Status error(m_opaque_sp->GetTargetList().CreateTarget( + *m_opaque_sp, filename, target_triple, + add_dependent_modules ? eLoadDependentsYes : eLoadDependentsNo, nullptr, + target_sp)); + sb_target.SetSP(target_sp); + } + + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); + if (log) + log->Printf("SBDebugger(%p)::CreateTargetWithFileAndTargetTriple " + "(filename=\"%s\", triple=%s) => SBTarget(%p)", + static_cast<void *>(m_opaque_sp.get()), filename, target_triple, + static_cast<void *>(target_sp.get())); + + return LLDB_RECORD_RESULT(sb_target); +} + +SBTarget SBDebugger::CreateTargetWithFileAndArch(const char *filename, + const char *arch_cstr) { + LLDB_RECORD_METHOD(lldb::SBTarget, SBDebugger, CreateTargetWithFileAndArch, + (const char *, const char *), filename, arch_cstr); + + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); + + SBTarget sb_target; + TargetSP target_sp; + if (m_opaque_sp) { + Status error; + const bool add_dependent_modules = true; + + error = m_opaque_sp->GetTargetList().CreateTarget( + *m_opaque_sp, filename, arch_cstr, + add_dependent_modules ? eLoadDependentsYes : eLoadDependentsNo, nullptr, + target_sp); + + if (error.Success()) { + m_opaque_sp->GetTargetList().SetSelectedTarget(target_sp.get()); + sb_target.SetSP(target_sp); + } + } + + if (log) + log->Printf("SBDebugger(%p)::CreateTargetWithFileAndArch (filename=\"%s\", " + "arch=%s) => SBTarget(%p)", + static_cast<void *>(m_opaque_sp.get()), filename, arch_cstr, + static_cast<void *>(target_sp.get())); + + return LLDB_RECORD_RESULT(sb_target); +} + +SBTarget SBDebugger::CreateTarget(const char *filename) { + LLDB_RECORD_METHOD(lldb::SBTarget, SBDebugger, CreateTarget, (const char *), + filename); + + SBTarget sb_target; + TargetSP target_sp; + if (m_opaque_sp) { + Status error; + const bool add_dependent_modules = true; + error = m_opaque_sp->GetTargetList().CreateTarget( + *m_opaque_sp, filename, "", + add_dependent_modules ? eLoadDependentsYes : eLoadDependentsNo, nullptr, + target_sp); + + if (error.Success()) { + m_opaque_sp->GetTargetList().SetSelectedTarget(target_sp.get()); + sb_target.SetSP(target_sp); + } + } + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); + if (log) + log->Printf( + "SBDebugger(%p)::CreateTarget (filename=\"%s\") => SBTarget(%p)", + static_cast<void *>(m_opaque_sp.get()), filename, + static_cast<void *>(target_sp.get())); + return LLDB_RECORD_RESULT(sb_target); +} + +SBTarget SBDebugger::GetDummyTarget() { + LLDB_RECORD_METHOD_NO_ARGS(lldb::SBTarget, SBDebugger, GetDummyTarget); + + SBTarget sb_target; + if (m_opaque_sp) { + sb_target.SetSP(m_opaque_sp->GetDummyTarget()->shared_from_this()); + } + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); + if (log) + log->Printf( + "SBDebugger(%p)::GetDummyTarget() => SBTarget(%p)", + static_cast<void *>(m_opaque_sp.get()), + static_cast<void *>(sb_target.GetSP().get())); + return LLDB_RECORD_RESULT(sb_target); +} + +bool SBDebugger::DeleteTarget(lldb::SBTarget &target) { + LLDB_RECORD_METHOD(bool, SBDebugger, DeleteTarget, (lldb::SBTarget &), + target); + + bool result = false; + if (m_opaque_sp) { + TargetSP target_sp(target.GetSP()); + if (target_sp) { + // No need to lock, the target list is thread safe + result = m_opaque_sp->GetTargetList().DeleteTarget(target_sp); + target_sp->Destroy(); + target.Clear(); + const bool mandatory = true; + ModuleList::RemoveOrphanSharedModules(mandatory); + } + } + + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); + if (log) + log->Printf("SBDebugger(%p)::DeleteTarget (SBTarget(%p)) => %i", + static_cast<void *>(m_opaque_sp.get()), + static_cast<void *>(target.m_opaque_sp.get()), result); + + return result; +} + +SBTarget SBDebugger::GetTargetAtIndex(uint32_t idx) { + LLDB_RECORD_METHOD(lldb::SBTarget, SBDebugger, GetTargetAtIndex, (uint32_t), + idx); + + SBTarget sb_target; + if (m_opaque_sp) { + // No need to lock, the target list is thread safe + sb_target.SetSP(m_opaque_sp->GetTargetList().GetTargetAtIndex(idx)); + } + return LLDB_RECORD_RESULT(sb_target); +} + +uint32_t SBDebugger::GetIndexOfTarget(lldb::SBTarget target) { + LLDB_RECORD_METHOD(uint32_t, SBDebugger, GetIndexOfTarget, (lldb::SBTarget), + target); + + lldb::TargetSP target_sp = target.GetSP(); + if (!target_sp) + return UINT32_MAX; + + if (!m_opaque_sp) + return UINT32_MAX; + + return m_opaque_sp->GetTargetList().GetIndexOfTarget(target.GetSP()); +} + +SBTarget SBDebugger::FindTargetWithProcessID(lldb::pid_t pid) { + LLDB_RECORD_METHOD(lldb::SBTarget, SBDebugger, FindTargetWithProcessID, + (lldb::pid_t), pid); + + SBTarget sb_target; + if (m_opaque_sp) { + // No need to lock, the target list is thread safe + sb_target.SetSP(m_opaque_sp->GetTargetList().FindTargetWithProcessID(pid)); + } + return LLDB_RECORD_RESULT(sb_target); +} + +SBTarget SBDebugger::FindTargetWithFileAndArch(const char *filename, + const char *arch_name) { + LLDB_RECORD_METHOD(lldb::SBTarget, SBDebugger, FindTargetWithFileAndArch, + (const char *, const char *), filename, arch_name); + + SBTarget sb_target; + if (m_opaque_sp && filename && filename[0]) { + // No need to lock, the target list is thread safe + ArchSpec arch = Platform::GetAugmentedArchSpec( + m_opaque_sp->GetPlatformList().GetSelectedPlatform().get(), arch_name); + TargetSP target_sp( + m_opaque_sp->GetTargetList().FindTargetWithExecutableAndArchitecture( + FileSpec(filename), arch_name ? &arch : nullptr)); + sb_target.SetSP(target_sp); + } + return LLDB_RECORD_RESULT(sb_target); +} + +SBTarget SBDebugger::FindTargetWithLLDBProcess(const ProcessSP &process_sp) { + SBTarget sb_target; + if (m_opaque_sp) { + // No need to lock, the target list is thread safe + sb_target.SetSP( + m_opaque_sp->GetTargetList().FindTargetWithProcess(process_sp.get())); + } + return sb_target; +} + +uint32_t SBDebugger::GetNumTargets() { + LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBDebugger, GetNumTargets); + + if (m_opaque_sp) { + // No need to lock, the target list is thread safe + return m_opaque_sp->GetTargetList().GetNumTargets(); + } + return 0; +} + +SBTarget SBDebugger::GetSelectedTarget() { + LLDB_RECORD_METHOD_NO_ARGS(lldb::SBTarget, SBDebugger, GetSelectedTarget); + + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); + + SBTarget sb_target; + TargetSP target_sp; + if (m_opaque_sp) { + // No need to lock, the target list is thread safe + target_sp = m_opaque_sp->GetTargetList().GetSelectedTarget(); + sb_target.SetSP(target_sp); + } + + if (log) { + SBStream sstr; + sb_target.GetDescription(sstr, eDescriptionLevelBrief); + log->Printf("SBDebugger(%p)::GetSelectedTarget () => SBTarget(%p): %s", + static_cast<void *>(m_opaque_sp.get()), + static_cast<void *>(target_sp.get()), sstr.GetData()); + } + + return LLDB_RECORD_RESULT(sb_target); +} + +void SBDebugger::SetSelectedTarget(SBTarget &sb_target) { + LLDB_RECORD_METHOD(void, SBDebugger, SetSelectedTarget, (lldb::SBTarget &), + sb_target); + + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); + + TargetSP target_sp(sb_target.GetSP()); + if (m_opaque_sp) { + m_opaque_sp->GetTargetList().SetSelectedTarget(target_sp.get()); + } + if (log) { + SBStream sstr; + sb_target.GetDescription(sstr, eDescriptionLevelBrief); + log->Printf("SBDebugger(%p)::SetSelectedTarget () => SBTarget(%p): %s", + static_cast<void *>(m_opaque_sp.get()), + static_cast<void *>(target_sp.get()), sstr.GetData()); + } +} + +SBPlatform SBDebugger::GetSelectedPlatform() { + LLDB_RECORD_METHOD_NO_ARGS(lldb::SBPlatform, SBDebugger, GetSelectedPlatform); + + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); + + SBPlatform sb_platform; + DebuggerSP debugger_sp(m_opaque_sp); + if (debugger_sp) { + sb_platform.SetSP(debugger_sp->GetPlatformList().GetSelectedPlatform()); + } + if (log) + log->Printf("SBDebugger(%p)::GetSelectedPlatform () => SBPlatform(%p): %s", + static_cast<void *>(m_opaque_sp.get()), + static_cast<void *>(sb_platform.GetSP().get()), + sb_platform.GetName()); + return LLDB_RECORD_RESULT(sb_platform); +} + +void SBDebugger::SetSelectedPlatform(SBPlatform &sb_platform) { + LLDB_RECORD_METHOD(void, SBDebugger, SetSelectedPlatform, + (lldb::SBPlatform &), sb_platform); + + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); + + DebuggerSP debugger_sp(m_opaque_sp); + if (debugger_sp) { + debugger_sp->GetPlatformList().SetSelectedPlatform(sb_platform.GetSP()); + } + + if (log) + log->Printf("SBDebugger(%p)::SetSelectedPlatform (SBPlatform(%p) %s)", + static_cast<void *>(m_opaque_sp.get()), + static_cast<void *>(sb_platform.GetSP().get()), + sb_platform.GetName()); +} + +uint32_t SBDebugger::GetNumPlatforms() { + LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBDebugger, GetNumPlatforms); + + if (m_opaque_sp) { + // No need to lock, the platform list is thread safe + return m_opaque_sp->GetPlatformList().GetSize(); + } + return 0; +} + +SBPlatform SBDebugger::GetPlatformAtIndex(uint32_t idx) { + LLDB_RECORD_METHOD(lldb::SBPlatform, SBDebugger, GetPlatformAtIndex, + (uint32_t), idx); + + SBPlatform sb_platform; + if (m_opaque_sp) { + // No need to lock, the platform list is thread safe + sb_platform.SetSP(m_opaque_sp->GetPlatformList().GetAtIndex(idx)); + } + return LLDB_RECORD_RESULT(sb_platform); +} + +uint32_t SBDebugger::GetNumAvailablePlatforms() { + LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBDebugger, GetNumAvailablePlatforms); + + uint32_t idx = 0; + while (true) { + if (!PluginManager::GetPlatformPluginNameAtIndex(idx)) { + break; + } + ++idx; + } + // +1 for the host platform, which should always appear first in the list. + return idx + 1; +} + +SBStructuredData SBDebugger::GetAvailablePlatformInfoAtIndex(uint32_t idx) { + LLDB_RECORD_METHOD(lldb::SBStructuredData, SBDebugger, + GetAvailablePlatformInfoAtIndex, (uint32_t), idx); + + SBStructuredData data; + auto platform_dict = llvm::make_unique<StructuredData::Dictionary>(); + llvm::StringRef name_str("name"), desc_str("description"); + + if (idx == 0) { + PlatformSP host_platform_sp(Platform::GetHostPlatform()); + platform_dict->AddStringItem( + name_str, host_platform_sp->GetPluginName().GetStringRef()); + platform_dict->AddStringItem( + desc_str, llvm::StringRef(host_platform_sp->GetDescription())); + } else if (idx > 0) { + const char *plugin_name = + PluginManager::GetPlatformPluginNameAtIndex(idx - 1); + if (!plugin_name) { + return LLDB_RECORD_RESULT(data); + } + platform_dict->AddStringItem(name_str, llvm::StringRef(plugin_name)); + + const char *plugin_desc = + PluginManager::GetPlatformPluginDescriptionAtIndex(idx - 1); + if (!plugin_desc) { + return LLDB_RECORD_RESULT(data); + } + platform_dict->AddStringItem(desc_str, llvm::StringRef(plugin_desc)); + } + + data.m_impl_up->SetObjectSP( + StructuredData::ObjectSP(platform_dict.release())); + return LLDB_RECORD_RESULT(data); +} + +void SBDebugger::DispatchInput(void *baton, const void *data, size_t data_len) { + LLDB_RECORD_DUMMY(void, SBDebugger, DispatchInput, + (void *, const void *, size_t), baton, data, data_len); + + DispatchInput(data, data_len); +} + +void SBDebugger::DispatchInput(const void *data, size_t data_len) { + LLDB_RECORD_DUMMY(void, SBDebugger, DispatchInput, (const void *, size_t), + data, data_len); + + // Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + // + // if (log) + // log->Printf ("SBDebugger(%p)::DispatchInput (data=\"%.*s\", + // size_t=%" PRIu64 ")", + // m_opaque_sp.get(), + // (int) data_len, + // (const char *) data, + // (uint64_t)data_len); + // + // if (m_opaque_sp) + // m_opaque_sp->DispatchInput ((const char *) data, data_len); +} + +void SBDebugger::DispatchInputInterrupt() { + LLDB_RECORD_METHOD_NO_ARGS(void, SBDebugger, DispatchInputInterrupt); + + if (m_opaque_sp) + m_opaque_sp->DispatchInputInterrupt(); +} + +void SBDebugger::DispatchInputEndOfFile() { + LLDB_RECORD_METHOD_NO_ARGS(void, SBDebugger, DispatchInputEndOfFile); + + if (m_opaque_sp) + m_opaque_sp->DispatchInputEndOfFile(); +} + +void SBDebugger::PushInputReader(SBInputReader &reader) { + LLDB_RECORD_METHOD(void, SBDebugger, PushInputReader, (lldb::SBInputReader &), + reader); +} + +void SBDebugger::RunCommandInterpreter(bool auto_handle_events, + bool spawn_thread) { + LLDB_RECORD_METHOD(void, SBDebugger, RunCommandInterpreter, (bool, bool), + auto_handle_events, spawn_thread); + + if (m_opaque_sp) { + CommandInterpreterRunOptions options; + + m_opaque_sp->GetCommandInterpreter().RunCommandInterpreter( + auto_handle_events, spawn_thread, options); + } +} + +void SBDebugger::RunCommandInterpreter(bool auto_handle_events, + bool spawn_thread, + SBCommandInterpreterRunOptions &options, + int &num_errors, bool &quit_requested, + bool &stopped_for_crash) + +{ + LLDB_RECORD_METHOD(void, SBDebugger, RunCommandInterpreter, + (bool, bool, lldb::SBCommandInterpreterRunOptions &, int &, + bool &, bool &), + auto_handle_events, spawn_thread, options, num_errors, + quit_requested, stopped_for_crash); + + if (m_opaque_sp) { + CommandInterpreter &interp = m_opaque_sp->GetCommandInterpreter(); + interp.RunCommandInterpreter(auto_handle_events, spawn_thread, + options.ref()); + num_errors = interp.GetNumErrors(); + quit_requested = interp.GetQuitRequested(); + stopped_for_crash = interp.GetStoppedForCrash(); + } +} + +SBError SBDebugger::RunREPL(lldb::LanguageType language, + const char *repl_options) { + LLDB_RECORD_METHOD(lldb::SBError, SBDebugger, RunREPL, + (lldb::LanguageType, const char *), language, + repl_options); + + SBError error; + if (m_opaque_sp) + error.ref() = m_opaque_sp->RunREPL(language, repl_options); + else + error.SetErrorString("invalid debugger"); + return LLDB_RECORD_RESULT(error); +} + +void SBDebugger::reset(const DebuggerSP &debugger_sp) { + m_opaque_sp = debugger_sp; +} + +Debugger *SBDebugger::get() const { return m_opaque_sp.get(); } + +Debugger &SBDebugger::ref() const { + assert(m_opaque_sp.get()); + return *m_opaque_sp; +} + +const lldb::DebuggerSP &SBDebugger::get_sp() const { return m_opaque_sp; } + +SBDebugger SBDebugger::FindDebuggerWithID(int id) { + LLDB_RECORD_STATIC_METHOD(lldb::SBDebugger, SBDebugger, FindDebuggerWithID, + (int), id); + + // No need to lock, the debugger list is thread safe + SBDebugger sb_debugger; + DebuggerSP debugger_sp = Debugger::FindDebuggerWithID(id); + if (debugger_sp) + sb_debugger.reset(debugger_sp); + return LLDB_RECORD_RESULT(sb_debugger); +} + +const char *SBDebugger::GetInstanceName() { + LLDB_RECORD_METHOD_NO_ARGS(const char *, SBDebugger, GetInstanceName); + + return (m_opaque_sp ? m_opaque_sp->GetInstanceName().AsCString() : nullptr); +} + +SBError SBDebugger::SetInternalVariable(const char *var_name, const char *value, + const char *debugger_instance_name) { + LLDB_RECORD_STATIC_METHOD(lldb::SBError, SBDebugger, SetInternalVariable, + (const char *, const char *, const char *), + var_name, value, debugger_instance_name); + + SBError sb_error; + DebuggerSP debugger_sp(Debugger::FindDebuggerWithInstanceName( + ConstString(debugger_instance_name))); + Status error; + if (debugger_sp) { + ExecutionContext exe_ctx( + debugger_sp->GetCommandInterpreter().GetExecutionContext()); + error = debugger_sp->SetPropertyValue(&exe_ctx, eVarSetOperationAssign, + var_name, value); + } else { + error.SetErrorStringWithFormat("invalid debugger instance name '%s'", + debugger_instance_name); + } + if (error.Fail()) + sb_error.SetError(error); + return LLDB_RECORD_RESULT(sb_error); +} + +SBStringList +SBDebugger::GetInternalVariableValue(const char *var_name, + const char *debugger_instance_name) { + LLDB_RECORD_STATIC_METHOD( + lldb::SBStringList, SBDebugger, GetInternalVariableValue, + (const char *, const char *), var_name, debugger_instance_name); + + SBStringList ret_value; + DebuggerSP debugger_sp(Debugger::FindDebuggerWithInstanceName( + ConstString(debugger_instance_name))); + Status error; + if (debugger_sp) { + ExecutionContext exe_ctx( + debugger_sp->GetCommandInterpreter().GetExecutionContext()); + lldb::OptionValueSP value_sp( + debugger_sp->GetPropertyValue(&exe_ctx, var_name, false, error)); + if (value_sp) { + StreamString value_strm; + value_sp->DumpValue(&exe_ctx, value_strm, OptionValue::eDumpOptionValue); + const std::string &value_str = value_strm.GetString(); + if (!value_str.empty()) { + StringList string_list; + string_list.SplitIntoLines(value_str); + return LLDB_RECORD_RESULT(SBStringList(&string_list)); + } + } + } + return LLDB_RECORD_RESULT(SBStringList()); +} + +uint32_t SBDebugger::GetTerminalWidth() const { + LLDB_RECORD_METHOD_CONST_NO_ARGS(uint32_t, SBDebugger, GetTerminalWidth); + + return (m_opaque_sp ? m_opaque_sp->GetTerminalWidth() : 0); +} + +void SBDebugger::SetTerminalWidth(uint32_t term_width) { + LLDB_RECORD_METHOD(void, SBDebugger, SetTerminalWidth, (uint32_t), + term_width); + + if (m_opaque_sp) + m_opaque_sp->SetTerminalWidth(term_width); +} + +const char *SBDebugger::GetPrompt() const { + LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBDebugger, GetPrompt); + + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); + + if (log) + log->Printf("SBDebugger(%p)::GetPrompt () => \"%s\"", + static_cast<void *>(m_opaque_sp.get()), + (m_opaque_sp ? m_opaque_sp->GetPrompt().str().c_str() : "")); + + return (m_opaque_sp ? ConstString(m_opaque_sp->GetPrompt()).GetCString() + : nullptr); +} + +void SBDebugger::SetPrompt(const char *prompt) { + LLDB_RECORD_METHOD(void, SBDebugger, SetPrompt, (const char *), prompt); + + if (m_opaque_sp) + m_opaque_sp->SetPrompt(llvm::StringRef::withNullAsEmpty(prompt)); +} + +const char *SBDebugger::GetReproducerPath() const { + LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBDebugger, GetReproducerPath); + + return (m_opaque_sp + ? ConstString(m_opaque_sp->GetReproducerPath()).GetCString() + : nullptr); +} + +ScriptLanguage SBDebugger::GetScriptLanguage() const { + LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::ScriptLanguage, SBDebugger, + GetScriptLanguage); + + return (m_opaque_sp ? m_opaque_sp->GetScriptLanguage() : eScriptLanguageNone); +} + +void SBDebugger::SetScriptLanguage(ScriptLanguage script_lang) { + LLDB_RECORD_METHOD(void, SBDebugger, SetScriptLanguage, + (lldb::ScriptLanguage), script_lang); + + if (m_opaque_sp) { + m_opaque_sp->SetScriptLanguage(script_lang); + } +} + +bool SBDebugger::SetUseExternalEditor(bool value) { + LLDB_RECORD_METHOD(bool, SBDebugger, SetUseExternalEditor, (bool), value); + + return (m_opaque_sp ? m_opaque_sp->SetUseExternalEditor(value) : false); +} + +bool SBDebugger::GetUseExternalEditor() { + LLDB_RECORD_METHOD_NO_ARGS(bool, SBDebugger, GetUseExternalEditor); + + return (m_opaque_sp ? m_opaque_sp->GetUseExternalEditor() : false); +} + +bool SBDebugger::SetUseColor(bool value) { + LLDB_RECORD_METHOD(bool, SBDebugger, SetUseColor, (bool), value); + + return (m_opaque_sp ? m_opaque_sp->SetUseColor(value) : false); +} + +bool SBDebugger::GetUseColor() const { + LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBDebugger, GetUseColor); + + return (m_opaque_sp ? m_opaque_sp->GetUseColor() : false); +} + +bool SBDebugger::GetDescription(SBStream &description) { + LLDB_RECORD_METHOD(bool, SBDebugger, GetDescription, (lldb::SBStream &), + description); + + Stream &strm = description.ref(); + + if (m_opaque_sp) { + const char *name = m_opaque_sp->GetInstanceName().AsCString(); + user_id_t id = m_opaque_sp->GetID(); + strm.Printf("Debugger (instance: \"%s\", id: %" PRIu64 ")", name, id); + } else + strm.PutCString("No value"); + + return true; +} + +user_id_t SBDebugger::GetID() { + LLDB_RECORD_METHOD_NO_ARGS(lldb::user_id_t, SBDebugger, GetID); + + return (m_opaque_sp ? m_opaque_sp->GetID() : LLDB_INVALID_UID); +} + +SBError SBDebugger::SetCurrentPlatform(const char *platform_name_cstr) { + LLDB_RECORD_METHOD(lldb::SBError, SBDebugger, SetCurrentPlatform, + (const char *), platform_name_cstr); + + SBError sb_error; + if (m_opaque_sp) { + if (platform_name_cstr && platform_name_cstr[0]) { + ConstString platform_name(platform_name_cstr); + PlatformSP platform_sp(Platform::Find(platform_name)); + + if (platform_sp) { + // Already have a platform with this name, just select it + m_opaque_sp->GetPlatformList().SetSelectedPlatform(platform_sp); + } else { + // We don't have a platform by this name yet, create one + platform_sp = Platform::Create(platform_name, sb_error.ref()); + if (platform_sp) { + // We created the platform, now append and select it + bool make_selected = true; + m_opaque_sp->GetPlatformList().Append(platform_sp, make_selected); + } + } + } else { + sb_error.ref().SetErrorString("invalid platform name"); + } + } else { + sb_error.ref().SetErrorString("invalid debugger"); + } + return LLDB_RECORD_RESULT(sb_error); +} + +bool SBDebugger::SetCurrentPlatformSDKRoot(const char *sysroot) { + LLDB_RECORD_METHOD(bool, SBDebugger, SetCurrentPlatformSDKRoot, + (const char *), sysroot); + + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); + if (m_opaque_sp) { + PlatformSP platform_sp( + m_opaque_sp->GetPlatformList().GetSelectedPlatform()); + + if (platform_sp) { + if (log && sysroot) + log->Printf("SBDebugger::SetCurrentPlatformSDKRoot (\"%s\")", sysroot); + platform_sp->SetSDKRootDirectory(ConstString(sysroot)); + return true; + } + } + return false; +} + +bool SBDebugger::GetCloseInputOnEOF() const { + LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBDebugger, GetCloseInputOnEOF); + + return (m_opaque_sp ? m_opaque_sp->GetCloseInputOnEOF() : false); +} + +void SBDebugger::SetCloseInputOnEOF(bool b) { + LLDB_RECORD_METHOD(void, SBDebugger, SetCloseInputOnEOF, (bool), b); + + if (m_opaque_sp) + m_opaque_sp->SetCloseInputOnEOF(b); +} + +SBTypeCategory SBDebugger::GetCategory(const char *category_name) { + LLDB_RECORD_METHOD(lldb::SBTypeCategory, SBDebugger, GetCategory, + (const char *), category_name); + + if (!category_name || *category_name == 0) + return LLDB_RECORD_RESULT(SBTypeCategory()); + + TypeCategoryImplSP category_sp; + + if (DataVisualization::Categories::GetCategory(ConstString(category_name), + category_sp, false)) { + return LLDB_RECORD_RESULT(SBTypeCategory(category_sp)); + } else { + return LLDB_RECORD_RESULT(SBTypeCategory()); + } +} + +SBTypeCategory SBDebugger::GetCategory(lldb::LanguageType lang_type) { + LLDB_RECORD_METHOD(lldb::SBTypeCategory, SBDebugger, GetCategory, + (lldb::LanguageType), lang_type); + + TypeCategoryImplSP category_sp; + if (DataVisualization::Categories::GetCategory(lang_type, category_sp)) { + return LLDB_RECORD_RESULT(SBTypeCategory(category_sp)); + } else { + return LLDB_RECORD_RESULT(SBTypeCategory()); + } +} + +SBTypeCategory SBDebugger::CreateCategory(const char *category_name) { + LLDB_RECORD_METHOD(lldb::SBTypeCategory, SBDebugger, CreateCategory, + (const char *), category_name); + + if (!category_name || *category_name == 0) + return LLDB_RECORD_RESULT(SBTypeCategory()); + + TypeCategoryImplSP category_sp; + + if (DataVisualization::Categories::GetCategory(ConstString(category_name), + category_sp, true)) { + return LLDB_RECORD_RESULT(SBTypeCategory(category_sp)); + } else { + return LLDB_RECORD_RESULT(SBTypeCategory()); + } +} + +bool SBDebugger::DeleteCategory(const char *category_name) { + LLDB_RECORD_METHOD(bool, SBDebugger, DeleteCategory, (const char *), + category_name); + + if (!category_name || *category_name == 0) + return false; + + return DataVisualization::Categories::Delete(ConstString(category_name)); +} + +uint32_t SBDebugger::GetNumCategories() { + LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBDebugger, GetNumCategories); + + return DataVisualization::Categories::GetCount(); +} + +SBTypeCategory SBDebugger::GetCategoryAtIndex(uint32_t index) { + LLDB_RECORD_METHOD(lldb::SBTypeCategory, SBDebugger, GetCategoryAtIndex, + (uint32_t), index); + + return LLDB_RECORD_RESULT( + SBTypeCategory(DataVisualization::Categories::GetCategoryAtIndex(index))); +} + +SBTypeCategory SBDebugger::GetDefaultCategory() { + LLDB_RECORD_METHOD_NO_ARGS(lldb::SBTypeCategory, SBDebugger, + GetDefaultCategory); + + return LLDB_RECORD_RESULT(GetCategory("default")); +} + +SBTypeFormat SBDebugger::GetFormatForType(SBTypeNameSpecifier type_name) { + LLDB_RECORD_METHOD(lldb::SBTypeFormat, SBDebugger, GetFormatForType, + (lldb::SBTypeNameSpecifier), type_name); + + SBTypeCategory default_category_sb = GetDefaultCategory(); + if (default_category_sb.GetEnabled()) + return LLDB_RECORD_RESULT(default_category_sb.GetFormatForType(type_name)); + return LLDB_RECORD_RESULT(SBTypeFormat()); +} + +SBTypeSummary SBDebugger::GetSummaryForType(SBTypeNameSpecifier type_name) { + LLDB_RECORD_METHOD(lldb::SBTypeSummary, SBDebugger, GetSummaryForType, + (lldb::SBTypeNameSpecifier), type_name); + + if (!type_name.IsValid()) + return LLDB_RECORD_RESULT(SBTypeSummary()); + return LLDB_RECORD_RESULT( + SBTypeSummary(DataVisualization::GetSummaryForType(type_name.GetSP()))); +} + +SBTypeFilter SBDebugger::GetFilterForType(SBTypeNameSpecifier type_name) { + LLDB_RECORD_METHOD(lldb::SBTypeFilter, SBDebugger, GetFilterForType, + (lldb::SBTypeNameSpecifier), type_name); + + if (!type_name.IsValid()) + return LLDB_RECORD_RESULT(SBTypeFilter()); + return LLDB_RECORD_RESULT( + SBTypeFilter(DataVisualization::GetFilterForType(type_name.GetSP()))); +} + +SBTypeSynthetic SBDebugger::GetSyntheticForType(SBTypeNameSpecifier type_name) { + LLDB_RECORD_METHOD(lldb::SBTypeSynthetic, SBDebugger, GetSyntheticForType, + (lldb::SBTypeNameSpecifier), type_name); + + if (!type_name.IsValid()) + return LLDB_RECORD_RESULT(SBTypeSynthetic()); + return LLDB_RECORD_RESULT(SBTypeSynthetic( + DataVisualization::GetSyntheticForType(type_name.GetSP()))); +} + +static llvm::ArrayRef<const char *> GetCategoryArray(const char **categories) { + if (categories == nullptr) + return {}; + size_t len = 0; + while (categories[len] != nullptr) + ++len; + return llvm::makeArrayRef(categories, len); +} + +bool SBDebugger::EnableLog(const char *channel, const char **categories) { + LLDB_RECORD_METHOD(bool, SBDebugger, EnableLog, (const char *, const char **), + channel, categories); + + if (m_opaque_sp) { + uint32_t log_options = + LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME; + std::string error; + llvm::raw_string_ostream error_stream(error); + return m_opaque_sp->EnableLog(channel, GetCategoryArray(categories), "", + log_options, error_stream); + } else + return false; +} + +void SBDebugger::SetLoggingCallback(lldb::LogOutputCallback log_callback, + void *baton) { + LLDB_RECORD_DUMMY(void, SBDebugger, SetLoggingCallback, + (lldb::LogOutputCallback, void *), log_callback, baton); + + if (m_opaque_sp) { + return m_opaque_sp->SetLoggingCallback(log_callback, baton); + } +} + +namespace lldb_private { +namespace repro { + +template <> +void RegisterMethods<SBInputReader>(Registry &R) { + LLDB_REGISTER_METHOD(void, SBInputReader, SetIsDone, (bool)); + LLDB_REGISTER_METHOD_CONST(bool, SBInputReader, IsActive, ()); +} + +static void SetFileHandleRedirect(SBDebugger *, FILE *, bool) { + // Do nothing. +} + +static bool GetDefaultArchitectureRedirect(char *arch_name, + size_t arch_name_len) { + // The function is writing to its argument. Without the redirect it would + // write into the replay buffer. + char buffer[1024]; + return SBDebugger::GetDefaultArchitecture(buffer, arch_name_len); +} + +template <> +void RegisterMethods<SBDebugger>(Registry &R) { + // Custom implementation. + R.Register(&invoke<void (SBDebugger::*)( + FILE *, bool)>::method<&SBDebugger::SetErrorFileHandle>::doit, + &SetFileHandleRedirect); + R.Register(&invoke<void (SBDebugger::*)( + FILE *, bool)>::method<&SBDebugger::SetOutputFileHandle>::doit, + &SetFileHandleRedirect); + R.Register<bool(char *, size_t)>(static_cast<bool (*)(char *, size_t)>( + &SBDebugger::GetDefaultArchitecture), + &GetDefaultArchitectureRedirect); + + LLDB_REGISTER_CONSTRUCTOR(SBDebugger, ()); + LLDB_REGISTER_CONSTRUCTOR(SBDebugger, (const lldb::DebuggerSP &)); + LLDB_REGISTER_CONSTRUCTOR(SBDebugger, (const lldb::SBDebugger &)); + LLDB_REGISTER_METHOD(lldb::SBDebugger &, + SBDebugger, operator=,(const lldb::SBDebugger &)); + LLDB_REGISTER_STATIC_METHOD(void, SBDebugger, Initialize, ()); + LLDB_REGISTER_STATIC_METHOD(lldb::SBError, SBDebugger, + InitializeWithErrorHandling, ()); + LLDB_REGISTER_STATIC_METHOD(void, SBDebugger, Terminate, ()); + LLDB_REGISTER_METHOD(void, SBDebugger, Clear, ()); + LLDB_REGISTER_STATIC_METHOD(lldb::SBDebugger, SBDebugger, Create, ()); + LLDB_REGISTER_STATIC_METHOD(lldb::SBDebugger, SBDebugger, Create, (bool)); + LLDB_REGISTER_STATIC_METHOD(void, SBDebugger, Destroy, + (lldb::SBDebugger &)); + LLDB_REGISTER_STATIC_METHOD(void, SBDebugger, MemoryPressureDetected, ()); + LLDB_REGISTER_METHOD_CONST(bool, SBDebugger, IsValid, ()); + LLDB_REGISTER_METHOD_CONST(bool, SBDebugger, operator bool, ()); + LLDB_REGISTER_METHOD(void, SBDebugger, SetAsync, (bool)); + LLDB_REGISTER_METHOD(bool, SBDebugger, GetAsync, ()); + LLDB_REGISTER_METHOD(void, SBDebugger, SkipLLDBInitFiles, (bool)); + LLDB_REGISTER_METHOD(void, SBDebugger, SkipAppInitFiles, (bool)); + LLDB_REGISTER_METHOD(void, SBDebugger, SetInputFileHandle, (FILE *, bool)); + LLDB_REGISTER_METHOD(FILE *, SBDebugger, GetInputFileHandle, ()); + LLDB_REGISTER_METHOD(FILE *, SBDebugger, GetOutputFileHandle, ()); + LLDB_REGISTER_METHOD(FILE *, SBDebugger, GetErrorFileHandle, ()); + LLDB_REGISTER_METHOD(void, SBDebugger, SaveInputTerminalState, ()); + LLDB_REGISTER_METHOD(void, SBDebugger, RestoreInputTerminalState, ()); + LLDB_REGISTER_METHOD(lldb::SBCommandInterpreter, SBDebugger, + GetCommandInterpreter, ()); + LLDB_REGISTER_METHOD(void, SBDebugger, HandleCommand, (const char *)); + LLDB_REGISTER_METHOD(lldb::SBListener, SBDebugger, GetListener, ()); + LLDB_REGISTER_METHOD( + void, SBDebugger, HandleProcessEvent, + (const lldb::SBProcess &, const lldb::SBEvent &, FILE *, FILE *)); + LLDB_REGISTER_METHOD(lldb::SBSourceManager, SBDebugger, GetSourceManager, + ()); + LLDB_REGISTER_STATIC_METHOD(bool, SBDebugger, SetDefaultArchitecture, + (const char *)); + LLDB_REGISTER_METHOD(lldb::ScriptLanguage, SBDebugger, GetScriptingLanguage, + (const char *)); + LLDB_REGISTER_STATIC_METHOD(const char *, SBDebugger, GetVersionString, ()); + LLDB_REGISTER_STATIC_METHOD(const char *, SBDebugger, StateAsCString, + (lldb::StateType)); + LLDB_REGISTER_STATIC_METHOD(lldb::SBStructuredData, SBDebugger, + GetBuildConfiguration, ()); + LLDB_REGISTER_STATIC_METHOD(bool, SBDebugger, StateIsRunningState, + (lldb::StateType)); + LLDB_REGISTER_STATIC_METHOD(bool, SBDebugger, StateIsStoppedState, + (lldb::StateType)); + LLDB_REGISTER_METHOD( + lldb::SBTarget, SBDebugger, CreateTarget, + (const char *, const char *, const char *, bool, lldb::SBError &)); + LLDB_REGISTER_METHOD(lldb::SBTarget, SBDebugger, + CreateTargetWithFileAndTargetTriple, + (const char *, const char *)); + LLDB_REGISTER_METHOD(lldb::SBTarget, SBDebugger, + CreateTargetWithFileAndArch, + (const char *, const char *)); + LLDB_REGISTER_METHOD(lldb::SBTarget, SBDebugger, CreateTarget, + (const char *)); + LLDB_REGISTER_METHOD(lldb::SBTarget, SBDebugger, GetDummyTarget, ()); + LLDB_REGISTER_METHOD(bool, SBDebugger, DeleteTarget, (lldb::SBTarget &)); + LLDB_REGISTER_METHOD(lldb::SBTarget, SBDebugger, GetTargetAtIndex, + (uint32_t)); + LLDB_REGISTER_METHOD(uint32_t, SBDebugger, GetIndexOfTarget, + (lldb::SBTarget)); + LLDB_REGISTER_METHOD(lldb::SBTarget, SBDebugger, FindTargetWithProcessID, + (lldb::pid_t)); + LLDB_REGISTER_METHOD(lldb::SBTarget, SBDebugger, FindTargetWithFileAndArch, + (const char *, const char *)); + LLDB_REGISTER_METHOD(uint32_t, SBDebugger, GetNumTargets, ()); + LLDB_REGISTER_METHOD(lldb::SBTarget, SBDebugger, GetSelectedTarget, ()); + LLDB_REGISTER_METHOD(void, SBDebugger, SetSelectedTarget, + (lldb::SBTarget &)); + LLDB_REGISTER_METHOD(lldb::SBPlatform, SBDebugger, GetSelectedPlatform, ()); + LLDB_REGISTER_METHOD(void, SBDebugger, SetSelectedPlatform, + (lldb::SBPlatform &)); + LLDB_REGISTER_METHOD(uint32_t, SBDebugger, GetNumPlatforms, ()); + LLDB_REGISTER_METHOD(lldb::SBPlatform, SBDebugger, GetPlatformAtIndex, + (uint32_t)); + LLDB_REGISTER_METHOD(uint32_t, SBDebugger, GetNumAvailablePlatforms, ()); + LLDB_REGISTER_METHOD(lldb::SBStructuredData, SBDebugger, + GetAvailablePlatformInfoAtIndex, (uint32_t)); + LLDB_REGISTER_METHOD(void, SBDebugger, DispatchInputInterrupt, ()); + LLDB_REGISTER_METHOD(void, SBDebugger, DispatchInputEndOfFile, ()); + LLDB_REGISTER_METHOD(void, SBDebugger, PushInputReader, + (lldb::SBInputReader &)); + LLDB_REGISTER_METHOD(void, SBDebugger, RunCommandInterpreter, (bool, bool)); + LLDB_REGISTER_METHOD(void, SBDebugger, RunCommandInterpreter, + (bool, bool, lldb::SBCommandInterpreterRunOptions &, + int &, bool &, bool &)); + LLDB_REGISTER_METHOD(lldb::SBError, SBDebugger, RunREPL, + (lldb::LanguageType, const char *)); + LLDB_REGISTER_STATIC_METHOD(lldb::SBDebugger, SBDebugger, + FindDebuggerWithID, (int)); + LLDB_REGISTER_METHOD(const char *, SBDebugger, GetInstanceName, ()); + LLDB_REGISTER_STATIC_METHOD(lldb::SBError, SBDebugger, SetInternalVariable, + (const char *, const char *, const char *)); + LLDB_REGISTER_STATIC_METHOD(lldb::SBStringList, SBDebugger, + GetInternalVariableValue, + (const char *, const char *)); + LLDB_REGISTER_METHOD_CONST(uint32_t, SBDebugger, GetTerminalWidth, ()); + LLDB_REGISTER_METHOD(void, SBDebugger, SetTerminalWidth, (uint32_t)); + LLDB_REGISTER_METHOD_CONST(const char *, SBDebugger, GetPrompt, ()); + LLDB_REGISTER_METHOD(void, SBDebugger, SetPrompt, (const char *)); + LLDB_REGISTER_METHOD_CONST(const char *, SBDebugger, GetReproducerPath, ()); + LLDB_REGISTER_METHOD_CONST(lldb::ScriptLanguage, SBDebugger, + GetScriptLanguage, ()); + LLDB_REGISTER_METHOD(void, SBDebugger, SetScriptLanguage, + (lldb::ScriptLanguage)); + LLDB_REGISTER_METHOD(bool, SBDebugger, SetUseExternalEditor, (bool)); + LLDB_REGISTER_METHOD(bool, SBDebugger, GetUseExternalEditor, ()); + LLDB_REGISTER_METHOD(bool, SBDebugger, SetUseColor, (bool)); + LLDB_REGISTER_METHOD_CONST(bool, SBDebugger, GetUseColor, ()); + LLDB_REGISTER_METHOD(bool, SBDebugger, GetDescription, (lldb::SBStream &)); + LLDB_REGISTER_METHOD(lldb::user_id_t, SBDebugger, GetID, ()); + LLDB_REGISTER_METHOD(lldb::SBError, SBDebugger, SetCurrentPlatform, + (const char *)); + LLDB_REGISTER_METHOD(bool, SBDebugger, SetCurrentPlatformSDKRoot, + (const char *)); + LLDB_REGISTER_METHOD_CONST(bool, SBDebugger, GetCloseInputOnEOF, ()); + LLDB_REGISTER_METHOD(void, SBDebugger, SetCloseInputOnEOF, (bool)); + LLDB_REGISTER_METHOD(lldb::SBTypeCategory, SBDebugger, GetCategory, + (const char *)); + LLDB_REGISTER_METHOD(lldb::SBTypeCategory, SBDebugger, GetCategory, + (lldb::LanguageType)); + LLDB_REGISTER_METHOD(lldb::SBTypeCategory, SBDebugger, CreateCategory, + (const char *)); + LLDB_REGISTER_METHOD(bool, SBDebugger, DeleteCategory, (const char *)); + LLDB_REGISTER_METHOD(uint32_t, SBDebugger, GetNumCategories, ()); + LLDB_REGISTER_METHOD(lldb::SBTypeCategory, SBDebugger, GetCategoryAtIndex, + (uint32_t)); + LLDB_REGISTER_METHOD(lldb::SBTypeCategory, SBDebugger, GetDefaultCategory, + ()); + LLDB_REGISTER_METHOD(lldb::SBTypeFormat, SBDebugger, GetFormatForType, + (lldb::SBTypeNameSpecifier)); + LLDB_REGISTER_METHOD(lldb::SBTypeSummary, SBDebugger, GetSummaryForType, + (lldb::SBTypeNameSpecifier)); + LLDB_REGISTER_METHOD(lldb::SBTypeSynthetic, SBDebugger, GetSyntheticForType, + (lldb::SBTypeNameSpecifier)); + LLDB_REGISTER_METHOD(lldb::SBTypeFilter, SBDebugger, GetFilterForType, + (lldb::SBTypeNameSpecifier)); + LLDB_REGISTER_METHOD(bool, SBDebugger, EnableLog, + (const char *, const char **)); +} + +} +} |