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