13#include <sys/ptrace.h>
14#include <sys/sysctl.h>
17#include <machine/elf.h>
25#include "llvm/Support/Errno.h"
37 int status = fcntl(fd, F_GETFL);
43 if (fcntl(fd, F_SETFL, status | flags) == -1) {
53 size_t len =
sizeof(proc_debug);
54 ret = ::sysctlbyname(
"security.bsd.unprivileged_proc_debug", &proc_debug,
58 "sysctlbyname() security.bsd.unprivileged_proc_debug failed");
62 "process debug disabled by security.bsd.unprivileged_proc_debug oid");
69llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
80 LLDB_LOG(log,
"failed to launch process: {0}", status);
83 return error.ToError();
89 ::pid_t wpid = llvm::sys::RetryAfterSignal(-1, ::waitpid, pid, &wstatus, 0);
92 if (!WIFSTOPPED(wstatus)) {
93 LLDB_LOG(log,
"Could not sync with inferior process: wstatus={1}",
95 return llvm::make_error<StringError>(
"Could not sync with inferior process",
96 llvm::inconvertibleErrorCode());
98 LLDB_LOG(log,
"inferior started, now in stopped state");
102 return llvm::make_error<StringError>(
"Cannot get process architecture",
103 llvm::inconvertibleErrorCode());
107 LLDB_LOG(log,
"pid = {0:x}, detected architecture {1}", pid,
108 Info.GetArchitecture().GetArchitectureName());
114 status = process_up->SetupTrace();
118 for (
const auto &thread : process_up->m_threads)
120 process_up->SetState(StateType::eStateStopped,
false);
122 return std::move(process_up);
125llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
134 return llvm::make_error<StringError>(
"Cannot get process architecture",
135 llvm::inconvertibleErrorCode());
139 pid, -1, native_delegate, Info.GetArchitecture(), m_mainloop));
141 Status status = process_up->Attach();
145 return std::move(process_up);
151#if defined(PT_COREDUMP)
193 LLDB_LOG(log,
"got exit signal({0}) , pid = {1}", status, pid);
201 SetState(StateType::eStateExited,
true);
210 SetState(StateType::eStateStopped,
true);
215 struct ptrace_lwpinfo info;
217 const auto siginfo_err =
PtraceWrapper(PT_LWPINFO, pid, &info,
sizeof(info));
218 if (siginfo_err.Fail()) {
219 LLDB_LOG(log,
"PT_LWPINFO failed {0}", siginfo_err);
222 assert(info.pl_event == PL_EVENT_SIGNAL);
224 LLDB_LOG(log,
"got SIGTRAP, pid = {0}, lwpid = {1}, flags = {2:x}", pid,
225 info.pl_lwpid, info.pl_flags);
228 if (info.pl_flags & (PL_FLAG_BORN | PL_FLAG_EXITED)) {
229 if (info.pl_flags & PL_FLAG_BORN) {
230 LLDB_LOG(log,
"monitoring new thread, tid = {0}", info.pl_lwpid);
246 "failed to copy watchpoints to new thread {1}: {0}",
252 LLDB_LOG(log,
"thread exited, tid = {0}", info.pl_lwpid);
257 PtraceWrapper(PT_CONTINUE, pid,
reinterpret_cast<void *
>(1), 0);
263 if (info.pl_flags & PL_FLAG_EXEC) {
276 SetState(StateType::eStateStopped,
true);
280 if (info.pl_lwpid > 0) {
282 if (t->GetID() ==
static_cast<lldb::tid_t>(info.pl_lwpid))
287 LLDB_LOG(log,
"thread not found in m_threads, pid = {0}, LWP = {1}", pid,
291 if (info.pl_flags & PL_FLAG_FORKED) {
293 MonitorClone(info.pl_child_pid, info.pl_flags & PL_FLAG_VFORKED, *thread);
297 if (info.pl_flags & PL_FLAG_VFORK_DONE) {
301 SetState(StateType::eStateStopped,
true);
304 PtraceWrapper(PT_CONTINUE, pid,
reinterpret_cast<void *
>(1), 0);
311 if (info.pl_flags & PL_FLAG_SI) {
312 assert(info.pl_siginfo.si_signo ==
SIGTRAP);
313 LLDB_LOG(log,
"SIGTRAP siginfo: si_code = {0}, pid = {1}",
314 info.pl_siginfo.si_code, info.pl_siginfo.si_pid);
316 switch (info.pl_siginfo.si_code) {
318 LLDB_LOG(log,
"SIGTRAP/TRAP_BRKPT: si_addr: {0}",
319 info.pl_siginfo.si_addr);
327 thread_info->second == regctx.GetPC()) {
330 if (brkpt_error.
Fail())
331 LLDB_LOG(log,
"pid = {0} remove stepping breakpoint: {1}",
332 thread_info->first, brkpt_error);
339 SetState(StateType::eStateStopped,
true);
342 LLDB_LOG(log,
"SIGTRAP/TRAP_TRACE: si_addr: {0}",
343 info.pl_siginfo.si_addr);
350 wp_index,
reinterpret_cast<uintptr_t
>(info.pl_siginfo.si_addr));
353 "received error while checking for watchpoint hits, pid = "
354 "{0}, LWP = {1}, error = {2}",
355 pid, info.pl_lwpid,
error);
357 regctx.ClearWatchpointHit(wp_index);
360 SetState(StateType::eStateStopped,
true);
368 SetState(StateType::eStateStopped,
true);
375 LLDB_LOG(log,
"unknown SIGTRAP, passing to generic handler");
381 struct ptrace_lwpinfo info;
383 const auto siginfo_err =
PtraceWrapper(PT_LWPINFO, pid, &info,
sizeof(info));
384 if (siginfo_err.Fail()) {
385 LLDB_LOG(log,
"PT_LWPINFO failed {0}", siginfo_err);
388 assert(info.pl_event == PL_EVENT_SIGNAL);
390 assert(info.pl_flags & PL_FLAG_SI);
391 assert(info.pl_siginfo.si_signo == signal);
393 for (
const auto &abs_thread :
m_threads) {
396 assert(info.pl_lwpid >= 0);
397 if (info.pl_lwpid == 0 ||
404 SetState(StateType::eStateStopped,
true);
408 int data,
int *result) {
415 ptrace(req,
static_cast<::
pid_t>(pid),
static_cast<caddr_t
>(addr), data);
426 LLDB_LOG(log,
"ptrace({0}, {1}, {2}, {3})={4:x}", req, pid, addr, data, ret);
434llvm::Expected<llvm::ArrayRef<uint8_t>>
436 static const uint8_t g_arm_opcode[] = {0xfe, 0xde, 0xff, 0xe7};
437 static const uint8_t g_thumb_opcode[] = {0x01, 0xde};
440 case llvm::Triple::arm:
443 return llvm::ArrayRef(g_thumb_opcode);
445 return llvm::ArrayRef(g_arm_opcode);
447 return llvm::createStringError(llvm::inconvertibleErrorCode(),
448 "Unrecognised trap opcode size hint!");
462 for (
const auto &abs_thread :
m_threads) {
463 assert(abs_thread &&
"thread list should not contain NULL threads");
474 if (action ==
nullptr) {
475 LLDB_LOG(log,
"no action specified for pid {0} tid {1}",
GetID(),
477 action = &suspend_action;
482 "processing resume action state {0} signal {1} for pid {2} tid {3}",
485 switch (action->
state) {
496 "Passing signal to suspended thread unsupported");
503 "NativeProcessFreeBSD::%s (): unexpected state %s specified "
504 "for pid %" PRIu64
", tid %" PRIu64,
549 if (kill(
GetID(), signo))
564 case StateType::eStateInvalid:
565 case StateType::eStateExited:
566 case StateType::eStateCrashed:
567 case StateType::eStateDetached:
568 case StateType::eStateUnloaded:
570 LLDB_LOG(log,
"ignored for PID {0} due to current state: {1}",
GetID(),
574 case StateType::eStateConnected:
575 case StateType::eStateAttaching:
576 case StateType::eStateLaunching:
577 case StateType::eStateStopped:
578 case StateType::eStateRunning:
579 case StateType::eStateStepping:
580 case StateType::eStateSuspended:
610 "descending memory map entries detected, unexpected");
626 range_info = proc_entry_info;
649 LLDB_LOG(log,
"reusing {0} cached memory region entries",
654 int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_VMMAP,
static_cast<int>(
m_pid)};
658 ret = ::sysctl(mib, 4,
nullptr, &len,
nullptr, 0);
664 std::unique_ptr<WritableMemoryBuffer> buf =
665 llvm::WritableMemoryBuffer::getNewMemBuffer(len);
666 ret = ::sysctl(mib, 4, buf->getBufferStart(), &len,
nullptr, 0);
672 char *bp = buf->getBufferStart();
673 char *end = bp + len;
675 auto *kv =
reinterpret_cast<struct kinfo_vmentry *
>(bp);
676 if (kv->kve_structsize == 0)
678 bp += kv->kve_structsize;
686 if (kv->kve_protection & VM_PROT_READ)
691 if (kv->kve_protection & VM_PROT_WRITE)
696 if (kv->kve_protection & VM_PROT_EXECUTE)
711 LLDB_LOG(log,
"failed to find any vmmap entries, assuming no support "
712 "for memory region metadata retrieval");
716 LLDB_LOG(log,
"read {0} memory region entries from process {1}",
743 FileSpec module_file_spec(module_path);
748 if (it.second.GetFilename() == module_file_spec.
GetFilename()) {
749 file_spec = it.second;
754 "Module file (%s) not found in process' memory map!",
772 if (it.second == file) {
773 load_addr = it.first.GetRange().GetRangeBase();
778 file_name.str().c_str());
785 llvm::sys::RetryAfterSignal(-1, waitpid,
GetID(), &status, WNOHANG);
790 if (wait_pid == -1) {
802 "waitpid ({0}, &status, _) => pid = {1}, status = {2}, exited = {3}",
803 GetID(), wait_pid, status, exited);
815 assert(thread &&
"thread list should not contain NULL threads");
816 if (thread->GetID() == thread_id) {
828 LLDB_LOG(log,
"pid {0} adding thread with tid {1}",
GetID(), thread_id);
830 assert(thread_id > 0);
832 "attempted to add a thread by id that already exists");
838 m_threads.push_back(std::make_unique<NativeThreadFreeBSD>(*
this, thread_id));
844 LLDB_LOG(log,
"pid {0} removing thread with tid {1}",
GetID(), thread_id);
846 assert(thread_id > 0);
848 "attempted to remove a thread that does not exist");
851 if ((*it)->GetID() == thread_id) {
871 if ((wstatus = llvm::sys::RetryAfterSignal(-1, waitpid,
m_pid,
nullptr, 0)) <
886 SetState(StateType::eStateStopped,
false);
891 size_t size,
size_t &bytes_read) {
892 unsigned char *dst =
static_cast<unsigned char *
>(buf);
893 struct ptrace_io_desc io;
896 LLDB_LOG(log,
"addr = {0}, buf = {1}, size = {2}", addr, buf, size);
899 io.piod_op = PIOD_READ_D;
903 io.piod_offs = (
void *)(addr + bytes_read);
904 io.piod_addr = dst + bytes_read;
907 if (
error.Fail() || io.piod_len == 0)
910 bytes_read += io.piod_len;
911 io.piod_len = size - bytes_read;
912 }
while (bytes_read < size);
918 size_t size,
size_t &bytes_written) {
919 const unsigned char *src =
static_cast<const unsigned char *
>(buf);
921 struct ptrace_io_desc io;
924 LLDB_LOG(log,
"addr = {0}, buf = {1}, size = {2}", addr, buf, size);
927 io.piod_op = PIOD_WRITE_D;
932 const_cast<void *
>(
static_cast<const void *
>(src + bytes_written));
933 io.piod_offs = (
void *)(addr + bytes_written);
936 if (
error.Fail() || io.piod_len == 0)
939 bytes_written += io.piod_len;
940 io.piod_len = size - bytes_written;
941 }
while (bytes_written < size);
946llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
948 int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_AUXV,
static_cast<int>(
GetID())};
949 size_t auxv_size = AT_COUNT *
sizeof(Elf_Auxinfo);
950 std::unique_ptr<WritableMemoryBuffer> buf =
951 llvm::WritableMemoryBuffer::getNewMemBuffer(auxv_size);
953 if (::sysctl(mib, 4, buf->getBufferStart(), &auxv_size,
nullptr, 0) != 0)
954 return std::error_code(errno, std::generic_category());
966 events |= PTRACE_LWP | PTRACE_FORK | PTRACE_VFORK;
983 std::vector<lwpid_t> lwp_ids;
984 lwp_ids.resize(num_lwps);
986 lwp_ids.size() *
sizeof(lwpid_t), &num_lwps);
991 for (lwpid_t lwp : lwp_ids)
1004 LLDB_LOG(log,
"fork, child_pid={0}", child_pid);
1008 llvm::sys::RetryAfterSignal(-1, ::waitpid, child_pid, &status, 0);
1009 if (wait_pid != child_pid) {
1011 "waiting for pid {0} failed. Assuming the pid has "
1012 "disappeared in the meantime",
1016 if (WIFEXITED(status)) {
1018 "waiting for pid {0} returned an 'exited' event. Not "
1024 struct ptrace_lwpinfo info;
1025 const auto siginfo_err =
PtraceWrapper(PT_LWPINFO, child_pid, &info,
sizeof(info));
1026 if (siginfo_err.Fail()) {
1027 LLDB_LOG(log,
"PT_LWPINFO failed {0}", siginfo_err);
1030 assert(info.pl_event == PL_EVENT_SIGNAL);
1033 std::unique_ptr<NativeProcessFreeBSD> child_process{
1041 child_process->SetupTrace();
1042 for (
const auto &thread : child_process->m_threads)
1044 child_process->SetState(StateType::eStateStopped,
false);
1051 SetState(StateType::eStateStopped,
true);
1053 child_process->Detach();
1056 if (pt_error.
Fail()) {
1058 "unable to resume parent process {1}: {0}",
GetID());
1059 SetState(StateType::eStateInvalid);
1064llvm::Expected<std::string>
1066#if defined(PT_COREDUMP)
1067 using namespace llvm::sys::fs;
1069 llvm::SmallString<128> path{path_hint};
1071 struct ptrace_coredump
pc = {};
1076 openFile(path,
pc.pc_fd, CD_CreateNew, FA_Write, OF_None)) {
1077 if (std::error_code errc =
1078 createTemporaryFile(
"lldb",
"core",
pc.pc_fd, path))
1079 return llvm::createStringError(errc,
"Unable to create a temporary file");
1083 std::error_code close_err = closeFile(
pc.pc_fd);
1085 return error.ToError();
1087 return llvm::createStringError(
1088 close_err,
"Unable to close the core dump after writing");
1089 return path.str().str();
1091 return llvm::createStringError(
1092 llvm::inconvertibleErrorCode(),
1093 "PT_COREDUMP not supported in the FreeBSD version used to build LLDB");
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
#define LLDB_LOG_ERROR(log, error,...)
static Status EnsureFDFlags(int fd, int flags)
An architecture specification class.
bool IsMIPS() const
if MIPS architecture return true.
const char * AsCString(const char *value_if_empty=nullptr) const
Get the string value as a C string.
const char * GetCString() const
Get the string value as a C string.
const ConstString & GetFilename() const
Filename string const get accessor.
void Clear()
Clears the object state.
void Resolve(llvm::SmallVectorImpl< char > &path)
Resolve path to make it canonical.
static FileSystem & Instance()
lldb::pid_t GetProcessId() const
static bool GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &proc_info)
SignalHandleUP RegisterSignal(int signo, const Callback &callback, Status &error)
void SetMapped(OptionalBool val)
ConstString GetName() const
void SetReadable(OptionalBool val)
void SetExecutable(OptionalBool val)
void SetName(const char *name)
void SetWritable(OptionalBool val)
Abstract class that extends NativeProcessProtocol with ELF specific logic.
void NotifyDidExec() override
Notify the delegate that an exec occurred.
virtual void NewSubprocess(NativeProcessProtocol *parent_process, std::unique_ptr< NativeProcessProtocol > child_process)=0
lldb::pid_t GetID() const
Status SetSoftwareBreakpoint(lldb::addr_t addr, uint32_t size_hint)
void SetState(lldb::StateType state, bool notify_delegates=true)
NativeThreadProtocol * GetCurrentThread()
void SetCurrentThreadID(lldb::tid_t tid)
std::vector< std::unique_ptr< NativeThreadProtocol > > m_threads
virtual bool SetExitStatus(WaitStatus status, bool bNotifyStateChange)
virtual Status RemoveBreakpoint(lldb::addr_t addr, bool hardware=false)
NativeDelegate & m_delegate
void FixupBreakpointPCAsNeeded(NativeThreadProtocol &thread)
lldb::tid_t GetCurrentThreadID() const
Extension
Extension flag constants, returned by Manager::GetSupportedExtensions() and passed to SetEnabledExten...
virtual Status SetHardwareBreakpoint(lldb::addr_t addr, size_t size)
virtual llvm::Expected< llvm::ArrayRef< uint8_t > > GetSoftwareBreakpointTrapOpcode(size_t size_hint)
Extension m_enabled_extensions
std::unordered_map< lldb::addr_t, SoftwareBreakpoint > m_software_breakpoints
std::map< lldb::tid_t, lldb::addr_t > m_threads_stepping_with_breakpoint
lldb::tid_t GetID() const
PseudoTerminal & GetPTY()
HostProcess LaunchProcess(const ProcessLaunchInfo &launch_info, Status &error) override
int ReleasePrimaryFileDescriptor()
Release the primary file descriptor.
const ResumeAction * GetActionForThread(lldb::tid_t tid, bool default_ok) const
static Status FromErrno()
Set the current error to errno.
llvm::Error ToError() const
FIXME: Replace all uses with takeError() instead.
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
static Status FromErrorString(const char *str)
bool Fail() const
Test for error condition.
bool Success() const
Test for success condition.
llvm::Expected< std::unique_ptr< NativeProcessProtocol > > Launch(ProcessLaunchInfo &launch_info, NativeDelegate &native_delegate) override
Launch a process for debugging.
llvm::Expected< std::unique_ptr< NativeProcessProtocol > > Attach(lldb::pid_t pid, NativeDelegate &native_delegate) override
Attach to an existing process.
Extension GetSupportedExtensions() const override
Get the bitmask of extensions supported by this process plugin.
Manages communication with the inferior (debugee) process.
NativeThreadFreeBSD & AddThread(lldb::tid_t thread_id)
void MonitorCallback(lldb::pid_t pid, int signal)
void RemoveThread(lldb::tid_t thread_id)
void MonitorSIGSTOP(lldb::pid_t pid)
Status GetMemoryRegionInfo(lldb::addr_t load_addr, MemoryRegionInfo &range_info) override
void MonitorSignal(lldb::pid_t pid, int signal)
void MonitorSIGTRAP(lldb::pid_t pid)
MainLoop::SignalHandleUP m_sigchld_handle
Status Resume(const ResumeActionList &resume_actions) override
Status PopulateMemoryRegionCache()
llvm::Expected< std::string > SaveCore(llvm::StringRef path_hint) override
Write a core dump (without crashing the program).
Status GetFileLoadAddress(const llvm::StringRef &file_name, lldb::addr_t &load_addr) override
size_t UpdateThreads() override
LazyBool m_supports_mem_region
llvm::ErrorOr< std::unique_ptr< llvm::MemoryBuffer > > GetAuxvData() const override
const ArchSpec & GetArchitecture() const override
void MonitorClone(::pid_t child_pid, bool is_vfork, NativeThreadFreeBSD &parent_thread)
static Status PtraceWrapper(int req, lldb::pid_t pid, void *addr=nullptr, int data=0, int *result=nullptr)
Status Interrupt() override
Tells a process to interrupt all operations as if by a Ctrl-C.
Status ReinitializeThreads()
Status Signal(int signo) override
Sends a process a UNIX signal signal.
Status ReadMemory(lldb::addr_t addr, void *buf, size_t size, size_t &bytes_read) override
Status GetLoadedModuleFileSpec(const char *module_path, FileSpec &file_spec) override
llvm::Expected< llvm::ArrayRef< uint8_t > > GetSoftwareBreakpointTrapOpcode(size_t size_hint) override
void MonitorExited(lldb::pid_t pid, WaitStatus status)
NativeProcessFreeBSD(::pid_t pid, int terminal_fd, NativeDelegate &delegate, const ArchSpec &arch, MainLoop &mainloop)
bool HasThreadNoLock(lldb::tid_t thread_id)
std::vector< std::pair< MemoryRegionInfo, FileSpec > > m_mem_region_cache
Status WriteMemory(lldb::addr_t addr, const void *buf, size_t size, size_t &bytes_written) override
bool SupportHardwareSingleStepping() const
Status SetBreakpoint(lldb::addr_t addr, uint32_t size, bool hardware) override
void SetStoppedByVForkDone()
NativeRegisterContextFreeBSD & GetRegisterContext() override
llvm::Error CopyWatchpointsFrom(NativeThreadFreeBSD &source)
void SetStoppedWithNoReason()
void SetStoppedByVFork(lldb::pid_t child_pid, lldb::tid_t child_tid)
void SetStoppedByFork(lldb::pid_t child_pid, lldb::tid_t child_tid)
void SetStoppedBySignal(uint32_t signo, const siginfo_t *info=nullptr)
void SetStoppedByWatchpoint(uint32_t wp_index)
void SetStoppedByBreakpoint()
#define LLDB_INVALID_SIGNAL_NUMBER
#define LLDB_INVALID_INDEX32
#define UNUSED_IF_ASSERT_DISABLED(x)
#define LLDB_INVALID_ADDRESS
#define LLDB_INVALID_PROCESS_ID
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.
bool StateIsStoppedState(lldb::StateType state, bool must_exist)
Check if a state represents a state where the process or thread is stopped.
const char * StateAsCString(lldb::StateType state)
Converts a StateType to a C string.
@ 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.
@ eStateStepping
Process or thread is in the process of stepping and can not be examined.
@ eErrorTypePOSIX
POSIX error codes.
bool Contains(BaseType r) const
BaseType GetRangeBase() const
void SetRangeEnd(BaseType end)
void SetRangeBase(BaseType b)
Set the start value for the range, and keep the same size.
void SetByteSize(SizeType s)
static WaitStatus Decode(int wstatus)