diff options
Diffstat (limited to 'contrib/llvm/tools/lldb/source/API/SBProcess.cpp')
-rw-r--r-- | contrib/llvm/tools/lldb/source/API/SBProcess.cpp | 1465 |
1 files changed, 1465 insertions, 0 deletions
diff --git a/contrib/llvm/tools/lldb/source/API/SBProcess.cpp b/contrib/llvm/tools/lldb/source/API/SBProcess.cpp new file mode 100644 index 0000000..dceadec --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBProcess.cpp @@ -0,0 +1,1465 @@ +//===-- SBProcess.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/SBProcess.h" + +// C Includes +#include <inttypes.h> + +#include "lldb/lldb-defines.h" +#include "lldb/lldb-types.h" + +#include "lldb/Interpreter/Args.h" +#include "lldb/Core/Debugger.h" +#include "lldb/Core/Log.h" +#include "lldb/Core/Module.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Core/State.h" +#include "lldb/Core/Stream.h" +#include "lldb/Core/StreamFile.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/RegisterContext.h" +#include "lldb/Target/SystemRuntime.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/Thread.h" + +// Project includes + +#include "lldb/API/SBBroadcaster.h" +#include "lldb/API/SBCommandReturnObject.h" +#include "lldb/API/SBDebugger.h" +#include "lldb/API/SBEvent.h" +#include "lldb/API/SBFileSpec.h" +#include "lldb/API/SBThread.h" +#include "lldb/API/SBThreadCollection.h" +#include "lldb/API/SBStream.h" +#include "lldb/API/SBStringList.h" +#include "lldb/API/SBUnixSignals.h" + +using namespace lldb; +using namespace lldb_private; + + +SBProcess::SBProcess () : + m_opaque_wp() +{ +} + + +//---------------------------------------------------------------------- +// SBProcess constructor +//---------------------------------------------------------------------- + +SBProcess::SBProcess (const SBProcess& rhs) : + m_opaque_wp (rhs.m_opaque_wp) +{ +} + + +SBProcess::SBProcess (const lldb::ProcessSP &process_sp) : + m_opaque_wp (process_sp) +{ +} + +const SBProcess& +SBProcess::operator = (const SBProcess& rhs) +{ + if (this != &rhs) + m_opaque_wp = rhs.m_opaque_wp; + return *this; +} + +//---------------------------------------------------------------------- +// Destructor +//---------------------------------------------------------------------- +SBProcess::~SBProcess() +{ +} + +const char * +SBProcess::GetBroadcasterClassName () +{ + return Process::GetStaticBroadcasterClass().AsCString(); +} + +const char * +SBProcess::GetPluginName () +{ + ProcessSP process_sp(GetSP()); + if (process_sp) + { + return process_sp->GetPluginName().GetCString(); + } + return "<Unknown>"; +} + +const char * +SBProcess::GetShortPluginName () +{ + ProcessSP process_sp(GetSP()); + if (process_sp) + { + return process_sp->GetPluginName().GetCString(); + } + return "<Unknown>"; +} + + +lldb::ProcessSP +SBProcess::GetSP() const +{ + return m_opaque_wp.lock(); +} + +void +SBProcess::SetSP (const ProcessSP &process_sp) +{ + m_opaque_wp = process_sp; +} + +void +SBProcess::Clear () +{ + m_opaque_wp.reset(); +} + + +bool +SBProcess::IsValid() const +{ + ProcessSP process_sp(m_opaque_wp.lock()); + return ((bool) process_sp && process_sp->IsValid()); +} + +bool +SBProcess::RemoteLaunch (char const **argv, + char const **envp, + const char *stdin_path, + const char *stdout_path, + const char *stderr_path, + const char *working_directory, + uint32_t launch_flags, + bool stop_at_entry, + lldb::SBError& error) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBProcess(%p)::RemoteLaunch (argv=%p, envp=%p, stdin=%s, stdout=%s, stderr=%s, working-dir=%s, launch_flags=0x%x, stop_at_entry=%i, &error (%p))...", + static_cast<void*>(m_opaque_wp.lock().get()), + static_cast<void*>(argv), static_cast<void*>(envp), + stdin_path ? stdin_path : "NULL", + stdout_path ? stdout_path : "NULL", + stderr_path ? stderr_path : "NULL", + working_directory ? working_directory : "NULL", + launch_flags, stop_at_entry, + static_cast<void*>(error.get())); + + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + if (process_sp->GetState() == eStateConnected) + { + if (stop_at_entry) + launch_flags |= eLaunchFlagStopAtEntry; + ProcessLaunchInfo launch_info(FileSpec{stdin_path, false}, + FileSpec{stdout_path, false}, + FileSpec{stderr_path, false}, + FileSpec{working_directory, false}, + launch_flags); + Module *exe_module = process_sp->GetTarget().GetExecutableModulePointer(); + if (exe_module) + launch_info.SetExecutableFile(exe_module->GetPlatformFileSpec(), true); + if (argv) + launch_info.GetArguments().AppendArguments (argv); + if (envp) + launch_info.GetEnvironmentEntries ().SetArguments (envp); + error.SetError (process_sp->Launch (launch_info)); + } + else + { + error.SetErrorString ("must be in eStateConnected to call RemoteLaunch"); + } + } + else + { + error.SetErrorString ("unable to attach pid"); + } + + if (log) { + SBStream sstr; + error.GetDescription (sstr); + log->Printf ("SBProcess(%p)::RemoteLaunch (...) => SBError (%p): %s", + static_cast<void*>(process_sp.get()), + static_cast<void*>(error.get()), sstr.GetData()); + } + + return error.Success(); +} + +bool +SBProcess::RemoteAttachToProcessWithID (lldb::pid_t pid, lldb::SBError& error) +{ + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + if (process_sp->GetState() == eStateConnected) + { + ProcessAttachInfo attach_info; + attach_info.SetProcessID (pid); + error.SetError (process_sp->Attach (attach_info)); + } + else + { + error.SetErrorString ("must be in eStateConnected to call RemoteAttachToProcessWithID"); + } + } + else + { + error.SetErrorString ("unable to attach pid"); + } + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) { + SBStream sstr; + error.GetDescription (sstr); + log->Printf ("SBProcess(%p)::RemoteAttachToProcessWithID (%" PRIu64 ") => SBError (%p): %s", + static_cast<void*>(process_sp.get()), pid, + static_cast<void*>(error.get()), sstr.GetData()); + } + + return error.Success(); +} + + +uint32_t +SBProcess::GetNumThreads () +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + uint32_t num_threads = 0; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Process::StopLocker stop_locker; + + const bool can_update = stop_locker.TryLock(&process_sp->GetRunLock()); + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + num_threads = process_sp->GetThreadList().GetSize(can_update); + } + + if (log) + log->Printf ("SBProcess(%p)::GetNumThreads () => %d", + static_cast<void*>(process_sp.get()), num_threads); + + return num_threads; +} + +SBThread +SBProcess::GetSelectedThread () const +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + SBThread sb_thread; + ThreadSP thread_sp; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + thread_sp = process_sp->GetThreadList().GetSelectedThread(); + sb_thread.SetThread (thread_sp); + } + + if (log) + log->Printf ("SBProcess(%p)::GetSelectedThread () => SBThread(%p)", + static_cast<void*>(process_sp.get()), + static_cast<void*>(thread_sp.get())); + + return sb_thread; +} + +SBThread +SBProcess::CreateOSPluginThread (lldb::tid_t tid, lldb::addr_t context) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + SBThread sb_thread; + ThreadSP thread_sp; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + thread_sp = process_sp->CreateOSPluginThread(tid, context); + sb_thread.SetThread (thread_sp); + } + + if (log) + log->Printf ("SBProcess(%p)::CreateOSPluginThread (tid=0x%" PRIx64 ", context=0x%" PRIx64 ") => SBThread(%p)", + static_cast<void*>(process_sp.get()), tid, context, + static_cast<void*>(thread_sp.get())); + + return sb_thread; +} + +SBTarget +SBProcess::GetTarget() const +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + SBTarget sb_target; + TargetSP target_sp; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + target_sp = process_sp->GetTarget().shared_from_this(); + sb_target.SetSP (target_sp); + } + + if (log) + log->Printf ("SBProcess(%p)::GetTarget () => SBTarget(%p)", + static_cast<void*>(process_sp.get()), + static_cast<void*>(target_sp.get())); + + return sb_target; +} + + +size_t +SBProcess::PutSTDIN (const char *src, size_t src_len) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + size_t ret_val = 0; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Error error; + ret_val = process_sp->PutSTDIN (src, src_len, error); + } + + if (log) + log->Printf("SBProcess(%p)::PutSTDIN (src=\"%s\", src_len=%" PRIu64 ") => %" PRIu64, + static_cast<void*>(process_sp.get()), src, + static_cast<uint64_t>(src_len), + static_cast<uint64_t>(ret_val)); + + return ret_val; +} + +size_t +SBProcess::GetSTDOUT (char *dst, size_t dst_len) const +{ + size_t bytes_read = 0; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Error error; + bytes_read = process_sp->GetSTDOUT (dst, dst_len, error); + } + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBProcess(%p)::GetSTDOUT (dst=\"%.*s\", dst_len=%" PRIu64 ") => %" PRIu64, + static_cast<void*>(process_sp.get()), + static_cast<int>(bytes_read), dst, + static_cast<uint64_t>(dst_len), + static_cast<uint64_t>(bytes_read)); + + return bytes_read; +} + +size_t +SBProcess::GetSTDERR (char *dst, size_t dst_len) const +{ + size_t bytes_read = 0; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Error error; + bytes_read = process_sp->GetSTDERR (dst, dst_len, error); + } + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBProcess(%p)::GetSTDERR (dst=\"%.*s\", dst_len=%" PRIu64 ") => %" PRIu64, + static_cast<void*>(process_sp.get()), + static_cast<int>(bytes_read), dst, + static_cast<uint64_t>(dst_len), + static_cast<uint64_t>(bytes_read)); + + return bytes_read; +} + +size_t +SBProcess::GetAsyncProfileData(char *dst, size_t dst_len) const +{ + size_t bytes_read = 0; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Error error; + bytes_read = process_sp->GetAsyncProfileData (dst, dst_len, error); + } + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBProcess(%p)::GetAsyncProfileData (dst=\"%.*s\", dst_len=%" PRIu64 ") => %" PRIu64, + static_cast<void*>(process_sp.get()), + static_cast<int>(bytes_read), dst, + static_cast<uint64_t>(dst_len), + static_cast<uint64_t>(bytes_read)); + + return bytes_read; +} + +void +SBProcess::ReportEventState (const SBEvent &event, FILE *out) const +{ + if (out == NULL) + return; + + ProcessSP process_sp(GetSP()); + if (process_sp) + { + const StateType event_state = SBProcess::GetStateFromEvent (event); + char message[1024]; + int message_len = ::snprintf (message, + sizeof (message), + "Process %" PRIu64 " %s\n", + process_sp->GetID(), + SBDebugger::StateAsCString (event_state)); + + if (message_len > 0) + ::fwrite (message, 1, message_len, out); + } +} + +void +SBProcess::AppendEventStateReport (const SBEvent &event, SBCommandReturnObject &result) +{ + ProcessSP process_sp(GetSP()); + if (process_sp) + { + const StateType event_state = SBProcess::GetStateFromEvent (event); + char message[1024]; + ::snprintf (message, + sizeof (message), + "Process %" PRIu64 " %s\n", + process_sp->GetID(), + SBDebugger::StateAsCString (event_state)); + + result.AppendMessage (message); + } +} + +bool +SBProcess::SetSelectedThread (const SBThread &thread) +{ + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + return process_sp->GetThreadList().SetSelectedThreadByID (thread.GetThreadID()); + } + return false; +} + +bool +SBProcess::SetSelectedThreadByID (lldb::tid_t tid) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + bool ret_val = false; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + ret_val = process_sp->GetThreadList().SetSelectedThreadByID (tid); + } + + if (log) + log->Printf ("SBProcess(%p)::SetSelectedThreadByID (tid=0x%4.4" PRIx64 ") => %s", + static_cast<void*>(process_sp.get()), tid, + (ret_val ? "true" : "false")); + + return ret_val; +} + +bool +SBProcess::SetSelectedThreadByIndexID (uint32_t index_id) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + bool ret_val = false; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + ret_val = process_sp->GetThreadList().SetSelectedThreadByIndexID (index_id); + } + + if (log) + log->Printf ("SBProcess(%p)::SetSelectedThreadByID (tid=0x%x) => %s", + static_cast<void*>(process_sp.get()), index_id, + (ret_val ? "true" : "false")); + + return ret_val; +} + +SBThread +SBProcess::GetThreadAtIndex (size_t index) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + SBThread sb_thread; + ThreadSP thread_sp; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Process::StopLocker stop_locker; + const bool can_update = stop_locker.TryLock(&process_sp->GetRunLock()); + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + thread_sp = process_sp->GetThreadList().GetThreadAtIndex(index, can_update); + sb_thread.SetThread (thread_sp); + } + + if (log) + log->Printf ("SBProcess(%p)::GetThreadAtIndex (index=%d) => SBThread(%p)", + static_cast<void*>(process_sp.get()), + static_cast<uint32_t>(index), + static_cast<void*>(thread_sp.get())); + + return sb_thread; +} + +uint32_t +SBProcess::GetNumQueues () +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + uint32_t num_queues = 0; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Process::StopLocker stop_locker; + + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + num_queues = process_sp->GetQueueList().GetSize(); + } + + if (log) + log->Printf ("SBProcess(%p)::GetNumQueues () => %d", + static_cast<void*>(process_sp.get()), num_queues); + + return num_queues; +} + +SBQueue +SBProcess::GetQueueAtIndex (size_t index) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + SBQueue sb_queue; + QueueSP queue_sp; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Process::StopLocker stop_locker; + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + queue_sp = process_sp->GetQueueList().GetQueueAtIndex(index); + sb_queue.SetQueue (queue_sp); + } + + if (log) + log->Printf ("SBProcess(%p)::GetQueueAtIndex (index=%d) => SBQueue(%p)", + static_cast<void*>(process_sp.get()), + static_cast<uint32_t>(index), + static_cast<void*>(queue_sp.get())); + + return sb_queue; +} + + +uint32_t +SBProcess::GetStopID(bool include_expression_stops) +{ + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + if (include_expression_stops) + return process_sp->GetStopID(); + else + return process_sp->GetLastNaturalStopID(); + } + return 0; +} + +SBEvent +SBProcess::GetStopEventForStopID(uint32_t stop_id) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + SBEvent sb_event; + EventSP event_sp; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + event_sp = process_sp->GetStopEventForStopID(stop_id); + sb_event.reset(event_sp); + } + + if (log) + log->Printf ("SBProcess(%p)::GetStopEventForStopID (stop_id=%" PRIu32 ") => SBEvent(%p)", + static_cast<void*>(process_sp.get()), + stop_id, + static_cast<void*>(event_sp.get())); + + return sb_event; +} + +StateType +SBProcess::GetState () +{ + + StateType ret_val = eStateInvalid; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + ret_val = process_sp->GetState(); + } + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBProcess(%p)::GetState () => %s", + static_cast<void*>(process_sp.get()), + lldb_private::StateAsCString (ret_val)); + + return ret_val; +} + + +int +SBProcess::GetExitStatus () +{ + int exit_status = 0; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + exit_status = process_sp->GetExitStatus (); + } + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBProcess(%p)::GetExitStatus () => %i (0x%8.8x)", + static_cast<void*>(process_sp.get()), exit_status, + exit_status); + + return exit_status; +} + +const char * +SBProcess::GetExitDescription () +{ + const char *exit_desc = NULL; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + exit_desc = process_sp->GetExitDescription (); + } + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBProcess(%p)::GetExitDescription () => %s", + static_cast<void*>(process_sp.get()), exit_desc); + return exit_desc; +} + +lldb::pid_t +SBProcess::GetProcessID () +{ + lldb::pid_t ret_val = LLDB_INVALID_PROCESS_ID; + ProcessSP process_sp(GetSP()); + if (process_sp) + ret_val = process_sp->GetID(); + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBProcess(%p)::GetProcessID () => %" PRIu64, + static_cast<void*>(process_sp.get()), ret_val); + + return ret_val; +} + +uint32_t +SBProcess::GetUniqueID() +{ + uint32_t ret_val = 0; + ProcessSP process_sp(GetSP()); + if (process_sp) + ret_val = process_sp->GetUniqueID(); + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBProcess(%p)::GetUniqueID () => %" PRIu32, + static_cast<void*>(process_sp.get()), ret_val); + return ret_val; +} + +ByteOrder +SBProcess::GetByteOrder () const +{ + ByteOrder byteOrder = eByteOrderInvalid; + ProcessSP process_sp(GetSP()); + if (process_sp) + byteOrder = process_sp->GetTarget().GetArchitecture().GetByteOrder(); + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBProcess(%p)::GetByteOrder () => %d", + static_cast<void*>(process_sp.get()), byteOrder); + + return byteOrder; +} + +uint32_t +SBProcess::GetAddressByteSize () const +{ + uint32_t size = 0; + ProcessSP process_sp(GetSP()); + if (process_sp) + size = process_sp->GetTarget().GetArchitecture().GetAddressByteSize(); + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBProcess(%p)::GetAddressByteSize () => %d", + static_cast<void*>(process_sp.get()), size); + + return size; +} + +SBError +SBProcess::Continue () +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + SBError sb_error; + ProcessSP process_sp(GetSP()); + + if (log) + log->Printf ("SBProcess(%p)::Continue ()...", + static_cast<void*>(process_sp.get())); + + if (process_sp) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + + if (process_sp->GetTarget().GetDebugger().GetAsyncExecution ()) + sb_error.ref() = process_sp->Resume (); + else + sb_error.ref() = process_sp->ResumeSynchronous (NULL); + } + else + sb_error.SetErrorString ("SBProcess is invalid"); + + if (log) + { + SBStream sstr; + sb_error.GetDescription (sstr); + log->Printf ("SBProcess(%p)::Continue () => SBError (%p): %s", + static_cast<void*>(process_sp.get()), + static_cast<void*>(sb_error.get()), sstr.GetData()); + } + + return sb_error; +} + + +SBError +SBProcess::Destroy () +{ + SBError sb_error; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + sb_error.SetError(process_sp->Destroy(false)); + } + else + sb_error.SetErrorString ("SBProcess is invalid"); + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + { + SBStream sstr; + sb_error.GetDescription (sstr); + log->Printf ("SBProcess(%p)::Destroy () => SBError (%p): %s", + static_cast<void*>(process_sp.get()), + static_cast<void*>(sb_error.get()), sstr.GetData()); + } + + return sb_error; +} + + +SBError +SBProcess::Stop () +{ + SBError sb_error; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + sb_error.SetError (process_sp->Halt()); + } + else + sb_error.SetErrorString ("SBProcess is invalid"); + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + { + SBStream sstr; + sb_error.GetDescription (sstr); + log->Printf ("SBProcess(%p)::Stop () => SBError (%p): %s", + static_cast<void*>(process_sp.get()), + static_cast<void*>(sb_error.get()), sstr.GetData()); + } + + return sb_error; +} + +SBError +SBProcess::Kill () +{ + SBError sb_error; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + sb_error.SetError (process_sp->Destroy(true)); + } + else + sb_error.SetErrorString ("SBProcess is invalid"); + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + { + SBStream sstr; + sb_error.GetDescription (sstr); + log->Printf ("SBProcess(%p)::Kill () => SBError (%p): %s", + static_cast<void*>(process_sp.get()), + static_cast<void*>(sb_error.get()), sstr.GetData()); + } + + return sb_error; +} + +SBError +SBProcess::Detach () +{ + // FIXME: This should come from a process default. + bool keep_stopped = false; + return Detach (keep_stopped); +} + +SBError +SBProcess::Detach (bool keep_stopped) +{ + SBError sb_error; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + sb_error.SetError (process_sp->Detach(keep_stopped)); + } + else + sb_error.SetErrorString ("SBProcess is invalid"); + + return sb_error; +} + +SBError +SBProcess::Signal (int signo) +{ + SBError sb_error; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + sb_error.SetError (process_sp->Signal (signo)); + } + else + sb_error.SetErrorString ("SBProcess is invalid"); + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + { + SBStream sstr; + sb_error.GetDescription (sstr); + log->Printf ("SBProcess(%p)::Signal (signo=%i) => SBError (%p): %s", + static_cast<void*>(process_sp.get()), signo, + static_cast<void*>(sb_error.get()), sstr.GetData()); + } + return sb_error; +} + +SBUnixSignals +SBProcess::GetUnixSignals() +{ + if (auto process_sp = GetSP()) + return SBUnixSignals{process_sp}; + + return {}; +} + +void +SBProcess::SendAsyncInterrupt () +{ + ProcessSP process_sp(GetSP()); + if (process_sp) + { + process_sp->SendAsyncInterrupt (); + } +} + +SBThread +SBProcess::GetThreadByID (tid_t tid) +{ + SBThread sb_thread; + ThreadSP thread_sp; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Process::StopLocker stop_locker; + const bool can_update = stop_locker.TryLock(&process_sp->GetRunLock()); + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + thread_sp = process_sp->GetThreadList().FindThreadByID (tid, can_update); + sb_thread.SetThread (thread_sp); + } + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBProcess(%p)::GetThreadByID (tid=0x%4.4" PRIx64 ") => SBThread (%p)", + static_cast<void*>(process_sp.get()), tid, + static_cast<void*>(thread_sp.get())); + + return sb_thread; +} + +SBThread +SBProcess::GetThreadByIndexID (uint32_t index_id) +{ + SBThread sb_thread; + ThreadSP thread_sp; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Process::StopLocker stop_locker; + const bool can_update = stop_locker.TryLock(&process_sp->GetRunLock()); + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + thread_sp = process_sp->GetThreadList().FindThreadByIndexID (index_id, can_update); + sb_thread.SetThread (thread_sp); + } + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBProcess(%p)::GetThreadByID (tid=0x%x) => SBThread (%p)", + static_cast<void*>(process_sp.get()), index_id, + static_cast<void*>(thread_sp.get())); + + return sb_thread; +} + +StateType +SBProcess::GetStateFromEvent (const SBEvent &event) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + StateType ret_val = Process::ProcessEventData::GetStateFromEvent (event.get()); + + if (log) + log->Printf ("SBProcess::GetStateFromEvent (event.sp=%p) => %s", + static_cast<void*>(event.get()), + lldb_private::StateAsCString (ret_val)); + + return ret_val; +} + +bool +SBProcess::GetRestartedFromEvent (const SBEvent &event) +{ + return Process::ProcessEventData::GetRestartedFromEvent (event.get()); +} + +size_t +SBProcess::GetNumRestartedReasonsFromEvent (const lldb::SBEvent &event) +{ + return Process::ProcessEventData::GetNumRestartedReasons(event.get()); +} + +const char * +SBProcess::GetRestartedReasonAtIndexFromEvent (const lldb::SBEvent &event, size_t idx) +{ + return Process::ProcessEventData::GetRestartedReasonAtIndex(event.get(), idx); +} + +SBProcess +SBProcess::GetProcessFromEvent (const SBEvent &event) +{ + SBProcess process(Process::ProcessEventData::GetProcessFromEvent (event.get())); + return process; +} + +bool +SBProcess::GetInterruptedFromEvent (const SBEvent &event) +{ + return Process::ProcessEventData::GetInterruptedFromEvent(event.get()); +} + +bool +SBProcess::EventIsProcessEvent (const SBEvent &event) +{ + return event.GetBroadcasterClass() == SBProcess::GetBroadcasterClass(); +} + +SBBroadcaster +SBProcess::GetBroadcaster () const +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + ProcessSP process_sp(GetSP()); + + SBBroadcaster broadcaster(process_sp.get(), false); + + if (log) + log->Printf ("SBProcess(%p)::GetBroadcaster () => SBBroadcaster (%p)", + static_cast<void*>(process_sp.get()), + static_cast<void*>(broadcaster.get())); + + return broadcaster; +} + +const char * +SBProcess::GetBroadcasterClass () +{ + return Process::GetStaticBroadcasterClass().AsCString(); +} + +size_t +SBProcess::ReadMemory (addr_t addr, void *dst, size_t dst_len, SBError &sb_error) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + size_t bytes_read = 0; + + ProcessSP process_sp(GetSP()); + + if (log) + log->Printf ("SBProcess(%p)::ReadMemory (addr=0x%" PRIx64 ", dst=%p, dst_len=%" PRIu64 ", SBError (%p))...", + static_cast<void*>(process_sp.get()), addr, + static_cast<void*>(dst), static_cast<uint64_t>(dst_len), + static_cast<void*>(sb_error.get())); + + if (process_sp) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&process_sp->GetRunLock())) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + bytes_read = process_sp->ReadMemory (addr, dst, dst_len, sb_error.ref()); + } + else + { + if (log) + log->Printf ("SBProcess(%p)::ReadMemory() => error: process is running", + static_cast<void*>(process_sp.get())); + sb_error.SetErrorString("process is running"); + } + } + else + { + sb_error.SetErrorString ("SBProcess is invalid"); + } + + if (log) + { + SBStream sstr; + sb_error.GetDescription (sstr); + log->Printf ("SBProcess(%p)::ReadMemory (addr=0x%" PRIx64 ", dst=%p, dst_len=%" PRIu64 ", SBError (%p): %s) => %" PRIu64, + static_cast<void*>(process_sp.get()), addr, + static_cast<void*>(dst), static_cast<uint64_t>(dst_len), + static_cast<void*>(sb_error.get()), sstr.GetData(), + static_cast<uint64_t>(bytes_read)); + } + + return bytes_read; +} + +size_t +SBProcess::ReadCStringFromMemory (addr_t addr, void *buf, size_t size, lldb::SBError &sb_error) +{ + size_t bytes_read = 0; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&process_sp->GetRunLock())) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + bytes_read = process_sp->ReadCStringFromMemory (addr, (char *)buf, size, sb_error.ref()); + } + else + { + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBProcess(%p)::ReadCStringFromMemory() => error: process is running", + static_cast<void*>(process_sp.get())); + sb_error.SetErrorString("process is running"); + } + } + else + { + sb_error.SetErrorString ("SBProcess is invalid"); + } + return bytes_read; +} + +uint64_t +SBProcess::ReadUnsignedFromMemory (addr_t addr, uint32_t byte_size, lldb::SBError &sb_error) +{ + uint64_t value = 0; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&process_sp->GetRunLock())) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + value = process_sp->ReadUnsignedIntegerFromMemory (addr, byte_size, 0, sb_error.ref()); + } + else + { + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBProcess(%p)::ReadUnsignedFromMemory() => error: process is running", + static_cast<void*>(process_sp.get())); + sb_error.SetErrorString("process is running"); + } + } + else + { + sb_error.SetErrorString ("SBProcess is invalid"); + } + return value; +} + +lldb::addr_t +SBProcess::ReadPointerFromMemory (addr_t addr, lldb::SBError &sb_error) +{ + lldb::addr_t ptr = LLDB_INVALID_ADDRESS; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&process_sp->GetRunLock())) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + ptr = process_sp->ReadPointerFromMemory (addr, sb_error.ref()); + } + else + { + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBProcess(%p)::ReadPointerFromMemory() => error: process is running", + static_cast<void*>(process_sp.get())); + sb_error.SetErrorString("process is running"); + } + } + else + { + sb_error.SetErrorString ("SBProcess is invalid"); + } + return ptr; +} + +size_t +SBProcess::WriteMemory (addr_t addr, const void *src, size_t src_len, SBError &sb_error) +{ + size_t bytes_written = 0; + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + ProcessSP process_sp(GetSP()); + + if (log) + log->Printf ("SBProcess(%p)::WriteMemory (addr=0x%" PRIx64 ", src=%p, src_len=%" PRIu64 ", SBError (%p))...", + static_cast<void*>(process_sp.get()), addr, + static_cast<const void*>(src), + static_cast<uint64_t>(src_len), + static_cast<void*>(sb_error.get())); + + if (process_sp) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&process_sp->GetRunLock())) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + bytes_written = process_sp->WriteMemory (addr, src, src_len, sb_error.ref()); + } + else + { + if (log) + log->Printf ("SBProcess(%p)::WriteMemory() => error: process is running", + static_cast<void*>(process_sp.get())); + sb_error.SetErrorString("process is running"); + } + } + + if (log) + { + SBStream sstr; + sb_error.GetDescription (sstr); + log->Printf ("SBProcess(%p)::WriteMemory (addr=0x%" PRIx64 ", src=%p, src_len=%" PRIu64 ", SBError (%p): %s) => %" PRIu64, + static_cast<void*>(process_sp.get()), addr, + static_cast<const void*>(src), + static_cast<uint64_t>(src_len), + static_cast<void*>(sb_error.get()), sstr.GetData(), + static_cast<uint64_t>(bytes_written)); + } + + return bytes_written; +} + +bool +SBProcess::GetDescription (SBStream &description) +{ + Stream &strm = description.ref(); + + ProcessSP process_sp(GetSP()); + if (process_sp) + { + char path[PATH_MAX]; + GetTarget().GetExecutable().GetPath (path, sizeof(path)); + Module *exe_module = process_sp->GetTarget().GetExecutableModulePointer(); + const char *exe_name = NULL; + if (exe_module) + exe_name = exe_module->GetFileSpec().GetFilename().AsCString(); + + strm.Printf ("SBProcess: pid = %" PRIu64 ", state = %s, threads = %d%s%s", + process_sp->GetID(), + lldb_private::StateAsCString (GetState()), + GetNumThreads(), + exe_name ? ", executable = " : "", + exe_name ? exe_name : ""); + } + else + strm.PutCString ("No value"); + + return true; +} + +uint32_t +SBProcess::GetNumSupportedHardwareWatchpoints (lldb::SBError &sb_error) const +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + uint32_t num = 0; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + sb_error.SetError(process_sp->GetWatchpointSupportInfo (num)); + if (log) + log->Printf ("SBProcess(%p)::GetNumSupportedHardwareWatchpoints () => %u", + static_cast<void*>(process_sp.get()), num); + } + else + { + sb_error.SetErrorString ("SBProcess is invalid"); + } + return num; +} + +uint32_t +SBProcess::LoadImage (lldb::SBFileSpec &sb_remote_image_spec, lldb::SBError &sb_error) +{ + return LoadImage(SBFileSpec(), sb_remote_image_spec, sb_error); +} + +uint32_t +SBProcess::LoadImage (const lldb::SBFileSpec &sb_local_image_spec, + const lldb::SBFileSpec &sb_remote_image_spec, + lldb::SBError &sb_error) +{ + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&process_sp->GetRunLock())) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + PlatformSP platform_sp = process_sp->GetTarget().GetPlatform(); + return platform_sp->LoadImage (process_sp.get(), + *sb_local_image_spec, + *sb_remote_image_spec, + sb_error.ref()); + } + else + { + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBProcess(%p)::LoadImage() => error: process is running", + static_cast<void*>(process_sp.get())); + sb_error.SetErrorString("process is running"); + } + } + return LLDB_INVALID_IMAGE_TOKEN; +} + +lldb::SBError +SBProcess::UnloadImage (uint32_t image_token) +{ + lldb::SBError sb_error; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&process_sp->GetRunLock())) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + PlatformSP platform_sp = process_sp->GetTarget().GetPlatform(); + sb_error.SetError (platform_sp->UnloadImage (process_sp.get(), image_token)); + } + else + { + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBProcess(%p)::UnloadImage() => error: process is running", + static_cast<void*>(process_sp.get())); + sb_error.SetErrorString("process is running"); + } + } + else + sb_error.SetErrorString("invalid process"); + return sb_error; +} + +lldb::SBError +SBProcess::SendEventData (const char *event_data) +{ + lldb::SBError sb_error; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&process_sp->GetRunLock())) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + sb_error.SetError (process_sp->SendEventData (event_data)); + } + else + { + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBProcess(%p)::SendEventData() => error: process is running", + static_cast<void*>(process_sp.get())); + sb_error.SetErrorString("process is running"); + } + } + else + sb_error.SetErrorString("invalid process"); + return sb_error; +} + +uint32_t +SBProcess::GetNumExtendedBacktraceTypes () +{ + ProcessSP process_sp(GetSP()); + if (process_sp && process_sp->GetSystemRuntime()) + { + SystemRuntime *runtime = process_sp->GetSystemRuntime(); + return runtime->GetExtendedBacktraceTypes().size(); + } + return 0; +} + +const char * +SBProcess::GetExtendedBacktraceTypeAtIndex (uint32_t idx) +{ + ProcessSP process_sp(GetSP()); + if (process_sp && process_sp->GetSystemRuntime()) + { + SystemRuntime *runtime = process_sp->GetSystemRuntime(); + const std::vector<ConstString> &names = runtime->GetExtendedBacktraceTypes(); + if (idx < names.size()) + { + return names[idx].AsCString(); + } + else + { + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf("SBProcess(%p)::GetExtendedBacktraceTypeAtIndex() => error: requested extended backtrace name out of bounds", + static_cast<void*>(process_sp.get())); + } + } + return NULL; +} + +SBThreadCollection +SBProcess::GetHistoryThreads (addr_t addr) +{ + ProcessSP process_sp(GetSP()); + SBThreadCollection threads; + if (process_sp) + { + threads = SBThreadCollection(process_sp->GetHistoryThreads(addr)); + } + return threads; +} + +bool +SBProcess::IsInstrumentationRuntimePresent(InstrumentationRuntimeType type) +{ + ProcessSP process_sp(GetSP()); + if (! process_sp) + return false; + + InstrumentationRuntimeSP runtime_sp = process_sp->GetInstrumentationRuntime(type); + + if (! runtime_sp.get()) + return false; + + return runtime_sp->IsActive(); +} + +lldb::SBError +SBProcess::SaveCore(const char *file_name) +{ + lldb::SBError error; + ProcessSP process_sp(GetSP()); + if (!process_sp) + { + error.SetErrorString("SBProcess is invalid"); + return error; + } + + Mutex::Locker api_locker(process_sp->GetTarget().GetAPIMutex()); + + if (process_sp->GetState() != eStateStopped) + { + error.SetErrorString("the process is not stopped"); + return error; + } + + FileSpec core_file(file_name, false); + error.ref() = PluginManager::SaveCore(process_sp, core_file); + return error; +} |