mirror of
https://github.com/llvm/llvm-project.git
synced 2025-05-03 18:36:05 +00:00

A lot of comments in LLDB are surrounded by an ASCII line to delimit the begging and end of the comment. Its use is not really consistent across the code base, sometimes the lines are longer, sometimes they are shorter and sometimes they are omitted. Furthermore, it looks kind of weird with the 80 column limit, where the comment actually extends past the line, but not by much. Furthermore, when /// is used for Doxygen comments, it looks particularly odd. And when // is used, it incorrectly gives the impression that it's actually a Doxygen comment. I assume these lines were added to improve distinguishing between comments and code. However, given that todays editors and IDEs do a great job at highlighting comments, I think it's worth to drop this for the sake of consistency. The alternative is fixing all the inconsistencies, which would create a lot more churn. Differential revision: https://reviews.llvm.org/D60508 llvm-svn: 358135
1405 lines
47 KiB
C++
1405 lines
47 KiB
C++
//===-- SBProcess.cpp -------------------------------------------*- C++ -*-===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "lldb/API/SBProcess.h"
|
|
#include "SBReproducerPrivate.h"
|
|
|
|
#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/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/ProcessInfo.h"
|
|
#include "lldb/Utility/State.h"
|
|
#include "lldb/Utility/Stream.h"
|
|
|
|
|
|
#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() {
|
|
LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBProcess);
|
|
}
|
|
|
|
// SBProcess constructor
|
|
|
|
SBProcess::SBProcess(const SBProcess &rhs) : m_opaque_wp(rhs.m_opaque_wp) {
|
|
LLDB_RECORD_CONSTRUCTOR(SBProcess, (const lldb::SBProcess &), rhs);
|
|
}
|
|
|
|
SBProcess::SBProcess(const lldb::ProcessSP &process_sp)
|
|
: m_opaque_wp(process_sp) {
|
|
LLDB_RECORD_CONSTRUCTOR(SBProcess, (const lldb::ProcessSP &), process_sp);
|
|
}
|
|
|
|
const SBProcess &SBProcess::operator=(const SBProcess &rhs) {
|
|
LLDB_RECORD_METHOD(const lldb::SBProcess &,
|
|
SBProcess, operator=,(const lldb::SBProcess &), rhs);
|
|
|
|
if (this != &rhs)
|
|
m_opaque_wp = rhs.m_opaque_wp;
|
|
return LLDB_RECORD_RESULT(*this);
|
|
}
|
|
|
|
// Destructor
|
|
SBProcess::~SBProcess() {}
|
|
|
|
const char *SBProcess::GetBroadcasterClassName() {
|
|
LLDB_RECORD_STATIC_METHOD_NO_ARGS(const char *, SBProcess,
|
|
GetBroadcasterClassName);
|
|
|
|
return Process::GetStaticBroadcasterClass().AsCString();
|
|
}
|
|
|
|
const char *SBProcess::GetPluginName() {
|
|
LLDB_RECORD_METHOD_NO_ARGS(const char *, SBProcess, GetPluginName);
|
|
|
|
ProcessSP process_sp(GetSP());
|
|
if (process_sp) {
|
|
return process_sp->GetPluginName().GetCString();
|
|
}
|
|
return "<Unknown>";
|
|
}
|
|
|
|
const char *SBProcess::GetShortPluginName() {
|
|
LLDB_RECORD_METHOD_NO_ARGS(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() {
|
|
LLDB_RECORD_METHOD_NO_ARGS(void, SBProcess, Clear);
|
|
|
|
m_opaque_wp.reset();
|
|
}
|
|
|
|
bool SBProcess::IsValid() const {
|
|
LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBProcess, IsValid);
|
|
return this->operator bool();
|
|
}
|
|
SBProcess::operator bool() const {
|
|
LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBProcess, operator bool);
|
|
|
|
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) {
|
|
LLDB_RECORD_METHOD(bool, SBProcess, RemoteLaunch,
|
|
(const char **, const char **, const char *, const char *,
|
|
const char *, const char *, uint32_t, bool,
|
|
lldb::SBError &),
|
|
argv, envp, stdin_path, stdout_path, stderr_path,
|
|
working_directory, launch_flags, stop_at_entry, error);
|
|
|
|
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), FileSpec(stdout_path),
|
|
FileSpec(stderr_path),
|
|
FileSpec(working_directory), 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");
|
|
}
|
|
|
|
return error.Success();
|
|
}
|
|
|
|
bool SBProcess::RemoteAttachToProcessWithID(lldb::pid_t pid,
|
|
lldb::SBError &error) {
|
|
LLDB_RECORD_METHOD(bool, SBProcess, RemoteAttachToProcessWithID,
|
|
(lldb::pid_t, lldb::SBError &), pid, 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");
|
|
}
|
|
|
|
return error.Success();
|
|
}
|
|
|
|
uint32_t SBProcess::GetNumThreads() {
|
|
LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBProcess, GetNumThreads);
|
|
|
|
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);
|
|
}
|
|
|
|
return num_threads;
|
|
}
|
|
|
|
SBThread SBProcess::GetSelectedThread() const {
|
|
LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::SBThread, SBProcess,
|
|
GetSelectedThread);
|
|
|
|
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);
|
|
}
|
|
|
|
return LLDB_RECORD_RESULT(sb_thread);
|
|
}
|
|
|
|
SBThread SBProcess::CreateOSPluginThread(lldb::tid_t tid,
|
|
lldb::addr_t context) {
|
|
LLDB_RECORD_METHOD(lldb::SBThread, SBProcess, CreateOSPluginThread,
|
|
(lldb::tid_t, lldb::addr_t), tid, context);
|
|
|
|
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);
|
|
}
|
|
|
|
return LLDB_RECORD_RESULT(sb_thread);
|
|
}
|
|
|
|
SBTarget SBProcess::GetTarget() const {
|
|
LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::SBTarget, SBProcess, GetTarget);
|
|
|
|
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);
|
|
}
|
|
|
|
return LLDB_RECORD_RESULT(sb_target);
|
|
}
|
|
|
|
size_t SBProcess::PutSTDIN(const char *src, size_t src_len) {
|
|
LLDB_RECORD_METHOD(size_t, SBProcess, PutSTDIN, (const char *, size_t), src,
|
|
src_len);
|
|
|
|
size_t ret_val = 0;
|
|
ProcessSP process_sp(GetSP());
|
|
if (process_sp) {
|
|
Status error;
|
|
ret_val = process_sp->PutSTDIN(src, src_len, error);
|
|
}
|
|
|
|
return ret_val;
|
|
}
|
|
|
|
size_t SBProcess::GetSTDOUT(char *dst, size_t dst_len) const {
|
|
LLDB_RECORD_METHOD_CONST(size_t, SBProcess, GetSTDOUT, (char *, size_t), dst,
|
|
dst_len);
|
|
|
|
size_t bytes_read = 0;
|
|
ProcessSP process_sp(GetSP());
|
|
if (process_sp) {
|
|
Status error;
|
|
bytes_read = process_sp->GetSTDOUT(dst, dst_len, error);
|
|
}
|
|
|
|
return bytes_read;
|
|
}
|
|
|
|
size_t SBProcess::GetSTDERR(char *dst, size_t dst_len) const {
|
|
LLDB_RECORD_METHOD_CONST(size_t, SBProcess, GetSTDERR, (char *, size_t), dst,
|
|
dst_len);
|
|
|
|
size_t bytes_read = 0;
|
|
ProcessSP process_sp(GetSP());
|
|
if (process_sp) {
|
|
Status error;
|
|
bytes_read = process_sp->GetSTDERR(dst, dst_len, error);
|
|
}
|
|
|
|
return bytes_read;
|
|
}
|
|
|
|
size_t SBProcess::GetAsyncProfileData(char *dst, size_t dst_len) const {
|
|
LLDB_RECORD_METHOD_CONST(size_t, SBProcess, GetAsyncProfileData,
|
|
(char *, size_t), dst, dst_len);
|
|
|
|
size_t bytes_read = 0;
|
|
ProcessSP process_sp(GetSP());
|
|
if (process_sp) {
|
|
Status error;
|
|
bytes_read = process_sp->GetAsyncProfileData(dst, dst_len, error);
|
|
}
|
|
|
|
return bytes_read;
|
|
}
|
|
|
|
lldb::SBTrace SBProcess::StartTrace(SBTraceOptions &options,
|
|
lldb::SBError &error) {
|
|
LLDB_RECORD_METHOD(lldb::SBTrace, SBProcess, StartTrace,
|
|
(lldb::SBTraceOptions &, lldb::SBError &), options, error);
|
|
|
|
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);
|
|
}
|
|
return LLDB_RECORD_RESULT(trace_instance);
|
|
}
|
|
|
|
void SBProcess::ReportEventState(const SBEvent &event, FILE *out) const {
|
|
LLDB_RECORD_METHOD_CONST(void, SBProcess, ReportEventState,
|
|
(const lldb::SBEvent &, FILE *), event, out);
|
|
|
|
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) {
|
|
LLDB_RECORD_METHOD(void, SBProcess, AppendEventStateReport,
|
|
(const lldb::SBEvent &, lldb::SBCommandReturnObject &),
|
|
event, 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) {
|
|
LLDB_RECORD_METHOD(bool, SBProcess, SetSelectedThread,
|
|
(const lldb::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) {
|
|
LLDB_RECORD_METHOD(bool, SBProcess, SetSelectedThreadByID, (lldb::tid_t),
|
|
tid);
|
|
|
|
|
|
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);
|
|
}
|
|
|
|
return ret_val;
|
|
}
|
|
|
|
bool SBProcess::SetSelectedThreadByIndexID(uint32_t index_id) {
|
|
LLDB_RECORD_METHOD(bool, SBProcess, SetSelectedThreadByIndexID, (uint32_t),
|
|
index_id);
|
|
|
|
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);
|
|
}
|
|
|
|
|
|
return ret_val;
|
|
}
|
|
|
|
SBThread SBProcess::GetThreadAtIndex(size_t index) {
|
|
LLDB_RECORD_METHOD(lldb::SBThread, SBProcess, GetThreadAtIndex, (size_t),
|
|
index);
|
|
|
|
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);
|
|
}
|
|
|
|
return LLDB_RECORD_RESULT(sb_thread);
|
|
}
|
|
|
|
uint32_t SBProcess::GetNumQueues() {
|
|
LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBProcess, GetNumQueues);
|
|
|
|
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();
|
|
}
|
|
}
|
|
|
|
return num_queues;
|
|
}
|
|
|
|
SBQueue SBProcess::GetQueueAtIndex(size_t index) {
|
|
LLDB_RECORD_METHOD(lldb::SBQueue, SBProcess, GetQueueAtIndex, (size_t),
|
|
index);
|
|
|
|
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);
|
|
}
|
|
}
|
|
|
|
return LLDB_RECORD_RESULT(sb_queue);
|
|
}
|
|
|
|
uint32_t SBProcess::GetStopID(bool include_expression_stops) {
|
|
LLDB_RECORD_METHOD(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) {
|
|
LLDB_RECORD_METHOD(lldb::SBEvent, SBProcess, GetStopEventForStopID,
|
|
(uint32_t), stop_id);
|
|
|
|
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);
|
|
}
|
|
|
|
return LLDB_RECORD_RESULT(sb_event);
|
|
}
|
|
|
|
StateType SBProcess::GetState() {
|
|
LLDB_RECORD_METHOD_NO_ARGS(lldb::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();
|
|
}
|
|
|
|
return ret_val;
|
|
}
|
|
|
|
int SBProcess::GetExitStatus() {
|
|
LLDB_RECORD_METHOD_NO_ARGS(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();
|
|
}
|
|
|
|
return exit_status;
|
|
}
|
|
|
|
const char *SBProcess::GetExitDescription() {
|
|
LLDB_RECORD_METHOD_NO_ARGS(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();
|
|
}
|
|
return exit_desc;
|
|
}
|
|
|
|
lldb::pid_t SBProcess::GetProcessID() {
|
|
LLDB_RECORD_METHOD_NO_ARGS(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();
|
|
|
|
return ret_val;
|
|
}
|
|
|
|
uint32_t SBProcess::GetUniqueID() {
|
|
LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBProcess, GetUniqueID);
|
|
|
|
uint32_t ret_val = 0;
|
|
ProcessSP process_sp(GetSP());
|
|
if (process_sp)
|
|
ret_val = process_sp->GetUniqueID();
|
|
return ret_val;
|
|
}
|
|
|
|
ByteOrder SBProcess::GetByteOrder() const {
|
|
LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::ByteOrder, SBProcess, GetByteOrder);
|
|
|
|
ByteOrder byteOrder = eByteOrderInvalid;
|
|
ProcessSP process_sp(GetSP());
|
|
if (process_sp)
|
|
byteOrder = process_sp->GetTarget().GetArchitecture().GetByteOrder();
|
|
|
|
|
|
return byteOrder;
|
|
}
|
|
|
|
uint32_t SBProcess::GetAddressByteSize() const {
|
|
LLDB_RECORD_METHOD_CONST_NO_ARGS(uint32_t, SBProcess, GetAddressByteSize);
|
|
|
|
uint32_t size = 0;
|
|
ProcessSP process_sp(GetSP());
|
|
if (process_sp)
|
|
size = process_sp->GetTarget().GetArchitecture().GetAddressByteSize();
|
|
|
|
|
|
return size;
|
|
}
|
|
|
|
SBError SBProcess::Continue() {
|
|
LLDB_RECORD_METHOD_NO_ARGS(lldb::SBError, SBProcess, Continue);
|
|
|
|
SBError sb_error;
|
|
ProcessSP process_sp(GetSP());
|
|
|
|
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");
|
|
|
|
return LLDB_RECORD_RESULT(sb_error);
|
|
}
|
|
|
|
SBError SBProcess::Destroy() {
|
|
LLDB_RECORD_METHOD_NO_ARGS(lldb::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");
|
|
|
|
return LLDB_RECORD_RESULT(sb_error);
|
|
}
|
|
|
|
SBError SBProcess::Stop() {
|
|
LLDB_RECORD_METHOD_NO_ARGS(lldb::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");
|
|
|
|
return LLDB_RECORD_RESULT(sb_error);
|
|
}
|
|
|
|
SBError SBProcess::Kill() {
|
|
LLDB_RECORD_METHOD_NO_ARGS(lldb::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");
|
|
|
|
return LLDB_RECORD_RESULT(sb_error);
|
|
}
|
|
|
|
SBError SBProcess::Detach() {
|
|
LLDB_RECORD_METHOD_NO_ARGS(lldb::SBError, SBProcess, Detach);
|
|
|
|
// FIXME: This should come from a process default.
|
|
bool keep_stopped = false;
|
|
return LLDB_RECORD_RESULT(Detach(keep_stopped));
|
|
}
|
|
|
|
SBError SBProcess::Detach(bool keep_stopped) {
|
|
LLDB_RECORD_METHOD(lldb::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 LLDB_RECORD_RESULT(sb_error);
|
|
}
|
|
|
|
SBError SBProcess::Signal(int signo) {
|
|
LLDB_RECORD_METHOD(lldb::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");
|
|
|
|
return LLDB_RECORD_RESULT(sb_error);
|
|
}
|
|
|
|
SBUnixSignals SBProcess::GetUnixSignals() {
|
|
LLDB_RECORD_METHOD_NO_ARGS(lldb::SBUnixSignals, SBProcess, GetUnixSignals);
|
|
|
|
if (auto process_sp = GetSP())
|
|
return LLDB_RECORD_RESULT(SBUnixSignals{process_sp});
|
|
|
|
return LLDB_RECORD_RESULT(SBUnixSignals{});
|
|
}
|
|
|
|
void SBProcess::SendAsyncInterrupt() {
|
|
LLDB_RECORD_METHOD_NO_ARGS(void, SBProcess, SendAsyncInterrupt);
|
|
|
|
ProcessSP process_sp(GetSP());
|
|
if (process_sp) {
|
|
process_sp->SendAsyncInterrupt();
|
|
}
|
|
}
|
|
|
|
SBThread SBProcess::GetThreadByID(tid_t tid) {
|
|
LLDB_RECORD_METHOD(lldb::SBThread, SBProcess, GetThreadByID, (lldb::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);
|
|
}
|
|
|
|
return LLDB_RECORD_RESULT(sb_thread);
|
|
}
|
|
|
|
SBThread SBProcess::GetThreadByIndexID(uint32_t index_id) {
|
|
LLDB_RECORD_METHOD(lldb::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);
|
|
}
|
|
|
|
return LLDB_RECORD_RESULT(sb_thread);
|
|
}
|
|
|
|
StateType SBProcess::GetStateFromEvent(const SBEvent &event) {
|
|
LLDB_RECORD_STATIC_METHOD(lldb::StateType, SBProcess, GetStateFromEvent,
|
|
(const lldb::SBEvent &), event);
|
|
|
|
StateType ret_val = Process::ProcessEventData::GetStateFromEvent(event.get());
|
|
|
|
return ret_val;
|
|
}
|
|
|
|
bool SBProcess::GetRestartedFromEvent(const SBEvent &event) {
|
|
LLDB_RECORD_STATIC_METHOD(bool, SBProcess, GetRestartedFromEvent,
|
|
(const lldb::SBEvent &), event);
|
|
|
|
bool ret_val = Process::ProcessEventData::GetRestartedFromEvent(event.get());
|
|
|
|
return ret_val;
|
|
}
|
|
|
|
size_t SBProcess::GetNumRestartedReasonsFromEvent(const lldb::SBEvent &event) {
|
|
LLDB_RECORD_STATIC_METHOD(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) {
|
|
LLDB_RECORD_STATIC_METHOD(const char *, SBProcess,
|
|
GetRestartedReasonAtIndexFromEvent,
|
|
(const lldb::SBEvent &, size_t), event, idx);
|
|
|
|
return Process::ProcessEventData::GetRestartedReasonAtIndex(event.get(), idx);
|
|
}
|
|
|
|
SBProcess SBProcess::GetProcessFromEvent(const SBEvent &event) {
|
|
LLDB_RECORD_STATIC_METHOD(lldb::SBProcess, SBProcess, GetProcessFromEvent,
|
|
(const lldb::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 LLDB_RECORD_RESULT(SBProcess(process_sp));
|
|
}
|
|
|
|
bool SBProcess::GetInterruptedFromEvent(const SBEvent &event) {
|
|
LLDB_RECORD_STATIC_METHOD(bool, SBProcess, GetInterruptedFromEvent,
|
|
(const lldb::SBEvent &), event);
|
|
|
|
return Process::ProcessEventData::GetInterruptedFromEvent(event.get());
|
|
}
|
|
|
|
lldb::SBStructuredData
|
|
SBProcess::GetStructuredDataFromEvent(const lldb::SBEvent &event) {
|
|
LLDB_RECORD_STATIC_METHOD(lldb::SBStructuredData, SBProcess,
|
|
GetStructuredDataFromEvent, (const lldb::SBEvent &),
|
|
event);
|
|
|
|
return LLDB_RECORD_RESULT(SBStructuredData(event.GetSP()));
|
|
}
|
|
|
|
bool SBProcess::EventIsProcessEvent(const SBEvent &event) {
|
|
LLDB_RECORD_STATIC_METHOD(bool, SBProcess, EventIsProcessEvent,
|
|
(const lldb::SBEvent &), event);
|
|
|
|
return (event.GetBroadcasterClass() == SBProcess::GetBroadcasterClass()) &&
|
|
!EventIsStructuredDataEvent(event);
|
|
}
|
|
|
|
bool SBProcess::EventIsStructuredDataEvent(const lldb::SBEvent &event) {
|
|
LLDB_RECORD_STATIC_METHOD(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 {
|
|
LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::SBBroadcaster, SBProcess,
|
|
GetBroadcaster);
|
|
|
|
|
|
ProcessSP process_sp(GetSP());
|
|
|
|
SBBroadcaster broadcaster(process_sp.get(), false);
|
|
|
|
|
|
return LLDB_RECORD_RESULT(broadcaster);
|
|
}
|
|
|
|
const char *SBProcess::GetBroadcasterClass() {
|
|
LLDB_RECORD_STATIC_METHOD_NO_ARGS(const char *, SBProcess,
|
|
GetBroadcasterClass);
|
|
|
|
return Process::GetStaticBroadcasterClass().AsCString();
|
|
}
|
|
|
|
size_t SBProcess::ReadMemory(addr_t addr, void *dst, size_t dst_len,
|
|
SBError &sb_error) {
|
|
LLDB_RECORD_DUMMY(size_t, SBProcess, ReadMemory,
|
|
(lldb::addr_t, void *, size_t, lldb::SBError &), addr, dst,
|
|
dst_len, 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->ReadMemory(addr, dst, dst_len, sb_error.ref());
|
|
} else {
|
|
sb_error.SetErrorString("process is running");
|
|
}
|
|
} else {
|
|
sb_error.SetErrorString("SBProcess is invalid");
|
|
}
|
|
|
|
return bytes_read;
|
|
}
|
|
|
|
size_t SBProcess::ReadCStringFromMemory(addr_t addr, void *buf, size_t size,
|
|
lldb::SBError &sb_error) {
|
|
LLDB_RECORD_DUMMY(size_t, SBProcess, ReadCStringFromMemory,
|
|
(lldb::addr_t, void *, size_t, lldb::SBError &), addr, buf,
|
|
size, 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 {
|
|
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) {
|
|
LLDB_RECORD_METHOD(uint64_t, SBProcess, ReadUnsignedFromMemory,
|
|
(lldb::addr_t, uint32_t, lldb::SBError &), addr, byte_size,
|
|
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 {
|
|
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_RECORD_METHOD(lldb::addr_t, SBProcess, ReadPointerFromMemory,
|
|
(lldb::addr_t, lldb::SBError &), addr, 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 {
|
|
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) {
|
|
LLDB_RECORD_DUMMY(size_t, SBProcess, WriteMemory,
|
|
(lldb::addr_t, const void *, size_t, lldb::SBError &), addr,
|
|
src, src_len, sb_error);
|
|
|
|
size_t bytes_written = 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_written =
|
|
process_sp->WriteMemory(addr, src, src_len, sb_error.ref());
|
|
} else {
|
|
sb_error.SetErrorString("process is running");
|
|
}
|
|
}
|
|
|
|
return bytes_written;
|
|
}
|
|
|
|
bool SBProcess::GetDescription(SBStream &description) {
|
|
LLDB_RECORD_METHOD(bool, SBProcess, GetDescription, (lldb::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 {
|
|
LLDB_RECORD_METHOD_CONST(uint32_t, SBProcess,
|
|
GetNumSupportedHardwareWatchpoints,
|
|
(lldb::SBError &), sb_error);
|
|
|
|
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));
|
|
} else {
|
|
sb_error.SetErrorString("SBProcess is invalid");
|
|
}
|
|
return num;
|
|
}
|
|
|
|
uint32_t SBProcess::LoadImage(lldb::SBFileSpec &sb_remote_image_spec,
|
|
lldb::SBError &sb_error) {
|
|
LLDB_RECORD_METHOD(uint32_t, SBProcess, LoadImage,
|
|
(lldb::SBFileSpec &, lldb::SBError &),
|
|
sb_remote_image_spec, 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) {
|
|
LLDB_RECORD_METHOD(
|
|
uint32_t, SBProcess, LoadImage,
|
|
(const lldb::SBFileSpec &, const lldb::SBFileSpec &, lldb::SBError &),
|
|
sb_local_image_spec, sb_remote_image_spec, 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();
|
|
return platform_sp->LoadImage(process_sp.get(), *sb_local_image_spec,
|
|
*sb_remote_image_spec, sb_error.ref());
|
|
} else {
|
|
sb_error.SetErrorString("process is running");
|
|
}
|
|
} else {
|
|
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) {
|
|
LLDB_RECORD_METHOD(uint32_t, SBProcess, LoadImageUsingPaths,
|
|
(const lldb::SBFileSpec &, lldb::SBStringList &,
|
|
lldb::SBFileSpec &, lldb::SBError &),
|
|
image_spec, paths, loaded_path, 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();
|
|
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 {
|
|
error.SetErrorString("process is running");
|
|
}
|
|
} else {
|
|
error.SetErrorString("process is invalid");
|
|
}
|
|
|
|
return LLDB_INVALID_IMAGE_TOKEN;
|
|
}
|
|
|
|
lldb::SBError SBProcess::UnloadImage(uint32_t image_token) {
|
|
LLDB_RECORD_METHOD(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 {
|
|
sb_error.SetErrorString("process is running");
|
|
}
|
|
} else
|
|
sb_error.SetErrorString("invalid process");
|
|
return LLDB_RECORD_RESULT(sb_error);
|
|
}
|
|
|
|
lldb::SBError SBProcess::SendEventData(const char *event_data) {
|
|
LLDB_RECORD_METHOD(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 {
|
|
sb_error.SetErrorString("process is running");
|
|
}
|
|
} else
|
|
sb_error.SetErrorString("invalid process");
|
|
return LLDB_RECORD_RESULT(sb_error);
|
|
}
|
|
|
|
uint32_t SBProcess::GetNumExtendedBacktraceTypes() {
|
|
LLDB_RECORD_METHOD_NO_ARGS(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) {
|
|
LLDB_RECORD_METHOD(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();
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
SBThreadCollection SBProcess::GetHistoryThreads(addr_t addr) {
|
|
LLDB_RECORD_METHOD(lldb::SBThreadCollection, SBProcess, GetHistoryThreads,
|
|
(lldb::addr_t), addr);
|
|
|
|
ProcessSP process_sp(GetSP());
|
|
SBThreadCollection threads;
|
|
if (process_sp) {
|
|
threads = SBThreadCollection(process_sp->GetHistoryThreads(addr));
|
|
}
|
|
return LLDB_RECORD_RESULT(threads);
|
|
}
|
|
|
|
bool SBProcess::IsInstrumentationRuntimePresent(
|
|
InstrumentationRuntimeType type) {
|
|
LLDB_RECORD_METHOD(bool, SBProcess, IsInstrumentationRuntimePresent,
|
|
(lldb::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_RECORD_METHOD(lldb::SBError, SBProcess, SaveCore, (const char *),
|
|
file_name);
|
|
|
|
lldb::SBError error;
|
|
ProcessSP process_sp(GetSP());
|
|
if (!process_sp) {
|
|
error.SetErrorString("SBProcess is invalid");
|
|
return LLDB_RECORD_RESULT(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 LLDB_RECORD_RESULT(error);
|
|
}
|
|
|
|
FileSpec core_file(file_name);
|
|
error.ref() = PluginManager::SaveCore(process_sp, core_file);
|
|
return LLDB_RECORD_RESULT(error);
|
|
}
|
|
|
|
lldb::SBError
|
|
SBProcess::GetMemoryRegionInfo(lldb::addr_t load_addr,
|
|
SBMemoryRegionInfo &sb_region_info) {
|
|
LLDB_RECORD_METHOD(lldb::SBError, SBProcess, GetMemoryRegionInfo,
|
|
(lldb::addr_t, lldb::SBMemoryRegionInfo &), load_addr,
|
|
sb_region_info);
|
|
|
|
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.ref() =
|
|
process_sp->GetMemoryRegionInfo(load_addr, sb_region_info.ref());
|
|
} else {
|
|
sb_error.SetErrorString("process is running");
|
|
}
|
|
} else {
|
|
sb_error.SetErrorString("SBProcess is invalid");
|
|
}
|
|
return LLDB_RECORD_RESULT(sb_error);
|
|
}
|
|
|
|
lldb::SBMemoryRegionInfoList SBProcess::GetMemoryRegions() {
|
|
LLDB_RECORD_METHOD_NO_ARGS(lldb::SBMemoryRegionInfoList, SBProcess,
|
|
GetMemoryRegions);
|
|
|
|
lldb::SBMemoryRegionInfoList sb_region_list;
|
|
|
|
ProcessSP process_sp(GetSP());
|
|
Process::StopLocker stop_locker;
|
|
if (process_sp && stop_locker.TryLock(&process_sp->GetRunLock())) {
|
|
std::lock_guard<std::recursive_mutex> guard(
|
|
process_sp->GetTarget().GetAPIMutex());
|
|
|
|
process_sp->GetMemoryRegions(sb_region_list.ref());
|
|
}
|
|
|
|
return LLDB_RECORD_RESULT(sb_region_list);
|
|
}
|
|
|
|
lldb::SBProcessInfo SBProcess::GetProcessInfo() {
|
|
LLDB_RECORD_METHOD_NO_ARGS(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 LLDB_RECORD_RESULT(sb_proc_info);
|
|
}
|
|
|
|
namespace lldb_private {
|
|
namespace repro {
|
|
|
|
template <>
|
|
void RegisterMethods<SBProcess>(Registry &R) {
|
|
LLDB_REGISTER_CONSTRUCTOR(SBProcess, ());
|
|
LLDB_REGISTER_CONSTRUCTOR(SBProcess, (const lldb::SBProcess &));
|
|
LLDB_REGISTER_CONSTRUCTOR(SBProcess, (const lldb::ProcessSP &));
|
|
LLDB_REGISTER_METHOD(const lldb::SBProcess &,
|
|
SBProcess, operator=,(const lldb::SBProcess &));
|
|
LLDB_REGISTER_STATIC_METHOD(const char *, SBProcess,
|
|
GetBroadcasterClassName, ());
|
|
LLDB_REGISTER_METHOD(const char *, SBProcess, GetPluginName, ());
|
|
LLDB_REGISTER_METHOD(const char *, SBProcess, GetShortPluginName, ());
|
|
LLDB_REGISTER_METHOD(void, SBProcess, Clear, ());
|
|
LLDB_REGISTER_METHOD_CONST(bool, SBProcess, IsValid, ());
|
|
LLDB_REGISTER_METHOD_CONST(bool, SBProcess, operator bool, ());
|
|
LLDB_REGISTER_METHOD(bool, SBProcess, RemoteLaunch,
|
|
(const char **, const char **, const char *,
|
|
const char *, const char *, const char *, uint32_t,
|
|
bool, lldb::SBError &));
|
|
LLDB_REGISTER_METHOD(bool, SBProcess, RemoteAttachToProcessWithID,
|
|
(lldb::pid_t, lldb::SBError &));
|
|
LLDB_REGISTER_METHOD(uint32_t, SBProcess, GetNumThreads, ());
|
|
LLDB_REGISTER_METHOD_CONST(lldb::SBThread, SBProcess, GetSelectedThread,
|
|
());
|
|
LLDB_REGISTER_METHOD(lldb::SBThread, SBProcess, CreateOSPluginThread,
|
|
(lldb::tid_t, lldb::addr_t));
|
|
LLDB_REGISTER_METHOD_CONST(lldb::SBTarget, SBProcess, GetTarget, ());
|
|
LLDB_REGISTER_METHOD(size_t, SBProcess, PutSTDIN, (const char *, size_t));
|
|
LLDB_REGISTER_METHOD_CONST(size_t, SBProcess, GetSTDOUT, (char *, size_t));
|
|
LLDB_REGISTER_METHOD_CONST(size_t, SBProcess, GetSTDERR, (char *, size_t));
|
|
LLDB_REGISTER_METHOD_CONST(size_t, SBProcess, GetAsyncProfileData,
|
|
(char *, size_t));
|
|
LLDB_REGISTER_METHOD(lldb::SBTrace, SBProcess, StartTrace,
|
|
(lldb::SBTraceOptions &, lldb::SBError &));
|
|
LLDB_REGISTER_METHOD_CONST(void, SBProcess, ReportEventState,
|
|
(const lldb::SBEvent &, FILE *));
|
|
LLDB_REGISTER_METHOD(
|
|
void, SBProcess, AppendEventStateReport,
|
|
(const lldb::SBEvent &, lldb::SBCommandReturnObject &));
|
|
LLDB_REGISTER_METHOD(bool, SBProcess, SetSelectedThread,
|
|
(const lldb::SBThread &));
|
|
LLDB_REGISTER_METHOD(bool, SBProcess, SetSelectedThreadByID, (lldb::tid_t));
|
|
LLDB_REGISTER_METHOD(bool, SBProcess, SetSelectedThreadByIndexID,
|
|
(uint32_t));
|
|
LLDB_REGISTER_METHOD(lldb::SBThread, SBProcess, GetThreadAtIndex, (size_t));
|
|
LLDB_REGISTER_METHOD(uint32_t, SBProcess, GetNumQueues, ());
|
|
LLDB_REGISTER_METHOD(lldb::SBQueue, SBProcess, GetQueueAtIndex, (size_t));
|
|
LLDB_REGISTER_METHOD(uint32_t, SBProcess, GetStopID, (bool));
|
|
LLDB_REGISTER_METHOD(lldb::SBEvent, SBProcess, GetStopEventForStopID,
|
|
(uint32_t));
|
|
LLDB_REGISTER_METHOD(lldb::StateType, SBProcess, GetState, ());
|
|
LLDB_REGISTER_METHOD(int, SBProcess, GetExitStatus, ());
|
|
LLDB_REGISTER_METHOD(const char *, SBProcess, GetExitDescription, ());
|
|
LLDB_REGISTER_METHOD(lldb::pid_t, SBProcess, GetProcessID, ());
|
|
LLDB_REGISTER_METHOD(uint32_t, SBProcess, GetUniqueID, ());
|
|
LLDB_REGISTER_METHOD_CONST(lldb::ByteOrder, SBProcess, GetByteOrder, ());
|
|
LLDB_REGISTER_METHOD_CONST(uint32_t, SBProcess, GetAddressByteSize, ());
|
|
LLDB_REGISTER_METHOD(lldb::SBError, SBProcess, Continue, ());
|
|
LLDB_REGISTER_METHOD(lldb::SBError, SBProcess, Destroy, ());
|
|
LLDB_REGISTER_METHOD(lldb::SBError, SBProcess, Stop, ());
|
|
LLDB_REGISTER_METHOD(lldb::SBError, SBProcess, Kill, ());
|
|
LLDB_REGISTER_METHOD(lldb::SBError, SBProcess, Detach, ());
|
|
LLDB_REGISTER_METHOD(lldb::SBError, SBProcess, Detach, (bool));
|
|
LLDB_REGISTER_METHOD(lldb::SBError, SBProcess, Signal, (int));
|
|
LLDB_REGISTER_METHOD(lldb::SBUnixSignals, SBProcess, GetUnixSignals, ());
|
|
LLDB_REGISTER_METHOD(void, SBProcess, SendAsyncInterrupt, ());
|
|
LLDB_REGISTER_METHOD(lldb::SBThread, SBProcess, GetThreadByID,
|
|
(lldb::tid_t));
|
|
LLDB_REGISTER_METHOD(lldb::SBThread, SBProcess, GetThreadByIndexID,
|
|
(uint32_t));
|
|
LLDB_REGISTER_STATIC_METHOD(lldb::StateType, SBProcess, GetStateFromEvent,
|
|
(const lldb::SBEvent &));
|
|
LLDB_REGISTER_STATIC_METHOD(bool, SBProcess, GetRestartedFromEvent,
|
|
(const lldb::SBEvent &));
|
|
LLDB_REGISTER_STATIC_METHOD(size_t, SBProcess,
|
|
GetNumRestartedReasonsFromEvent,
|
|
(const lldb::SBEvent &));
|
|
LLDB_REGISTER_STATIC_METHOD(const char *, SBProcess,
|
|
GetRestartedReasonAtIndexFromEvent,
|
|
(const lldb::SBEvent &, size_t));
|
|
LLDB_REGISTER_STATIC_METHOD(lldb::SBProcess, SBProcess, GetProcessFromEvent,
|
|
(const lldb::SBEvent &));
|
|
LLDB_REGISTER_STATIC_METHOD(bool, SBProcess, GetInterruptedFromEvent,
|
|
(const lldb::SBEvent &));
|
|
LLDB_REGISTER_STATIC_METHOD(lldb::SBStructuredData, SBProcess,
|
|
GetStructuredDataFromEvent,
|
|
(const lldb::SBEvent &));
|
|
LLDB_REGISTER_STATIC_METHOD(bool, SBProcess, EventIsProcessEvent,
|
|
(const lldb::SBEvent &));
|
|
LLDB_REGISTER_STATIC_METHOD(bool, SBProcess, EventIsStructuredDataEvent,
|
|
(const lldb::SBEvent &));
|
|
LLDB_REGISTER_METHOD_CONST(lldb::SBBroadcaster, SBProcess, GetBroadcaster,
|
|
());
|
|
LLDB_REGISTER_STATIC_METHOD(const char *, SBProcess, GetBroadcasterClass,
|
|
());
|
|
LLDB_REGISTER_METHOD(uint64_t, SBProcess, ReadUnsignedFromMemory,
|
|
(lldb::addr_t, uint32_t, lldb::SBError &));
|
|
LLDB_REGISTER_METHOD(lldb::addr_t, SBProcess, ReadPointerFromMemory,
|
|
(lldb::addr_t, lldb::SBError &));
|
|
LLDB_REGISTER_METHOD(bool, SBProcess, GetDescription, (lldb::SBStream &));
|
|
LLDB_REGISTER_METHOD_CONST(uint32_t, SBProcess,
|
|
GetNumSupportedHardwareWatchpoints,
|
|
(lldb::SBError &));
|
|
LLDB_REGISTER_METHOD(uint32_t, SBProcess, LoadImage,
|
|
(lldb::SBFileSpec &, lldb::SBError &));
|
|
LLDB_REGISTER_METHOD(
|
|
uint32_t, SBProcess, LoadImage,
|
|
(const lldb::SBFileSpec &, const lldb::SBFileSpec &, lldb::SBError &));
|
|
LLDB_REGISTER_METHOD(uint32_t, SBProcess, LoadImageUsingPaths,
|
|
(const lldb::SBFileSpec &, lldb::SBStringList &,
|
|
lldb::SBFileSpec &, lldb::SBError &));
|
|
LLDB_REGISTER_METHOD(lldb::SBError, SBProcess, UnloadImage, (uint32_t));
|
|
LLDB_REGISTER_METHOD(lldb::SBError, SBProcess, SendEventData,
|
|
(const char *));
|
|
LLDB_REGISTER_METHOD(uint32_t, SBProcess, GetNumExtendedBacktraceTypes, ());
|
|
LLDB_REGISTER_METHOD(const char *, SBProcess,
|
|
GetExtendedBacktraceTypeAtIndex, (uint32_t));
|
|
LLDB_REGISTER_METHOD(lldb::SBThreadCollection, SBProcess, GetHistoryThreads,
|
|
(lldb::addr_t));
|
|
LLDB_REGISTER_METHOD(bool, SBProcess, IsInstrumentationRuntimePresent,
|
|
(lldb::InstrumentationRuntimeType));
|
|
LLDB_REGISTER_METHOD(lldb::SBError, SBProcess, SaveCore, (const char *));
|
|
LLDB_REGISTER_METHOD(lldb::SBError, SBProcess, GetMemoryRegionInfo,
|
|
(lldb::addr_t, lldb::SBMemoryRegionInfo &));
|
|
LLDB_REGISTER_METHOD(lldb::SBMemoryRegionInfoList, SBProcess,
|
|
GetMemoryRegions, ());
|
|
LLDB_REGISTER_METHOD(lldb::SBProcessInfo, SBProcess, GetProcessInfo, ());
|
|
}
|
|
|
|
}
|
|
}
|