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