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