| //===-- 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/Core/Debugger.h" |
| #include "lldb/Core/Module.h" |
| #include "lldb/Core/PluginManager.h" |
| #include "lldb/Core/State.h" |
| #include "lldb/Core/StreamFile.h" |
| #include "lldb/Target/MemoryRegionInfo.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" |
| #include "lldb/Utility/Args.h" |
| #include "lldb/Utility/Log.h" |
| #include "lldb/Utility/Stream.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/SBMemoryRegionInfo.h" |
| #include "lldb/API/SBMemoryRegionInfoList.h" |
| #include "lldb/API/SBStream.h" |
| #include "lldb/API/SBStringList.h" |
| #include "lldb/API/SBStructuredData.h" |
| #include "lldb/API/SBThread.h" |
| #include "lldb/API/SBThreadCollection.h" |
| #include "lldb/API/SBTrace.h" |
| #include "lldb/API/SBTraceOptions.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) { |
| std::lock_guard<std::recursive_mutex> guard( |
| 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.GetEnvironment() = Environment(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) { |
| std::lock_guard<std::recursive_mutex> guard( |
| 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()); |
| std::lock_guard<std::recursive_mutex> guard( |
| 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) { |
| std::lock_guard<std::recursive_mutex> guard( |
| 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) { |
| std::lock_guard<std::recursive_mutex> guard( |
| 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) { |
| Status 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) { |
| Status 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) { |
| Status 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) { |
| Status 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; |
| } |
| |
| lldb::SBTrace SBProcess::StartTrace(SBTraceOptions &options, |
| lldb::SBError &error) { |
| Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); |
| ProcessSP process_sp(GetSP()); |
| error.Clear(); |
| SBTrace trace_instance; |
| trace_instance.SetSP(process_sp); |
| lldb::user_id_t uid = LLDB_INVALID_UID; |
| |
| if (!process_sp) { |
| error.SetErrorString("invalid process"); |
| } else { |
| uid = process_sp->StartTrace(*(options.m_traceoptions_sp), error.ref()); |
| trace_instance.SetTraceUID(uid); |
| LLDB_LOG(log, "SBProcess::returned uid - {0}", uid); |
| } |
| return trace_instance; |
| } |
| |
| 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) { |
| std::lock_guard<std::recursive_mutex> guard( |
| 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) { |
| std::lock_guard<std::recursive_mutex> guard( |
| 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) { |
| std::lock_guard<std::recursive_mutex> guard( |
| 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()); |
| std::lock_guard<std::recursive_mutex> guard( |
| 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; |
| if (stop_locker.TryLock(&process_sp->GetRunLock())) { |
| std::lock_guard<std::recursive_mutex> guard( |
| 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; |
| if (stop_locker.TryLock(&process_sp->GetRunLock())) { |
| std::lock_guard<std::recursive_mutex> guard( |
| 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) { |
| std::lock_guard<std::recursive_mutex> guard( |
| 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) { |
| std::lock_guard<std::recursive_mutex> guard( |
| 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) { |
| std::lock_guard<std::recursive_mutex> guard( |
| 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) { |
| std::lock_guard<std::recursive_mutex> guard( |
| 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) { |
| std::lock_guard<std::recursive_mutex> guard( |
| 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) { |
| std::lock_guard<std::recursive_mutex> guard( |
| 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) { |
| std::lock_guard<std::recursive_mutex> guard( |
| 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) { |
| std::lock_guard<std::recursive_mutex> guard( |
| 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) { |
| std::lock_guard<std::recursive_mutex> guard( |
| 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) { |
| std::lock_guard<std::recursive_mutex> guard( |
| 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) { |
| std::lock_guard<std::recursive_mutex> guard( |
| 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()); |
| std::lock_guard<std::recursive_mutex> guard( |
| 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()); |
| std::lock_guard<std::recursive_mutex> guard( |
| 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) { |
| Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); |
| |
| bool ret_val = Process::ProcessEventData::GetRestartedFromEvent(event.get()); |
| |
| if (log) |
| log->Printf("SBProcess::%s (event.sp=%p) => %d", __FUNCTION__, |
| static_cast<void *>(event.get()), ret_val); |
| |
| return ret_val; |
| } |
| |
| 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) { |
| ProcessSP process_sp = |
| Process::ProcessEventData::GetProcessFromEvent(event.get()); |
| if (!process_sp) { |
| // StructuredData events also know the process they come from. Try that. |
| process_sp = EventDataStructuredData::GetProcessFromEvent(event.get()); |
| } |
| |
| return SBProcess(process_sp); |
| } |
| |
| bool SBProcess::GetInterruptedFromEvent(const SBEvent &event) { |
| return Process::ProcessEventData::GetInterruptedFromEvent(event.get()); |
| } |
| |
| lldb::SBStructuredData |
| SBProcess::GetStructuredDataFromEvent(const lldb::SBEvent &event) { |
| return SBStructuredData(event.GetSP()); |
| } |
| |
| bool SBProcess::EventIsProcessEvent(const SBEvent &event) { |
| return (event.GetBroadcasterClass() == SBProcess::GetBroadcasterClass()) && |
| !EventIsStructuredDataEvent(event); |
| } |
| |
| bool SBProcess::EventIsStructuredDataEvent(const lldb::SBEvent &event) { |
| EventSP event_sp = event.GetSP(); |
| EventData *event_data = event_sp ? event_sp->GetData() : nullptr; |
| return event_data && (event_data->GetFlavor() == |
| EventDataStructuredData::GetFlavorString()); |
| } |
| |
| 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())) { |
| std::lock_guard<std::recursive_mutex> guard( |
| 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())) { |
| std::lock_guard<std::recursive_mutex> guard( |
| 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())) { |
| std::lock_guard<std::recursive_mutex> guard( |
| 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())) { |
| std::lock_guard<std::recursive_mutex> guard( |
| 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())) { |
| std::lock_guard<std::recursive_mutex> guard( |
| 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) { |
| std::lock_guard<std::recursive_mutex> guard( |
| 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) { |
| Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); |
| ProcessSP process_sp(GetSP()); |
| if (process_sp) { |
| Process::StopLocker stop_locker; |
| if (stop_locker.TryLock(&process_sp->GetRunLock())) { |
| if (log) |
| log->Printf("SBProcess(%p)::LoadImage() => calling Platform::LoadImage" |
| "for: %s", |
| static_cast<void *>(process_sp.get()), |
| sb_local_image_spec.GetFilename()); |
| |
| std::lock_guard<std::recursive_mutex> guard( |
| 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 { |
| if (log) |
| log->Printf("SBProcess(%p)::LoadImage() => error: process is running", |
| static_cast<void *>(process_sp.get())); |
| sb_error.SetErrorString("process is running"); |
| } |
| } else { |
| if (log) |
| log->Printf("SBProcess(%p)::LoadImage() => error: called with invalid" |
| " process", |
| static_cast<void *>(process_sp.get())); |
| sb_error.SetErrorString("process is invalid"); |
| } |
| return LLDB_INVALID_IMAGE_TOKEN; |
| } |
| |
| uint32_t SBProcess::LoadImageUsingPaths(const lldb::SBFileSpec &image_spec, |
| SBStringList &paths, |
| lldb::SBFileSpec &loaded_path, |
| lldb::SBError &error) { |
| Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); |
| ProcessSP process_sp(GetSP()); |
| if (process_sp) { |
| Process::StopLocker stop_locker; |
| if (stop_locker.TryLock(&process_sp->GetRunLock())) { |
| if (log) |
| log->Printf("SBProcess(%p)::LoadImageUsingPaths() => " |
| "calling Platform::LoadImageUsingPaths for: %s", |
| static_cast<void *>(process_sp.get()), |
| image_spec.GetFilename()); |
| |
| std::lock_guard<std::recursive_mutex> guard( |
| process_sp->GetTarget().GetAPIMutex()); |
| PlatformSP platform_sp = process_sp->GetTarget().GetPlatform(); |
| size_t num_paths = paths.GetSize(); |
| std::vector<std::string> paths_vec; |
| paths_vec.reserve(num_paths); |
| for (size_t i = 0; i < num_paths; i++) |
| paths_vec.push_back(paths.GetStringAtIndex(i)); |
| FileSpec loaded_spec; |
| |
| uint32_t token = platform_sp->LoadImageUsingPaths(process_sp.get(), |
| *image_spec, |
| paths_vec, |
| error.ref(), |
| &loaded_spec); |
| if (token != LLDB_INVALID_IMAGE_TOKEN) |
| loaded_path = loaded_spec; |
| return token; |
| } else { |
| if (log) |
| log->Printf("SBProcess(%p)::LoadImageUsingPaths() => error: " |
| "process is running", |
| static_cast<void *>(process_sp.get())); |
| error.SetErrorString("process is running"); |
| } |
| } else { |
| if (log) |
| log->Printf("SBProcess(%p)::LoadImageUsingPaths() => error: " |
| "called with invalid process", |
| static_cast<void *>(process_sp.get())); |
| error.SetErrorString("process is invalid"); |
| } |
| |
| 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())) { |
| std::lock_guard<std::recursive_mutex> guard( |
| 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())) { |
| std::lock_guard<std::recursive_mutex> guard( |
| 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; |
| } |
| |
| std::lock_guard<std::recursive_mutex> guard( |
| 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; |
| } |
| |
| lldb::SBError |
| SBProcess::GetMemoryRegionInfo(lldb::addr_t load_addr, |
| SBMemoryRegionInfo &sb_region_info) { |
| lldb::SBError sb_error; |
| ProcessSP process_sp(GetSP()); |
| MemoryRegionInfoSP region_info_sp = |
| std::make_shared<lldb_private::MemoryRegionInfo>(); |
| if (process_sp) { |
| Process::StopLocker stop_locker; |
| if (stop_locker.TryLock(&process_sp->GetRunLock())) { |
| std::lock_guard<std::recursive_mutex> guard( |
| process_sp->GetTarget().GetAPIMutex()); |
| sb_error.ref() = |
| process_sp->GetMemoryRegionInfo(load_addr, *region_info_sp); |
| if (sb_error.Success()) { |
| sb_region_info.ref() = *region_info_sp; |
| } |
| } else { |
| Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); |
| if (log) |
| log->Printf( |
| "SBProcess(%p)::GetMemoryRegionInfo() => error: process is running", |
| static_cast<void *>(process_sp.get())); |
| sb_error.SetErrorString("process is running"); |
| } |
| } else { |
| sb_error.SetErrorString("SBProcess is invalid"); |
| } |
| return sb_error; |
| } |
| |
| lldb::SBMemoryRegionInfoList SBProcess::GetMemoryRegions() { |
| lldb::SBError sb_error; |
| lldb::SBMemoryRegionInfoList sb_region_list; |
| ProcessSP process_sp(GetSP()); |
| if (process_sp) { |
| Process::StopLocker stop_locker; |
| if (stop_locker.TryLock(&process_sp->GetRunLock())) { |
| std::lock_guard<std::recursive_mutex> guard( |
| process_sp->GetTarget().GetAPIMutex()); |
| std::vector<MemoryRegionInfoSP> region_list; |
| sb_error.ref() = process_sp->GetMemoryRegions(region_list); |
| if (sb_error.Success()) { |
| std::vector<MemoryRegionInfoSP>::iterator end = region_list.end(); |
| for (std::vector<MemoryRegionInfoSP>::iterator it = region_list.begin(); |
| it != end; it++) { |
| SBMemoryRegionInfo sb_region_info(it->get()); |
| sb_region_list.Append(sb_region_info); |
| } |
| } |
| } else { |
| Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); |
| if (log) |
| log->Printf( |
| "SBProcess(%p)::GetMemoryRegionInfo() => error: process is running", |
| static_cast<void *>(process_sp.get())); |
| sb_error.SetErrorString("process is running"); |
| } |
| } else { |
| sb_error.SetErrorString("SBProcess is invalid"); |
| } |
| return sb_region_list; |
| } |
| |
| lldb::SBProcessInfo SBProcess::GetProcessInfo() { |
| lldb::SBProcessInfo sb_proc_info; |
| ProcessSP process_sp(GetSP()); |
| ProcessInstanceInfo proc_info; |
| if (process_sp && process_sp->GetProcessInfo(proc_info)) { |
| sb_proc_info.SetProcessInfo(proc_info); |
| } |
| return sb_proc_info; |
| } |