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