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);
39 error.SetErrorToErrno();
43 if (fcntl(fd, F_SETFL, status | flags) == -1) {
44 error.SetErrorToErrno();
53 size_t len =
sizeof(proc_debug);
54 ret = ::sysctlbyname(
"security.bsd.unprivileged_proc_debug", &proc_debug,
57 return Status(
"sysctlbyname() security.bsd.unprivileged_proc_debug failed");
61 "process debug disabled by security.bsd.unprivileged_proc_debug oid");
68llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
79 LLDB_LOG(log,
"failed to launch process: {0}", status);
82 return error.ToError();
88 ::pid_t wpid = llvm::sys::RetryAfterSignal(-1, ::waitpid, pid, &wstatus, 0);
91 if (!WIFSTOPPED(wstatus)) {
92 LLDB_LOG(log,
"Could not sync with inferior process: wstatus={1}",
94 return llvm::make_error<StringError>(
"Could not sync with inferior process",
95 llvm::inconvertibleErrorCode());
97 LLDB_LOG(log,
"inferior started, now in stopped state");
101 return llvm::make_error<StringError>(
"Cannot get process architecture",
102 llvm::inconvertibleErrorCode());
106 LLDB_LOG(log,
"pid = {0:x}, detected architecture {1}", pid,
107 Info.GetArchitecture().GetArchitectureName());
113 status = process_up->SetupTrace();
117 for (
const auto &thread : process_up->m_threads)
119 process_up->SetState(StateType::eStateStopped,
false);
121 return std::move(process_up);
124llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
133 return llvm::make_error<StringError>(
"Cannot get process architecture",
134 llvm::inconvertibleErrorCode());
138 pid, -1, native_delegate, Info.GetArchitecture(), m_mainloop));
140 Status status = process_up->Attach();
144 return std::move(process_up);
150#if defined(PT_COREDUMP)
192 LLDB_LOG(log,
"got exit signal({0}) , pid = {1}", status, pid);
200 SetState(StateType::eStateExited,
true);
209 SetState(StateType::eStateStopped,
true);
214 struct ptrace_lwpinfo info;
216 const auto siginfo_err =
PtraceWrapper(PT_LWPINFO, pid, &info,
sizeof(info));
217 if (siginfo_err.Fail()) {
218 LLDB_LOG(log,
"PT_LWPINFO failed {0}", siginfo_err);
221 assert(info.pl_event == PL_EVENT_SIGNAL);
223 LLDB_LOG(log,
"got SIGTRAP, pid = {0}, lwpid = {1}, flags = {2:x}", pid,
224 info.pl_lwpid, info.pl_flags);
227 if (info.pl_flags & (PL_FLAG_BORN | PL_FLAG_EXITED)) {
228 if (info.pl_flags & PL_FLAG_BORN) {
229 LLDB_LOG(log,
"monitoring new thread, tid = {0}", info.pl_lwpid);
245 "failed to copy watchpoints to new thread {1}: {0}",
251 LLDB_LOG(log,
"thread exited, tid = {0}", info.pl_lwpid);
256 PtraceWrapper(PT_CONTINUE, pid,
reinterpret_cast<void *
>(1), 0);
262 if (info.pl_flags & PL_FLAG_EXEC) {
275 SetState(StateType::eStateStopped,
true);
279 if (info.pl_lwpid > 0) {
281 if (t->GetID() ==
static_cast<lldb::tid_t>(info.pl_lwpid))
286 LLDB_LOG(log,
"thread not found in m_threads, pid = {0}, LWP = {1}", pid,
290 if (info.pl_flags & PL_FLAG_FORKED) {
292 MonitorClone(info.pl_child_pid, info.pl_flags & PL_FLAG_VFORKED, *thread);
296 if (info.pl_flags & PL_FLAG_VFORK_DONE) {
300 SetState(StateType::eStateStopped,
true);
303 PtraceWrapper(PT_CONTINUE, pid,
reinterpret_cast<void *
>(1), 0);
310 if (info.pl_flags & PL_FLAG_SI) {
311 assert(info.pl_siginfo.si_signo ==
SIGTRAP);
312 LLDB_LOG(log,
"SIGTRAP siginfo: si_code = {0}, pid = {1}",
313 info.pl_siginfo.si_code, info.pl_siginfo.si_pid);
315 switch (info.pl_siginfo.si_code) {
317 LLDB_LOG(log,
"SIGTRAP/TRAP_BRKPT: si_addr: {0}",
318 info.pl_siginfo.si_addr);
326 if (brkpt_error.
Fail())
327 LLDB_LOG(log,
"pid = {0} remove stepping breakpoint: {1}",
328 thread_info->first, brkpt_error);
335 SetState(StateType::eStateStopped,
true);
338 LLDB_LOG(log,
"SIGTRAP/TRAP_TRACE: si_addr: {0}",
339 info.pl_siginfo.si_addr);
346 wp_index,
reinterpret_cast<uintptr_t
>(info.pl_siginfo.si_addr));
349 "received error while checking for watchpoint hits, pid = "
350 "{0}, LWP = {1}, error = {2}",
351 pid, info.pl_lwpid,
error);
353 regctx.ClearWatchpointHit(wp_index);
356 SetState(StateType::eStateStopped,
true);
364 SetState(StateType::eStateStopped,
true);
371 LLDB_LOG(log,
"unknown SIGTRAP, passing to generic handler");
377 struct ptrace_lwpinfo info;
379 const auto siginfo_err =
PtraceWrapper(PT_LWPINFO, pid, &info,
sizeof(info));
380 if (siginfo_err.Fail()) {
381 LLDB_LOG(log,
"PT_LWPINFO failed {0}", siginfo_err);
384 assert(info.pl_event == PL_EVENT_SIGNAL);
386 assert(info.pl_flags & PL_FLAG_SI);
387 assert(info.pl_siginfo.si_signo == signal);
389 for (
const auto &abs_thread :
m_threads) {
392 assert(info.pl_lwpid >= 0);
393 if (info.pl_lwpid == 0 ||
400 SetState(StateType::eStateStopped,
true);
404 int data,
int *result) {
411 ptrace(req,
static_cast<::
pid_t>(pid),
static_cast<caddr_t
>(addr), data);
416 error.SetErrorToErrno();
422 LLDB_LOG(log,
"ptrace({0}, {1}, {2}, {3})={4:x}", req, pid, addr, data, ret);
430llvm::Expected<llvm::ArrayRef<uint8_t>>
432 static const uint8_t g_arm_opcode[] = {0xfe, 0xde, 0xff, 0xe7};
433 static const uint8_t g_thumb_opcode[] = {0x01, 0xde};
436 case llvm::Triple::arm:
439 return llvm::ArrayRef(g_thumb_opcode);
441 return llvm::ArrayRef(g_arm_opcode);
443 return llvm::createStringError(llvm::inconvertibleErrorCode(),
444 "Unrecognised trap opcode size hint!");
458 for (
const auto &abs_thread :
m_threads) {
459 assert(abs_thread &&
"thread list should not contain NULL threads");
470 if (action ==
nullptr) {
471 LLDB_LOG(log,
"no action specified for pid {0} tid {1}",
GetID(),
473 action = &suspend_action;
478 "processing resume action state {0} signal {1} for pid {2} tid {3}",
481 switch (action->
state) {
491 return Status(
"Passing signal to suspended thread unsupported");
498 "NativeProcessFreeBSD::%s (): unexpected state %s specified "
499 "for pid %" PRIu64
", tid %" PRIu64,
524 error.SetErrorToErrno();
544 if (kill(
GetID(), signo))
545 error.SetErrorToErrno();
559 case StateType::eStateInvalid:
560 case StateType::eStateExited:
561 case StateType::eStateCrashed:
562 case StateType::eStateDetached:
563 case StateType::eStateUnloaded:
565 LLDB_LOG(log,
"ignored for PID {0} due to current state: {1}",
GetID(),
569 case StateType::eStateConnected:
570 case StateType::eStateAttaching:
571 case StateType::eStateLaunching:
572 case StateType::eStateStopped:
573 case StateType::eStateRunning:
574 case StateType::eStateStepping:
575 case StateType::eStateSuspended:
588 return Status(
"unsupported");
605 "descending memory map entries detected, unexpected");
621 range_info = proc_entry_info;
644 LLDB_LOG(log,
"reusing {0} cached memory region entries",
649 int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_VMMAP,
static_cast<int>(
m_pid)};
653 ret = ::sysctl(mib, 4,
nullptr, &len,
nullptr, 0);
656 return Status(
"sysctl() for KERN_PROC_VMMAP failed");
659 std::unique_ptr<WritableMemoryBuffer> buf =
660 llvm::WritableMemoryBuffer::getNewMemBuffer(len);
661 ret = ::sysctl(mib, 4, buf->getBufferStart(), &len,
nullptr, 0);
664 return Status(
"sysctl() for KERN_PROC_VMMAP failed");
667 char *bp = buf->getBufferStart();
668 char *end = bp + len;
670 auto *kv =
reinterpret_cast<struct kinfo_vmentry *
>(bp);
671 if (kv->kve_structsize == 0)
673 bp += kv->kve_structsize;
681 if (kv->kve_protection & VM_PROT_READ)
686 if (kv->kve_protection & VM_PROT_WRITE)
691 if (kv->kve_protection & VM_PROT_EXECUTE)
706 LLDB_LOG(log,
"failed to find any vmmap entries, assuming no support "
707 "for memory region metadata retrieval");
709 return Status(
"not supported");
711 LLDB_LOG(log,
"read {0} memory region entries from process {1}",
738 FileSpec module_file_spec(module_path);
743 if (it.second.GetFilename() == module_file_spec.
GetFilename()) {
744 file_spec = it.second;
748 return Status(
"Module file (%s) not found in process' memory map!",
766 if (it.second == file) {
767 load_addr = it.first.GetRange().GetRangeBase();
771 return Status(
"No load address found for file %s.", file_name.str().c_str());
778 llvm::sys::RetryAfterSignal(-1, waitpid,
GetID(), &status, WNOHANG);
783 if (wait_pid == -1) {
795 "waitpid ({0}, &status, _) => pid = {1}, status = {2}, exited = {3}",
796 GetID(), wait_pid, status, exited);
808 assert(thread &&
"thread list should not contain NULL threads");
809 if (thread->GetID() == thread_id) {
821 LLDB_LOG(log,
"pid {0} adding thread with tid {1}",
GetID(), thread_id);
823 assert(thread_id > 0);
825 "attempted to add a thread by id that already exists");
831 m_threads.push_back(std::make_unique<NativeThreadFreeBSD>(*
this, thread_id));
837 LLDB_LOG(log,
"pid {0} removing thread with tid {1}",
GetID(), thread_id);
839 assert(thread_id > 0);
841 "attempted to remove a thread that does not exist");
844 if ((*it)->GetID() == thread_id) {
864 if ((wstatus = llvm::sys::RetryAfterSignal(-1, waitpid,
m_pid,
nullptr, 0)) <
879 SetState(StateType::eStateStopped,
false);
884 size_t size,
size_t &bytes_read) {
885 unsigned char *dst =
static_cast<unsigned char *
>(buf);
886 struct ptrace_io_desc io;
889 LLDB_LOG(log,
"addr = {0}, buf = {1}, size = {2}", addr, buf, size);
892 io.piod_op = PIOD_READ_D;
896 io.piod_offs = (
void *)(addr + bytes_read);
897 io.piod_addr = dst + bytes_read;
900 if (
error.Fail() || io.piod_len == 0)
903 bytes_read += io.piod_len;
904 io.piod_len = size - bytes_read;
905 }
while (bytes_read < size);
911 size_t size,
size_t &bytes_written) {
912 const unsigned char *src =
static_cast<const unsigned char *
>(buf);
914 struct ptrace_io_desc io;
917 LLDB_LOG(log,
"addr = {0}, buf = {1}, size = {2}", addr, buf, size);
920 io.piod_op = PIOD_WRITE_D;
925 const_cast<void *
>(
static_cast<const void *
>(src + bytes_written));
926 io.piod_offs = (
void *)(addr + bytes_written);
929 if (
error.Fail() || io.piod_len == 0)
932 bytes_written += io.piod_len;
933 io.piod_len = size - bytes_written;
934 }
while (bytes_written < size);
939llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
941 int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_AUXV,
static_cast<int>(
GetID())};
942 size_t auxv_size = AT_COUNT *
sizeof(Elf_Auxinfo);
943 std::unique_ptr<WritableMemoryBuffer> buf =
944 llvm::WritableMemoryBuffer::getNewMemBuffer(auxv_size);
946 if (::sysctl(mib, 4, buf->getBufferStart(), &auxv_size,
nullptr, 0) != 0)
947 return std::error_code(errno, std::generic_category());
959 events |= PTRACE_LWP | PTRACE_FORK | PTRACE_VFORK;
976 std::vector<lwpid_t> lwp_ids;
977 lwp_ids.resize(num_lwps);
979 lwp_ids.size() *
sizeof(lwpid_t), &num_lwps);
984 for (lwpid_t lwp : lwp_ids)
997 LLDB_LOG(log,
"fork, child_pid={0}", child_pid);
1001 llvm::sys::RetryAfterSignal(-1, ::waitpid, child_pid, &status, 0);
1002 if (wait_pid != child_pid) {
1004 "waiting for pid {0} failed. Assuming the pid has "
1005 "disappeared in the meantime",
1009 if (WIFEXITED(status)) {
1011 "waiting for pid {0} returned an 'exited' event. Not "
1017 struct ptrace_lwpinfo info;
1018 const auto siginfo_err =
PtraceWrapper(PT_LWPINFO, child_pid, &info,
sizeof(info));
1019 if (siginfo_err.Fail()) {
1020 LLDB_LOG(log,
"PT_LWPINFO failed {0}", siginfo_err);
1023 assert(info.pl_event == PL_EVENT_SIGNAL);
1026 std::unique_ptr<NativeProcessFreeBSD> child_process{
1034 child_process->SetupTrace();
1035 for (
const auto &thread : child_process->m_threads)
1037 child_process->SetState(StateType::eStateStopped,
false);
1044 SetState(StateType::eStateStopped,
true);
1046 child_process->Detach();
1049 if (pt_error.
Fail()) {
1051 "unable to resume parent process {1}: {0}",
GetID());
1052 SetState(StateType::eStateInvalid);
1057llvm::Expected<std::string>
1059#if defined(PT_COREDUMP)
1060 using namespace llvm::sys::fs;
1062 llvm::SmallString<128> path{path_hint};
1064 struct ptrace_coredump
pc = {};
1069 openFile(path,
pc.pc_fd, CD_CreateNew, FA_Write, OF_None)) {
1070 if (std::error_code errc =
1071 createTemporaryFile(
"lldb",
"core",
pc.pc_fd, path))
1072 return llvm::createStringError(errc,
"Unable to create a temporary file");
1076 std::error_code close_err = closeFile(
pc.pc_fd);
1078 return error.ToError();
1080 return llvm::createStringError(
1081 close_err,
"Unable to close the core dump after writing");
1082 return path.str().str();
1084 return llvm::createStringError(
1085 llvm::inconvertibleErrorCode(),
1086 "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
llvm::Error ToError() const
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)