diff options
Diffstat (limited to 'contrib/llvm/tools/lldb/source/API/SBDebugger.cpp')
-rw-r--r-- | contrib/llvm/tools/lldb/source/API/SBDebugger.cpp | 1396 |
1 files changed, 1396 insertions, 0 deletions
diff --git a/contrib/llvm/tools/lldb/source/API/SBDebugger.cpp b/contrib/llvm/tools/lldb/source/API/SBDebugger.cpp new file mode 100644 index 0000000..a95f2ff --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBDebugger.cpp @@ -0,0 +1,1396 @@ +//===-- SBDebugger.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/lldb-python.h" + +#include "lldb/API/SBDebugger.h" + +#include "lldb/lldb-private.h" + +#include "lldb/API/SBListener.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/SBProcess.h" +#include "lldb/API/SBSourceManager.h" +#include "lldb/API/SBStream.h" +#include "lldb/API/SBStringList.h" +#include "lldb/API/SBTarget.h" +#include "lldb/API/SBThread.h" +#include "lldb/API/SBTypeCategory.h" +#include "lldb/API/SBTypeFormat.h" +#include "lldb/API/SBTypeFilter.h" +#include "lldb/API/SBTypeNameSpecifier.h" +#include "lldb/API/SBTypeSummary.h" +#include "lldb/API/SBTypeSynthetic.h" + + +#include "lldb/Core/Debugger.h" +#include "lldb/Core/State.h" +#include "lldb/Core/StreamFile.h" +#include "lldb/DataFormatters/DataVisualization.h" +#include "lldb/Interpreter/Args.h" +#include "lldb/Interpreter/CommandInterpreter.h" +#include "lldb/Interpreter/OptionGroupPlatform.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/TargetList.h" + +#include "llvm/Support/DynamicLibrary.h" + +using namespace lldb; +using namespace lldb_private; + + +SBInputReader::SBInputReader() +{ +} +SBInputReader::~SBInputReader() +{ +} + +SBError +SBInputReader::Initialize(lldb::SBDebugger& sb_debugger, unsigned long (*)(void*, lldb::SBInputReader*, lldb::InputReaderAction, char const*, unsigned long), void*, lldb::InputReaderGranularity, char const*, char const*, bool) +{ + return SBError(); +} + +void +SBInputReader::SetIsDone(bool) +{ +} +bool +SBInputReader::IsActive() const +{ + return false; +} + +static llvm::sys::DynamicLibrary +LoadPlugin (const lldb::DebuggerSP &debugger_sp, const FileSpec& spec, Error& 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)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 (spec.Exists()) + error.SetErrorString("this file does not represent a loadable dylib"); + else + error.SetErrorString("no such file"); + } + return llvm::sys::DynamicLibrary(); +} + +void +SBDebugger::Initialize () +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (log) + log->Printf ("SBDebugger::Initialize ()"); + + SBCommandInterpreter::InitializeSWIG (); + + Debugger::Initialize(LoadPlugin); +} + +void +SBDebugger::Terminate () +{ + Debugger::Terminate(); +} + +void +SBDebugger::Clear () +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (log) + log->Printf ("SBDebugger(%p)::Clear ()", + static_cast<void*>(m_opaque_sp.get())); + + if (m_opaque_sp) + m_opaque_sp->ClearIOHandlers (); + + m_opaque_sp.reset(); +} + +SBDebugger +SBDebugger::Create() +{ + return SBDebugger::Create(false, NULL, NULL); +} + +SBDebugger +SBDebugger::Create(bool source_init_files) +{ + return SBDebugger::Create (source_init_files, NULL, NULL); +} + +SBDebugger +SBDebugger::Create(bool source_init_files, lldb::LogOutputCallback callback, void *baton) + +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + 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 Mutex g_mutex(Mutex::eMutexTypeRecursive); + Mutex::Locker locker(g_mutex); + + debugger.reset(Debugger::CreateInstance(callback, baton)); + + if (log) + { + SBStream sstr; + debugger.GetDescription (sstr); + log->Printf ("SBDebugger::Create () => SBDebugger(%p): %s", + static_cast<void*>(debugger.m_opaque_sp.get()), + sstr.GetData()); + } + + 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) +{ + Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (log) + { + SBStream sstr; + debugger.GetDescription (sstr); + log->Printf ("SBDebugger::Destroy () => SBDebugger(%p): %s", + static_cast<void*>(debugger.m_opaque_sp.get()), + sstr.GetData()); + } + + Debugger::Destroy (debugger.m_opaque_sp); + + if (debugger.m_opaque_sp.get() != NULL) + debugger.m_opaque_sp.reset(); +} + +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. + Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + const bool mandatory = false; + if (log) + { + log->Printf ("SBDebugger::MemoryPressureDetected (), mandatory = %d", mandatory); + } + + ModuleList::RemoveOrphanSharedModules(mandatory); +} + +SBDebugger::SBDebugger () : + m_opaque_sp () +{ +} + +SBDebugger::SBDebugger(const lldb::DebuggerSP &debugger_sp) : + m_opaque_sp(debugger_sp) +{ +} + +SBDebugger::SBDebugger(const SBDebugger &rhs) : + m_opaque_sp (rhs.m_opaque_sp) +{ +} + +SBDebugger & +SBDebugger::operator = (const SBDebugger &rhs) +{ + if (this != &rhs) + { + m_opaque_sp = rhs.m_opaque_sp; + } + return *this; +} + +SBDebugger::~SBDebugger () +{ +} + +bool +SBDebugger::IsValid() const +{ + return m_opaque_sp.get() != NULL; +} + + +void +SBDebugger::SetAsync (bool b) +{ + if (m_opaque_sp) + m_opaque_sp->SetAsyncExecution(b); +} + +bool +SBDebugger::GetAsync () +{ + if (m_opaque_sp) + return m_opaque_sp->GetAsyncExecution(); + else + return false; +} + +void +SBDebugger::SkipLLDBInitFiles (bool b) +{ + if (m_opaque_sp) + m_opaque_sp->GetCommandInterpreter().SkipLLDBInitFiles (b); +} + +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) +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (log) + log->Printf ("SBDebugger(%p)::SetInputFileHandle (fh=%p, transfer_ownership=%i)", + static_cast<void*>(m_opaque_sp.get()), + static_cast<void*>(fh), transfer_ownership); + + if (m_opaque_sp) + m_opaque_sp->SetInputFileHandle (fh, transfer_ownership); +} + +void +SBDebugger::SetOutputFileHandle (FILE *fh, bool transfer_ownership) +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + + if (log) + log->Printf ("SBDebugger(%p)::SetOutputFileHandle (fh=%p, transfer_ownership=%i)", + static_cast<void*>(m_opaque_sp.get()), + static_cast<void*>(fh), transfer_ownership); + + if (m_opaque_sp) + m_opaque_sp->SetOutputFileHandle (fh, transfer_ownership); +} + +void +SBDebugger::SetErrorFileHandle (FILE *fh, bool transfer_ownership) +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + + if (log) + log->Printf ("SBDebugger(%p)::SetErrorFileHandle (fh=%p, transfer_ownership=%i)", + static_cast<void*>(m_opaque_sp.get()), + static_cast<void*>(fh), transfer_ownership); + + if (m_opaque_sp) + m_opaque_sp->SetErrorFileHandle (fh, transfer_ownership); +} + +FILE * +SBDebugger::GetInputFileHandle () +{ + if (m_opaque_sp) + { + StreamFileSP stream_file_sp (m_opaque_sp->GetInputFile()); + if (stream_file_sp) + return stream_file_sp->GetFile().GetStream(); + } + return NULL; +} + +FILE * +SBDebugger::GetOutputFileHandle () +{ + if (m_opaque_sp) + { + StreamFileSP stream_file_sp (m_opaque_sp->GetOutputFile()); + if (stream_file_sp) + return stream_file_sp->GetFile().GetStream(); + } + return NULL; +} + +FILE * +SBDebugger::GetErrorFileHandle () +{ + if (m_opaque_sp) + if (m_opaque_sp) + { + StreamFileSP stream_file_sp (m_opaque_sp->GetErrorFile()); + if (stream_file_sp) + return stream_file_sp->GetFile().GetStream(); + } + return NULL; +} + +void +SBDebugger::SaveInputTerminalState() +{ + if (m_opaque_sp) + m_opaque_sp->SaveInputTerminalState(); +} + +void +SBDebugger::RestoreInputTerminalState() +{ + if (m_opaque_sp) + m_opaque_sp->RestoreInputTerminalState(); + +} +SBCommandInterpreter +SBDebugger::GetCommandInterpreter () +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + SBCommandInterpreter sb_interpreter; + if (m_opaque_sp) + sb_interpreter.reset (&m_opaque_sp->GetCommandInterpreter()); + + if (log) + log->Printf ("SBDebugger(%p)::GetCommandInterpreter () => SBCommandInterpreter(%p)", + static_cast<void*>(m_opaque_sp.get()), + static_cast<void*>(sb_interpreter.get())); + + return sb_interpreter; +} + +void +SBDebugger::HandleCommand (const char *command) +{ + if (m_opaque_sp) + { + TargetSP target_sp (m_opaque_sp->GetSelectedTarget()); + Mutex::Locker api_locker; + if (target_sp) + api_locker.Lock(target_sp->GetAPIMutex()); + + SBCommandInterpreter sb_interpreter(GetCommandInterpreter ()); + SBCommandReturnObject result; + + sb_interpreter.HandleCommand (command, result, false); + + if (GetErrorFileHandle() != NULL) + result.PutError (GetErrorFileHandle()); + if (GetOutputFileHandle() != NULL) + result.PutOutput (GetOutputFileHandle()); + + if (m_opaque_sp->GetAsyncExecution() == false) + { + SBProcess process(GetCommandInterpreter().GetProcess ()); + ProcessSP process_sp (process.GetSP()); + if (process_sp) + { + EventSP event_sp; + Listener &lldb_listener = m_opaque_sp->GetListener(); + while (lldb_listener.GetNextEventForBroadcaster (process_sp.get(), event_sp)) + { + SBEvent event(event_sp); + HandleProcessEvent (process, event, GetOutputFileHandle(), GetErrorFileHandle()); + } + } + } + } +} + +SBListener +SBDebugger::GetListener () +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + SBListener sb_listener; + if (m_opaque_sp) + sb_listener.reset(&m_opaque_sp->GetListener(), false); + + if (log) + log->Printf ("SBDebugger(%p)::GetListener () => SBListener(%p)", + static_cast<void*>(m_opaque_sp.get()), + static_cast<void*>(sb_listener.get())); + + return sb_listener; +} + +void +SBDebugger::HandleProcessEvent (const SBProcess &process, const SBEvent &event, FILE *out, FILE *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; + + Mutex::Locker api_locker (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 != NULL) + ::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 != NULL) + ::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 () +{ + SBSourceManager sb_source_manager (*this); + return sb_source_manager; +} + + +bool +SBDebugger::GetDefaultArchitecture (char *arch_name, 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) +{ + 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) +{ + + return Args::StringToScriptLanguage (script_language_name, + eScriptLanguageDefault, + NULL); +} + +const char * +SBDebugger::GetVersionString () +{ + return lldb_private::GetVersion(); +} + +const char * +SBDebugger::StateAsCString (StateType state) +{ + return lldb_private::StateAsCString (state); +} + +bool +SBDebugger::StateIsRunningState (StateType state) +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + const bool result = lldb_private::StateIsRunningState (state); + if (log) + log->Printf ("SBDebugger::StateIsRunningState (state=%s) => %i", + StateAsCString (state), result); + + return result; +} + +bool +SBDebugger::StateIsStoppedState (StateType state) +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + const bool result = lldb_private::StateIsStoppedState (state, false); + if (log) + log->Printf ("SBDebugger::StateIsStoppedState (state=%s) => %i", + StateAsCString (state), result); + + 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) +{ + 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, + &platform_options, + target_sp); + + if (sb_error.Success()) + sb_target.SetSP (target_sp); + } + else + { + sb_error.SetErrorString("invalid target"); + } + + 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 sb_target; +} + +SBTarget +SBDebugger::CreateTargetWithFileAndTargetTriple (const char *filename, + const char *target_triple) +{ + SBTarget sb_target; + TargetSP target_sp; + if (m_opaque_sp) + { + const bool add_dependent_modules = true; + Error error (m_opaque_sp->GetTargetList().CreateTarget (*m_opaque_sp, + filename, + target_triple, + add_dependent_modules, + NULL, + 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 sb_target; +} + +SBTarget +SBDebugger::CreateTargetWithFileAndArch (const char *filename, const char *arch_cstr) +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + SBTarget sb_target; + TargetSP target_sp; + if (m_opaque_sp) + { + Error error; + const bool add_dependent_modules = true; + + error = m_opaque_sp->GetTargetList().CreateTarget (*m_opaque_sp, + filename, + arch_cstr, + add_dependent_modules, + NULL, + 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 sb_target; +} + +SBTarget +SBDebugger::CreateTarget (const char *filename) +{ + SBTarget sb_target; + TargetSP target_sp; + if (m_opaque_sp) + { + Error error; + const bool add_dependent_modules = true; + error = m_opaque_sp->GetTargetList().CreateTarget (*m_opaque_sp, + filename, + NULL, + add_dependent_modules, + NULL, + 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 sb_target; +} + +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) +{ + 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 sb_target; +} + +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) +{ + 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 sb_target; +} + +SBTarget +SBDebugger::FindTargetWithFileAndArch (const char *filename, const char *arch_name) +{ + SBTarget sb_target; + if (m_opaque_sp && filename && filename[0]) + { + // No need to lock, the target list is thread safe + ArchSpec arch (arch_name, m_opaque_sp->GetPlatformList().GetSelectedPlatform().get()); + TargetSP target_sp (m_opaque_sp->GetTargetList().FindTargetWithExecutableAndArchitecture (FileSpec(filename, false), arch_name ? &arch : NULL)); + sb_target.SetSP (target_sp); + } + return 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 () +{ + 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 () +{ + 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 sb_target; +} + +void +SBDebugger::SetSelectedTarget (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() +{ + 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 sb_platform; +} + +void +SBDebugger::SetSelectedPlatform(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()); +} + +void +SBDebugger::DispatchInput (void* baton, const void *data, size_t data_len) +{ + DispatchInput (data,data_len); +} + +void +SBDebugger::DispatchInput (const void *data, size_t 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 () +{ + if (m_opaque_sp) + m_opaque_sp->DispatchInputInterrupt (); +} + +void +SBDebugger::DispatchInputEndOfFile () +{ + if (m_opaque_sp) + m_opaque_sp->DispatchInputEndOfFile (); +} + +void +SBDebugger::PushInputReader (SBInputReader &reader) +{ +} + +void +SBDebugger::RunCommandInterpreter (bool auto_handle_events, + bool 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) + +{ + 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(); + } +} + +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) +{ + // 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 sb_debugger; +} + +const char * +SBDebugger::GetInstanceName() +{ + if (m_opaque_sp) + return m_opaque_sp->GetInstanceName().AsCString(); + else + return NULL; +} + +SBError +SBDebugger::SetInternalVariable (const char *var_name, const char *value, const char *debugger_instance_name) +{ + SBError sb_error; + DebuggerSP debugger_sp(Debugger::FindDebuggerWithInstanceName (ConstString(debugger_instance_name))); + Error 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 sb_error; +} + +SBStringList +SBDebugger::GetInternalVariableValue (const char *var_name, const char *debugger_instance_name) +{ + SBStringList ret_value; + DebuggerSP debugger_sp(Debugger::FindDebuggerWithInstanceName (ConstString(debugger_instance_name))); + Error 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 SBStringList(&string_list); + } + } + } + return SBStringList(); +} + +uint32_t +SBDebugger::GetTerminalWidth () const +{ + if (m_opaque_sp) + return m_opaque_sp->GetTerminalWidth (); + return 0; +} + +void +SBDebugger::SetTerminalWidth (uint32_t term_width) +{ + if (m_opaque_sp) + m_opaque_sp->SetTerminalWidth (term_width); +} + +const char * +SBDebugger::GetPrompt() const +{ + 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() : "")); + + if (m_opaque_sp) + return m_opaque_sp->GetPrompt (); + return 0; +} + +void +SBDebugger::SetPrompt (const char *prompt) +{ + if (m_opaque_sp) + m_opaque_sp->SetPrompt (prompt); +} + + +ScriptLanguage +SBDebugger::GetScriptLanguage() const +{ + if (m_opaque_sp) + return m_opaque_sp->GetScriptLanguage (); + return eScriptLanguageNone; +} + +void +SBDebugger::SetScriptLanguage (ScriptLanguage script_lang) +{ + if (m_opaque_sp) + { + m_opaque_sp->SetScriptLanguage (script_lang); + } +} + +bool +SBDebugger::SetUseExternalEditor (bool value) +{ + if (m_opaque_sp) + return m_opaque_sp->SetUseExternalEditor (value); + return false; +} + +bool +SBDebugger::GetUseExternalEditor () +{ + if (m_opaque_sp) + return m_opaque_sp->GetUseExternalEditor (); + return false; +} + +bool +SBDebugger::SetUseColor (bool value) +{ + if (m_opaque_sp) + return m_opaque_sp->SetUseColor (value); + return false; +} + +bool +SBDebugger::GetUseColor () const +{ + if (m_opaque_sp) + return m_opaque_sp->GetUseColor (); + return false; +} + +bool +SBDebugger::GetDescription (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() +{ + if (m_opaque_sp) + return m_opaque_sp->GetID(); + return LLDB_INVALID_UID; +} + + +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 sb_error; +} + +bool +SBDebugger::SetCurrentPlatformSDKRoot (const char *sysroot) +{ + if (m_opaque_sp) + { + PlatformSP platform_sp (m_opaque_sp->GetPlatformList().GetSelectedPlatform()); + + if (platform_sp) + { + platform_sp->SetSDKRootDirectory (ConstString (sysroot)); + return true; + } + } + return false; +} + +bool +SBDebugger::GetCloseInputOnEOF () const +{ + if (m_opaque_sp) + return m_opaque_sp->GetCloseInputOnEOF (); + return false; +} + +void +SBDebugger::SetCloseInputOnEOF (bool b) +{ + if (m_opaque_sp) + m_opaque_sp->SetCloseInputOnEOF (b); +} + +SBTypeCategory +SBDebugger::GetCategory (const char* category_name) +{ + if (!category_name || *category_name == 0) + return SBTypeCategory(); + + TypeCategoryImplSP category_sp; + + if (DataVisualization::Categories::GetCategory(ConstString(category_name), category_sp, false)) + return SBTypeCategory(category_sp); + else + return SBTypeCategory(); +} + +SBTypeCategory +SBDebugger::CreateCategory (const char* category_name) +{ + if (!category_name || *category_name == 0) + return SBTypeCategory(); + + TypeCategoryImplSP category_sp; + + if (DataVisualization::Categories::GetCategory(ConstString(category_name), category_sp, true)) + return SBTypeCategory(category_sp); + else + return SBTypeCategory(); +} + +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() +{ + return DataVisualization::Categories::GetCount(); +} + +SBTypeCategory +SBDebugger::GetCategoryAtIndex (uint32_t index) +{ + return SBTypeCategory(DataVisualization::Categories::GetCategoryAtIndex(index)); +} + +SBTypeCategory +SBDebugger::GetDefaultCategory() +{ + return GetCategory("default"); +} + +SBTypeFormat +SBDebugger::GetFormatForType (SBTypeNameSpecifier type_name) +{ + SBTypeCategory default_category_sb = GetDefaultCategory(); + if (default_category_sb.GetEnabled()) + return default_category_sb.GetFormatForType(type_name); + return SBTypeFormat(); +} + +#ifndef LLDB_DISABLE_PYTHON +SBTypeSummary +SBDebugger::GetSummaryForType (SBTypeNameSpecifier type_name) +{ + if (type_name.IsValid() == false) + return SBTypeSummary(); + return SBTypeSummary(DataVisualization::GetSummaryForType(type_name.GetSP())); +} +#endif // LLDB_DISABLE_PYTHON + +SBTypeFilter +SBDebugger::GetFilterForType (SBTypeNameSpecifier type_name) +{ + if (type_name.IsValid() == false) + return SBTypeFilter(); + return SBTypeFilter(DataVisualization::GetFilterForType(type_name.GetSP())); +} + +#ifndef LLDB_DISABLE_PYTHON +SBTypeSynthetic +SBDebugger::GetSyntheticForType (SBTypeNameSpecifier type_name) +{ + if (type_name.IsValid() == false) + return SBTypeSynthetic(); + return SBTypeSynthetic(DataVisualization::GetSyntheticForType(type_name.GetSP())); +} +#endif // LLDB_DISABLE_PYTHON + +bool +SBDebugger::EnableLog (const char *channel, const char **categories) +{ + if (m_opaque_sp) + { + uint32_t log_options = LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME; + StreamString errors; + return m_opaque_sp->EnableLog (channel, categories, NULL, log_options, errors); + + } + else + return false; +} + +void +SBDebugger::SetLoggingCallback (lldb::LogOutputCallback log_callback, void *baton) +{ + if (m_opaque_sp) + { + return m_opaque_sp->SetLoggingCallback (log_callback, baton); + } +} + + |