20#include "llvm/Support/Errno.h"
21#include "llvm/Support/Error.h"
27#include <sys/ptrace.h>
29#define DECLARE_REGISTER_INFOS_PPC64_STRUCT
31#undef DECLARE_REGISTER_INFOS_PPC64_STRUCT
40 "Size of long must be larger than ptrace word size");
45 int status = fcntl(fd, F_GETFL);
47 return errorCodeToError(errnoAsErrorCode());
48 if (fcntl(fd, F_SETFL, status | flags) == -1)
49 return errorCodeToError(errnoAsErrorCode());
50 return Error::success();
63llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
74 LLDB_LOG(log,
"failed to launch process: {0}", status);
80 ::pid_t wpid = llvm::sys::RetryAfterSignal(-1, ::waitpid, pid, &wstatus, 0);
83 if (!WIFSTOPPED(wstatus)) {
84 LLDB_LOG(log,
"Could not sync with inferior process: wstatus={1}",
86 return llvm::createStringError(
"could not sync with inferior process");
88 LLDB_LOG(log,
"inferior started, now in stopped state");
92 return llvm::make_error<StringError>(
"Cannot get process architecture",
93 llvm::inconvertibleErrorCode());
97 LLDB_LOG(log,
"pid = {0}, detected architecture {1}", pid,
98 Info.GetArchitecture().GetArchitectureName());
102 Info.GetArchitecture(), *
this, {pid}));
105llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
113 return tids_or.takeError();
116 pid, -1, native_delegate,
117 HostInfo::GetArchitecture(HostInfo::eArchKind64), *
this, *tids_or));
124static std::optional<std::pair<lldb::pid_t, WaitStatus>>
WaitPid() {
129 llvm::sys::RetryAfterSignal(-1, ::waitpid, -1, &status, WNOHANG);
134 if (wait_pid == -1) {
142 LLDB_LOG(log,
"waitpid(-1, &status, _) = {0}, status = {1}", wait_pid,
144 return std::make_pair(wait_pid, wait_status);
162 llvm::ArrayRef<::pid_t> tids)
177 if (llvm::Error err =
PtraceWrapper(PT_ATTACH, pid).takeError())
180 int wpid = llvm::sys::RetryAfterSignal(-1, ::waitpid, pid,
nullptr, WNOHANG);
182 return llvm::errorCodeToError(errnoAsErrorCode());
183 LLDB_LOG(log,
"adding pid = {0}", pid);
185 return std::vector<::pid_t>{pid};
191 return Status(
"unsupported");
216 LLDB_LOG(log,
"ignored for PID {0} due to current state: {1}",
GetID(),
231 llvm::Expected<int> result =
234 std::string error_string = std::string(
"Kill failed for process. error: ") +
235 llvm::toString(result.takeError());
236 error.FromErrorString(error_string.c_str());
242 size_t &bytes_read) {
243 return Status(
"unsupported");
247 size_t size,
size_t &bytes_written) {
248 return Status(
"unsupported");
260 return Status(
"unsupported");
265 return Status(
"unsupported");
285template <
typename GPR_T,
typename PTSPRS_T>
289 int ret = ptrace64(req, tid,
reinterpret_cast<long long>(&sprs), 0, 0);
292 gpr->cr = sprs.pt_cr;
293 gpr->msr = sprs.pt_msr;
294 gpr->xer = sprs.pt_xer;
295 gpr->lr = sprs.pt_lr;
296 gpr->ctr = sprs.pt_ctr;
297 gpr->pc = sprs.pt_iar;
302template <
typename GPR_T,
typename PTSPRS_T>
306 sprs.pt_cr = gpr->cr;
307 sprs.pt_msr = gpr->msr;
308 sprs.pt_xer = gpr->xer;
309 sprs.pt_lr = gpr->lr;
310 sprs.pt_ctr = gpr->ctr;
311 sprs.pt_iar = gpr->pc;
313 return ptrace64(req, tid,
reinterpret_cast<long long>(&sprs), 0, 0);
317 void *addr,
void *data,
327 llvm::SmallString<128> proc_lwp_dir;
328 llvm::sys::path::append(proc_lwp_dir,
"/proc/", std::to_string(pid),
"/lwp/");
333 if (!llvm::sys::fs::is_directory(proc_lwp_dir, result) && result) {
334 for (sys::fs::directory_iterator it(proc_lwp_dir, ec), end;
335 it != end && !ec; it.increment(ec)) {
336 llvm::StringRef name = llvm::sys::path::filename(it->path());
338 if (name ==
"." || name ==
"..")
341 if (!name.getAsInteger(10, tid)) {
353 if (data_size ==
sizeof(GPR_PPC))
355 static_cast<GPR_PPC *
>(data));
356 else if (data_size ==
sizeof(GPR_PPC64))
358 static_cast<GPR_PPC64 *
>(data));
361 ret = ptrace64(req, tid,
reinterpret_cast<long long>(data), 0,
366 if (data_size ==
sizeof(GPR_PPC))
368 static_cast<GPR_PPC *
>(data));
369 else if (data_size ==
sizeof(GPR_PPC64))
371 static_cast<GPR_PPC64 *
>(data));
374 ret = ptrace64(req, tid,
reinterpret_cast<long long>(data), 0,
380 ret = ptrace64(req, pid, 0, 0,
nullptr);
383 llvm_unreachable(
"PT_ request not supported yet.");
386 LLDB_LOG(log,
"ptrace({0}, {1}, {2}, {3}, {4})={5:x}", req, pid, addr, data,
391 return llvm::errorCodeToError(errnoAsErrorCode());
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
static std::optional< std::pair< lldb::pid_t, WaitStatus > > WaitPid()
static constexpr unsigned k_ptrace_word_size
int GetSPRs(int req, lldb::tid_t tid, GPR_T *gpr)
static llvm::Error SetFDFlags(int fd, int flags)
int SetSPRs(int req, lldb::tid_t tid, GPR_T *gpr)
An architecture specification class.
lldb::pid_t GetProcessId() const
static bool GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &proc_info)
SignalHandleUP RegisterSignal(int signo, const Callback &callback, Status &error)
NativeProcessProtocol(lldb::pid_t pid, int terminal_fd, NativeDelegate &delegate)
lldb::pid_t GetID() const
Status SetSoftwareBreakpoint(lldb::addr_t addr, uint32_t size_hint)
void SetState(lldb::StateType state, bool notify_delegates=true)
void SetCurrentThreadID(lldb::tid_t tid)
std::vector< std::unique_ptr< NativeThreadProtocol > > m_threads
virtual Status RemoveBreakpoint(lldb::addr_t addr, bool hardware=false)
virtual Status SetHardwareBreakpoint(lldb::addr_t addr, size_t size)
virtual Status RemoveHardwareBreakpoint(lldb::addr_t addr)
HostProcess LaunchProcess(const ProcessLaunchInfo &launch_info, Status &error) override
int ReleasePrimaryFileDescriptor()
Release the primary file descriptor.
llvm::Error ToError() const
FIXME: Replace all uses with takeError() instead.
bool Fail() const
Test for error condition.
bool Success() const
Test for success condition.
void AddProcess(NativeProcessAIX &process)
llvm::Expected< std::unique_ptr< NativeProcessProtocol > > Launch(ProcessLaunchInfo &launch_info, NativeDelegate &native_delegate) override
Launch a process for debugging.
Manager(MainLoop &mainloop)
llvm::Expected< std::unique_ptr< NativeProcessProtocol > > Attach(lldb::pid_t pid, NativeDelegate &native_delegate) override
Attach to an existing process.
MainLoop::SignalHandleUP m_sigchld_handle
void CollectThread(::pid_t tid)
Status ReadMemory(lldb::addr_t addr, void *buf, size_t size, size_t &bytes_read) override
static llvm::Expected< std::vector<::pid_t > > Attach(::pid_t pid)
Status WriteMemory(lldb::addr_t addr, const void *buf, size_t size, size_t &bytes_written) override
bool SupportHardwareSingleStepping() const
Status RemoveBreakpoint(lldb::addr_t addr, bool hardware=false) override
size_t UpdateThreads() override
static llvm::Expected< int > PtraceWrapper(int req, lldb::pid_t pid, void *addr=nullptr, void *data=nullptr, size_t data_size=0)
Status GetLoadedModuleFileSpec(const char *module_path, FileSpec &file_spec) override
Status Signal(int signo) override
Sends a process a UNIX signal signal.
Status Interrupt() override
Tells a process to interrupt all operations as if by a Ctrl-C.
lldb::addr_t GetSharedLibraryInfoAddress() override
Status Resume(const ResumeActionList &resume_actions) override
NativeProcessAIX(::pid_t pid, int terminal_fd, NativeDelegate &delegate, const ArchSpec &arch, Manager &manager, llvm::ArrayRef<::pid_t > tids)
Status SetBreakpoint(lldb::addr_t addr, uint32_t size, bool hardware) override
Status GetFileLoadAddress(const llvm::StringRef &file_name, lldb::addr_t &load_addr) override
#define UNUSED_IF_ASSERT_DISABLED(x)
#define LLDB_INVALID_ADDRESS
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
@ eStateUnloaded
Process is object is valid, but not currently loaded.
@ eStateConnected
Process is connected to remote debug services, but not launched or attached to anything yet.
@ eStateDetached
Process has been detached and can't be examined.
@ eStateStopped
Process or thread is stopped and can be examined.
@ eStateSuspended
Process or thread is in a suspended state as far as the debugger is concerned while other processes o...
@ eStateRunning
Process or thread is running and can't be examined.
@ eStateLaunching
Process is in the process of launching.
@ eStateAttaching
Process is currently trying to attach.
@ eStateExited
Process has exited and can't be examined.
@ eStateStepping
Process or thread is in the process of stepping and can not be examined.
@ eStateCrashed
Process or thread has crashed and can be examined.
@ eErrorTypePOSIX
POSIX error codes.
static WaitStatus Decode(int wstatus)