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