1 //===-- NativeProcessNetBSD.cpp ------------------------------- -*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "NativeProcessNetBSD.h" 11 12 // C Includes 13 14 // C++ Includes 15 16 // Other libraries and framework includes 17 #include "Plugins/Process/POSIX/ProcessPOSIXLog.h" 18 #include "lldb/Host/HostProcess.h" 19 #include "lldb/Host/common/NativeRegisterContext.h" 20 #include "lldb/Host/posix/ProcessLauncherPosixFork.h" 21 #include "lldb/Target/Process.h" 22 #include "lldb/Utility/State.h" 23 #include "llvm/Support/Errno.h" 24 25 // System includes - They have to be included after framework includes because 26 // they define some macros which collide with variable names in other modules 27 // clang-format off 28 #include <sys/types.h> 29 #include <sys/ptrace.h> 30 #include <sys/sysctl.h> 31 #include <sys/wait.h> 32 #include <uvm/uvm_prot.h> 33 #include <elf.h> 34 #include <util.h> 35 // clang-format on 36 37 using namespace lldb; 38 using namespace lldb_private; 39 using namespace lldb_private::process_netbsd; 40 using namespace llvm; 41 42 // Simple helper function to ensure flags are enabled on the given file 43 // descriptor. 44 static Status EnsureFDFlags(int fd, int flags) { 45 Status error; 46 47 int status = fcntl(fd, F_GETFL); 48 if (status == -1) { 49 error.SetErrorToErrno(); 50 return error; 51 } 52 53 if (fcntl(fd, F_SETFL, status | flags) == -1) { 54 error.SetErrorToErrno(); 55 return error; 56 } 57 58 return error; 59 } 60 61 // ----------------------------------------------------------------------------- 62 // Public Static Methods 63 // ----------------------------------------------------------------------------- 64 65 llvm::Expected<std::unique_ptr<NativeProcessProtocol>> 66 NativeProcessNetBSD::Factory::Launch(ProcessLaunchInfo &launch_info, 67 NativeDelegate &native_delegate, 68 MainLoop &mainloop) const { 69 Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); 70 71 Status status; 72 ::pid_t pid = ProcessLauncherPosixFork() 73 .LaunchProcess(launch_info, status) 74 .GetProcessId(); 75 LLDB_LOG(log, "pid = {0:x}", pid); 76 if (status.Fail()) { 77 LLDB_LOG(log, "failed to launch process: {0}", status); 78 return status.ToError(); 79 } 80 81 // Wait for the child process to trap on its call to execve. 82 int wstatus; 83 ::pid_t wpid = llvm::sys::RetryAfterSignal(-1, ::waitpid, pid, &wstatus, 0); 84 assert(wpid == pid); 85 (void)wpid; 86 if (!WIFSTOPPED(wstatus)) { 87 LLDB_LOG(log, "Could not sync with inferior process: wstatus={1}", 88 WaitStatus::Decode(wstatus)); 89 return llvm::make_error<StringError>("Could not sync with inferior process", 90 llvm::inconvertibleErrorCode()); 91 } 92 LLDB_LOG(log, "inferior started, now in stopped state"); 93 94 ProcessInstanceInfo Info; 95 if (!Host::GetProcessInfo(pid, Info)) { 96 return llvm::make_error<StringError>("Cannot get process architecture", 97 llvm::inconvertibleErrorCode()); 98 } 99 100 // Set the architecture to the exe architecture. 101 LLDB_LOG(log, "pid = {0:x}, detected architecture {1}", pid, 102 Info.GetArchitecture().GetArchitectureName()); 103 104 std::unique_ptr<NativeProcessNetBSD> process_up(new NativeProcessNetBSD( 105 pid, launch_info.GetPTY().ReleaseMasterFileDescriptor(), native_delegate, 106 Info.GetArchitecture(), mainloop)); 107 108 status = process_up->ReinitializeThreads(); 109 if (status.Fail()) 110 return status.ToError(); 111 112 for (const auto &thread : process_up->m_threads) 113 static_cast<NativeThreadNetBSD &>(*thread).SetStoppedBySignal(SIGSTOP); 114 process_up->SetState(StateType::eStateStopped, false); 115 116 return std::move(process_up); 117 } 118 119 llvm::Expected<std::unique_ptr<NativeProcessProtocol>> 120 NativeProcessNetBSD::Factory::Attach( 121 lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &native_delegate, 122 MainLoop &mainloop) const { 123 Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); 124 LLDB_LOG(log, "pid = {0:x}", pid); 125 126 // Retrieve the architecture for the running process. 127 ProcessInstanceInfo Info; 128 if (!Host::GetProcessInfo(pid, Info)) { 129 return llvm::make_error<StringError>("Cannot get process architecture", 130 llvm::inconvertibleErrorCode()); 131 } 132 133 std::unique_ptr<NativeProcessNetBSD> process_up(new NativeProcessNetBSD( 134 pid, -1, native_delegate, Info.GetArchitecture(), mainloop)); 135 136 Status status = process_up->Attach(); 137 if (!status.Success()) 138 return status.ToError(); 139 140 return std::move(process_up); 141 } 142 143 // ----------------------------------------------------------------------------- 144 // Public Instance Methods 145 // ----------------------------------------------------------------------------- 146 147 NativeProcessNetBSD::NativeProcessNetBSD(::pid_t pid, int terminal_fd, 148 NativeDelegate &delegate, 149 const ArchSpec &arch, 150 MainLoop &mainloop) 151 : NativeProcessProtocol(pid, terminal_fd, delegate), m_arch(arch) { 152 if (m_terminal_fd != -1) { 153 Status status = EnsureFDFlags(m_terminal_fd, O_NONBLOCK); 154 assert(status.Success()); 155 } 156 157 Status status; 158 m_sigchld_handle = mainloop.RegisterSignal( 159 SIGCHLD, [this](MainLoopBase &) { SigchldHandler(); }, status); 160 assert(m_sigchld_handle && status.Success()); 161 } 162 163 // Handles all waitpid events from the inferior process. 164 void NativeProcessNetBSD::MonitorCallback(lldb::pid_t pid, int signal) { 165 switch (signal) { 166 case SIGTRAP: 167 return MonitorSIGTRAP(pid); 168 case SIGSTOP: 169 return MonitorSIGSTOP(pid); 170 default: 171 return MonitorSignal(pid, signal); 172 } 173 } 174 175 void NativeProcessNetBSD::MonitorExited(lldb::pid_t pid, WaitStatus status) { 176 Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); 177 178 LLDB_LOG(log, "got exit signal({0}) , pid = {1}", status, pid); 179 180 /* Stop Tracking All Threads attached to Process */ 181 m_threads.clear(); 182 183 SetExitStatus(status, true); 184 185 // Notify delegate that our process has exited. 186 SetState(StateType::eStateExited, true); 187 } 188 189 void NativeProcessNetBSD::MonitorSIGSTOP(lldb::pid_t pid) { 190 ptrace_siginfo_t info; 191 192 const auto siginfo_err = 193 PtraceWrapper(PT_GET_SIGINFO, pid, &info, sizeof(info)); 194 195 // Get details on the signal raised. 196 if (siginfo_err.Success()) { 197 // Handle SIGSTOP from LLGS (LLDB GDB Server) 198 if (info.psi_siginfo.si_code == SI_USER && 199 info.psi_siginfo.si_pid == ::getpid()) { 200 /* Stop Tracking all Threads attached to Process */ 201 for (const auto &thread : m_threads) { 202 static_cast<NativeThreadNetBSD &>(*thread).SetStoppedBySignal( 203 SIGSTOP, &info.psi_siginfo); 204 } 205 } 206 } 207 } 208 209 void NativeProcessNetBSD::MonitorSIGTRAP(lldb::pid_t pid) { 210 Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); 211 ptrace_siginfo_t info; 212 213 const auto siginfo_err = 214 PtraceWrapper(PT_GET_SIGINFO, pid, &info, sizeof(info)); 215 216 // Get details on the signal raised. 217 if (siginfo_err.Fail()) { 218 return; 219 } 220 221 switch (info.psi_siginfo.si_code) { 222 case TRAP_BRKPT: 223 for (const auto &thread : m_threads) { 224 static_cast<NativeThreadNetBSD &>(*thread).SetStoppedByBreakpoint(); 225 FixupBreakpointPCAsNeeded(static_cast<NativeThreadNetBSD &>(*thread)); 226 } 227 SetState(StateType::eStateStopped, true); 228 break; 229 case TRAP_TRACE: 230 for (const auto &thread : m_threads) 231 static_cast<NativeThreadNetBSD &>(*thread).SetStoppedByTrace(); 232 SetState(StateType::eStateStopped, true); 233 break; 234 case TRAP_EXEC: { 235 Status error = ReinitializeThreads(); 236 if (error.Fail()) { 237 SetState(StateType::eStateInvalid); 238 return; 239 } 240 241 // Let our delegate know we have just exec'd. 242 NotifyDidExec(); 243 244 for (const auto &thread : m_threads) 245 static_cast<NativeThreadNetBSD &>(*thread).SetStoppedByExec(); 246 SetState(StateType::eStateStopped, true); 247 } break; 248 case TRAP_DBREG: { 249 // If a watchpoint was hit, report it 250 uint32_t wp_index; 251 Status error = static_cast<NativeThreadNetBSD &>(*m_threads[info.psi_lwpid]) 252 .GetRegisterContext() 253 .GetWatchpointHitIndex( 254 wp_index, (uintptr_t)info.psi_siginfo.si_addr); 255 if (error.Fail()) 256 LLDB_LOG(log, 257 "received error while checking for watchpoint hits, pid = " 258 "{0}, LWP = {1}, error = {2}", 259 GetID(), info.psi_lwpid, error); 260 if (wp_index != LLDB_INVALID_INDEX32) { 261 for (const auto &thread : m_threads) 262 static_cast<NativeThreadNetBSD &>(*thread).SetStoppedByWatchpoint( 263 wp_index); 264 SetState(StateType::eStateStopped, true); 265 break; 266 } 267 268 // If a breakpoint was hit, report it 269 uint32_t bp_index; 270 error = static_cast<NativeThreadNetBSD &>(*m_threads[info.psi_lwpid]) 271 .GetRegisterContext() 272 .GetHardwareBreakHitIndex(bp_index, 273 (uintptr_t)info.psi_siginfo.si_addr); 274 if (error.Fail()) 275 LLDB_LOG(log, 276 "received error while checking for hardware " 277 "breakpoint hits, pid = {0}, LWP = {1}, error = {2}", 278 GetID(), info.psi_lwpid, error); 279 if (bp_index != LLDB_INVALID_INDEX32) { 280 for (const auto &thread : m_threads) 281 static_cast<NativeThreadNetBSD &>(*thread).SetStoppedByBreakpoint(); 282 SetState(StateType::eStateStopped, true); 283 break; 284 } 285 } break; 286 } 287 } 288 289 void NativeProcessNetBSD::MonitorSignal(lldb::pid_t pid, int signal) { 290 ptrace_siginfo_t info; 291 const auto siginfo_err = 292 PtraceWrapper(PT_GET_SIGINFO, pid, &info, sizeof(info)); 293 294 for (const auto &thread : m_threads) { 295 static_cast<NativeThreadNetBSD &>(*thread).SetStoppedBySignal( 296 info.psi_siginfo.si_signo, &info.psi_siginfo); 297 } 298 SetState(StateType::eStateStopped, true); 299 } 300 301 Status NativeProcessNetBSD::PtraceWrapper(int req, lldb::pid_t pid, void *addr, 302 int data, int *result) { 303 Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE)); 304 Status error; 305 int ret; 306 307 errno = 0; 308 ret = ptrace(req, static_cast<::pid_t>(pid), addr, data); 309 310 if (ret == -1) 311 error.SetErrorToErrno(); 312 313 if (result) 314 *result = ret; 315 316 LLDB_LOG(log, "ptrace({0}, {1}, {2}, {3})={4:x}", req, pid, addr, data, ret); 317 318 if (error.Fail()) 319 LLDB_LOG(log, "ptrace() failed: {0}", error); 320 321 return error; 322 } 323 324 Status NativeProcessNetBSD::Resume(const ResumeActionList &resume_actions) { 325 Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); 326 LLDB_LOG(log, "pid {0}", GetID()); 327 328 const auto &thread = m_threads[0]; 329 const ResumeAction *const action = 330 resume_actions.GetActionForThread(thread->GetID(), true); 331 332 if (action == nullptr) { 333 LLDB_LOG(log, "no action specified for pid {0} tid {1}", GetID(), 334 thread->GetID()); 335 return Status(); 336 } 337 338 Status error; 339 340 switch (action->state) { 341 case eStateRunning: { 342 // Run the thread, possibly feeding it the signal. 343 error = NativeProcessNetBSD::PtraceWrapper(PT_CONTINUE, GetID(), (void *)1, 344 action->signal); 345 if (!error.Success()) 346 return error; 347 for (const auto &thread : m_threads) 348 static_cast<NativeThreadNetBSD &>(*thread).SetRunning(); 349 SetState(eStateRunning, true); 350 break; 351 } 352 case eStateStepping: 353 // Run the thread, possibly feeding it the signal. 354 error = NativeProcessNetBSD::PtraceWrapper(PT_STEP, GetID(), (void *)1, 355 action->signal); 356 if (!error.Success()) 357 return error; 358 for (const auto &thread : m_threads) 359 static_cast<NativeThreadNetBSD &>(*thread).SetStepping(); 360 SetState(eStateStepping, true); 361 break; 362 363 case eStateSuspended: 364 case eStateStopped: 365 llvm_unreachable("Unexpected state"); 366 367 default: 368 return Status("NativeProcessNetBSD::%s (): unexpected state %s specified " 369 "for pid %" PRIu64 ", tid %" PRIu64, 370 __FUNCTION__, StateAsCString(action->state), GetID(), 371 thread->GetID()); 372 } 373 374 return Status(); 375 } 376 377 Status NativeProcessNetBSD::Halt() { 378 Status error; 379 380 if (kill(GetID(), SIGSTOP) != 0) 381 error.SetErrorToErrno(); 382 383 return error; 384 } 385 386 Status NativeProcessNetBSD::Detach() { 387 Status error; 388 389 // Stop monitoring the inferior. 390 m_sigchld_handle.reset(); 391 392 // Tell ptrace to detach from the process. 393 if (GetID() == LLDB_INVALID_PROCESS_ID) 394 return error; 395 396 return PtraceWrapper(PT_DETACH, GetID()); 397 } 398 399 Status NativeProcessNetBSD::Signal(int signo) { 400 Status error; 401 402 if (kill(GetID(), signo)) 403 error.SetErrorToErrno(); 404 405 return error; 406 } 407 408 Status NativeProcessNetBSD::Kill() { 409 Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); 410 LLDB_LOG(log, "pid {0}", GetID()); 411 412 Status error; 413 414 switch (m_state) { 415 case StateType::eStateInvalid: 416 case StateType::eStateExited: 417 case StateType::eStateCrashed: 418 case StateType::eStateDetached: 419 case StateType::eStateUnloaded: 420 // Nothing to do - the process is already dead. 421 LLDB_LOG(log, "ignored for PID {0} due to current state: {1}", GetID(), 422 StateAsCString(m_state)); 423 return error; 424 425 case StateType::eStateConnected: 426 case StateType::eStateAttaching: 427 case StateType::eStateLaunching: 428 case StateType::eStateStopped: 429 case StateType::eStateRunning: 430 case StateType::eStateStepping: 431 case StateType::eStateSuspended: 432 // We can try to kill a process in these states. 433 break; 434 } 435 436 if (kill(GetID(), SIGKILL) != 0) { 437 error.SetErrorToErrno(); 438 return error; 439 } 440 441 return error; 442 } 443 444 Status NativeProcessNetBSD::GetMemoryRegionInfo(lldb::addr_t load_addr, 445 MemoryRegionInfo &range_info) { 446 447 if (m_supports_mem_region == LazyBool::eLazyBoolNo) { 448 // We're done. 449 return Status("unsupported"); 450 } 451 452 Status error = PopulateMemoryRegionCache(); 453 if (error.Fail()) { 454 return error; 455 } 456 457 lldb::addr_t prev_base_address = 0; 458 // FIXME start by finding the last region that is <= target address using 459 // binary search. Data is sorted. 460 // There can be a ton of regions on pthreads apps with lots of threads. 461 for (auto it = m_mem_region_cache.begin(); it != m_mem_region_cache.end(); 462 ++it) { 463 MemoryRegionInfo &proc_entry_info = it->first; 464 // Sanity check assumption that memory map entries are ascending. 465 assert((proc_entry_info.GetRange().GetRangeBase() >= prev_base_address) && 466 "descending memory map entries detected, unexpected"); 467 prev_base_address = proc_entry_info.GetRange().GetRangeBase(); 468 UNUSED_IF_ASSERT_DISABLED(prev_base_address); 469 // If the target address comes before this entry, indicate distance to next 470 // region. 471 if (load_addr < proc_entry_info.GetRange().GetRangeBase()) { 472 range_info.GetRange().SetRangeBase(load_addr); 473 range_info.GetRange().SetByteSize( 474 proc_entry_info.GetRange().GetRangeBase() - load_addr); 475 range_info.SetReadable(MemoryRegionInfo::OptionalBool::eNo); 476 range_info.SetWritable(MemoryRegionInfo::OptionalBool::eNo); 477 range_info.SetExecutable(MemoryRegionInfo::OptionalBool::eNo); 478 range_info.SetMapped(MemoryRegionInfo::OptionalBool::eNo); 479 return error; 480 } else if (proc_entry_info.GetRange().Contains(load_addr)) { 481 // The target address is within the memory region we're processing here. 482 range_info = proc_entry_info; 483 return error; 484 } 485 // The target memory address comes somewhere after the region we just 486 // parsed. 487 } 488 // If we made it here, we didn't find an entry that contained the given 489 // address. Return the load_addr as start and the amount of bytes betwwen 490 // load address and the end of the memory as size. 491 range_info.GetRange().SetRangeBase(load_addr); 492 range_info.GetRange().SetRangeEnd(LLDB_INVALID_ADDRESS); 493 range_info.SetReadable(MemoryRegionInfo::OptionalBool::eNo); 494 range_info.SetWritable(MemoryRegionInfo::OptionalBool::eNo); 495 range_info.SetExecutable(MemoryRegionInfo::OptionalBool::eNo); 496 range_info.SetMapped(MemoryRegionInfo::OptionalBool::eNo); 497 return error; 498 } 499 500 Status NativeProcessNetBSD::PopulateMemoryRegionCache() { 501 Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); 502 // If our cache is empty, pull the latest. There should always be at least 503 // one memory region if memory region handling is supported. 504 if (!m_mem_region_cache.empty()) { 505 LLDB_LOG(log, "reusing {0} cached memory region entries", 506 m_mem_region_cache.size()); 507 return Status(); 508 } 509 510 struct kinfo_vmentry *vm; 511 size_t count, i; 512 vm = kinfo_getvmmap(GetID(), &count); 513 if (vm == NULL) { 514 m_supports_mem_region = LazyBool::eLazyBoolNo; 515 Status error; 516 error.SetErrorString("not supported"); 517 return error; 518 } 519 for (i = 0; i < count; i++) { 520 MemoryRegionInfo info; 521 info.Clear(); 522 info.GetRange().SetRangeBase(vm[i].kve_start); 523 info.GetRange().SetRangeEnd(vm[i].kve_end); 524 info.SetMapped(MemoryRegionInfo::OptionalBool::eYes); 525 526 if (vm[i].kve_protection & VM_PROT_READ) 527 info.SetReadable(MemoryRegionInfo::OptionalBool::eYes); 528 else 529 info.SetReadable(MemoryRegionInfo::OptionalBool::eNo); 530 531 if (vm[i].kve_protection & VM_PROT_WRITE) 532 info.SetWritable(MemoryRegionInfo::OptionalBool::eYes); 533 else 534 info.SetWritable(MemoryRegionInfo::OptionalBool::eNo); 535 536 if (vm[i].kve_protection & VM_PROT_EXECUTE) 537 info.SetExecutable(MemoryRegionInfo::OptionalBool::eYes); 538 else 539 info.SetExecutable(MemoryRegionInfo::OptionalBool::eNo); 540 541 if (vm[i].kve_path[0]) 542 info.SetName(vm[i].kve_path); 543 544 m_mem_region_cache.emplace_back( 545 info, FileSpec(info.GetName().GetCString())); 546 } 547 free(vm); 548 549 if (m_mem_region_cache.empty()) { 550 // No entries after attempting to read them. This shouldn't happen. Assume 551 // we don't support map entries. 552 LLDB_LOG(log, "failed to find any vmmap entries, assuming no support " 553 "for memory region metadata retrieval"); 554 m_supports_mem_region = LazyBool::eLazyBoolNo; 555 Status error; 556 error.SetErrorString("not supported"); 557 return error; 558 } 559 LLDB_LOG(log, "read {0} memory region entries from process {1}", 560 m_mem_region_cache.size(), GetID()); 561 // We support memory retrieval, remember that. 562 m_supports_mem_region = LazyBool::eLazyBoolYes; 563 return Status(); 564 } 565 566 Status NativeProcessNetBSD::AllocateMemory(size_t size, uint32_t permissions, 567 lldb::addr_t &addr) { 568 return Status("Unimplemented"); 569 } 570 571 Status NativeProcessNetBSD::DeallocateMemory(lldb::addr_t addr) { 572 return Status("Unimplemented"); 573 } 574 575 lldb::addr_t NativeProcessNetBSD::GetSharedLibraryInfoAddress() { 576 // punt on this for now 577 return LLDB_INVALID_ADDRESS; 578 } 579 580 size_t NativeProcessNetBSD::UpdateThreads() { return m_threads.size(); } 581 582 Status NativeProcessNetBSD::SetBreakpoint(lldb::addr_t addr, uint32_t size, 583 bool hardware) { 584 if (hardware) 585 return Status("NativeProcessNetBSD does not support hardware breakpoints"); 586 else 587 return SetSoftwareBreakpoint(addr, size); 588 } 589 590 Status NativeProcessNetBSD::GetLoadedModuleFileSpec(const char *module_path, 591 FileSpec &file_spec) { 592 return Status("Unimplemented"); 593 } 594 595 Status NativeProcessNetBSD::GetFileLoadAddress(const llvm::StringRef &file_name, 596 lldb::addr_t &load_addr) { 597 load_addr = LLDB_INVALID_ADDRESS; 598 return Status(); 599 } 600 601 void NativeProcessNetBSD::SigchldHandler() { 602 Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); 603 // Process all pending waitpid notifications. 604 int status; 605 ::pid_t wait_pid = 606 llvm::sys::RetryAfterSignal(-1, waitpid, GetID(), &status, WALLSIG | WNOHANG); 607 608 if (wait_pid == 0) 609 return; // We are done. 610 611 if (wait_pid == -1) { 612 Status error(errno, eErrorTypePOSIX); 613 LLDB_LOG(log, "waitpid ({0}, &status, _) failed: {1}", GetID(), error); 614 } 615 616 WaitStatus wait_status = WaitStatus::Decode(status); 617 bool exited = wait_status.type == WaitStatus::Exit || 618 (wait_status.type == WaitStatus::Signal && 619 wait_pid == static_cast<::pid_t>(GetID())); 620 621 LLDB_LOG(log, 622 "waitpid ({0}, &status, _) => pid = {1}, status = {2}, exited = {3}", 623 GetID(), wait_pid, status, exited); 624 625 if (exited) 626 MonitorExited(wait_pid, wait_status); 627 else { 628 assert(wait_status.type == WaitStatus::Stop); 629 MonitorCallback(wait_pid, wait_status.status); 630 } 631 } 632 633 bool NativeProcessNetBSD::HasThreadNoLock(lldb::tid_t thread_id) { 634 for (const auto &thread : m_threads) { 635 assert(thread && "thread list should not contain NULL threads"); 636 if (thread->GetID() == thread_id) { 637 // We have this thread. 638 return true; 639 } 640 } 641 642 // We don't have this thread. 643 return false; 644 } 645 646 NativeThreadNetBSD &NativeProcessNetBSD::AddThread(lldb::tid_t thread_id) { 647 648 Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD)); 649 LLDB_LOG(log, "pid {0} adding thread with tid {1}", GetID(), thread_id); 650 651 assert(!HasThreadNoLock(thread_id) && 652 "attempted to add a thread by id that already exists"); 653 654 // If this is the first thread, save it as the current thread 655 if (m_threads.empty()) 656 SetCurrentThreadID(thread_id); 657 658 m_threads.push_back(llvm::make_unique<NativeThreadNetBSD>(*this, thread_id)); 659 return static_cast<NativeThreadNetBSD &>(*m_threads.back()); 660 } 661 662 Status NativeProcessNetBSD::Attach() { 663 // Attach to the requested process. 664 // An attach will cause the thread to stop with a SIGSTOP. 665 Status status = PtraceWrapper(PT_ATTACH, m_pid); 666 if (status.Fail()) 667 return status; 668 669 int wstatus; 670 // Need to use WALLSIG otherwise we receive an error with errno=ECHLD At this 671 // point we should have a thread stopped if waitpid succeeds. 672 if ((wstatus = waitpid(m_pid, NULL, WALLSIG)) < 0) 673 return Status(errno, eErrorTypePOSIX); 674 675 /* Initialize threads */ 676 status = ReinitializeThreads(); 677 if (status.Fail()) 678 return status; 679 680 for (const auto &thread : m_threads) 681 static_cast<NativeThreadNetBSD &>(*thread).SetStoppedBySignal(SIGSTOP); 682 683 // Let our process instance know the thread has stopped. 684 SetState(StateType::eStateStopped); 685 return Status(); 686 } 687 688 Status NativeProcessNetBSD::ReadMemory(lldb::addr_t addr, void *buf, 689 size_t size, size_t &bytes_read) { 690 unsigned char *dst = static_cast<unsigned char *>(buf); 691 struct ptrace_io_desc io; 692 693 Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_MEMORY)); 694 LLDB_LOG(log, "addr = {0}, buf = {1}, size = {2}", addr, buf, size); 695 696 bytes_read = 0; 697 io.piod_op = PIOD_READ_D; 698 io.piod_len = size; 699 700 do { 701 io.piod_offs = (void *)(addr + bytes_read); 702 io.piod_addr = dst + bytes_read; 703 704 Status error = NativeProcessNetBSD::PtraceWrapper(PT_IO, GetID(), &io); 705 if (error.Fail()) 706 return error; 707 708 bytes_read = io.piod_len; 709 io.piod_len = size - bytes_read; 710 } while (bytes_read < size); 711 712 return Status(); 713 } 714 715 Status NativeProcessNetBSD::WriteMemory(lldb::addr_t addr, const void *buf, 716 size_t size, size_t &bytes_written) { 717 const unsigned char *src = static_cast<const unsigned char *>(buf); 718 Status error; 719 struct ptrace_io_desc io; 720 721 Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_MEMORY)); 722 LLDB_LOG(log, "addr = {0}, buf = {1}, size = {2}", addr, buf, size); 723 724 bytes_written = 0; 725 io.piod_op = PIOD_WRITE_D; 726 io.piod_len = size; 727 728 do { 729 io.piod_addr = const_cast<void *>(static_cast<const void *>(src + bytes_written)); 730 io.piod_offs = (void *)(addr + bytes_written); 731 732 Status error = NativeProcessNetBSD::PtraceWrapper(PT_IO, GetID(), &io); 733 if (error.Fail()) 734 return error; 735 736 bytes_written = io.piod_len; 737 io.piod_len = size - bytes_written; 738 } while (bytes_written < size); 739 740 return error; 741 } 742 743 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> 744 NativeProcessNetBSD::GetAuxvData() const { 745 /* 746 * ELF_AUX_ENTRIES is currently restricted to kernel 747 * (<sys/exec_elf.h> r. 1.155 specifies 15) 748 * 749 * ptrace(2) returns the whole AUXV including extra fiels after AT_NULL this 750 * information isn't needed. 751 */ 752 size_t auxv_size = 100 * sizeof(AuxInfo); 753 754 ErrorOr<std::unique_ptr<WritableMemoryBuffer>> buf = 755 llvm::WritableMemoryBuffer::getNewMemBuffer(auxv_size); 756 757 struct ptrace_io_desc io; 758 io.piod_op = PIOD_READ_AUXV; 759 io.piod_offs = 0; 760 io.piod_addr = static_cast<void *>(buf.get()->getBufferStart()); 761 io.piod_len = auxv_size; 762 763 Status error = NativeProcessNetBSD::PtraceWrapper(PT_IO, GetID(), &io); 764 765 if (error.Fail()) 766 return std::error_code(error.GetError(), std::generic_category()); 767 768 if (io.piod_len < 1) 769 return std::error_code(ECANCELED, std::generic_category()); 770 771 return std::move(buf); 772 } 773 774 Status NativeProcessNetBSD::ReinitializeThreads() { 775 // Clear old threads 776 m_threads.clear(); 777 778 // Initialize new thread 779 struct ptrace_lwpinfo info = {}; 780 Status error = PtraceWrapper(PT_LWPINFO, GetID(), &info, sizeof(info)); 781 if (error.Fail()) { 782 return error; 783 } 784 // Reinitialize from scratch threads and register them in process 785 while (info.pl_lwpid != 0) { 786 AddThread(info.pl_lwpid); 787 error = PtraceWrapper(PT_LWPINFO, GetID(), &info, sizeof(info)); 788 if (error.Fail()) { 789 return error; 790 } 791 } 792 793 return error; 794 } 795