1*be691f3bSpatrick //===-- NativeProcessFreeBSD.cpp ------------------------------------------===// 2*be691f3bSpatrick // 3*be691f3bSpatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*be691f3bSpatrick // See https://llvm.org/LICENSE.txt for license information. 5*be691f3bSpatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*be691f3bSpatrick // 7*be691f3bSpatrick //===----------------------------------------------------------------------===// 8*be691f3bSpatrick 9*be691f3bSpatrick #include "NativeProcessFreeBSD.h" 10*be691f3bSpatrick 11*be691f3bSpatrick // clang-format off 12*be691f3bSpatrick #include <sys/types.h> 13*be691f3bSpatrick #include <sys/ptrace.h> 14*be691f3bSpatrick #include <sys/sysctl.h> 15*be691f3bSpatrick #include <sys/user.h> 16*be691f3bSpatrick #include <sys/wait.h> 17*be691f3bSpatrick #include <machine/elf.h> 18*be691f3bSpatrick // clang-format on 19*be691f3bSpatrick 20*be691f3bSpatrick #include "Plugins/Process/POSIX/ProcessPOSIXLog.h" 21*be691f3bSpatrick #include "lldb/Host/HostProcess.h" 22*be691f3bSpatrick #include "lldb/Host/posix/ProcessLauncherPosixFork.h" 23*be691f3bSpatrick #include "lldb/Target/Process.h" 24*be691f3bSpatrick #include "lldb/Utility/State.h" 25*be691f3bSpatrick #include "llvm/Support/Errno.h" 26*be691f3bSpatrick 27*be691f3bSpatrick using namespace lldb; 28*be691f3bSpatrick using namespace lldb_private; 29*be691f3bSpatrick using namespace lldb_private::process_freebsd; 30*be691f3bSpatrick using namespace llvm; 31*be691f3bSpatrick 32*be691f3bSpatrick // Simple helper function to ensure flags are enabled on the given file 33*be691f3bSpatrick // descriptor. 34*be691f3bSpatrick static Status EnsureFDFlags(int fd, int flags) { 35*be691f3bSpatrick Status error; 36*be691f3bSpatrick 37*be691f3bSpatrick int status = fcntl(fd, F_GETFL); 38*be691f3bSpatrick if (status == -1) { 39*be691f3bSpatrick error.SetErrorToErrno(); 40*be691f3bSpatrick return error; 41*be691f3bSpatrick } 42*be691f3bSpatrick 43*be691f3bSpatrick if (fcntl(fd, F_SETFL, status | flags) == -1) { 44*be691f3bSpatrick error.SetErrorToErrno(); 45*be691f3bSpatrick return error; 46*be691f3bSpatrick } 47*be691f3bSpatrick 48*be691f3bSpatrick return error; 49*be691f3bSpatrick } 50*be691f3bSpatrick 51*be691f3bSpatrick // Public Static Methods 52*be691f3bSpatrick 53*be691f3bSpatrick llvm::Expected<std::unique_ptr<NativeProcessProtocol>> 54*be691f3bSpatrick NativeProcessFreeBSD::Factory::Launch(ProcessLaunchInfo &launch_info, 55*be691f3bSpatrick NativeDelegate &native_delegate, 56*be691f3bSpatrick MainLoop &mainloop) const { 57*be691f3bSpatrick Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); 58*be691f3bSpatrick 59*be691f3bSpatrick Status status; 60*be691f3bSpatrick ::pid_t pid = ProcessLauncherPosixFork() 61*be691f3bSpatrick .LaunchProcess(launch_info, status) 62*be691f3bSpatrick .GetProcessId(); 63*be691f3bSpatrick LLDB_LOG(log, "pid = {0:x}", pid); 64*be691f3bSpatrick if (status.Fail()) { 65*be691f3bSpatrick LLDB_LOG(log, "failed to launch process: {0}", status); 66*be691f3bSpatrick return status.ToError(); 67*be691f3bSpatrick } 68*be691f3bSpatrick 69*be691f3bSpatrick // Wait for the child process to trap on its call to execve. 70*be691f3bSpatrick int wstatus; 71*be691f3bSpatrick ::pid_t wpid = llvm::sys::RetryAfterSignal(-1, ::waitpid, pid, &wstatus, 0); 72*be691f3bSpatrick assert(wpid == pid); 73*be691f3bSpatrick (void)wpid; 74*be691f3bSpatrick if (!WIFSTOPPED(wstatus)) { 75*be691f3bSpatrick LLDB_LOG(log, "Could not sync with inferior process: wstatus={1}", 76*be691f3bSpatrick WaitStatus::Decode(wstatus)); 77*be691f3bSpatrick return llvm::make_error<StringError>("Could not sync with inferior process", 78*be691f3bSpatrick llvm::inconvertibleErrorCode()); 79*be691f3bSpatrick } 80*be691f3bSpatrick LLDB_LOG(log, "inferior started, now in stopped state"); 81*be691f3bSpatrick 82*be691f3bSpatrick ProcessInstanceInfo Info; 83*be691f3bSpatrick if (!Host::GetProcessInfo(pid, Info)) { 84*be691f3bSpatrick return llvm::make_error<StringError>("Cannot get process architecture", 85*be691f3bSpatrick llvm::inconvertibleErrorCode()); 86*be691f3bSpatrick } 87*be691f3bSpatrick 88*be691f3bSpatrick // Set the architecture to the exe architecture. 89*be691f3bSpatrick LLDB_LOG(log, "pid = {0:x}, detected architecture {1}", pid, 90*be691f3bSpatrick Info.GetArchitecture().GetArchitectureName()); 91*be691f3bSpatrick 92*be691f3bSpatrick std::unique_ptr<NativeProcessFreeBSD> process_up(new NativeProcessFreeBSD( 93*be691f3bSpatrick pid, launch_info.GetPTY().ReleasePrimaryFileDescriptor(), native_delegate, 94*be691f3bSpatrick Info.GetArchitecture(), mainloop)); 95*be691f3bSpatrick 96*be691f3bSpatrick status = process_up->SetupTrace(); 97*be691f3bSpatrick if (status.Fail()) 98*be691f3bSpatrick return status.ToError(); 99*be691f3bSpatrick 100*be691f3bSpatrick for (const auto &thread : process_up->m_threads) 101*be691f3bSpatrick static_cast<NativeThreadFreeBSD &>(*thread).SetStoppedBySignal(SIGSTOP); 102*be691f3bSpatrick process_up->SetState(StateType::eStateStopped, false); 103*be691f3bSpatrick 104*be691f3bSpatrick return std::move(process_up); 105*be691f3bSpatrick } 106*be691f3bSpatrick 107*be691f3bSpatrick llvm::Expected<std::unique_ptr<NativeProcessProtocol>> 108*be691f3bSpatrick NativeProcessFreeBSD::Factory::Attach( 109*be691f3bSpatrick lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &native_delegate, 110*be691f3bSpatrick MainLoop &mainloop) const { 111*be691f3bSpatrick Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); 112*be691f3bSpatrick LLDB_LOG(log, "pid = {0:x}", pid); 113*be691f3bSpatrick 114*be691f3bSpatrick // Retrieve the architecture for the running process. 115*be691f3bSpatrick ProcessInstanceInfo Info; 116*be691f3bSpatrick if (!Host::GetProcessInfo(pid, Info)) { 117*be691f3bSpatrick return llvm::make_error<StringError>("Cannot get process architecture", 118*be691f3bSpatrick llvm::inconvertibleErrorCode()); 119*be691f3bSpatrick } 120*be691f3bSpatrick 121*be691f3bSpatrick std::unique_ptr<NativeProcessFreeBSD> process_up(new NativeProcessFreeBSD( 122*be691f3bSpatrick pid, -1, native_delegate, Info.GetArchitecture(), mainloop)); 123*be691f3bSpatrick 124*be691f3bSpatrick Status status = process_up->Attach(); 125*be691f3bSpatrick if (!status.Success()) 126*be691f3bSpatrick return status.ToError(); 127*be691f3bSpatrick 128*be691f3bSpatrick return std::move(process_up); 129*be691f3bSpatrick } 130*be691f3bSpatrick 131*be691f3bSpatrick NativeProcessFreeBSD::Extension 132*be691f3bSpatrick NativeProcessFreeBSD::Factory::GetSupportedExtensions() const { 133*be691f3bSpatrick return Extension::multiprocess | Extension::fork | Extension::vfork | 134*be691f3bSpatrick Extension::pass_signals | Extension::auxv | Extension::libraries_svr4; 135*be691f3bSpatrick } 136*be691f3bSpatrick 137*be691f3bSpatrick // Public Instance Methods 138*be691f3bSpatrick 139*be691f3bSpatrick NativeProcessFreeBSD::NativeProcessFreeBSD(::pid_t pid, int terminal_fd, 140*be691f3bSpatrick NativeDelegate &delegate, 141*be691f3bSpatrick const ArchSpec &arch, 142*be691f3bSpatrick MainLoop &mainloop) 143*be691f3bSpatrick : NativeProcessELF(pid, terminal_fd, delegate), m_arch(arch), 144*be691f3bSpatrick m_main_loop(mainloop) { 145*be691f3bSpatrick if (m_terminal_fd != -1) { 146*be691f3bSpatrick Status status = EnsureFDFlags(m_terminal_fd, O_NONBLOCK); 147*be691f3bSpatrick assert(status.Success()); 148*be691f3bSpatrick } 149*be691f3bSpatrick 150*be691f3bSpatrick Status status; 151*be691f3bSpatrick m_sigchld_handle = mainloop.RegisterSignal( 152*be691f3bSpatrick SIGCHLD, [this](MainLoopBase &) { SigchldHandler(); }, status); 153*be691f3bSpatrick assert(m_sigchld_handle && status.Success()); 154*be691f3bSpatrick } 155*be691f3bSpatrick 156*be691f3bSpatrick // Handles all waitpid events from the inferior process. 157*be691f3bSpatrick void NativeProcessFreeBSD::MonitorCallback(lldb::pid_t pid, int signal) { 158*be691f3bSpatrick switch (signal) { 159*be691f3bSpatrick case SIGTRAP: 160*be691f3bSpatrick return MonitorSIGTRAP(pid); 161*be691f3bSpatrick case SIGSTOP: 162*be691f3bSpatrick return MonitorSIGSTOP(pid); 163*be691f3bSpatrick default: 164*be691f3bSpatrick return MonitorSignal(pid, signal); 165*be691f3bSpatrick } 166*be691f3bSpatrick } 167*be691f3bSpatrick 168*be691f3bSpatrick void NativeProcessFreeBSD::MonitorExited(lldb::pid_t pid, WaitStatus status) { 169*be691f3bSpatrick Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); 170*be691f3bSpatrick 171*be691f3bSpatrick LLDB_LOG(log, "got exit signal({0}) , pid = {1}", status, pid); 172*be691f3bSpatrick 173*be691f3bSpatrick /* Stop Tracking All Threads attached to Process */ 174*be691f3bSpatrick m_threads.clear(); 175*be691f3bSpatrick 176*be691f3bSpatrick SetExitStatus(status, true); 177*be691f3bSpatrick 178*be691f3bSpatrick // Notify delegate that our process has exited. 179*be691f3bSpatrick SetState(StateType::eStateExited, true); 180*be691f3bSpatrick } 181*be691f3bSpatrick 182*be691f3bSpatrick void NativeProcessFreeBSD::MonitorSIGSTOP(lldb::pid_t pid) { 183*be691f3bSpatrick /* Stop all Threads attached to Process */ 184*be691f3bSpatrick for (const auto &thread : m_threads) { 185*be691f3bSpatrick static_cast<NativeThreadFreeBSD &>(*thread).SetStoppedBySignal(SIGSTOP, 186*be691f3bSpatrick nullptr); 187*be691f3bSpatrick } 188*be691f3bSpatrick SetState(StateType::eStateStopped, true); 189*be691f3bSpatrick } 190*be691f3bSpatrick 191*be691f3bSpatrick void NativeProcessFreeBSD::MonitorSIGTRAP(lldb::pid_t pid) { 192*be691f3bSpatrick Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); 193*be691f3bSpatrick struct ptrace_lwpinfo info; 194*be691f3bSpatrick 195*be691f3bSpatrick const auto siginfo_err = PtraceWrapper(PT_LWPINFO, pid, &info, sizeof(info)); 196*be691f3bSpatrick if (siginfo_err.Fail()) { 197*be691f3bSpatrick LLDB_LOG(log, "PT_LWPINFO failed {0}", siginfo_err); 198*be691f3bSpatrick return; 199*be691f3bSpatrick } 200*be691f3bSpatrick assert(info.pl_event == PL_EVENT_SIGNAL); 201*be691f3bSpatrick 202*be691f3bSpatrick LLDB_LOG(log, "got SIGTRAP, pid = {0}, lwpid = {1}, flags = {2:x}", pid, 203*be691f3bSpatrick info.pl_lwpid, info.pl_flags); 204*be691f3bSpatrick NativeThreadFreeBSD *thread = nullptr; 205*be691f3bSpatrick 206*be691f3bSpatrick if (info.pl_flags & (PL_FLAG_BORN | PL_FLAG_EXITED)) { 207*be691f3bSpatrick if (info.pl_flags & PL_FLAG_BORN) { 208*be691f3bSpatrick LLDB_LOG(log, "monitoring new thread, tid = {0}", info.pl_lwpid); 209*be691f3bSpatrick NativeThreadFreeBSD &t = AddThread(info.pl_lwpid); 210*be691f3bSpatrick 211*be691f3bSpatrick // Technically, the FreeBSD kernel copies the debug registers to new 212*be691f3bSpatrick // threads. However, there is a non-negligible delay between acquiring 213*be691f3bSpatrick // the DR values and reporting the new thread during which the user may 214*be691f3bSpatrick // establish a new watchpoint. In order to ensure that watchpoints 215*be691f3bSpatrick // established during this period are propagated to new threads, 216*be691f3bSpatrick // explicitly copy the DR value at the time the new thread is reported. 217*be691f3bSpatrick // 218*be691f3bSpatrick // See also: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=250954 219*be691f3bSpatrick 220*be691f3bSpatrick llvm::Error error = t.CopyWatchpointsFrom( 221*be691f3bSpatrick static_cast<NativeThreadFreeBSD &>(*GetCurrentThread())); 222*be691f3bSpatrick if (error) { 223*be691f3bSpatrick LLDB_LOG_ERROR(log, std::move(error), 224*be691f3bSpatrick "failed to copy watchpoints to new thread {1}: {0}", 225*be691f3bSpatrick info.pl_lwpid); 226*be691f3bSpatrick SetState(StateType::eStateInvalid); 227*be691f3bSpatrick return; 228*be691f3bSpatrick } 229*be691f3bSpatrick } else /*if (info.pl_flags & PL_FLAG_EXITED)*/ { 230*be691f3bSpatrick LLDB_LOG(log, "thread exited, tid = {0}", info.pl_lwpid); 231*be691f3bSpatrick RemoveThread(info.pl_lwpid); 232*be691f3bSpatrick } 233*be691f3bSpatrick 234*be691f3bSpatrick Status error = 235*be691f3bSpatrick PtraceWrapper(PT_CONTINUE, pid, reinterpret_cast<void *>(1), 0); 236*be691f3bSpatrick if (error.Fail()) 237*be691f3bSpatrick SetState(StateType::eStateInvalid); 238*be691f3bSpatrick return; 239*be691f3bSpatrick } 240*be691f3bSpatrick 241*be691f3bSpatrick if (info.pl_flags & PL_FLAG_EXEC) { 242*be691f3bSpatrick Status error = ReinitializeThreads(); 243*be691f3bSpatrick if (error.Fail()) { 244*be691f3bSpatrick SetState(StateType::eStateInvalid); 245*be691f3bSpatrick return; 246*be691f3bSpatrick } 247*be691f3bSpatrick 248*be691f3bSpatrick // Let our delegate know we have just exec'd. 249*be691f3bSpatrick NotifyDidExec(); 250*be691f3bSpatrick 251*be691f3bSpatrick for (const auto &thread : m_threads) 252*be691f3bSpatrick static_cast<NativeThreadFreeBSD &>(*thread).SetStoppedByExec(); 253*be691f3bSpatrick SetState(StateType::eStateStopped, true); 254*be691f3bSpatrick return; 255*be691f3bSpatrick } 256*be691f3bSpatrick 257*be691f3bSpatrick if (info.pl_lwpid > 0) { 258*be691f3bSpatrick for (const auto &t : m_threads) { 259*be691f3bSpatrick if (t->GetID() == static_cast<lldb::tid_t>(info.pl_lwpid)) 260*be691f3bSpatrick thread = static_cast<NativeThreadFreeBSD *>(t.get()); 261*be691f3bSpatrick static_cast<NativeThreadFreeBSD *>(t.get())->SetStoppedWithNoReason(); 262*be691f3bSpatrick } 263*be691f3bSpatrick if (!thread) 264*be691f3bSpatrick LLDB_LOG(log, "thread not found in m_threads, pid = {0}, LWP = {1}", pid, 265*be691f3bSpatrick info.pl_lwpid); 266*be691f3bSpatrick } 267*be691f3bSpatrick 268*be691f3bSpatrick if (info.pl_flags & PL_FLAG_FORKED) { 269*be691f3bSpatrick assert(thread); 270*be691f3bSpatrick MonitorClone(info.pl_child_pid, info.pl_flags & PL_FLAG_VFORKED, *thread); 271*be691f3bSpatrick return; 272*be691f3bSpatrick } 273*be691f3bSpatrick 274*be691f3bSpatrick if (info.pl_flags & PL_FLAG_VFORK_DONE) { 275*be691f3bSpatrick assert(thread); 276*be691f3bSpatrick if ((m_enabled_extensions & Extension::vfork) == Extension::vfork) { 277*be691f3bSpatrick thread->SetStoppedByVForkDone(); 278*be691f3bSpatrick SetState(StateType::eStateStopped, true); 279*be691f3bSpatrick } else { 280*be691f3bSpatrick Status error = 281*be691f3bSpatrick PtraceWrapper(PT_CONTINUE, pid, reinterpret_cast<void *>(1), 0); 282*be691f3bSpatrick if (error.Fail()) 283*be691f3bSpatrick SetState(StateType::eStateInvalid); 284*be691f3bSpatrick } 285*be691f3bSpatrick return; 286*be691f3bSpatrick } 287*be691f3bSpatrick 288*be691f3bSpatrick if (info.pl_flags & PL_FLAG_SI) { 289*be691f3bSpatrick assert(info.pl_siginfo.si_signo == SIGTRAP); 290*be691f3bSpatrick LLDB_LOG(log, "SIGTRAP siginfo: si_code = {0}, pid = {1}", 291*be691f3bSpatrick info.pl_siginfo.si_code, info.pl_siginfo.si_pid); 292*be691f3bSpatrick 293*be691f3bSpatrick switch (info.pl_siginfo.si_code) { 294*be691f3bSpatrick case TRAP_BRKPT: 295*be691f3bSpatrick LLDB_LOG(log, "SIGTRAP/TRAP_BRKPT: si_addr: {0}", 296*be691f3bSpatrick info.pl_siginfo.si_addr); 297*be691f3bSpatrick 298*be691f3bSpatrick if (thread) { 299*be691f3bSpatrick auto thread_info = 300*be691f3bSpatrick m_threads_stepping_with_breakpoint.find(thread->GetID()); 301*be691f3bSpatrick if (thread_info != m_threads_stepping_with_breakpoint.end()) { 302*be691f3bSpatrick thread->SetStoppedByTrace(); 303*be691f3bSpatrick Status brkpt_error = RemoveBreakpoint(thread_info->second); 304*be691f3bSpatrick if (brkpt_error.Fail()) 305*be691f3bSpatrick LLDB_LOG(log, "pid = {0} remove stepping breakpoint: {1}", 306*be691f3bSpatrick thread_info->first, brkpt_error); 307*be691f3bSpatrick m_threads_stepping_with_breakpoint.erase(thread_info); 308*be691f3bSpatrick } else 309*be691f3bSpatrick thread->SetStoppedByBreakpoint(); 310*be691f3bSpatrick FixupBreakpointPCAsNeeded(*thread); 311*be691f3bSpatrick } 312*be691f3bSpatrick SetState(StateType::eStateStopped, true); 313*be691f3bSpatrick return; 314*be691f3bSpatrick case TRAP_TRACE: 315*be691f3bSpatrick LLDB_LOG(log, "SIGTRAP/TRAP_TRACE: si_addr: {0}", 316*be691f3bSpatrick info.pl_siginfo.si_addr); 317*be691f3bSpatrick 318*be691f3bSpatrick if (thread) { 319*be691f3bSpatrick auto ®ctx = static_cast<NativeRegisterContextFreeBSD &>( 320*be691f3bSpatrick thread->GetRegisterContext()); 321*be691f3bSpatrick uint32_t wp_index = LLDB_INVALID_INDEX32; 322*be691f3bSpatrick Status error = regctx.GetWatchpointHitIndex( 323*be691f3bSpatrick wp_index, reinterpret_cast<uintptr_t>(info.pl_siginfo.si_addr)); 324*be691f3bSpatrick if (error.Fail()) 325*be691f3bSpatrick LLDB_LOG(log, 326*be691f3bSpatrick "received error while checking for watchpoint hits, pid = " 327*be691f3bSpatrick "{0}, LWP = {1}, error = {2}", 328*be691f3bSpatrick pid, info.pl_lwpid, error); 329*be691f3bSpatrick if (wp_index != LLDB_INVALID_INDEX32) { 330*be691f3bSpatrick regctx.ClearWatchpointHit(wp_index); 331*be691f3bSpatrick thread->SetStoppedByWatchpoint(wp_index); 332*be691f3bSpatrick SetState(StateType::eStateStopped, true); 333*be691f3bSpatrick break; 334*be691f3bSpatrick } 335*be691f3bSpatrick 336*be691f3bSpatrick thread->SetStoppedByTrace(); 337*be691f3bSpatrick } 338*be691f3bSpatrick 339*be691f3bSpatrick SetState(StateType::eStateStopped, true); 340*be691f3bSpatrick return; 341*be691f3bSpatrick } 342*be691f3bSpatrick } 343*be691f3bSpatrick 344*be691f3bSpatrick // Either user-generated SIGTRAP or an unknown event that would 345*be691f3bSpatrick // otherwise leave the debugger hanging. 346*be691f3bSpatrick LLDB_LOG(log, "unknown SIGTRAP, passing to generic handler"); 347*be691f3bSpatrick MonitorSignal(pid, SIGTRAP); 348*be691f3bSpatrick } 349*be691f3bSpatrick 350*be691f3bSpatrick void NativeProcessFreeBSD::MonitorSignal(lldb::pid_t pid, int signal) { 351*be691f3bSpatrick Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); 352*be691f3bSpatrick struct ptrace_lwpinfo info; 353*be691f3bSpatrick 354*be691f3bSpatrick const auto siginfo_err = PtraceWrapper(PT_LWPINFO, pid, &info, sizeof(info)); 355*be691f3bSpatrick if (siginfo_err.Fail()) { 356*be691f3bSpatrick LLDB_LOG(log, "PT_LWPINFO failed {0}", siginfo_err); 357*be691f3bSpatrick return; 358*be691f3bSpatrick } 359*be691f3bSpatrick assert(info.pl_event == PL_EVENT_SIGNAL); 360*be691f3bSpatrick // TODO: do we need to handle !PL_FLAG_SI? 361*be691f3bSpatrick assert(info.pl_flags & PL_FLAG_SI); 362*be691f3bSpatrick assert(info.pl_siginfo.si_signo == signal); 363*be691f3bSpatrick 364*be691f3bSpatrick for (const auto &abs_thread : m_threads) { 365*be691f3bSpatrick NativeThreadFreeBSD &thread = 366*be691f3bSpatrick static_cast<NativeThreadFreeBSD &>(*abs_thread); 367*be691f3bSpatrick assert(info.pl_lwpid >= 0); 368*be691f3bSpatrick if (info.pl_lwpid == 0 || 369*be691f3bSpatrick static_cast<lldb::tid_t>(info.pl_lwpid) == thread.GetID()) 370*be691f3bSpatrick thread.SetStoppedBySignal(info.pl_siginfo.si_signo, &info.pl_siginfo); 371*be691f3bSpatrick else 372*be691f3bSpatrick thread.SetStoppedWithNoReason(); 373*be691f3bSpatrick } 374*be691f3bSpatrick SetState(StateType::eStateStopped, true); 375*be691f3bSpatrick } 376*be691f3bSpatrick 377*be691f3bSpatrick Status NativeProcessFreeBSD::PtraceWrapper(int req, lldb::pid_t pid, void *addr, 378*be691f3bSpatrick int data, int *result) { 379*be691f3bSpatrick Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE)); 380*be691f3bSpatrick Status error; 381*be691f3bSpatrick int ret; 382*be691f3bSpatrick 383*be691f3bSpatrick errno = 0; 384*be691f3bSpatrick ret = 385*be691f3bSpatrick ptrace(req, static_cast<::pid_t>(pid), static_cast<caddr_t>(addr), data); 386*be691f3bSpatrick 387*be691f3bSpatrick if (ret == -1) 388*be691f3bSpatrick error.SetErrorToErrno(); 389*be691f3bSpatrick 390*be691f3bSpatrick if (result) 391*be691f3bSpatrick *result = ret; 392*be691f3bSpatrick 393*be691f3bSpatrick LLDB_LOG(log, "ptrace({0}, {1}, {2}, {3})={4:x}", req, pid, addr, data, ret); 394*be691f3bSpatrick 395*be691f3bSpatrick if (error.Fail()) 396*be691f3bSpatrick LLDB_LOG(log, "ptrace() failed: {0}", error); 397*be691f3bSpatrick 398*be691f3bSpatrick return error; 399*be691f3bSpatrick } 400*be691f3bSpatrick 401*be691f3bSpatrick llvm::Expected<llvm::ArrayRef<uint8_t>> 402*be691f3bSpatrick NativeProcessFreeBSD::GetSoftwareBreakpointTrapOpcode(size_t size_hint) { 403*be691f3bSpatrick static const uint8_t g_arm_opcode[] = {0xfe, 0xde, 0xff, 0xe7}; 404*be691f3bSpatrick static const uint8_t g_thumb_opcode[] = {0x01, 0xde}; 405*be691f3bSpatrick 406*be691f3bSpatrick switch (GetArchitecture().GetMachine()) { 407*be691f3bSpatrick case llvm::Triple::arm: 408*be691f3bSpatrick switch (size_hint) { 409*be691f3bSpatrick case 2: 410*be691f3bSpatrick return llvm::makeArrayRef(g_thumb_opcode); 411*be691f3bSpatrick case 4: 412*be691f3bSpatrick return llvm::makeArrayRef(g_arm_opcode); 413*be691f3bSpatrick default: 414*be691f3bSpatrick return llvm::createStringError(llvm::inconvertibleErrorCode(), 415*be691f3bSpatrick "Unrecognised trap opcode size hint!"); 416*be691f3bSpatrick } 417*be691f3bSpatrick default: 418*be691f3bSpatrick return NativeProcessProtocol::GetSoftwareBreakpointTrapOpcode(size_hint); 419*be691f3bSpatrick } 420*be691f3bSpatrick } 421*be691f3bSpatrick 422*be691f3bSpatrick Status NativeProcessFreeBSD::Resume(const ResumeActionList &resume_actions) { 423*be691f3bSpatrick Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); 424*be691f3bSpatrick LLDB_LOG(log, "pid {0}", GetID()); 425*be691f3bSpatrick 426*be691f3bSpatrick Status ret; 427*be691f3bSpatrick 428*be691f3bSpatrick int signal = 0; 429*be691f3bSpatrick for (const auto &abs_thread : m_threads) { 430*be691f3bSpatrick assert(abs_thread && "thread list should not contain NULL threads"); 431*be691f3bSpatrick NativeThreadFreeBSD &thread = 432*be691f3bSpatrick static_cast<NativeThreadFreeBSD &>(*abs_thread); 433*be691f3bSpatrick 434*be691f3bSpatrick const ResumeAction *action = 435*be691f3bSpatrick resume_actions.GetActionForThread(thread.GetID(), true); 436*be691f3bSpatrick // we need to explicit issue suspend requests, so it is simpler to map it 437*be691f3bSpatrick // into proper action 438*be691f3bSpatrick ResumeAction suspend_action{thread.GetID(), eStateSuspended, 439*be691f3bSpatrick LLDB_INVALID_SIGNAL_NUMBER}; 440*be691f3bSpatrick 441*be691f3bSpatrick if (action == nullptr) { 442*be691f3bSpatrick LLDB_LOG(log, "no action specified for pid {0} tid {1}", GetID(), 443*be691f3bSpatrick thread.GetID()); 444*be691f3bSpatrick action = &suspend_action; 445*be691f3bSpatrick } 446*be691f3bSpatrick 447*be691f3bSpatrick LLDB_LOG( 448*be691f3bSpatrick log, 449*be691f3bSpatrick "processing resume action state {0} signal {1} for pid {2} tid {3}", 450*be691f3bSpatrick action->state, action->signal, GetID(), thread.GetID()); 451*be691f3bSpatrick 452*be691f3bSpatrick switch (action->state) { 453*be691f3bSpatrick case eStateRunning: 454*be691f3bSpatrick ret = thread.Resume(); 455*be691f3bSpatrick break; 456*be691f3bSpatrick case eStateStepping: 457*be691f3bSpatrick ret = thread.SingleStep(); 458*be691f3bSpatrick break; 459*be691f3bSpatrick case eStateSuspended: 460*be691f3bSpatrick case eStateStopped: 461*be691f3bSpatrick if (action->signal != LLDB_INVALID_SIGNAL_NUMBER) 462*be691f3bSpatrick return Status("Passing signal to suspended thread unsupported"); 463*be691f3bSpatrick 464*be691f3bSpatrick ret = thread.Suspend(); 465*be691f3bSpatrick break; 466*be691f3bSpatrick 467*be691f3bSpatrick default: 468*be691f3bSpatrick return Status( 469*be691f3bSpatrick "NativeProcessFreeBSD::%s (): unexpected state %s specified " 470*be691f3bSpatrick "for pid %" PRIu64 ", tid %" PRIu64, 471*be691f3bSpatrick __FUNCTION__, StateAsCString(action->state), GetID(), thread.GetID()); 472*be691f3bSpatrick } 473*be691f3bSpatrick 474*be691f3bSpatrick if (!ret.Success()) 475*be691f3bSpatrick return ret; 476*be691f3bSpatrick if (action->signal != LLDB_INVALID_SIGNAL_NUMBER) 477*be691f3bSpatrick signal = action->signal; 478*be691f3bSpatrick } 479*be691f3bSpatrick 480*be691f3bSpatrick ret = 481*be691f3bSpatrick PtraceWrapper(PT_CONTINUE, GetID(), reinterpret_cast<void *>(1), signal); 482*be691f3bSpatrick if (ret.Success()) 483*be691f3bSpatrick SetState(eStateRunning, true); 484*be691f3bSpatrick return ret; 485*be691f3bSpatrick } 486*be691f3bSpatrick 487*be691f3bSpatrick Status NativeProcessFreeBSD::Halt() { 488*be691f3bSpatrick Status error; 489*be691f3bSpatrick 490*be691f3bSpatrick if (kill(GetID(), SIGSTOP) != 0) 491*be691f3bSpatrick error.SetErrorToErrno(); 492*be691f3bSpatrick return error; 493*be691f3bSpatrick } 494*be691f3bSpatrick 495*be691f3bSpatrick Status NativeProcessFreeBSD::Detach() { 496*be691f3bSpatrick Status error; 497*be691f3bSpatrick 498*be691f3bSpatrick // Stop monitoring the inferior. 499*be691f3bSpatrick m_sigchld_handle.reset(); 500*be691f3bSpatrick 501*be691f3bSpatrick // Tell ptrace to detach from the process. 502*be691f3bSpatrick if (GetID() == LLDB_INVALID_PROCESS_ID) 503*be691f3bSpatrick return error; 504*be691f3bSpatrick 505*be691f3bSpatrick return PtraceWrapper(PT_DETACH, GetID()); 506*be691f3bSpatrick } 507*be691f3bSpatrick 508*be691f3bSpatrick Status NativeProcessFreeBSD::Signal(int signo) { 509*be691f3bSpatrick Status error; 510*be691f3bSpatrick 511*be691f3bSpatrick if (kill(GetID(), signo)) 512*be691f3bSpatrick error.SetErrorToErrno(); 513*be691f3bSpatrick 514*be691f3bSpatrick return error; 515*be691f3bSpatrick } 516*be691f3bSpatrick 517*be691f3bSpatrick Status NativeProcessFreeBSD::Interrupt() { return Halt(); } 518*be691f3bSpatrick 519*be691f3bSpatrick Status NativeProcessFreeBSD::Kill() { 520*be691f3bSpatrick Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); 521*be691f3bSpatrick LLDB_LOG(log, "pid {0}", GetID()); 522*be691f3bSpatrick 523*be691f3bSpatrick Status error; 524*be691f3bSpatrick 525*be691f3bSpatrick switch (m_state) { 526*be691f3bSpatrick case StateType::eStateInvalid: 527*be691f3bSpatrick case StateType::eStateExited: 528*be691f3bSpatrick case StateType::eStateCrashed: 529*be691f3bSpatrick case StateType::eStateDetached: 530*be691f3bSpatrick case StateType::eStateUnloaded: 531*be691f3bSpatrick // Nothing to do - the process is already dead. 532*be691f3bSpatrick LLDB_LOG(log, "ignored for PID {0} due to current state: {1}", GetID(), 533*be691f3bSpatrick StateAsCString(m_state)); 534*be691f3bSpatrick return error; 535*be691f3bSpatrick 536*be691f3bSpatrick case StateType::eStateConnected: 537*be691f3bSpatrick case StateType::eStateAttaching: 538*be691f3bSpatrick case StateType::eStateLaunching: 539*be691f3bSpatrick case StateType::eStateStopped: 540*be691f3bSpatrick case StateType::eStateRunning: 541*be691f3bSpatrick case StateType::eStateStepping: 542*be691f3bSpatrick case StateType::eStateSuspended: 543*be691f3bSpatrick // We can try to kill a process in these states. 544*be691f3bSpatrick break; 545*be691f3bSpatrick } 546*be691f3bSpatrick 547*be691f3bSpatrick return PtraceWrapper(PT_KILL, m_pid); 548*be691f3bSpatrick } 549*be691f3bSpatrick 550*be691f3bSpatrick Status NativeProcessFreeBSD::GetMemoryRegionInfo(lldb::addr_t load_addr, 551*be691f3bSpatrick MemoryRegionInfo &range_info) { 552*be691f3bSpatrick 553*be691f3bSpatrick if (m_supports_mem_region == LazyBool::eLazyBoolNo) { 554*be691f3bSpatrick // We're done. 555*be691f3bSpatrick return Status("unsupported"); 556*be691f3bSpatrick } 557*be691f3bSpatrick 558*be691f3bSpatrick Status error = PopulateMemoryRegionCache(); 559*be691f3bSpatrick if (error.Fail()) { 560*be691f3bSpatrick return error; 561*be691f3bSpatrick } 562*be691f3bSpatrick 563*be691f3bSpatrick lldb::addr_t prev_base_address = 0; 564*be691f3bSpatrick // FIXME start by finding the last region that is <= target address using 565*be691f3bSpatrick // binary search. Data is sorted. 566*be691f3bSpatrick // There can be a ton of regions on pthreads apps with lots of threads. 567*be691f3bSpatrick for (auto it = m_mem_region_cache.begin(); it != m_mem_region_cache.end(); 568*be691f3bSpatrick ++it) { 569*be691f3bSpatrick MemoryRegionInfo &proc_entry_info = it->first; 570*be691f3bSpatrick // Sanity check assumption that memory map entries are ascending. 571*be691f3bSpatrick assert((proc_entry_info.GetRange().GetRangeBase() >= prev_base_address) && 572*be691f3bSpatrick "descending memory map entries detected, unexpected"); 573*be691f3bSpatrick prev_base_address = proc_entry_info.GetRange().GetRangeBase(); 574*be691f3bSpatrick UNUSED_IF_ASSERT_DISABLED(prev_base_address); 575*be691f3bSpatrick // If the target address comes before this entry, indicate distance to next 576*be691f3bSpatrick // region. 577*be691f3bSpatrick if (load_addr < proc_entry_info.GetRange().GetRangeBase()) { 578*be691f3bSpatrick range_info.GetRange().SetRangeBase(load_addr); 579*be691f3bSpatrick range_info.GetRange().SetByteSize( 580*be691f3bSpatrick proc_entry_info.GetRange().GetRangeBase() - load_addr); 581*be691f3bSpatrick range_info.SetReadable(MemoryRegionInfo::OptionalBool::eNo); 582*be691f3bSpatrick range_info.SetWritable(MemoryRegionInfo::OptionalBool::eNo); 583*be691f3bSpatrick range_info.SetExecutable(MemoryRegionInfo::OptionalBool::eNo); 584*be691f3bSpatrick range_info.SetMapped(MemoryRegionInfo::OptionalBool::eNo); 585*be691f3bSpatrick return error; 586*be691f3bSpatrick } else if (proc_entry_info.GetRange().Contains(load_addr)) { 587*be691f3bSpatrick // The target address is within the memory region we're processing here. 588*be691f3bSpatrick range_info = proc_entry_info; 589*be691f3bSpatrick return error; 590*be691f3bSpatrick } 591*be691f3bSpatrick // The target memory address comes somewhere after the region we just 592*be691f3bSpatrick // parsed. 593*be691f3bSpatrick } 594*be691f3bSpatrick // If we made it here, we didn't find an entry that contained the given 595*be691f3bSpatrick // address. Return the load_addr as start and the amount of bytes betwwen 596*be691f3bSpatrick // load address and the end of the memory as size. 597*be691f3bSpatrick range_info.GetRange().SetRangeBase(load_addr); 598*be691f3bSpatrick range_info.GetRange().SetRangeEnd(LLDB_INVALID_ADDRESS); 599*be691f3bSpatrick range_info.SetReadable(MemoryRegionInfo::OptionalBool::eNo); 600*be691f3bSpatrick range_info.SetWritable(MemoryRegionInfo::OptionalBool::eNo); 601*be691f3bSpatrick range_info.SetExecutable(MemoryRegionInfo::OptionalBool::eNo); 602*be691f3bSpatrick range_info.SetMapped(MemoryRegionInfo::OptionalBool::eNo); 603*be691f3bSpatrick return error; 604*be691f3bSpatrick } 605*be691f3bSpatrick 606*be691f3bSpatrick Status NativeProcessFreeBSD::PopulateMemoryRegionCache() { 607*be691f3bSpatrick Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); 608*be691f3bSpatrick // If our cache is empty, pull the latest. There should always be at least 609*be691f3bSpatrick // one memory region if memory region handling is supported. 610*be691f3bSpatrick if (!m_mem_region_cache.empty()) { 611*be691f3bSpatrick LLDB_LOG(log, "reusing {0} cached memory region entries", 612*be691f3bSpatrick m_mem_region_cache.size()); 613*be691f3bSpatrick return Status(); 614*be691f3bSpatrick } 615*be691f3bSpatrick 616*be691f3bSpatrick int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_VMMAP, static_cast<int>(m_pid)}; 617*be691f3bSpatrick int ret; 618*be691f3bSpatrick size_t len; 619*be691f3bSpatrick 620*be691f3bSpatrick ret = ::sysctl(mib, 4, nullptr, &len, nullptr, 0); 621*be691f3bSpatrick if (ret != 0) { 622*be691f3bSpatrick m_supports_mem_region = LazyBool::eLazyBoolNo; 623*be691f3bSpatrick return Status("sysctl() for KERN_PROC_VMMAP failed"); 624*be691f3bSpatrick } 625*be691f3bSpatrick 626*be691f3bSpatrick std::unique_ptr<WritableMemoryBuffer> buf = 627*be691f3bSpatrick llvm::WritableMemoryBuffer::getNewMemBuffer(len); 628*be691f3bSpatrick ret = ::sysctl(mib, 4, buf->getBufferStart(), &len, nullptr, 0); 629*be691f3bSpatrick if (ret != 0) { 630*be691f3bSpatrick m_supports_mem_region = LazyBool::eLazyBoolNo; 631*be691f3bSpatrick return Status("sysctl() for KERN_PROC_VMMAP failed"); 632*be691f3bSpatrick } 633*be691f3bSpatrick 634*be691f3bSpatrick char *bp = buf->getBufferStart(); 635*be691f3bSpatrick char *end = bp + len; 636*be691f3bSpatrick while (bp < end) { 637*be691f3bSpatrick auto *kv = reinterpret_cast<struct kinfo_vmentry *>(bp); 638*be691f3bSpatrick if (kv->kve_structsize == 0) 639*be691f3bSpatrick break; 640*be691f3bSpatrick bp += kv->kve_structsize; 641*be691f3bSpatrick 642*be691f3bSpatrick MemoryRegionInfo info; 643*be691f3bSpatrick info.Clear(); 644*be691f3bSpatrick info.GetRange().SetRangeBase(kv->kve_start); 645*be691f3bSpatrick info.GetRange().SetRangeEnd(kv->kve_end); 646*be691f3bSpatrick info.SetMapped(MemoryRegionInfo::OptionalBool::eYes); 647*be691f3bSpatrick 648*be691f3bSpatrick if (kv->kve_protection & VM_PROT_READ) 649*be691f3bSpatrick info.SetReadable(MemoryRegionInfo::OptionalBool::eYes); 650*be691f3bSpatrick else 651*be691f3bSpatrick info.SetReadable(MemoryRegionInfo::OptionalBool::eNo); 652*be691f3bSpatrick 653*be691f3bSpatrick if (kv->kve_protection & VM_PROT_WRITE) 654*be691f3bSpatrick info.SetWritable(MemoryRegionInfo::OptionalBool::eYes); 655*be691f3bSpatrick else 656*be691f3bSpatrick info.SetWritable(MemoryRegionInfo::OptionalBool::eNo); 657*be691f3bSpatrick 658*be691f3bSpatrick if (kv->kve_protection & VM_PROT_EXECUTE) 659*be691f3bSpatrick info.SetExecutable(MemoryRegionInfo::OptionalBool::eYes); 660*be691f3bSpatrick else 661*be691f3bSpatrick info.SetExecutable(MemoryRegionInfo::OptionalBool::eNo); 662*be691f3bSpatrick 663*be691f3bSpatrick if (kv->kve_path[0]) 664*be691f3bSpatrick info.SetName(kv->kve_path); 665*be691f3bSpatrick 666*be691f3bSpatrick m_mem_region_cache.emplace_back(info, 667*be691f3bSpatrick FileSpec(info.GetName().GetCString())); 668*be691f3bSpatrick } 669*be691f3bSpatrick 670*be691f3bSpatrick if (m_mem_region_cache.empty()) { 671*be691f3bSpatrick // No entries after attempting to read them. This shouldn't happen. Assume 672*be691f3bSpatrick // we don't support map entries. 673*be691f3bSpatrick LLDB_LOG(log, "failed to find any vmmap entries, assuming no support " 674*be691f3bSpatrick "for memory region metadata retrieval"); 675*be691f3bSpatrick m_supports_mem_region = LazyBool::eLazyBoolNo; 676*be691f3bSpatrick return Status("not supported"); 677*be691f3bSpatrick } 678*be691f3bSpatrick LLDB_LOG(log, "read {0} memory region entries from process {1}", 679*be691f3bSpatrick m_mem_region_cache.size(), GetID()); 680*be691f3bSpatrick // We support memory retrieval, remember that. 681*be691f3bSpatrick m_supports_mem_region = LazyBool::eLazyBoolYes; 682*be691f3bSpatrick 683*be691f3bSpatrick return Status(); 684*be691f3bSpatrick } 685*be691f3bSpatrick 686*be691f3bSpatrick size_t NativeProcessFreeBSD::UpdateThreads() { return m_threads.size(); } 687*be691f3bSpatrick 688*be691f3bSpatrick Status NativeProcessFreeBSD::SetBreakpoint(lldb::addr_t addr, uint32_t size, 689*be691f3bSpatrick bool hardware) { 690*be691f3bSpatrick if (hardware) 691*be691f3bSpatrick return SetHardwareBreakpoint(addr, size); 692*be691f3bSpatrick return SetSoftwareBreakpoint(addr, size); 693*be691f3bSpatrick } 694*be691f3bSpatrick 695*be691f3bSpatrick Status NativeProcessFreeBSD::GetLoadedModuleFileSpec(const char *module_path, 696*be691f3bSpatrick FileSpec &file_spec) { 697*be691f3bSpatrick Status error = PopulateMemoryRegionCache(); 698*be691f3bSpatrick if (error.Fail()) 699*be691f3bSpatrick return error; 700*be691f3bSpatrick 701*be691f3bSpatrick FileSpec module_file_spec(module_path); 702*be691f3bSpatrick FileSystem::Instance().Resolve(module_file_spec); 703*be691f3bSpatrick 704*be691f3bSpatrick file_spec.Clear(); 705*be691f3bSpatrick for (const auto &it : m_mem_region_cache) { 706*be691f3bSpatrick if (it.second.GetFilename() == module_file_spec.GetFilename()) { 707*be691f3bSpatrick file_spec = it.second; 708*be691f3bSpatrick return Status(); 709*be691f3bSpatrick } 710*be691f3bSpatrick } 711*be691f3bSpatrick return Status("Module file (%s) not found in process' memory map!", 712*be691f3bSpatrick module_file_spec.GetFilename().AsCString()); 713*be691f3bSpatrick } 714*be691f3bSpatrick 715*be691f3bSpatrick Status 716*be691f3bSpatrick NativeProcessFreeBSD::GetFileLoadAddress(const llvm::StringRef &file_name, 717*be691f3bSpatrick lldb::addr_t &load_addr) { 718*be691f3bSpatrick load_addr = LLDB_INVALID_ADDRESS; 719*be691f3bSpatrick Status error = PopulateMemoryRegionCache(); 720*be691f3bSpatrick if (error.Fail()) 721*be691f3bSpatrick return error; 722*be691f3bSpatrick 723*be691f3bSpatrick FileSpec file(file_name); 724*be691f3bSpatrick for (const auto &it : m_mem_region_cache) { 725*be691f3bSpatrick if (it.second == file) { 726*be691f3bSpatrick load_addr = it.first.GetRange().GetRangeBase(); 727*be691f3bSpatrick return Status(); 728*be691f3bSpatrick } 729*be691f3bSpatrick } 730*be691f3bSpatrick return Status("No load address found for file %s.", file_name.str().c_str()); 731*be691f3bSpatrick } 732*be691f3bSpatrick 733*be691f3bSpatrick void NativeProcessFreeBSD::SigchldHandler() { 734*be691f3bSpatrick Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); 735*be691f3bSpatrick int status; 736*be691f3bSpatrick ::pid_t wait_pid = 737*be691f3bSpatrick llvm::sys::RetryAfterSignal(-1, waitpid, GetID(), &status, WNOHANG); 738*be691f3bSpatrick 739*be691f3bSpatrick if (wait_pid == 0) 740*be691f3bSpatrick return; 741*be691f3bSpatrick 742*be691f3bSpatrick if (wait_pid == -1) { 743*be691f3bSpatrick Status error(errno, eErrorTypePOSIX); 744*be691f3bSpatrick LLDB_LOG(log, "waitpid ({0}, &status, _) failed: {1}", GetID(), error); 745*be691f3bSpatrick return; 746*be691f3bSpatrick } 747*be691f3bSpatrick 748*be691f3bSpatrick WaitStatus wait_status = WaitStatus::Decode(status); 749*be691f3bSpatrick bool exited = wait_status.type == WaitStatus::Exit || 750*be691f3bSpatrick (wait_status.type == WaitStatus::Signal && 751*be691f3bSpatrick wait_pid == static_cast<::pid_t>(GetID())); 752*be691f3bSpatrick 753*be691f3bSpatrick LLDB_LOG(log, 754*be691f3bSpatrick "waitpid ({0}, &status, _) => pid = {1}, status = {2}, exited = {3}", 755*be691f3bSpatrick GetID(), wait_pid, status, exited); 756*be691f3bSpatrick 757*be691f3bSpatrick if (exited) 758*be691f3bSpatrick MonitorExited(wait_pid, wait_status); 759*be691f3bSpatrick else { 760*be691f3bSpatrick assert(wait_status.type == WaitStatus::Stop); 761*be691f3bSpatrick MonitorCallback(wait_pid, wait_status.status); 762*be691f3bSpatrick } 763*be691f3bSpatrick } 764*be691f3bSpatrick 765*be691f3bSpatrick bool NativeProcessFreeBSD::HasThreadNoLock(lldb::tid_t thread_id) { 766*be691f3bSpatrick for (const auto &thread : m_threads) { 767*be691f3bSpatrick assert(thread && "thread list should not contain NULL threads"); 768*be691f3bSpatrick if (thread->GetID() == thread_id) { 769*be691f3bSpatrick // We have this thread. 770*be691f3bSpatrick return true; 771*be691f3bSpatrick } 772*be691f3bSpatrick } 773*be691f3bSpatrick 774*be691f3bSpatrick // We don't have this thread. 775*be691f3bSpatrick return false; 776*be691f3bSpatrick } 777*be691f3bSpatrick 778*be691f3bSpatrick NativeThreadFreeBSD &NativeProcessFreeBSD::AddThread(lldb::tid_t thread_id) { 779*be691f3bSpatrick Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD)); 780*be691f3bSpatrick LLDB_LOG(log, "pid {0} adding thread with tid {1}", GetID(), thread_id); 781*be691f3bSpatrick 782*be691f3bSpatrick assert(thread_id > 0); 783*be691f3bSpatrick assert(!HasThreadNoLock(thread_id) && 784*be691f3bSpatrick "attempted to add a thread by id that already exists"); 785*be691f3bSpatrick 786*be691f3bSpatrick // If this is the first thread, save it as the current thread 787*be691f3bSpatrick if (m_threads.empty()) 788*be691f3bSpatrick SetCurrentThreadID(thread_id); 789*be691f3bSpatrick 790*be691f3bSpatrick m_threads.push_back(std::make_unique<NativeThreadFreeBSD>(*this, thread_id)); 791*be691f3bSpatrick return static_cast<NativeThreadFreeBSD &>(*m_threads.back()); 792*be691f3bSpatrick } 793*be691f3bSpatrick 794*be691f3bSpatrick void NativeProcessFreeBSD::RemoveThread(lldb::tid_t thread_id) { 795*be691f3bSpatrick Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD)); 796*be691f3bSpatrick LLDB_LOG(log, "pid {0} removing thread with tid {1}", GetID(), thread_id); 797*be691f3bSpatrick 798*be691f3bSpatrick assert(thread_id > 0); 799*be691f3bSpatrick assert(HasThreadNoLock(thread_id) && 800*be691f3bSpatrick "attempted to remove a thread that does not exist"); 801*be691f3bSpatrick 802*be691f3bSpatrick for (auto it = m_threads.begin(); it != m_threads.end(); ++it) { 803*be691f3bSpatrick if ((*it)->GetID() == thread_id) { 804*be691f3bSpatrick m_threads.erase(it); 805*be691f3bSpatrick break; 806*be691f3bSpatrick } 807*be691f3bSpatrick } 808*be691f3bSpatrick } 809*be691f3bSpatrick 810*be691f3bSpatrick Status NativeProcessFreeBSD::Attach() { 811*be691f3bSpatrick // Attach to the requested process. 812*be691f3bSpatrick // An attach will cause the thread to stop with a SIGSTOP. 813*be691f3bSpatrick Status status = PtraceWrapper(PT_ATTACH, m_pid); 814*be691f3bSpatrick if (status.Fail()) 815*be691f3bSpatrick return status; 816*be691f3bSpatrick 817*be691f3bSpatrick int wstatus; 818*be691f3bSpatrick // Need to use WALLSIG otherwise we receive an error with errno=ECHLD At this 819*be691f3bSpatrick // point we should have a thread stopped if waitpid succeeds. 820*be691f3bSpatrick if ((wstatus = llvm::sys::RetryAfterSignal(-1, waitpid, m_pid, nullptr, 0)) < 821*be691f3bSpatrick 0) 822*be691f3bSpatrick return Status(errno, eErrorTypePOSIX); 823*be691f3bSpatrick 824*be691f3bSpatrick // Initialize threads and tracing status 825*be691f3bSpatrick // NB: this needs to be called before we set thread state 826*be691f3bSpatrick status = SetupTrace(); 827*be691f3bSpatrick if (status.Fail()) 828*be691f3bSpatrick return status; 829*be691f3bSpatrick 830*be691f3bSpatrick for (const auto &thread : m_threads) 831*be691f3bSpatrick static_cast<NativeThreadFreeBSD &>(*thread).SetStoppedBySignal(SIGSTOP); 832*be691f3bSpatrick 833*be691f3bSpatrick // Let our process instance know the thread has stopped. 834*be691f3bSpatrick SetCurrentThreadID(m_threads.front()->GetID()); 835*be691f3bSpatrick SetState(StateType::eStateStopped, false); 836*be691f3bSpatrick return Status(); 837*be691f3bSpatrick } 838*be691f3bSpatrick 839*be691f3bSpatrick Status NativeProcessFreeBSD::ReadMemory(lldb::addr_t addr, void *buf, 840*be691f3bSpatrick size_t size, size_t &bytes_read) { 841*be691f3bSpatrick unsigned char *dst = static_cast<unsigned char *>(buf); 842*be691f3bSpatrick struct ptrace_io_desc io; 843*be691f3bSpatrick 844*be691f3bSpatrick Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_MEMORY)); 845*be691f3bSpatrick LLDB_LOG(log, "addr = {0}, buf = {1}, size = {2}", addr, buf, size); 846*be691f3bSpatrick 847*be691f3bSpatrick bytes_read = 0; 848*be691f3bSpatrick io.piod_op = PIOD_READ_D; 849*be691f3bSpatrick io.piod_len = size; 850*be691f3bSpatrick 851*be691f3bSpatrick do { 852*be691f3bSpatrick io.piod_offs = (void *)(addr + bytes_read); 853*be691f3bSpatrick io.piod_addr = dst + bytes_read; 854*be691f3bSpatrick 855*be691f3bSpatrick Status error = NativeProcessFreeBSD::PtraceWrapper(PT_IO, GetID(), &io); 856*be691f3bSpatrick if (error.Fail() || io.piod_len == 0) 857*be691f3bSpatrick return error; 858*be691f3bSpatrick 859*be691f3bSpatrick bytes_read += io.piod_len; 860*be691f3bSpatrick io.piod_len = size - bytes_read; 861*be691f3bSpatrick } while (bytes_read < size); 862*be691f3bSpatrick 863*be691f3bSpatrick return Status(); 864*be691f3bSpatrick } 865*be691f3bSpatrick 866*be691f3bSpatrick Status NativeProcessFreeBSD::WriteMemory(lldb::addr_t addr, const void *buf, 867*be691f3bSpatrick size_t size, size_t &bytes_written) { 868*be691f3bSpatrick const unsigned char *src = static_cast<const unsigned char *>(buf); 869*be691f3bSpatrick Status error; 870*be691f3bSpatrick struct ptrace_io_desc io; 871*be691f3bSpatrick 872*be691f3bSpatrick Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_MEMORY)); 873*be691f3bSpatrick LLDB_LOG(log, "addr = {0}, buf = {1}, size = {2}", addr, buf, size); 874*be691f3bSpatrick 875*be691f3bSpatrick bytes_written = 0; 876*be691f3bSpatrick io.piod_op = PIOD_WRITE_D; 877*be691f3bSpatrick io.piod_len = size; 878*be691f3bSpatrick 879*be691f3bSpatrick do { 880*be691f3bSpatrick io.piod_addr = 881*be691f3bSpatrick const_cast<void *>(static_cast<const void *>(src + bytes_written)); 882*be691f3bSpatrick io.piod_offs = (void *)(addr + bytes_written); 883*be691f3bSpatrick 884*be691f3bSpatrick Status error = NativeProcessFreeBSD::PtraceWrapper(PT_IO, GetID(), &io); 885*be691f3bSpatrick if (error.Fail() || io.piod_len == 0) 886*be691f3bSpatrick return error; 887*be691f3bSpatrick 888*be691f3bSpatrick bytes_written += io.piod_len; 889*be691f3bSpatrick io.piod_len = size - bytes_written; 890*be691f3bSpatrick } while (bytes_written < size); 891*be691f3bSpatrick 892*be691f3bSpatrick return error; 893*be691f3bSpatrick } 894*be691f3bSpatrick 895*be691f3bSpatrick llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> 896*be691f3bSpatrick NativeProcessFreeBSD::GetAuxvData() const { 897*be691f3bSpatrick int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_AUXV, static_cast<int>(GetID())}; 898*be691f3bSpatrick size_t auxv_size = AT_COUNT * sizeof(Elf_Auxinfo); 899*be691f3bSpatrick std::unique_ptr<WritableMemoryBuffer> buf = 900*be691f3bSpatrick llvm::WritableMemoryBuffer::getNewMemBuffer(auxv_size); 901*be691f3bSpatrick 902*be691f3bSpatrick if (::sysctl(mib, 4, buf->getBufferStart(), &auxv_size, nullptr, 0) != 0) 903*be691f3bSpatrick return std::error_code(errno, std::generic_category()); 904*be691f3bSpatrick 905*be691f3bSpatrick return buf; 906*be691f3bSpatrick } 907*be691f3bSpatrick 908*be691f3bSpatrick Status NativeProcessFreeBSD::SetupTrace() { 909*be691f3bSpatrick // Enable event reporting 910*be691f3bSpatrick int events; 911*be691f3bSpatrick Status status = 912*be691f3bSpatrick PtraceWrapper(PT_GET_EVENT_MASK, GetID(), &events, sizeof(events)); 913*be691f3bSpatrick if (status.Fail()) 914*be691f3bSpatrick return status; 915*be691f3bSpatrick events |= PTRACE_LWP | PTRACE_FORK | PTRACE_VFORK; 916*be691f3bSpatrick status = PtraceWrapper(PT_SET_EVENT_MASK, GetID(), &events, sizeof(events)); 917*be691f3bSpatrick if (status.Fail()) 918*be691f3bSpatrick return status; 919*be691f3bSpatrick 920*be691f3bSpatrick return ReinitializeThreads(); 921*be691f3bSpatrick } 922*be691f3bSpatrick 923*be691f3bSpatrick Status NativeProcessFreeBSD::ReinitializeThreads() { 924*be691f3bSpatrick // Clear old threads 925*be691f3bSpatrick m_threads.clear(); 926*be691f3bSpatrick 927*be691f3bSpatrick int num_lwps; 928*be691f3bSpatrick Status error = PtraceWrapper(PT_GETNUMLWPS, GetID(), nullptr, 0, &num_lwps); 929*be691f3bSpatrick if (error.Fail()) 930*be691f3bSpatrick return error; 931*be691f3bSpatrick 932*be691f3bSpatrick std::vector<lwpid_t> lwp_ids; 933*be691f3bSpatrick lwp_ids.resize(num_lwps); 934*be691f3bSpatrick error = PtraceWrapper(PT_GETLWPLIST, GetID(), lwp_ids.data(), 935*be691f3bSpatrick lwp_ids.size() * sizeof(lwpid_t), &num_lwps); 936*be691f3bSpatrick if (error.Fail()) 937*be691f3bSpatrick return error; 938*be691f3bSpatrick 939*be691f3bSpatrick // Reinitialize from scratch threads and register them in process 940*be691f3bSpatrick for (lwpid_t lwp : lwp_ids) 941*be691f3bSpatrick AddThread(lwp); 942*be691f3bSpatrick 943*be691f3bSpatrick return error; 944*be691f3bSpatrick } 945*be691f3bSpatrick 946*be691f3bSpatrick bool NativeProcessFreeBSD::SupportHardwareSingleStepping() const { 947*be691f3bSpatrick return !m_arch.IsMIPS(); 948*be691f3bSpatrick } 949*be691f3bSpatrick 950*be691f3bSpatrick void NativeProcessFreeBSD::MonitorClone(::pid_t child_pid, bool is_vfork, 951*be691f3bSpatrick NativeThreadFreeBSD &parent_thread) { 952*be691f3bSpatrick Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); 953*be691f3bSpatrick LLDB_LOG(log, "fork, child_pid={0}", child_pid); 954*be691f3bSpatrick 955*be691f3bSpatrick int status; 956*be691f3bSpatrick ::pid_t wait_pid = 957*be691f3bSpatrick llvm::sys::RetryAfterSignal(-1, ::waitpid, child_pid, &status, 0); 958*be691f3bSpatrick if (wait_pid != child_pid) { 959*be691f3bSpatrick LLDB_LOG(log, 960*be691f3bSpatrick "waiting for pid {0} failed. Assuming the pid has " 961*be691f3bSpatrick "disappeared in the meantime", 962*be691f3bSpatrick child_pid); 963*be691f3bSpatrick return; 964*be691f3bSpatrick } 965*be691f3bSpatrick if (WIFEXITED(status)) { 966*be691f3bSpatrick LLDB_LOG(log, 967*be691f3bSpatrick "waiting for pid {0} returned an 'exited' event. Not " 968*be691f3bSpatrick "tracking it.", 969*be691f3bSpatrick child_pid); 970*be691f3bSpatrick return; 971*be691f3bSpatrick } 972*be691f3bSpatrick 973*be691f3bSpatrick struct ptrace_lwpinfo info; 974*be691f3bSpatrick const auto siginfo_err = PtraceWrapper(PT_LWPINFO, child_pid, &info, sizeof(info)); 975*be691f3bSpatrick if (siginfo_err.Fail()) { 976*be691f3bSpatrick LLDB_LOG(log, "PT_LWPINFO failed {0}", siginfo_err); 977*be691f3bSpatrick return; 978*be691f3bSpatrick } 979*be691f3bSpatrick assert(info.pl_event == PL_EVENT_SIGNAL); 980*be691f3bSpatrick lldb::tid_t child_tid = info.pl_lwpid; 981*be691f3bSpatrick 982*be691f3bSpatrick std::unique_ptr<NativeProcessFreeBSD> child_process{ 983*be691f3bSpatrick new NativeProcessFreeBSD(static_cast<::pid_t>(child_pid), m_terminal_fd, 984*be691f3bSpatrick m_delegate, m_arch, m_main_loop)}; 985*be691f3bSpatrick if (!is_vfork) 986*be691f3bSpatrick child_process->m_software_breakpoints = m_software_breakpoints; 987*be691f3bSpatrick 988*be691f3bSpatrick Extension expected_ext = is_vfork ? Extension::vfork : Extension::fork; 989*be691f3bSpatrick if ((m_enabled_extensions & expected_ext) == expected_ext) { 990*be691f3bSpatrick child_process->SetupTrace(); 991*be691f3bSpatrick for (const auto &thread : child_process->m_threads) 992*be691f3bSpatrick static_cast<NativeThreadFreeBSD &>(*thread).SetStoppedBySignal(SIGSTOP); 993*be691f3bSpatrick child_process->SetState(StateType::eStateStopped, false); 994*be691f3bSpatrick 995*be691f3bSpatrick m_delegate.NewSubprocess(this, std::move(child_process)); 996*be691f3bSpatrick if (is_vfork) 997*be691f3bSpatrick parent_thread.SetStoppedByVFork(child_pid, child_tid); 998*be691f3bSpatrick else 999*be691f3bSpatrick parent_thread.SetStoppedByFork(child_pid, child_tid); 1000*be691f3bSpatrick SetState(StateType::eStateStopped, true); 1001*be691f3bSpatrick } else { 1002*be691f3bSpatrick child_process->Detach(); 1003*be691f3bSpatrick Status pt_error = 1004*be691f3bSpatrick PtraceWrapper(PT_CONTINUE, GetID(), reinterpret_cast<void *>(1), 0); 1005*be691f3bSpatrick if (pt_error.Fail()) { 1006*be691f3bSpatrick LLDB_LOG_ERROR(log, pt_error.ToError(), 1007*be691f3bSpatrick "unable to resume parent process {1}: {0}", GetID()); 1008*be691f3bSpatrick SetState(StateType::eStateInvalid); 1009*be691f3bSpatrick } 1010*be691f3bSpatrick } 1011*be691f3bSpatrick } 1012