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();
53llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
65 LLDB_LOG(log,
"failed to launch process: {0}", status);
71 ::pid_t wpid = llvm::sys::RetryAfterSignal(-1, ::waitpid, pid, &wstatus, 0);
74 if (!WIFSTOPPED(wstatus)) {
75 LLDB_LOG(log,
"Could not sync with inferior process: wstatus={1}",
77 return llvm::make_error<StringError>(
"Could not sync with inferior process",
78 llvm::inconvertibleErrorCode());
80 LLDB_LOG(log,
"inferior started, now in stopped state");
84 return llvm::make_error<StringError>(
"Cannot get process architecture",
85 llvm::inconvertibleErrorCode());
89 LLDB_LOG(log,
"pid = {0:x}, detected architecture {1}", pid,
90 Info.GetArchitecture().GetArchitectureName());
94 Info.GetArchitecture(), mainloop));
96 status = process_up->SetupTrace();
100 for (
const auto &thread : process_up->m_threads)
102 process_up->SetState(StateType::eStateStopped,
false);
104 return std::move(process_up);
107llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
117 return llvm::make_error<StringError>(
"Cannot get process architecture",
118 llvm::inconvertibleErrorCode());
122 pid, -1, native_delegate, Info.GetArchitecture(), mainloop));
124 Status status = process_up->Attach();
128 return std::move(process_up);
134#if defined(PT_COREDUMP)
176 LLDB_LOG(log,
"got exit signal({0}) , pid = {1}", status, pid);
184 SetState(StateType::eStateExited,
true);
193 SetState(StateType::eStateStopped,
true);
198 struct ptrace_lwpinfo info;
200 const auto siginfo_err =
PtraceWrapper(PT_LWPINFO, pid, &info,
sizeof(info));
201 if (siginfo_err.Fail()) {
202 LLDB_LOG(log,
"PT_LWPINFO failed {0}", siginfo_err);
205 assert(info.pl_event == PL_EVENT_SIGNAL);
207 LLDB_LOG(log,
"got SIGTRAP, pid = {0}, lwpid = {1}, flags = {2:x}", pid,
208 info.pl_lwpid, info.pl_flags);
211 if (info.pl_flags & (PL_FLAG_BORN | PL_FLAG_EXITED)) {
212 if (info.pl_flags & PL_FLAG_BORN) {
213 LLDB_LOG(log,
"monitoring new thread, tid = {0}", info.pl_lwpid);
229 "failed to copy watchpoints to new thread {1}: {0}",
235 LLDB_LOG(log,
"thread exited, tid = {0}", info.pl_lwpid);
240 PtraceWrapper(PT_CONTINUE, pid,
reinterpret_cast<void *
>(1), 0);
246 if (info.pl_flags & PL_FLAG_EXEC) {
259 SetState(StateType::eStateStopped,
true);
263 if (info.pl_lwpid > 0) {
265 if (t->GetID() ==
static_cast<lldb::tid_t>(info.pl_lwpid))
270 LLDB_LOG(log,
"thread not found in m_threads, pid = {0}, LWP = {1}", pid,
274 if (info.pl_flags & PL_FLAG_FORKED) {
276 MonitorClone(info.pl_child_pid, info.pl_flags & PL_FLAG_VFORKED, *thread);
280 if (info.pl_flags & PL_FLAG_VFORK_DONE) {
284 SetState(StateType::eStateStopped,
true);
287 PtraceWrapper(PT_CONTINUE, pid,
reinterpret_cast<void *
>(1), 0);
294 if (info.pl_flags & PL_FLAG_SI) {
295 assert(info.pl_siginfo.si_signo ==
SIGTRAP);
296 LLDB_LOG(log,
"SIGTRAP siginfo: si_code = {0}, pid = {1}",
297 info.pl_siginfo.si_code, info.pl_siginfo.si_pid);
299 switch (info.pl_siginfo.si_code) {
301 LLDB_LOG(log,
"SIGTRAP/TRAP_BRKPT: si_addr: {0}",
302 info.pl_siginfo.si_addr);
310 if (brkpt_error.
Fail())
311 LLDB_LOG(log,
"pid = {0} remove stepping breakpoint: {1}",
312 thread_info->first, brkpt_error);
319 SetState(StateType::eStateStopped,
true);
322 LLDB_LOG(log,
"SIGTRAP/TRAP_TRACE: si_addr: {0}",
323 info.pl_siginfo.si_addr);
330 wp_index,
reinterpret_cast<uintptr_t
>(info.pl_siginfo.si_addr));
333 "received error while checking for watchpoint hits, pid = "
334 "{0}, LWP = {1}, error = {2}",
335 pid, info.pl_lwpid,
error);
337 regctx.ClearWatchpointHit(wp_index);
340 SetState(StateType::eStateStopped,
true);
348 SetState(StateType::eStateStopped,
true);
355 LLDB_LOG(log,
"unknown SIGTRAP, passing to generic handler");
361 struct ptrace_lwpinfo info;
363 const auto siginfo_err =
PtraceWrapper(PT_LWPINFO, pid, &info,
sizeof(info));
364 if (siginfo_err.Fail()) {
365 LLDB_LOG(log,
"PT_LWPINFO failed {0}", siginfo_err);
368 assert(info.pl_event == PL_EVENT_SIGNAL);
370 assert(info.pl_flags & PL_FLAG_SI);
371 assert(info.pl_siginfo.si_signo == signal);
373 for (
const auto &abs_thread :
m_threads) {
376 assert(info.pl_lwpid >= 0);
377 if (info.pl_lwpid == 0 ||
384 SetState(StateType::eStateStopped,
true);
388 int data,
int *result) {
395 ptrace(req,
static_cast<::
pid_t>(pid),
static_cast<caddr_t
>(addr), data);
398 error.SetErrorToErrno();
403 LLDB_LOG(log,
"ptrace({0}, {1}, {2}, {3})={4:x}", req, pid, addr, data, ret);
411llvm::Expected<llvm::ArrayRef<uint8_t>>
413 static const uint8_t g_arm_opcode[] = {0xfe, 0xde, 0xff, 0xe7};
414 static const uint8_t g_thumb_opcode[] = {0x01, 0xde};
417 case llvm::Triple::arm:
420 return llvm::ArrayRef(g_thumb_opcode);
422 return llvm::ArrayRef(g_arm_opcode);
424 return llvm::createStringError(llvm::inconvertibleErrorCode(),
425 "Unrecognised trap opcode size hint!");
439 for (
const auto &abs_thread :
m_threads) {
440 assert(abs_thread &&
"thread list should not contain NULL threads");
451 if (action ==
nullptr) {
452 LLDB_LOG(log,
"no action specified for pid {0} tid {1}",
GetID(),
454 action = &suspend_action;
459 "processing resume action state {0} signal {1} for pid {2} tid {3}",
462 switch (action->
state) {
472 return Status(
"Passing signal to suspended thread unsupported");
479 "NativeProcessFreeBSD::%s (): unexpected state %s specified "
480 "for pid %" PRIu64
", tid %" PRIu64,
505 error.SetErrorToErrno();
525 if (kill(
GetID(), signo))
526 error.SetErrorToErrno();
540 case StateType::eStateInvalid:
541 case StateType::eStateExited:
542 case StateType::eStateCrashed:
543 case StateType::eStateDetached:
544 case StateType::eStateUnloaded:
546 LLDB_LOG(log,
"ignored for PID {0} due to current state: {1}",
GetID(),
550 case StateType::eStateConnected:
551 case StateType::eStateAttaching:
552 case StateType::eStateLaunching:
553 case StateType::eStateStopped:
554 case StateType::eStateRunning:
555 case StateType::eStateStepping:
556 case StateType::eStateSuspended:
569 return Status(
"unsupported");
586 "descending memory map entries detected, unexpected");
602 range_info = proc_entry_info;
625 LLDB_LOG(log,
"reusing {0} cached memory region entries",
630 int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_VMMAP,
static_cast<int>(
m_pid)};
634 ret = ::sysctl(mib, 4,
nullptr, &len,
nullptr, 0);
637 return Status(
"sysctl() for KERN_PROC_VMMAP failed");
640 std::unique_ptr<WritableMemoryBuffer> buf =
641 llvm::WritableMemoryBuffer::getNewMemBuffer(len);
642 ret = ::sysctl(mib, 4, buf->getBufferStart(), &len,
nullptr, 0);
645 return Status(
"sysctl() for KERN_PROC_VMMAP failed");
648 char *bp = buf->getBufferStart();
649 char *end = bp + len;
651 auto *kv =
reinterpret_cast<struct kinfo_vmentry *
>(bp);
652 if (kv->kve_structsize == 0)
654 bp += kv->kve_structsize;
662 if (kv->kve_protection & VM_PROT_READ)
667 if (kv->kve_protection & VM_PROT_WRITE)
672 if (kv->kve_protection & VM_PROT_EXECUTE)
687 LLDB_LOG(log,
"failed to find any vmmap entries, assuming no support "
688 "for memory region metadata retrieval");
690 return Status(
"not supported");
692 LLDB_LOG(log,
"read {0} memory region entries from process {1}",
715 FileSpec module_file_spec(module_path);
720 if (it.second.GetFilename() == module_file_spec.
GetFilename()) {
721 file_spec = it.second;
725 return Status(
"Module file (%s) not found in process' memory map!",
739 if (it.second == file) {
740 load_addr = it.first.GetRange().GetRangeBase();
744 return Status(
"No load address found for file %s.", file_name.str().c_str());
751 llvm::sys::RetryAfterSignal(-1, waitpid,
GetID(), &status, WNOHANG);
756 if (wait_pid == -1) {
768 "waitpid ({0}, &status, _) => pid = {1}, status = {2}, exited = {3}",
769 GetID(), wait_pid, status, exited);
781 assert(thread &&
"thread list should not contain NULL threads");
782 if (thread->GetID() == thread_id) {
794 LLDB_LOG(log,
"pid {0} adding thread with tid {1}",
GetID(), thread_id);
796 assert(thread_id > 0);
798 "attempted to add a thread by id that already exists");
804 m_threads.push_back(std::make_unique<NativeThreadFreeBSD>(*
this, thread_id));
810 LLDB_LOG(log,
"pid {0} removing thread with tid {1}",
GetID(), thread_id);
812 assert(thread_id > 0);
814 "attempted to remove a thread that does not exist");
817 if ((*it)->GetID() == thread_id) {
837 if ((wstatus = llvm::sys::RetryAfterSignal(-1, waitpid,
m_pid,
nullptr, 0)) <
852 SetState(StateType::eStateStopped,
false);
857 size_t size,
size_t &bytes_read) {
858 unsigned char *dst =
static_cast<unsigned char *
>(buf);
859 struct ptrace_io_desc io;
862 LLDB_LOG(log,
"addr = {0}, buf = {1}, size = {2}", addr, buf, size);
865 io.piod_op = PIOD_READ_D;
869 io.piod_offs = (
void *)(addr + bytes_read);
870 io.piod_addr = dst + bytes_read;
873 if (
error.Fail() || io.piod_len == 0)
876 bytes_read += io.piod_len;
877 io.piod_len = size - bytes_read;
878 }
while (bytes_read < size);
884 size_t size,
size_t &bytes_written) {
885 const unsigned char *src =
static_cast<const unsigned char *
>(buf);
887 struct ptrace_io_desc io;
890 LLDB_LOG(log,
"addr = {0}, buf = {1}, size = {2}", addr, buf, size);
893 io.piod_op = PIOD_WRITE_D;
898 const_cast<void *
>(
static_cast<const void *
>(src + bytes_written));
899 io.piod_offs = (
void *)(addr + bytes_written);
902 if (
error.Fail() || io.piod_len == 0)
905 bytes_written += io.piod_len;
906 io.piod_len = size - bytes_written;
907 }
while (bytes_written < size);
912llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
914 int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_AUXV,
static_cast<int>(
GetID())};
915 size_t auxv_size = AT_COUNT *
sizeof(Elf_Auxinfo);
916 std::unique_ptr<WritableMemoryBuffer> buf =
917 llvm::WritableMemoryBuffer::getNewMemBuffer(auxv_size);
919 if (::sysctl(mib, 4, buf->getBufferStart(), &auxv_size,
nullptr, 0) != 0)
920 return std::error_code(errno, std::generic_category());
932 events |= PTRACE_LWP | PTRACE_FORK | PTRACE_VFORK;
949 std::vector<lwpid_t> lwp_ids;
950 lwp_ids.resize(num_lwps);
952 lwp_ids.size() *
sizeof(lwpid_t), &num_lwps);
957 for (lwpid_t lwp : lwp_ids)
970 LLDB_LOG(log,
"fork, child_pid={0}", child_pid);
974 llvm::sys::RetryAfterSignal(-1, ::waitpid, child_pid, &status, 0);
975 if (wait_pid != child_pid) {
977 "waiting for pid {0} failed. Assuming the pid has "
978 "disappeared in the meantime",
982 if (WIFEXITED(status)) {
984 "waiting for pid {0} returned an 'exited' event. Not "
990 struct ptrace_lwpinfo info;
991 const auto siginfo_err =
PtraceWrapper(PT_LWPINFO, child_pid, &info,
sizeof(info));
992 if (siginfo_err.Fail()) {
993 LLDB_LOG(log,
"PT_LWPINFO failed {0}", siginfo_err);
996 assert(info.pl_event == PL_EVENT_SIGNAL);
999 std::unique_ptr<NativeProcessFreeBSD> child_process{
1007 child_process->SetupTrace();
1008 for (
const auto &thread : child_process->m_threads)
1010 child_process->SetState(StateType::eStateStopped,
false);
1017 SetState(StateType::eStateStopped,
true);
1019 child_process->Detach();
1022 if (pt_error.
Fail()) {
1024 "unable to resume parent process {1}: {0}",
GetID());
1025 SetState(StateType::eStateInvalid);
1030llvm::Expected<std::string>
1032#if defined(PT_COREDUMP)
1033 using namespace llvm::sys::fs;
1035 llvm::SmallString<128> path{path_hint};
1037 struct ptrace_coredump
pc = {};
1042 openFile(path,
pc.pc_fd, CD_CreateNew, FA_Write, OF_None)) {
1043 if (std::error_code errc =
1044 createTemporaryFile(
"lldb",
"core",
pc.pc_fd, path))
1045 return llvm::createStringError(errc,
"Unable to create a temporary file");
1049 std::error_code close_err = closeFile(
pc.pc_fd);
1051 return error.ToError();
1053 return llvm::createStringError(
1054 close_err,
"Unable to close the core dump after writing");
1055 return path.str().str();
1057 return llvm::createStringError(
1058 llvm::inconvertibleErrorCode(),
1059 "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 Factory::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.
Extension GetSupportedExtensions() const override
Get the bitmask of extensions supported by this process plugin.
llvm::Expected< std::unique_ptr< NativeProcessProtocol > > Attach(lldb::pid_t pid, NativeDelegate &native_delegate, MainLoop &mainloop) const override
Attach to an existing process.
llvm::Expected< std::unique_ptr< NativeProcessProtocol > > Launch(ProcessLaunchInfo &launch_info, NativeDelegate &native_delegate, MainLoop &mainloop) const override
Launch a process for debugging.
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)
void SetByteSize(SizeType s)
static WaitStatus Decode(int wstatus)