1 //===-- NativeProcessDarwin.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 "NativeProcessDarwin.h" 11 12 // C includes 13 #include <mach/mach_init.h> 14 #include <mach/mach_traps.h> 15 #include <sys/ptrace.h> 16 #include <sys/stat.h> 17 #include <sys/sysctl.h> 18 #include <sys/types.h> 19 20 // C++ includes 21 // LLDB includes 22 #include "lldb/Core/State.h" 23 #include "lldb/Host/PseudoTerminal.h" 24 #include "lldb/Target/ProcessLaunchInfo.h" 25 #include "lldb/Utility/Log.h" 26 #include "lldb/Utility/StreamString.h" 27 28 #include "CFBundle.h" 29 #include "CFString.h" 30 #include "DarwinProcessLauncher.h" 31 32 #include "MachException.h" 33 34 #include "llvm/Support/FileSystem.h" 35 36 using namespace lldb; 37 using namespace lldb_private; 38 using namespace lldb_private::process_darwin; 39 using namespace lldb_private::darwin_process_launcher; 40 41 // ----------------------------------------------------------------------------- 42 // Hidden Impl 43 // ----------------------------------------------------------------------------- 44 45 namespace { 46 struct hack_task_dyld_info { 47 mach_vm_address_t all_image_info_addr; 48 mach_vm_size_t all_image_info_size; 49 }; 50 } 51 52 // ----------------------------------------------------------------------------- 53 // Public Static Methods 54 // ----------------------------------------------------------------------------- 55 56 Status NativeProcessProtocol::Launch( 57 ProcessLaunchInfo &launch_info, 58 NativeProcessProtocol::NativeDelegate &native_delegate, MainLoop &mainloop, 59 NativeProcessProtocolSP &native_process_sp) { 60 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); 61 62 Status error; 63 64 // Verify the working directory is valid if one was specified. 65 FileSpec working_dir(launch_info.GetWorkingDirectory()); 66 if (working_dir && 67 (!working_dir.ResolvePath() || 68 !llvm::sys::fs::is_directory(working_dir.GetPath())) { 69 error.SetErrorStringWithFormat("No such file or directory: %s", 70 working_dir.GetCString()); 71 return error; 72 } 73 74 // Launch the inferior. 75 int pty_master_fd = -1; 76 LaunchFlavor launch_flavor = LaunchFlavor::Default; 77 78 error = LaunchInferior(launch_info, &pty_master_fd, &launch_flavor); 79 80 // Handle launch failure. 81 if (!error.Success()) { 82 if (log) 83 log->Printf("NativeProcessDarwin::%s() failed to launch process: " 84 "%s", 85 __FUNCTION__, error.AsCString()); 86 return error; 87 } 88 89 // Handle failure to return a pid. 90 if (launch_info.GetProcessID() == LLDB_INVALID_PROCESS_ID) { 91 if (log) 92 log->Printf("NativeProcessDarwin::%s() launch succeeded but no " 93 "pid was returned! Aborting.", 94 __FUNCTION__); 95 return error; 96 } 97 98 // Create the Darwin native process impl. 99 std::shared_ptr<NativeProcessDarwin> np_darwin_sp( 100 new NativeProcessDarwin(launch_info.GetProcessID(), pty_master_fd)); 101 if (!np_darwin_sp->RegisterNativeDelegate(native_delegate)) { 102 native_process_sp.reset(); 103 error.SetErrorStringWithFormat("failed to register the native delegate"); 104 return error; 105 } 106 107 // Finalize the processing needed to debug the launched process with 108 // a NativeProcessDarwin instance. 109 error = np_darwin_sp->FinalizeLaunch(launch_flavor, mainloop); 110 if (!error.Success()) { 111 if (log) 112 log->Printf("NativeProcessDarwin::%s() aborting, failed to finalize" 113 " the launching of the process: %s", 114 __FUNCTION__, error.AsCString()); 115 return error; 116 } 117 118 // Return the process and process id to the caller through the launch args. 119 native_process_sp = np_darwin_sp; 120 return error; 121 } 122 123 Status NativeProcessProtocol::Attach( 124 lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &native_delegate, 125 MainLoop &mainloop, NativeProcessProtocolSP &native_process_sp) { 126 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); 127 if (log) 128 log->Printf("NativeProcessDarwin::%s(pid = %" PRIi64 ")", __FUNCTION__, 129 pid); 130 131 // Retrieve the architecture for the running process. 132 ArchSpec process_arch; 133 Status error = ResolveProcessArchitecture(pid, process_arch); 134 if (!error.Success()) 135 return error; 136 137 // TODO get attach to return this value. 138 const int pty_master_fd = -1; 139 std::shared_ptr<NativeProcessDarwin> native_process_darwin_sp( 140 new NativeProcessDarwin(pid, pty_master_fd)); 141 142 if (!native_process_darwin_sp->RegisterNativeDelegate(native_delegate)) { 143 error.SetErrorStringWithFormat("failed to register the native " 144 "delegate"); 145 return error; 146 } 147 148 native_process_darwin_sp->AttachToInferior(mainloop, pid, error); 149 if (!error.Success()) 150 return error; 151 152 native_process_sp = native_process_darwin_sp; 153 return error; 154 } 155 156 // ----------------------------------------------------------------------------- 157 // ctor/dtor 158 // ----------------------------------------------------------------------------- 159 160 NativeProcessDarwin::NativeProcessDarwin(lldb::pid_t pid, int pty_master_fd) 161 : NativeProcessProtocol(pid), m_task(TASK_NULL), m_did_exec(false), 162 m_cpu_type(0), m_exception_port(MACH_PORT_NULL), m_exc_port_info(), 163 m_exception_thread(nullptr), m_exception_messages_mutex(), 164 m_sent_interrupt_signo(0), m_auto_resume_signo(0), m_thread_list(), 165 m_thread_actions(), m_waitpid_pipe(), m_waitpid_thread(nullptr), 166 m_waitpid_reader_handle() { 167 // TODO add this to the NativeProcessProtocol constructor. 168 m_terminal_fd = pty_master_fd; 169 } 170 171 NativeProcessDarwin::~NativeProcessDarwin() {} 172 173 // ----------------------------------------------------------------------------- 174 // Instance methods 175 // ----------------------------------------------------------------------------- 176 177 Status NativeProcessDarwin::FinalizeLaunch(LaunchFlavor launch_flavor, 178 MainLoop &main_loop) { 179 Status error; 180 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); 181 182 #if 0 183 m_path = path; 184 size_t i; 185 char const *arg; 186 for (i=0; (arg = argv[i]) != NULL; i++) 187 m_args.push_back(arg); 188 #endif 189 190 error = StartExceptionThread(); 191 if (!error.Success()) { 192 if (log) 193 log->Printf("NativeProcessDarwin::%s(): failure starting the " 194 "mach exception port monitor thread: %s", 195 __FUNCTION__, error.AsCString()); 196 197 // Terminate the inferior process. There's nothing meaningful we can 198 // do if we can't receive signals and exceptions. Since we launched 199 // the process, it's fair game for us to kill it. 200 ::ptrace(PT_KILL, m_pid, 0, 0); 201 SetState(eStateExited); 202 203 return error; 204 } 205 206 StartSTDIOThread(); 207 208 if (launch_flavor == LaunchFlavor::PosixSpawn) { 209 SetState(eStateAttaching); 210 errno = 0; 211 int err = ::ptrace(PT_ATTACHEXC, m_pid, 0, 0); 212 if (err == 0) { 213 // m_flags |= eMachProcessFlagsAttached; 214 if (log) 215 log->Printf("NativeProcessDarwin::%s(): successfully spawned " 216 "process with pid %" PRIu64, 217 __FUNCTION__, m_pid); 218 } else { 219 error.SetErrorToErrno(); 220 SetState(eStateExited); 221 if (log) 222 log->Printf("NativeProcessDarwin::%s(): error: failed to " 223 "attach to spawned pid %" PRIu64 " (error=%d (%s))", 224 __FUNCTION__, m_pid, (int)error.GetError(), 225 error.AsCString()); 226 return error; 227 } 228 } 229 230 if (log) 231 log->Printf("NativeProcessDarwin::%s(): new pid is %" PRIu64 "...", 232 __FUNCTION__, m_pid); 233 234 // Spawn a thread to reap our child inferior process... 235 error = StartWaitpidThread(main_loop); 236 if (error.Fail()) { 237 if (log) 238 log->Printf("NativeProcessDarwin::%s(): failed to start waitpid() " 239 "thread: %s", 240 __FUNCTION__, error.AsCString()); 241 kill(SIGKILL, static_cast<::pid_t>(m_pid)); 242 return error; 243 } 244 245 if (TaskPortForProcessID(error) == TASK_NULL) { 246 // We failed to get the task for our process ID which is bad. 247 // Kill our process; otherwise, it will be stopped at the entry 248 // point and get reparented to someone else and never go away. 249 if (log) 250 log->Printf("NativeProcessDarwin::%s(): could not get task port " 251 "for process, sending SIGKILL and exiting: %s", 252 __FUNCTION__, error.AsCString()); 253 kill(SIGKILL, static_cast<::pid_t>(m_pid)); 254 return error; 255 } 256 257 // Indicate that we're stopped, as we always launch suspended. 258 SetState(eStateStopped); 259 260 // Success. 261 return error; 262 } 263 264 Status NativeProcessDarwin::SaveExceptionPortInfo() { 265 return m_exc_port_info.Save(m_task); 266 } 267 268 bool NativeProcessDarwin::ProcessUsingSpringBoard() const { 269 // TODO implement flags 270 // return (m_flags & eMachProcessFlagsUsingSBS) != 0; 271 return false; 272 } 273 274 bool NativeProcessDarwin::ProcessUsingBackBoard() const { 275 // TODO implement flags 276 // return (m_flags & eMachProcessFlagsUsingBKS) != 0; 277 return false; 278 } 279 280 // Called by the exception thread when an exception has been received from 281 // our process. The exception message is completely filled and the exception 282 // data has already been copied. 283 void NativeProcessDarwin::ExceptionMessageReceived( 284 const MachException::Message &message) { 285 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE)); 286 287 std::lock_guard<std::recursive_mutex> locker(m_exception_messages_mutex); 288 if (m_exception_messages.empty()) { 289 // Suspend the task the moment we receive our first exception message. 290 SuspendTask(); 291 } 292 293 // Use a locker to automatically unlock our mutex in case of exceptions 294 // Add the exception to our internal exception stack 295 m_exception_messages.push_back(message); 296 297 if (log) 298 log->Printf("NativeProcessDarwin::%s(): new queued message count: %lu", 299 __FUNCTION__, m_exception_messages.size()); 300 } 301 302 void *NativeProcessDarwin::ExceptionThread(void *arg) { 303 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE)); 304 if (!arg) { 305 if (log) 306 log->Printf("NativeProcessDarwin::%s(): cannot run mach exception " 307 "thread, mandatory process arg was null", 308 __FUNCTION__); 309 return nullptr; 310 } 311 312 return reinterpret_cast<NativeProcessDarwin *>(arg)->DoExceptionThread(); 313 } 314 315 void *NativeProcessDarwin::DoExceptionThread() { 316 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE)); 317 318 if (log) 319 log->Printf("NativeProcessDarwin::%s(arg=%p) starting thread...", 320 __FUNCTION__, this); 321 322 pthread_setname_np("exception monitoring thread"); 323 324 // Ensure we don't get CPU starved. 325 MaybeRaiseThreadPriority(); 326 327 // We keep a count of the number of consecutive exceptions received so 328 // we know to grab all exceptions without a timeout. We do this to get a 329 // bunch of related exceptions on our exception port so we can process 330 // then together. When we have multiple threads, we can get an exception 331 // per thread and they will come in consecutively. The main loop in this 332 // thread can stop periodically if needed to service things related to this 333 // process. 334 // 335 // [did we lose some words here?] 336 // 337 // flag set in the options, so we will wait forever for an exception on 338 // 0 our exception port. After we get one exception, we then will use the 339 // MACH_RCV_TIMEOUT option with a zero timeout to grab all other current 340 // exceptions for our process. After we have received the last pending 341 // exception, we will get a timeout which enables us to then notify 342 // our main thread that we have an exception bundle available. We then wait 343 // for the main thread to tell this exception thread to start trying to get 344 // exceptions messages again and we start again with a mach_msg read with 345 // infinite timeout. 346 // 347 // We choose to park a thread on this, rather than polling, because the 348 // polling is expensive. On devices, we need to minimize overhead caused 349 // by the process monitor. 350 uint32_t num_exceptions_received = 0; 351 Status error; 352 task_t task = m_task; 353 mach_msg_timeout_t periodic_timeout = 0; 354 355 #if defined(WITH_SPRINGBOARD) && !defined(WITH_BKS) 356 mach_msg_timeout_t watchdog_elapsed = 0; 357 mach_msg_timeout_t watchdog_timeout = 60 * 1000; 358 ::pid_t pid = (::pid_t)process->GetID(); 359 CFReleaser<SBSWatchdogAssertionRef> watchdog; 360 361 if (process->ProcessUsingSpringBoard()) { 362 // Request a renewal for every 60 seconds if we attached using 363 // SpringBoard. 364 watchdog.reset(::SBSWatchdogAssertionCreateForPID(nullptr, pid, 60)); 365 if (log) 366 log->Printf("::SBSWatchdogAssertionCreateForPID(NULL, %4.4x, 60) " 367 "=> %p", 368 pid, watchdog.get()); 369 370 if (watchdog.get()) { 371 ::SBSWatchdogAssertionRenew(watchdog.get()); 372 373 CFTimeInterval watchdogRenewalInterval = 374 ::SBSWatchdogAssertionGetRenewalInterval(watchdog.get()); 375 if (log) 376 log->Printf("::SBSWatchdogAssertionGetRenewalInterval(%p) => " 377 "%g seconds", 378 watchdog.get(), watchdogRenewalInterval); 379 if (watchdogRenewalInterval > 0.0) { 380 watchdog_timeout = (mach_msg_timeout_t)watchdogRenewalInterval * 1000; 381 if (watchdog_timeout > 3000) { 382 // Give us a second to renew our timeout. 383 watchdog_timeout -= 1000; 384 } else if (watchdog_timeout > 1000) { 385 // Give us a quarter of a second to renew our timeout. 386 watchdog_timeout -= 250; 387 } 388 } 389 } 390 if (periodic_timeout == 0 || periodic_timeout > watchdog_timeout) 391 periodic_timeout = watchdog_timeout; 392 } 393 #endif // #if defined (WITH_SPRINGBOARD) && !defined (WITH_BKS) 394 395 #ifdef WITH_BKS 396 CFReleaser<BKSWatchdogAssertionRef> watchdog; 397 if (process->ProcessUsingBackBoard()) { 398 ::pid_t pid = process->GetID(); 399 CFAllocatorRef alloc = kCFAllocatorDefault; 400 watchdog.reset(::BKSWatchdogAssertionCreateForPID(alloc, pid)); 401 } 402 #endif // #ifdef WITH_BKS 403 404 // Do we want to use a weak pointer to the NativeProcessDarwin here, in 405 // which case we can guarantee we don't whack the process monitor if we 406 // race between this thread and the main one on shutdown? 407 while (IsExceptionPortValid()) { 408 ::pthread_testcancel(); 409 410 MachException::Message exception_message; 411 412 if (num_exceptions_received > 0) { 413 // We don't want a timeout here, just receive as many exceptions as 414 // we can since we already have one. We want to get all currently 415 // available exceptions for this task at once. 416 error = exception_message.Receive( 417 GetExceptionPort(), 418 MACH_RCV_MSG | MACH_RCV_INTERRUPT | MACH_RCV_TIMEOUT, 0); 419 } else if (periodic_timeout > 0) { 420 // We need to stop periodically in this loop, so try and get a mach 421 // message with a valid timeout (ms). 422 error = exception_message.Receive(GetExceptionPort(), 423 MACH_RCV_MSG | MACH_RCV_INTERRUPT | 424 MACH_RCV_TIMEOUT, 425 periodic_timeout); 426 } else { 427 // We don't need to parse all current exceptions or stop 428 // periodically, just wait for an exception forever. 429 error = exception_message.Receive(GetExceptionPort(), 430 MACH_RCV_MSG | MACH_RCV_INTERRUPT, 0); 431 } 432 433 if (error.Success()) { 434 // We successfully received an exception. 435 if (exception_message.CatchExceptionRaise(task)) { 436 ++num_exceptions_received; 437 ExceptionMessageReceived(exception_message); 438 } 439 } else { 440 if (error.GetError() == MACH_RCV_INTERRUPTED) { 441 // We were interrupted. 442 443 // If we have no task port we should exit this thread, as it implies 444 // the inferior went down. 445 if (!IsExceptionPortValid()) { 446 if (log) 447 log->Printf("NativeProcessDarwin::%s(): the inferior " 448 "exception port is no longer valid, " 449 "canceling exception thread...", 450 __FUNCTION__); 451 // Should we be setting a process state here? 452 break; 453 } 454 455 // Make sure the inferior task is still valid. 456 if (IsTaskValid()) { 457 // Task is still ok. 458 if (log) 459 log->Printf("NativeProcessDarwin::%s(): interrupted, but " 460 "the inferior task iss till valid, " 461 "continuing...", 462 __FUNCTION__); 463 continue; 464 } else { 465 // The inferior task is no longer valid. Time to exit as 466 // the process has gone away. 467 if (log) 468 log->Printf("NativeProcessDarwin::%s(): the inferior task " 469 "has exited, and so will we...", 470 __FUNCTION__); 471 // Does this race at all with our waitpid()? 472 SetState(eStateExited); 473 break; 474 } 475 } else if (error.GetError() == MACH_RCV_TIMED_OUT) { 476 // We timed out when waiting for exceptions. 477 478 if (num_exceptions_received > 0) { 479 // We were receiving all current exceptions with a timeout of 480 // zero. It is time to go back to our normal looping mode. 481 num_exceptions_received = 0; 482 483 // Notify our main thread we have a complete exception message 484 // bundle available. Get the possibly updated task port back 485 // from the process in case we exec'ed and our task port 486 // changed. 487 task = ExceptionMessageBundleComplete(); 488 489 // In case we use a timeout value when getting exceptions, 490 // make sure our task is still valid. 491 if (IsTaskValid(task)) { 492 // Task is still ok. 493 if (log) 494 log->Printf("NativeProcessDarwin::%s(): got a timeout, " 495 "continuing...", 496 __FUNCTION__); 497 continue; 498 } else { 499 // The inferior task is no longer valid. Time to exit as 500 // the process has gone away. 501 if (log) 502 log->Printf("NativeProcessDarwin::%s(): the inferior " 503 "task has exited, and so will we...", 504 __FUNCTION__); 505 // Does this race at all with our waitpid()? 506 SetState(eStateExited); 507 break; 508 } 509 } 510 511 #if defined(WITH_SPRINGBOARD) && !defined(WITH_BKS) 512 if (watchdog.get()) { 513 watchdog_elapsed += periodic_timeout; 514 if (watchdog_elapsed >= watchdog_timeout) { 515 if (log) 516 log->Printf("SBSWatchdogAssertionRenew(%p)", watchdog.get()); 517 ::SBSWatchdogAssertionRenew(watchdog.get()); 518 watchdog_elapsed = 0; 519 } 520 } 521 #endif 522 } else { 523 if (log) 524 log->Printf("NativeProcessDarwin::%s(): continuing after " 525 "receiving an unexpected error: %u (%s)", 526 __FUNCTION__, error.GetError(), error.AsCString()); 527 // TODO: notify of error? 528 } 529 } 530 } 531 532 #if defined(WITH_SPRINGBOARD) && !defined(WITH_BKS) 533 if (watchdog.get()) { 534 // TODO: change SBSWatchdogAssertionRelease to SBSWatchdogAssertionCancel 535 // when we 536 // all are up and running on systems that support it. The SBS framework has 537 // a #define 538 // that will forward SBSWatchdogAssertionRelease to 539 // SBSWatchdogAssertionCancel for now 540 // so it should still build either way. 541 DNBLogThreadedIf(LOG_TASK, "::SBSWatchdogAssertionRelease(%p)", 542 watchdog.get()); 543 ::SBSWatchdogAssertionRelease(watchdog.get()); 544 } 545 #endif // #if defined (WITH_SPRINGBOARD) && !defined (WITH_BKS) 546 547 if (log) 548 log->Printf("NativeProcessDarwin::%s(%p): thread exiting...", __FUNCTION__, 549 this); 550 return nullptr; 551 } 552 553 Status NativeProcessDarwin::StartExceptionThread() { 554 Status error; 555 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); 556 if (log) 557 log->Printf("NativeProcessDarwin::%s() called", __FUNCTION__); 558 559 // Make sure we've looked up the inferior port. 560 TaskPortForProcessID(error); 561 562 // Ensure the inferior task is valid. 563 if (!IsTaskValid()) { 564 error.SetErrorStringWithFormat("cannot start exception thread: " 565 "task 0x%4.4x is not valid", 566 m_task); 567 return error; 568 } 569 570 // Get the mach port for the process monitor. 571 mach_port_t task_self = mach_task_self(); 572 573 // Allocate an exception port that we will use to track our child process 574 auto mach_err = ::mach_port_allocate(task_self, MACH_PORT_RIGHT_RECEIVE, 575 &m_exception_port); 576 error.SetError(mach_err, eErrorTypeMachKernel); 577 if (error.Fail()) { 578 if (log) 579 log->Printf("NativeProcessDarwin::%s(): mach_port_allocate(" 580 "task_self=0x%4.4x, MACH_PORT_RIGHT_RECEIVE, " 581 "&m_exception_port) failed: %u (%s)", 582 __FUNCTION__, task_self, error.GetError(), error.AsCString()); 583 return error; 584 } 585 586 // Add the ability to send messages on the new exception port 587 mach_err = ::mach_port_insert_right( 588 task_self, m_exception_port, m_exception_port, MACH_MSG_TYPE_MAKE_SEND); 589 error.SetError(mach_err, eErrorTypeMachKernel); 590 if (error.Fail()) { 591 if (log) 592 log->Printf("NativeProcessDarwin::%s(): mach_port_insert_right(" 593 "task_self=0x%4.4x, m_exception_port=0x%4.4x, " 594 "m_exception_port=0x%4.4x, MACH_MSG_TYPE_MAKE_SEND) " 595 "failed: %u (%s)", 596 __FUNCTION__, task_self, m_exception_port, m_exception_port, 597 error.GetError(), error.AsCString()); 598 return error; 599 } 600 601 // Save the original state of the exception ports for our child process. 602 error = SaveExceptionPortInfo(); 603 if (error.Fail() || (m_exc_port_info.mask == 0)) { 604 if (log) 605 log->Printf("NativeProcessDarwin::%s(): SaveExceptionPortInfo() " 606 "failed, cannot install exception handler: %s", 607 __FUNCTION__, error.AsCString()); 608 return error; 609 } 610 611 // Set the ability to get all exceptions on this port. 612 mach_err = ::task_set_exception_ports( 613 m_task, m_exc_port_info.mask, m_exception_port, 614 EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES, THREAD_STATE_NONE); 615 error.SetError(mach_err, eErrorTypeMachKernel); 616 if (error.Fail()) { 617 if (log) 618 log->Printf("::task_set_exception_ports (task = 0x%4.4x, " 619 "exception_mask = 0x%8.8x, new_port = 0x%4.4x, " 620 "behavior = 0x%8.8x, new_flavor = 0x%8.8x) failed: " 621 "%u (%s)", 622 m_task, m_exc_port_info.mask, m_exception_port, 623 (EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES), THREAD_STATE_NONE, 624 error.GetError(), error.AsCString()); 625 return error; 626 } 627 628 // Create the exception thread. 629 auto pthread_err = 630 ::pthread_create(&m_exception_thread, nullptr, ExceptionThread, this); 631 error.SetError(pthread_err, eErrorTypePOSIX); 632 if (error.Fail()) { 633 if (log) 634 log->Printf("NativeProcessDarwin::%s(): failed to create Mach " 635 "exception-handling thread: %u (%s)", 636 __FUNCTION__, error.GetError(), error.AsCString()); 637 } 638 639 return error; 640 } 641 642 lldb::addr_t 643 NativeProcessDarwin::GetDYLDAllImageInfosAddress(Status &error) const { 644 error.Clear(); 645 646 struct hack_task_dyld_info dyld_info; 647 mach_msg_type_number_t count = TASK_DYLD_INFO_COUNT; 648 // Make sure that COUNT isn't bigger than our hacked up struct 649 // hack_task_dyld_info. If it is, then make COUNT smaller to match. 650 if (count > (sizeof(struct hack_task_dyld_info) / sizeof(natural_t))) { 651 count = (sizeof(struct hack_task_dyld_info) / sizeof(natural_t)); 652 } 653 654 TaskPortForProcessID(error); 655 if (error.Fail()) 656 return LLDB_INVALID_ADDRESS; 657 658 auto mach_err = 659 ::task_info(m_task, TASK_DYLD_INFO, (task_info_t)&dyld_info, &count); 660 error.SetError(mach_err, eErrorTypeMachKernel); 661 if (error.Success()) { 662 // We now have the address of the all image infos structure. 663 return dyld_info.all_image_info_addr; 664 } 665 666 // We don't have it. 667 return LLDB_INVALID_ADDRESS; 668 } 669 670 uint32_t NativeProcessDarwin::GetCPUTypeForLocalProcess(::pid_t pid) { 671 int mib[CTL_MAXNAME] = { 672 0, 673 }; 674 size_t len = CTL_MAXNAME; 675 676 if (::sysctlnametomib("sysctl.proc_cputype", mib, &len)) 677 return 0; 678 679 mib[len] = pid; 680 len++; 681 682 cpu_type_t cpu; 683 size_t cpu_len = sizeof(cpu); 684 if (::sysctl(mib, static_cast<u_int>(len), &cpu, &cpu_len, 0, 0)) 685 cpu = 0; 686 return cpu; 687 } 688 689 uint32_t NativeProcessDarwin::GetCPUType() const { 690 if (m_cpu_type == 0 && m_pid != 0) 691 m_cpu_type = GetCPUTypeForLocalProcess(m_pid); 692 return m_cpu_type; 693 } 694 695 task_t NativeProcessDarwin::ExceptionMessageBundleComplete() { 696 // We have a complete bundle of exceptions for our child process. 697 Status error; 698 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE)); 699 700 std::lock_guard<std::recursive_mutex> locker(m_exception_messages_mutex); 701 if (log) 702 log->Printf("NativeProcessDarwin::%s(): processing %lu exception " 703 "messages.", 704 __FUNCTION__, m_exception_messages.size()); 705 706 if (m_exception_messages.empty()) { 707 // Not particularly useful... 708 return m_task; 709 } 710 711 bool auto_resume = false; 712 m_did_exec = false; 713 714 // First check for any SIGTRAP and make sure we didn't exec 715 const task_t task = m_task; 716 size_t i; 717 if (m_pid != 0) { 718 bool received_interrupt = false; 719 uint32_t num_task_exceptions = 0; 720 for (i = 0; i < m_exception_messages.size(); ++i) { 721 if (m_exception_messages[i].state.task_port != task) { 722 // This is an exception that is not for our inferior, ignore. 723 continue; 724 } 725 726 // This is an exception for the inferior. 727 ++num_task_exceptions; 728 const int signo = m_exception_messages[i].state.SoftSignal(); 729 if (signo == SIGTRAP) { 730 // SIGTRAP could mean that we exec'ed. We need to check the 731 // dyld all_image_infos.infoArray to see if it is NULL and if 732 // so, say that we exec'ed. 733 const addr_t aii_addr = GetDYLDAllImageInfosAddress(error); 734 if (aii_addr == LLDB_INVALID_ADDRESS) 735 break; 736 737 const addr_t info_array_count_addr = aii_addr + 4; 738 uint32_t info_array_count = 0; 739 size_t bytes_read = 0; 740 Status read_error; 741 read_error = ReadMemory(info_array_count_addr, // source addr 742 &info_array_count, // dest addr 743 4, // byte count 744 bytes_read); // #bytes read 745 if (read_error.Success() && (bytes_read == 4)) { 746 if (info_array_count == 0) { 747 // We got the all infos address, and there are zero 748 // entries. We think we exec'd. 749 m_did_exec = true; 750 751 // Force the task port to update itself in case the 752 // task port changed after exec 753 const task_t old_task = m_task; 754 const bool force_update = true; 755 const task_t new_task = TaskPortForProcessID(error, force_update); 756 if (old_task != new_task) { 757 if (log) 758 log->Printf("exec: inferior task port changed " 759 "from 0x%4.4x to 0x%4.4x", 760 old_task, new_task); 761 } 762 } 763 } else { 764 if (log) 765 log->Printf("NativeProcessDarwin::%s() warning: " 766 "failed to read all_image_infos." 767 "infoArrayCount from 0x%8.8llx", 768 __FUNCTION__, info_array_count_addr); 769 } 770 } else if ((m_sent_interrupt_signo != 0) && 771 (signo == m_sent_interrupt_signo)) { 772 // We just received the interrupt that we sent to ourselves. 773 received_interrupt = true; 774 } 775 } 776 777 if (m_did_exec) { 778 cpu_type_t process_cpu_type = GetCPUTypeForLocalProcess(m_pid); 779 if (m_cpu_type != process_cpu_type) { 780 if (log) 781 log->Printf("NativeProcessDarwin::%s(): arch changed from " 782 "0x%8.8x to 0x%8.8x", 783 __FUNCTION__, m_cpu_type, process_cpu_type); 784 m_cpu_type = process_cpu_type; 785 // TODO figure out if we need to do something here. 786 // DNBArchProtocol::SetArchitecture (process_cpu_type); 787 } 788 m_thread_list.Clear(); 789 790 // TODO hook up breakpoints. 791 // m_breakpoints.DisableAll(); 792 } 793 794 if (m_sent_interrupt_signo != 0) { 795 if (received_interrupt) { 796 if (log) 797 log->Printf("NativeProcessDarwin::%s(): process " 798 "successfully interrupted with signal %i", 799 __FUNCTION__, m_sent_interrupt_signo); 800 801 // Mark that we received the interrupt signal 802 m_sent_interrupt_signo = 0; 803 // Now check if we had a case where: 804 // 1 - We called NativeProcessDarwin::Interrupt() but we stopped 805 // for another reason. 806 // 2 - We called NativeProcessDarwin::Resume() (but still 807 // haven't gotten the interrupt signal). 808 // 3 - We are now incorrectly stopped because we are handling 809 // the interrupt signal we missed. 810 // 4 - We might need to resume if we stopped only with the 811 // interrupt signal that we never handled. 812 if (m_auto_resume_signo != 0) { 813 // Only auto_resume if we stopped with _only_ the interrupt 814 // signal. 815 if (num_task_exceptions == 1) { 816 auto_resume = true; 817 if (log) 818 log->Printf("NativeProcessDarwin::%s(): auto " 819 "resuming due to unhandled interrupt " 820 "signal %i", 821 __FUNCTION__, m_auto_resume_signo); 822 } 823 m_auto_resume_signo = 0; 824 } 825 } else { 826 if (log) 827 log->Printf("NativeProcessDarwin::%s(): didn't get signal " 828 "%i after MachProcess::Interrupt()", 829 __FUNCTION__, m_sent_interrupt_signo); 830 } 831 } 832 } 833 834 // Let all threads recover from stopping and do any clean up based 835 // on the previous thread state (if any). 836 m_thread_list.ProcessDidStop(*this); 837 838 // Let each thread know of any exceptions 839 for (i = 0; i < m_exception_messages.size(); ++i) { 840 // Let the thread list forward all exceptions on down to each thread. 841 if (m_exception_messages[i].state.task_port == task) { 842 // This exception is for our inferior. 843 m_thread_list.NotifyException(m_exception_messages[i].state); 844 } 845 846 if (log) { 847 StreamString stream; 848 m_exception_messages[i].Dump(stream); 849 stream.Flush(); 850 log->PutCString(stream.GetString().c_str()); 851 } 852 } 853 854 if (log) { 855 StreamString stream; 856 m_thread_list.Dump(stream); 857 stream.Flush(); 858 log->PutCString(stream.GetString().c_str()); 859 } 860 861 bool step_more = false; 862 if (m_thread_list.ShouldStop(step_more) && (auto_resume == false)) { 863 // TODO - need to hook up event system here. !!!! 864 #if 0 865 // Wait for the eEventProcessRunningStateChanged event to be reset 866 // before changing state to stopped to avoid race condition with 867 // very fast start/stops. 868 struct timespec timeout; 869 870 //DNBTimer::OffsetTimeOfDay(&timeout, 0, 250 * 1000); // Wait for 250 ms 871 DNBTimer::OffsetTimeOfDay(&timeout, 1, 0); // Wait for 250 ms 872 m_events.WaitForEventsToReset(eEventProcessRunningStateChanged, 873 &timeout); 874 #endif 875 SetState(eStateStopped); 876 } else { 877 // Resume without checking our current state. 878 PrivateResume(); 879 } 880 881 return m_task; 882 } 883 884 void NativeProcessDarwin::StartSTDIOThread() { 885 // TODO implement 886 } 887 888 Status NativeProcessDarwin::StartWaitpidThread(MainLoop &main_loop) { 889 Status error; 890 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); 891 892 // Strategy: create a thread that sits on waitpid(), waiting for the 893 // inferior process to die, reaping it in the process. Arrange for 894 // the thread to have a pipe file descriptor that it can send a byte 895 // over when the waitpid completes. Have the main loop have a read 896 // object for the other side of the pipe, and have the callback for 897 // the read do the process termination message sending. 898 899 // Create a single-direction communication channel. 900 const bool child_inherits = false; 901 error = m_waitpid_pipe.CreateNew(child_inherits); 902 if (error.Fail()) { 903 if (log) 904 log->Printf("NativeProcessDarwin::%s(): failed to create waitpid " 905 "communication pipe: %s", 906 __FUNCTION__, error.AsCString()); 907 return error; 908 } 909 910 // Hook up the waitpid reader callback. 911 912 // TODO make PipePOSIX derive from IOObject. This is goofy here. 913 const bool transfer_ownership = false; 914 auto io_sp = IOObjectSP( 915 new File(m_waitpid_pipe.GetReadFileDescriptor(), transfer_ownership)); 916 m_waitpid_reader_handle = main_loop.RegisterReadObject( 917 io_sp, [this](MainLoopBase &) { HandleWaitpidResult(); }, error); 918 919 // Create the thread. 920 auto pthread_err = 921 ::pthread_create(&m_waitpid_thread, nullptr, WaitpidThread, this); 922 error.SetError(pthread_err, eErrorTypePOSIX); 923 if (error.Fail()) { 924 if (log) 925 log->Printf("NativeProcessDarwin::%s(): failed to create waitpid " 926 "handling thread: %u (%s)", 927 __FUNCTION__, error.GetError(), error.AsCString()); 928 return error; 929 } 930 931 return error; 932 } 933 934 void *NativeProcessDarwin::WaitpidThread(void *arg) { 935 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); 936 if (!arg) { 937 if (log) 938 log->Printf("NativeProcessDarwin::%s(): cannot run waitpid " 939 "thread, mandatory process arg was null", 940 __FUNCTION__); 941 return nullptr; 942 } 943 944 return reinterpret_cast<NativeProcessDarwin *>(arg)->DoWaitpidThread(); 945 } 946 947 void NativeProcessDarwin::MaybeRaiseThreadPriority() { 948 #if defined(__arm__) || defined(__arm64__) || defined(__aarch64__) 949 struct sched_param thread_param; 950 int thread_sched_policy; 951 if (pthread_getschedparam(pthread_self(), &thread_sched_policy, 952 &thread_param) == 0) { 953 thread_param.sched_priority = 47; 954 pthread_setschedparam(pthread_self(), thread_sched_policy, &thread_param); 955 } 956 #endif 957 } 958 959 void *NativeProcessDarwin::DoWaitpidThread() { 960 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); 961 962 if (m_pid == LLDB_INVALID_PROCESS_ID) { 963 if (log) 964 log->Printf("NativeProcessDarwin::%s(): inferior process ID is " 965 "not set, cannot waitpid on it", 966 __FUNCTION__); 967 return nullptr; 968 } 969 970 // Name the thread. 971 pthread_setname_np("waitpid thread"); 972 973 // Ensure we don't get CPU starved. 974 MaybeRaiseThreadPriority(); 975 976 Status error; 977 int status = -1; 978 979 while (1) { 980 // Do a waitpid. 981 ::pid_t child_pid = ::waitpid(m_pid, &status, 0); 982 if (child_pid < 0) 983 error.SetErrorToErrno(); 984 if (error.Fail()) { 985 if (error.GetError() == EINTR) { 986 // This is okay, we can keep going. 987 if (log) 988 log->Printf("NativeProcessDarwin::%s(): waitpid(pid = %" PRIu64 989 ", &status, 0) interrupted, continuing", 990 __FUNCTION__, m_pid); 991 continue; 992 } 993 994 // This error is not okay, abort. 995 if (log) 996 log->Printf("NativeProcessDarwin::%s(): waitpid(pid = %" PRIu64 997 ", &status, 0) aborting due to error: %u (%s)", 998 __FUNCTION__, m_pid, error.GetError(), error.AsCString()); 999 break; 1000 } 1001 1002 // Log the successful result. 1003 if (log) 1004 log->Printf("NativeProcessDarwin::%s(): waitpid(pid = %" PRIu64 1005 ", &status, 0) => %i, status = %i", 1006 __FUNCTION__, m_pid, child_pid, status); 1007 1008 // Handle the result. 1009 if (WIFSTOPPED(status)) { 1010 if (log) 1011 log->Printf("NativeProcessDarwin::%s(): waitpid(pid = %" PRIu64 1012 ") received a stop, continuing waitpid() loop", 1013 __FUNCTION__, m_pid); 1014 continue; 1015 } else // if (WIFEXITED(status) || WIFSIGNALED(status)) 1016 { 1017 if (log) 1018 log->Printf("NativeProcessDarwin::%s(pid = %" PRIu64 "): " 1019 "waitpid thread is setting exit status for pid = " 1020 "%i to %i", 1021 __FUNCTION__, m_pid, child_pid, status); 1022 1023 error = SendInferiorExitStatusToMainLoop(child_pid, status); 1024 return nullptr; 1025 } 1026 } 1027 1028 // We should never exit as long as our child process is alive. If we 1029 // get here, something completely unexpected went wrong and we should exit. 1030 if (log) 1031 log->Printf( 1032 "NativeProcessDarwin::%s(): internal error: waitpid thread " 1033 "exited out of its main loop in an unexpected way. pid = %" PRIu64 1034 ". Sending exit status of -1.", 1035 __FUNCTION__, m_pid); 1036 1037 error = SendInferiorExitStatusToMainLoop((::pid_t)m_pid, -1); 1038 return nullptr; 1039 } 1040 1041 Status NativeProcessDarwin::SendInferiorExitStatusToMainLoop(::pid_t pid, 1042 int status) { 1043 Status error; 1044 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); 1045 1046 size_t bytes_written = 0; 1047 1048 // Send the pid. 1049 error = m_waitpid_pipe.Write(&pid, sizeof(pid), bytes_written); 1050 if (error.Fail() || (bytes_written < sizeof(pid))) { 1051 if (log) 1052 log->Printf("NativeProcessDarwin::%s() - failed to write " 1053 "waitpid exiting pid to the pipe. Client will not " 1054 "hear about inferior exit status!", 1055 __FUNCTION__); 1056 return error; 1057 } 1058 1059 // Send the status. 1060 bytes_written = 0; 1061 error = m_waitpid_pipe.Write(&status, sizeof(status), bytes_written); 1062 if (error.Fail() || (bytes_written < sizeof(status))) { 1063 if (log) 1064 log->Printf("NativeProcessDarwin::%s() - failed to write " 1065 "waitpid exit result to the pipe. Client will not " 1066 "hear about inferior exit status!", 1067 __FUNCTION__); 1068 } 1069 return error; 1070 } 1071 1072 Status NativeProcessDarwin::HandleWaitpidResult() { 1073 Status error; 1074 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); 1075 1076 // Read the pid. 1077 const bool notify_status = true; 1078 1079 ::pid_t pid = -1; 1080 size_t bytes_read = 0; 1081 error = m_waitpid_pipe.Read(&pid, sizeof(pid), bytes_read); 1082 if (error.Fail() || (bytes_read < sizeof(pid))) { 1083 if (log) 1084 log->Printf("NativeProcessDarwin::%s() - failed to read " 1085 "waitpid exiting pid from the pipe. Will notify " 1086 "as if parent process died with exit status -1.", 1087 __FUNCTION__); 1088 SetExitStatus(WaitStatus(WaitStatus::Exit, -1), notify_status); 1089 return error; 1090 } 1091 1092 // Read the status. 1093 int status = -1; 1094 error = m_waitpid_pipe.Read(&status, sizeof(status), bytes_read); 1095 if (error.Fail() || (bytes_read < sizeof(status))) { 1096 if (log) 1097 log->Printf("NativeProcessDarwin::%s() - failed to read " 1098 "waitpid exit status from the pipe. Will notify " 1099 "as if parent process died with exit status -1.", 1100 __FUNCTION__); 1101 SetExitStatus(WaitStatus(WaitStatus::Exit, -1), notify_status); 1102 return error; 1103 } 1104 1105 // Notify the monitor that our state has changed. 1106 if (log) 1107 log->Printf("NativeProcessDarwin::%s(): main loop received waitpid " 1108 "exit status info: pid=%i (%s), status=%i", 1109 __FUNCTION__, pid, 1110 (pid == m_pid) ? "the inferior" : "not the inferior", status); 1111 1112 SetExitStatus(WaitStatus::Decode(status), notify_status); 1113 return error; 1114 } 1115 1116 task_t NativeProcessDarwin::TaskPortForProcessID(Status &error, 1117 bool force) const { 1118 if ((m_task == TASK_NULL) || force) { 1119 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); 1120 if (m_pid == LLDB_INVALID_PROCESS_ID) { 1121 if (log) 1122 log->Printf("NativeProcessDarwin::%s(): cannot get task due " 1123 "to invalid pid", 1124 __FUNCTION__); 1125 return TASK_NULL; 1126 } 1127 1128 const uint32_t num_retries = 10; 1129 const uint32_t usec_interval = 10000; 1130 1131 mach_port_t task_self = mach_task_self(); 1132 task_t task = TASK_NULL; 1133 1134 for (uint32_t i = 0; i < num_retries; i++) { 1135 kern_return_t err = ::task_for_pid(task_self, m_pid, &task); 1136 if (err == 0) { 1137 // Succeeded. Save and return it. 1138 error.Clear(); 1139 m_task = task; 1140 log->Printf("NativeProcessDarwin::%s(): ::task_for_pid(" 1141 "stub_port = 0x%4.4x, pid = %llu, &task) " 1142 "succeeded: inferior task port = 0x%4.4x", 1143 __FUNCTION__, task_self, m_pid, m_task); 1144 return m_task; 1145 } else { 1146 // Failed to get the task for the inferior process. 1147 error.SetError(err, eErrorTypeMachKernel); 1148 if (log) { 1149 log->Printf("NativeProcessDarwin::%s(): ::task_for_pid(" 1150 "stub_port = 0x%4.4x, pid = %llu, &task) " 1151 "failed, err = 0x%8.8x (%s)", 1152 __FUNCTION__, task_self, m_pid, err, error.AsCString()); 1153 } 1154 } 1155 1156 // Sleep a bit and try again 1157 ::usleep(usec_interval); 1158 } 1159 1160 // We failed to get the task for the inferior process. 1161 // Ensure that it is cleared out. 1162 m_task = TASK_NULL; 1163 } 1164 return m_task; 1165 } 1166 1167 void NativeProcessDarwin::AttachToInferior(MainLoop &mainloop, lldb::pid_t pid, 1168 Status &error) { 1169 error.SetErrorString("TODO: implement"); 1170 } 1171 1172 Status NativeProcessDarwin::PrivateResume() { 1173 Status error; 1174 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); 1175 1176 std::lock_guard<std::recursive_mutex> locker(m_exception_messages_mutex); 1177 m_auto_resume_signo = m_sent_interrupt_signo; 1178 1179 if (log) { 1180 if (m_auto_resume_signo) 1181 log->Printf("NativeProcessDarwin::%s(): task 0x%x resuming (with " 1182 "unhandled interrupt signal %i)...", 1183 __FUNCTION__, m_task, m_auto_resume_signo); 1184 else 1185 log->Printf("NativeProcessDarwin::%s(): task 0x%x resuming...", 1186 __FUNCTION__, m_task); 1187 } 1188 1189 error = ReplyToAllExceptions(); 1190 if (error.Fail()) { 1191 if (log) 1192 log->Printf("NativeProcessDarwin::%s(): aborting, failed to " 1193 "reply to exceptions: %s", 1194 __FUNCTION__, error.AsCString()); 1195 return error; 1196 } 1197 // bool stepOverBreakInstruction = step; 1198 1199 // Let the thread prepare to resume and see if any threads want us to 1200 // step over a breakpoint instruction (ProcessWillResume will modify 1201 // the value of stepOverBreakInstruction). 1202 m_thread_list.ProcessWillResume(*this, m_thread_actions); 1203 1204 // Set our state accordingly 1205 if (m_thread_actions.NumActionsWithState(eStateStepping)) 1206 SetState(eStateStepping); 1207 else 1208 SetState(eStateRunning); 1209 1210 // Now resume our task. 1211 error = ResumeTask(); 1212 return error; 1213 } 1214 1215 Status NativeProcessDarwin::ReplyToAllExceptions() { 1216 Status error; 1217 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE)); 1218 1219 TaskPortForProcessID(error); 1220 if (error.Fail()) { 1221 if (log) 1222 log->Printf("NativeProcessDarwin::%s(): no task port, aborting", 1223 __FUNCTION__); 1224 return error; 1225 } 1226 1227 std::lock_guard<std::recursive_mutex> locker(m_exception_messages_mutex); 1228 if (m_exception_messages.empty()) { 1229 // We're done. 1230 return error; 1231 } 1232 1233 size_t index = 0; 1234 for (auto &message : m_exception_messages) { 1235 if (log) { 1236 log->Printf("NativeProcessDarwin::%s(): replying to exception " 1237 "%zu...", 1238 __FUNCTION__, index++); 1239 } 1240 1241 int thread_reply_signal = 0; 1242 1243 const tid_t tid = 1244 m_thread_list.GetThreadIDByMachPortNumber(message.state.thread_port); 1245 const ResumeAction *action = nullptr; 1246 if (tid != LLDB_INVALID_THREAD_ID) 1247 action = m_thread_actions.GetActionForThread(tid, false); 1248 1249 if (action) { 1250 thread_reply_signal = action->signal; 1251 if (thread_reply_signal) 1252 m_thread_actions.SetSignalHandledForThread(tid); 1253 } 1254 1255 error = message.Reply(m_pid, m_task, thread_reply_signal); 1256 if (error.Fail() && log) { 1257 // We log any error here, but we don't stop the exception 1258 // response handling. 1259 log->Printf("NativeProcessDarwin::%s(): failed to reply to " 1260 "exception: %s", 1261 __FUNCTION__, error.AsCString()); 1262 error.Clear(); 1263 } 1264 } 1265 1266 // Erase all exception message as we should have used and replied 1267 // to them all already. 1268 m_exception_messages.clear(); 1269 return error; 1270 } 1271 1272 Status NativeProcessDarwin::ResumeTask() { 1273 Status error; 1274 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); 1275 1276 TaskPortForProcessID(error); 1277 if (error.Fail()) { 1278 if (log) 1279 log->Printf("NativeProcessDarwin::%s(): failed to get task port " 1280 "for process when attempting to resume: %s", 1281 __FUNCTION__, error.AsCString()); 1282 return error; 1283 } 1284 if (m_task == TASK_NULL) { 1285 error.SetErrorString("task port retrieval succeeded but task port is " 1286 "null when attempting to resume the task"); 1287 return error; 1288 } 1289 1290 if (log) 1291 log->Printf("NativeProcessDarwin::%s(): requesting resume of task " 1292 "0x%4.4x", 1293 __FUNCTION__, m_task); 1294 1295 // Get the BasicInfo struct to verify that we're suspended before we try 1296 // to resume the task. 1297 struct task_basic_info task_info; 1298 error = GetTaskBasicInfo(m_task, &task_info); 1299 if (error.Fail()) { 1300 if (log) 1301 log->Printf("NativeProcessDarwin::%s(): failed to get task " 1302 "BasicInfo when attempting to resume: %s", 1303 __FUNCTION__, error.AsCString()); 1304 return error; 1305 } 1306 1307 // task_resume isn't counted like task_suspend calls are, so if the 1308 // task is not suspended, don't try and resume it since it is already 1309 // running 1310 if (task_info.suspend_count > 0) { 1311 auto mach_err = ::task_resume(m_task); 1312 error.SetError(mach_err, eErrorTypeMachKernel); 1313 if (log) { 1314 if (error.Success()) 1315 log->Printf("::task_resume(target_task = 0x%4.4x): success", m_task); 1316 else 1317 log->Printf("::task_resume(target_task = 0x%4.4x) error: %s", m_task, 1318 error.AsCString()); 1319 } 1320 } else { 1321 if (log) 1322 log->Printf("::task_resume(target_task = 0x%4.4x): ignored, " 1323 "already running", 1324 m_task); 1325 } 1326 1327 return error; 1328 } 1329 1330 bool NativeProcessDarwin::IsTaskValid() const { 1331 if (m_task == TASK_NULL) 1332 return false; 1333 1334 struct task_basic_info task_info; 1335 return GetTaskBasicInfo(m_task, &task_info).Success(); 1336 } 1337 1338 bool NativeProcessDarwin::IsTaskValid(task_t task) const { 1339 if (task == TASK_NULL) 1340 return false; 1341 1342 struct task_basic_info task_info; 1343 return GetTaskBasicInfo(task, &task_info).Success(); 1344 } 1345 1346 mach_port_t NativeProcessDarwin::GetExceptionPort() const { 1347 return m_exception_port; 1348 } 1349 1350 bool NativeProcessDarwin::IsExceptionPortValid() const { 1351 return MACH_PORT_VALID(m_exception_port); 1352 } 1353 1354 Status 1355 NativeProcessDarwin::GetTaskBasicInfo(task_t task, 1356 struct task_basic_info *info) const { 1357 Status error; 1358 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); 1359 1360 // Validate args. 1361 if (info == NULL) { 1362 error.SetErrorStringWithFormat("NativeProcessDarwin::%s(): mandatory " 1363 "info arg is null", 1364 __FUNCTION__); 1365 return error; 1366 } 1367 1368 // Grab the task if we don't already have it. 1369 if (task == TASK_NULL) { 1370 error.SetErrorStringWithFormat("NativeProcessDarwin::%s(): given task " 1371 "is invalid", 1372 __FUNCTION__); 1373 } 1374 1375 mach_msg_type_number_t count = TASK_BASIC_INFO_COUNT; 1376 auto err = ::task_info(m_task, TASK_BASIC_INFO, (task_info_t)info, &count); 1377 error.SetError(err, eErrorTypeMachKernel); 1378 if (error.Fail()) { 1379 if (log) 1380 log->Printf("::task_info(target_task = 0x%4.4x, " 1381 "flavor = TASK_BASIC_INFO, task_info_out => %p, " 1382 "task_info_outCnt => %u) failed: %u (%s)", 1383 m_task, info, count, error.GetError(), error.AsCString()); 1384 return error; 1385 } 1386 1387 Log *verbose_log( 1388 GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE)); 1389 if (verbose_log) { 1390 float user = (float)info->user_time.seconds + 1391 (float)info->user_time.microseconds / 1000000.0f; 1392 float system = (float)info->user_time.seconds + 1393 (float)info->user_time.microseconds / 1000000.0f; 1394 verbose_log->Printf("task_basic_info = { suspend_count = %i, " 1395 "virtual_size = 0x%8.8llx, resident_size = " 1396 "0x%8.8llx, user_time = %f, system_time = %f }", 1397 info->suspend_count, (uint64_t)info->virtual_size, 1398 (uint64_t)info->resident_size, user, system); 1399 } 1400 return error; 1401 } 1402 1403 Status NativeProcessDarwin::SuspendTask() { 1404 Status error; 1405 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); 1406 1407 if (m_task == TASK_NULL) { 1408 error.SetErrorString("task port is null, cannot suspend task"); 1409 if (log) 1410 log->Printf("NativeProcessDarwin::%s() failed: %s", __FUNCTION__, 1411 error.AsCString()); 1412 return error; 1413 } 1414 1415 auto mach_err = ::task_suspend(m_task); 1416 error.SetError(mach_err, eErrorTypeMachKernel); 1417 if (error.Fail() && log) 1418 log->Printf("::task_suspend(target_task = 0x%4.4x)", m_task); 1419 1420 return error; 1421 } 1422 1423 Status NativeProcessDarwin::Resume(const ResumeActionList &resume_actions) { 1424 Status error; 1425 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); 1426 1427 if (log) 1428 log->Printf("NativeProcessDarwin::%s() called", __FUNCTION__); 1429 1430 if (CanResume()) { 1431 m_thread_actions = resume_actions; 1432 error = PrivateResume(); 1433 return error; 1434 } 1435 1436 auto state = GetState(); 1437 if (state == eStateRunning) { 1438 if (log) 1439 log->Printf("NativeProcessDarwin::%s(): task 0x%x is already " 1440 "running, ignoring...", 1441 __FUNCTION__, TaskPortForProcessID(error)); 1442 return error; 1443 } 1444 1445 // We can't resume from this state. 1446 error.SetErrorStringWithFormat("task 0x%x has state %s, can't resume", 1447 TaskPortForProcessID(error), 1448 StateAsCString(state)); 1449 return error; 1450 } 1451 1452 Status NativeProcessDarwin::Halt() { 1453 Status error; 1454 error.SetErrorString("TODO: implement"); 1455 return error; 1456 } 1457 1458 Status NativeProcessDarwin::Detach() { 1459 Status error; 1460 error.SetErrorString("TODO: implement"); 1461 return error; 1462 } 1463 1464 Status NativeProcessDarwin::Signal(int signo) { 1465 Status error; 1466 error.SetErrorString("TODO: implement"); 1467 return error; 1468 } 1469 1470 Status NativeProcessDarwin::Interrupt() { 1471 Status error; 1472 error.SetErrorString("TODO: implement"); 1473 return error; 1474 } 1475 1476 Status NativeProcessDarwin::Kill() { 1477 Status error; 1478 error.SetErrorString("TODO: implement"); 1479 return error; 1480 } 1481 1482 Status NativeProcessDarwin::GetMemoryRegionInfo(lldb::addr_t load_addr, 1483 MemoryRegionInfo &range_info) { 1484 Status error; 1485 error.SetErrorString("TODO: implement"); 1486 return error; 1487 } 1488 1489 Status NativeProcessDarwin::ReadMemory(lldb::addr_t addr, void *buf, 1490 size_t size, size_t &bytes_read) { 1491 Status error; 1492 error.SetErrorString("TODO: implement"); 1493 return error; 1494 } 1495 1496 Status NativeProcessDarwin::ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf, 1497 size_t size, 1498 size_t &bytes_read) { 1499 Status error; 1500 error.SetErrorString("TODO: implement"); 1501 return error; 1502 } 1503 1504 Status NativeProcessDarwin::WriteMemory(lldb::addr_t addr, const void *buf, 1505 size_t size, size_t &bytes_written) { 1506 Status error; 1507 error.SetErrorString("TODO: implement"); 1508 return error; 1509 } 1510 1511 Status NativeProcessDarwin::AllocateMemory(size_t size, uint32_t permissions, 1512 lldb::addr_t &addr) { 1513 Status error; 1514 error.SetErrorString("TODO: implement"); 1515 return error; 1516 } 1517 1518 Status NativeProcessDarwin::DeallocateMemory(lldb::addr_t addr) { 1519 Status error; 1520 error.SetErrorString("TODO: implement"); 1521 return error; 1522 } 1523 1524 lldb::addr_t NativeProcessDarwin::GetSharedLibraryInfoAddress() { 1525 return LLDB_INVALID_ADDRESS; 1526 } 1527 1528 size_t NativeProcessDarwin::UpdateThreads() { return 0; } 1529 1530 bool NativeProcessDarwin::GetArchitecture(ArchSpec &arch) const { 1531 return false; 1532 } 1533 1534 Status NativeProcessDarwin::SetBreakpoint(lldb::addr_t addr, uint32_t size, 1535 bool hardware) { 1536 Status error; 1537 error.SetErrorString("TODO: implement"); 1538 return error; 1539 } 1540 1541 void NativeProcessDarwin::DoStopIDBumped(uint32_t newBumpId) {} 1542 1543 Status NativeProcessDarwin::GetLoadedModuleFileSpec(const char *module_path, 1544 FileSpec &file_spec) { 1545 Status error; 1546 error.SetErrorString("TODO: implement"); 1547 return error; 1548 } 1549 1550 Status NativeProcessDarwin::GetFileLoadAddress(const llvm::StringRef &file_name, 1551 lldb::addr_t &load_addr) { 1552 Status error; 1553 error.SetErrorString("TODO: implement"); 1554 return error; 1555 } 1556 1557 // ----------------------------------------------------------------- 1558 // NativeProcessProtocol protected interface 1559 // ----------------------------------------------------------------- 1560 Status NativeProcessDarwin::GetSoftwareBreakpointTrapOpcode( 1561 size_t trap_opcode_size_hint, size_t &actual_opcode_size, 1562 const uint8_t *&trap_opcode_bytes) { 1563 Status error; 1564 error.SetErrorString("TODO: implement"); 1565 return error; 1566 } 1567