1 //===-- NativeProcessDarwin.cpp ---------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "NativeProcessDarwin.h"
13 #include <mach/mach_init.h>
14 #include <mach/mach_traps.h>
15 #include <sys/ptrace.h>
17 #include <sys/sysctl.h>
18 #include <sys/types.h>
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"
30 #include "DarwinProcessLauncher.h"
32 #include "MachException.h"
34 #include "llvm/Support/FileSystem.h"
37 using namespace lldb_private;
38 using namespace lldb_private::process_darwin;
39 using namespace lldb_private::darwin_process_launcher;
41 // -----------------------------------------------------------------------------
43 // -----------------------------------------------------------------------------
46 struct hack_task_dyld_info {
47 mach_vm_address_t all_image_info_addr;
48 mach_vm_size_t all_image_info_size;
52 // -----------------------------------------------------------------------------
53 // Public Static Methods
54 // -----------------------------------------------------------------------------
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));
64 // Verify the working directory is valid if one was specified.
65 FileSpec working_dir(launch_info.GetWorkingDirectory());
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());
74 // Launch the inferior.
75 int pty_master_fd = -1;
76 LaunchFlavor launch_flavor = LaunchFlavor::Default;
78 error = LaunchInferior(launch_info, &pty_master_fd, &launch_flavor);
80 // Handle launch failure.
81 if (!error.Success()) {
83 log->Printf("NativeProcessDarwin::%s() failed to launch process: "
85 __FUNCTION__, error.AsCString());
89 // Handle failure to return a pid.
90 if (launch_info.GetProcessID() == LLDB_INVALID_PROCESS_ID) {
92 log->Printf("NativeProcessDarwin::%s() launch succeeded but no "
93 "pid was returned! Aborting.",
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");
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()) {
112 log->Printf("NativeProcessDarwin::%s() aborting, failed to finalize"
113 " the launching of the process: %s",
114 __FUNCTION__, error.AsCString());
118 // Return the process and process id to the caller through the launch args.
119 native_process_sp = np_darwin_sp;
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));
128 log->Printf("NativeProcessDarwin::%s(pid = %" PRIi64 ")", __FUNCTION__,
131 // Retrieve the architecture for the running process.
132 ArchSpec process_arch;
133 Status error = ResolveProcessArchitecture(pid, process_arch);
134 if (!error.Success())
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));
142 if (!native_process_darwin_sp->RegisterNativeDelegate(native_delegate)) {
143 error.SetErrorStringWithFormat("failed to register the native "
148 native_process_darwin_sp->AttachToInferior(mainloop, pid, error);
149 if (!error.Success())
152 native_process_sp = native_process_darwin_sp;
156 // -----------------------------------------------------------------------------
158 // -----------------------------------------------------------------------------
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;
171 NativeProcessDarwin::~NativeProcessDarwin() {}
173 // -----------------------------------------------------------------------------
175 // -----------------------------------------------------------------------------
177 Status NativeProcessDarwin::FinalizeLaunch(LaunchFlavor launch_flavor,
178 MainLoop &main_loop) {
180 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
186 for (i=0; (arg = argv[i]) != NULL; i++)
187 m_args.push_back(arg);
190 error = StartExceptionThread();
191 if (!error.Success()) {
193 log->Printf("NativeProcessDarwin::%s(): failure starting the "
194 "mach exception port monitor thread: %s",
195 __FUNCTION__, error.AsCString());
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);
208 if (launch_flavor == LaunchFlavor::PosixSpawn) {
209 SetState(eStateAttaching);
211 int err = ::ptrace(PT_ATTACHEXC, m_pid, 0, 0);
213 // m_flags |= eMachProcessFlagsAttached;
215 log->Printf("NativeProcessDarwin::%s(): successfully spawned "
216 "process with pid %" PRIu64,
217 __FUNCTION__, m_pid);
219 error.SetErrorToErrno();
220 SetState(eStateExited);
222 log->Printf("NativeProcessDarwin::%s(): error: failed to "
223 "attach to spawned pid %" PRIu64 " (error=%d (%s))",
224 __FUNCTION__, m_pid, (int)error.GetError(),
231 log->Printf("NativeProcessDarwin::%s(): new pid is %" PRIu64 "...",
232 __FUNCTION__, m_pid);
234 // Spawn a thread to reap our child inferior process...
235 error = StartWaitpidThread(main_loop);
238 log->Printf("NativeProcessDarwin::%s(): failed to start waitpid() "
240 __FUNCTION__, error.AsCString());
241 kill(SIGKILL, static_cast<::pid_t>(m_pid));
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.
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));
257 // Indicate that we're stopped, as we always launch suspended.
258 SetState(eStateStopped);
264 Status NativeProcessDarwin::SaveExceptionPortInfo() {
265 return m_exc_port_info.Save(m_task);
268 bool NativeProcessDarwin::ProcessUsingSpringBoard() const {
269 // TODO implement flags
270 // return (m_flags & eMachProcessFlagsUsingSBS) != 0;
274 bool NativeProcessDarwin::ProcessUsingBackBoard() const {
275 // TODO implement flags
276 // return (m_flags & eMachProcessFlagsUsingBKS) != 0;
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));
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.
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);
298 log->Printf("NativeProcessDarwin::%s(): new queued message count: %lu",
299 __FUNCTION__, m_exception_messages.size());
302 void *NativeProcessDarwin::ExceptionThread(void *arg) {
303 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
306 log->Printf("NativeProcessDarwin::%s(): cannot run mach exception "
307 "thread, mandatory process arg was null",
312 return reinterpret_cast<NativeProcessDarwin *>(arg)->DoExceptionThread();
315 void *NativeProcessDarwin::DoExceptionThread() {
316 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
319 log->Printf("NativeProcessDarwin::%s(arg=%p) starting thread...",
322 pthread_setname_np("exception monitoring thread");
324 // Ensure we don't get CPU starved.
325 MaybeRaiseThreadPriority();
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.
334 // [did we lose some words here?]
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
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;
351 task_t task = m_task;
352 mach_msg_timeout_t periodic_timeout = 0;
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;
360 if (process->ProcessUsingSpringBoard()) {
361 // Request a renewal for every 60 seconds if we attached using SpringBoard.
362 watchdog.reset(::SBSWatchdogAssertionCreateForPID(nullptr, pid, 60));
364 log->Printf("::SBSWatchdogAssertionCreateForPID(NULL, %4.4x, 60) "
366 pid, watchdog.get());
368 if (watchdog.get()) {
369 ::SBSWatchdogAssertionRenew(watchdog.get());
371 CFTimeInterval watchdogRenewalInterval =
372 ::SBSWatchdogAssertionGetRenewalInterval(watchdog.get());
374 log->Printf("::SBSWatchdogAssertionGetRenewalInterval(%p) => "
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;
388 if (periodic_timeout == 0 || periodic_timeout > watchdog_timeout)
389 periodic_timeout = watchdog_timeout;
391 #endif // #if defined (WITH_SPRINGBOARD) && !defined (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));
400 #endif // #ifdef WITH_BKS
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();
408 MachException::Message exception_message;
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(
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 |
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);
431 if (error.Success()) {
432 // We successfully received an exception.
433 if (exception_message.CatchExceptionRaise(task)) {
434 ++num_exceptions_received;
435 ExceptionMessageReceived(exception_message);
438 if (error.GetError() == MACH_RCV_INTERRUPTED) {
439 // We were interrupted.
441 // If we have no task port we should exit this thread, as it implies
442 // the inferior went down.
443 if (!IsExceptionPortValid()) {
445 log->Printf("NativeProcessDarwin::%s(): the inferior "
446 "exception port is no longer valid, "
447 "canceling exception thread...",
449 // Should we be setting a process state here?
453 // Make sure the inferior task is still valid.
457 log->Printf("NativeProcessDarwin::%s(): interrupted, but "
458 "the inferior task iss till valid, "
463 // The inferior task is no longer valid. Time to exit as the process
466 log->Printf("NativeProcessDarwin::%s(): the inferior task "
467 "has exited, and so will we...",
469 // Does this race at all with our waitpid()?
470 SetState(eStateExited);
473 } else if (error.GetError() == MACH_RCV_TIMED_OUT) {
474 // We timed out when waiting for exceptions.
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;
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();
486 // In case we use a timeout value when getting exceptions, make sure
487 // our task is still valid.
488 if (IsTaskValid(task)) {
491 log->Printf("NativeProcessDarwin::%s(): got a timeout, "
496 // The inferior task is no longer valid. Time to exit as the
497 // process has gone away.
499 log->Printf("NativeProcessDarwin::%s(): the inferior "
500 "task has exited, and so will we...",
502 // Does this race at all with our waitpid()?
503 SetState(eStateExited);
508 #if defined(WITH_SPRINGBOARD) && !defined(WITH_BKS)
509 if (watchdog.get()) {
510 watchdog_elapsed += periodic_timeout;
511 if (watchdog_elapsed >= watchdog_timeout) {
513 log->Printf("SBSWatchdogAssertionRenew(%p)", watchdog.get());
514 ::SBSWatchdogAssertionRenew(watchdog.get());
515 watchdog_elapsed = 0;
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?
529 #if defined(WITH_SPRINGBOARD) && !defined(WITH_BKS)
530 if (watchdog.get()) {
531 // TODO: change SBSWatchdogAssertionRelease to SBSWatchdogAssertionCancel
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)",
538 ::SBSWatchdogAssertionRelease(watchdog.get());
540 #endif // #if defined (WITH_SPRINGBOARD) && !defined (WITH_BKS)
543 log->Printf("NativeProcessDarwin::%s(%p): thread exiting...", __FUNCTION__,
548 Status NativeProcessDarwin::StartExceptionThread() {
550 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
552 log->Printf("NativeProcessDarwin::%s() called", __FUNCTION__);
554 // Make sure we've looked up the inferior port.
555 TaskPortForProcessID(error);
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",
565 // Get the mach port for the process monitor.
566 mach_port_t task_self = mach_task_self();
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,
571 error.SetError(mach_err, eErrorTypeMachKernel);
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());
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);
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) "
591 __FUNCTION__, task_self, m_exception_port, m_exception_port,
592 error.GetError(), error.AsCString());
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)) {
600 log->Printf("NativeProcessDarwin::%s(): SaveExceptionPortInfo() "
601 "failed, cannot install exception handler: %s",
602 __FUNCTION__, error.AsCString());
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);
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: "
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());
623 // Create the exception thread.
625 ::pthread_create(&m_exception_thread, nullptr, ExceptionThread, this);
626 error.SetError(pthread_err, eErrorTypePOSIX);
629 log->Printf("NativeProcessDarwin::%s(): failed to create Mach "
630 "exception-handling thread: %u (%s)",
631 __FUNCTION__, error.GetError(), error.AsCString());
638 NativeProcessDarwin::GetDYLDAllImageInfosAddress(Status &error) const {
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));
649 TaskPortForProcessID(error);
651 return LLDB_INVALID_ADDRESS;
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;
662 return LLDB_INVALID_ADDRESS;
665 uint32_t NativeProcessDarwin::GetCPUTypeForLocalProcess(::pid_t pid) {
666 int mib[CTL_MAXNAME] = {
669 size_t len = CTL_MAXNAME;
671 if (::sysctlnametomib("sysctl.proc_cputype", mib, &len))
678 size_t cpu_len = sizeof(cpu);
679 if (::sysctl(mib, static_cast<u_int>(len), &cpu, &cpu_len, 0, 0))
684 uint32_t NativeProcessDarwin::GetCPUType() const {
685 if (m_cpu_type == 0 && m_pid != 0)
686 m_cpu_type = GetCPUTypeForLocalProcess(m_pid);
690 task_t NativeProcessDarwin::ExceptionMessageBundleComplete() {
691 // We have a complete bundle of exceptions for our child process.
693 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
695 std::lock_guard<std::recursive_mutex> locker(m_exception_messages_mutex);
697 log->Printf("NativeProcessDarwin::%s(): processing %lu exception "
699 __FUNCTION__, m_exception_messages.size());
701 if (m_exception_messages.empty()) {
702 // Not particularly useful...
706 bool auto_resume = false;
709 // First check for any SIGTRAP and make sure we didn't exec
710 const task_t task = m_task;
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.
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
728 const addr_t aii_addr = GetDYLDAllImageInfosAddress(error);
729 if (aii_addr == LLDB_INVALID_ADDRESS)
732 const addr_t info_array_count_addr = aii_addr + 4;
733 uint32_t info_array_count = 0;
734 size_t bytes_read = 0;
736 read_error = ReadMemory(info_array_count_addr, // source addr
737 &info_array_count, // dest addr
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
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) {
753 log->Printf("exec: inferior task port changed "
754 "from 0x%4.4x to 0x%4.4x",
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);
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;
773 cpu_type_t process_cpu_type = GetCPUTypeForLocalProcess(m_pid);
774 if (m_cpu_type != process_cpu_type) {
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);
783 m_thread_list.Clear();
785 // TODO hook up breakpoints.
786 // m_breakpoints.DisableAll();
789 if (m_sent_interrupt_signo != 0) {
790 if (received_interrupt) {
792 log->Printf("NativeProcessDarwin::%s(): process "
793 "successfully interrupted with signal %i",
794 __FUNCTION__, m_sent_interrupt_signo);
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) {
812 log->Printf("NativeProcessDarwin::%s(): auto "
813 "resuming due to unhandled interrupt "
815 __FUNCTION__, m_auto_resume_signo);
817 m_auto_resume_signo = 0;
821 log->Printf("NativeProcessDarwin::%s(): didn't get signal "
822 "%i after MachProcess::Interrupt()",
823 __FUNCTION__, m_sent_interrupt_signo);
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);
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);
842 m_exception_messages[i].Dump(stream);
844 log->PutCString(stream.GetString().c_str());
850 m_thread_list.Dump(stream);
852 log->PutCString(stream.GetString().c_str());
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. !!!!
859 // Wait for the eEventProcessRunningStateChanged event to be reset
860 // before changing state to stopped to avoid race condition with very
862 struct timespec timeout;
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,
869 SetState(eStateStopped);
871 // Resume without checking our current state.
878 void NativeProcessDarwin::StartSTDIOThread() {
882 Status NativeProcessDarwin::StartWaitpidThread(MainLoop &main_loop) {
884 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
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
893 // Create a single-direction communication channel.
894 const bool child_inherits = false;
895 error = m_waitpid_pipe.CreateNew(child_inherits);
898 log->Printf("NativeProcessDarwin::%s(): failed to create waitpid "
899 "communication pipe: %s",
900 __FUNCTION__, error.AsCString());
904 // Hook up the waitpid reader callback.
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);
913 // Create the thread.
915 ::pthread_create(&m_waitpid_thread, nullptr, WaitpidThread, this);
916 error.SetError(pthread_err, eErrorTypePOSIX);
919 log->Printf("NativeProcessDarwin::%s(): failed to create waitpid "
920 "handling thread: %u (%s)",
921 __FUNCTION__, error.GetError(), error.AsCString());
928 void *NativeProcessDarwin::WaitpidThread(void *arg) {
929 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
932 log->Printf("NativeProcessDarwin::%s(): cannot run waitpid "
933 "thread, mandatory process arg was null",
938 return reinterpret_cast<NativeProcessDarwin *>(arg)->DoWaitpidThread();
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);
953 void *NativeProcessDarwin::DoWaitpidThread() {
954 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
956 if (m_pid == LLDB_INVALID_PROCESS_ID) {
958 log->Printf("NativeProcessDarwin::%s(): inferior process ID is "
959 "not set, cannot waitpid on it",
965 pthread_setname_np("waitpid thread");
967 // Ensure we don't get CPU starved.
968 MaybeRaiseThreadPriority();
975 ::pid_t child_pid = ::waitpid(m_pid, &status, 0);
977 error.SetErrorToErrno();
979 if (error.GetError() == EINTR) {
980 // This is okay, we can keep going.
982 log->Printf("NativeProcessDarwin::%s(): waitpid(pid = %" PRIu64
983 ", &status, 0) interrupted, continuing",
984 __FUNCTION__, m_pid);
988 // This error is not okay, abort.
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());
996 // Log the successful result.
998 log->Printf("NativeProcessDarwin::%s(): waitpid(pid = %" PRIu64
999 ", &status, 0) => %i, status = %i",
1000 __FUNCTION__, m_pid, child_pid, status);
1002 // Handle the result.
1003 if (WIFSTOPPED(status)) {
1005 log->Printf("NativeProcessDarwin::%s(): waitpid(pid = %" PRIu64
1006 ") received a stop, continuing waitpid() loop",
1007 __FUNCTION__, m_pid);
1009 } else // if (WIFEXITED(status) || WIFSIGNALED(status))
1012 log->Printf("NativeProcessDarwin::%s(pid = %" PRIu64 "): "
1013 "waitpid thread is setting exit status for pid = "
1015 __FUNCTION__, m_pid, child_pid, status);
1017 error = SendInferiorExitStatusToMainLoop(child_pid, status);
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.
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);
1031 error = SendInferiorExitStatusToMainLoop((::pid_t)m_pid, -1);
1035 Status NativeProcessDarwin::SendInferiorExitStatusToMainLoop(::pid_t pid,
1038 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
1040 size_t bytes_written = 0;
1043 error = m_waitpid_pipe.Write(&pid, sizeof(pid), bytes_written);
1044 if (error.Fail() || (bytes_written < sizeof(pid))) {
1046 log->Printf("NativeProcessDarwin::%s() - failed to write "
1047 "waitpid exiting pid to the pipe. Client will not "
1048 "hear about inferior exit status!",
1055 error = m_waitpid_pipe.Write(&status, sizeof(status), bytes_written);
1056 if (error.Fail() || (bytes_written < sizeof(status))) {
1058 log->Printf("NativeProcessDarwin::%s() - failed to write "
1059 "waitpid exit result to the pipe. Client will not "
1060 "hear about inferior exit status!",
1066 Status NativeProcessDarwin::HandleWaitpidResult() {
1068 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
1071 const bool notify_status = true;
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))) {
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.",
1082 SetExitStatus(WaitStatus(WaitStatus::Exit, -1), notify_status);
1088 error = m_waitpid_pipe.Read(&status, sizeof(status), bytes_read);
1089 if (error.Fail() || (bytes_read < sizeof(status))) {
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.",
1095 SetExitStatus(WaitStatus(WaitStatus::Exit, -1), notify_status);
1099 // Notify the monitor that our state has changed.
1101 log->Printf("NativeProcessDarwin::%s(): main loop received waitpid "
1102 "exit status info: pid=%i (%s), status=%i",
1104 (pid == m_pid) ? "the inferior" : "not the inferior", status);
1106 SetExitStatus(WaitStatus::Decode(status), notify_status);
1110 task_t NativeProcessDarwin::TaskPortForProcessID(Status &error,
1112 if ((m_task == TASK_NULL) || force) {
1113 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
1114 if (m_pid == LLDB_INVALID_PROCESS_ID) {
1116 log->Printf("NativeProcessDarwin::%s(): cannot get task due "
1122 const uint32_t num_retries = 10;
1123 const uint32_t usec_interval = 10000;
1125 mach_port_t task_self = mach_task_self();
1126 task_t task = TASK_NULL;
1128 for (uint32_t i = 0; i < num_retries; i++) {
1129 kern_return_t err = ::task_for_pid(task_self, m_pid, &task);
1131 // Succeeded. Save and return it.
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);
1140 // Failed to get the task for the inferior process.
1141 error.SetError(err, eErrorTypeMachKernel);
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());
1150 // Sleep a bit and try again
1151 ::usleep(usec_interval);
1154 // We failed to get the task for the inferior process. Ensure that it is
1161 void NativeProcessDarwin::AttachToInferior(MainLoop &mainloop, lldb::pid_t pid,
1163 error.SetErrorString("TODO: implement");
1166 Status NativeProcessDarwin::PrivateResume() {
1168 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
1170 std::lock_guard<std::recursive_mutex> locker(m_exception_messages_mutex);
1171 m_auto_resume_signo = m_sent_interrupt_signo;
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);
1179 log->Printf("NativeProcessDarwin::%s(): task 0x%x resuming...",
1180 __FUNCTION__, m_task);
1183 error = ReplyToAllExceptions();
1186 log->Printf("NativeProcessDarwin::%s(): aborting, failed to "
1187 "reply to exceptions: %s",
1188 __FUNCTION__, error.AsCString());
1191 // bool stepOverBreakInstruction = step;
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);
1198 // Set our state accordingly
1199 if (m_thread_actions.NumActionsWithState(eStateStepping))
1200 SetState(eStateStepping);
1202 SetState(eStateRunning);
1204 // Now resume our task.
1205 error = ResumeTask();
1209 Status NativeProcessDarwin::ReplyToAllExceptions() {
1211 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
1213 TaskPortForProcessID(error);
1216 log->Printf("NativeProcessDarwin::%s(): no task port, aborting",
1221 std::lock_guard<std::recursive_mutex> locker(m_exception_messages_mutex);
1222 if (m_exception_messages.empty()) {
1228 for (auto &message : m_exception_messages) {
1230 log->Printf("NativeProcessDarwin::%s(): replying to exception "
1232 __FUNCTION__, index++);
1235 int thread_reply_signal = 0;
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);
1244 thread_reply_signal = action->signal;
1245 if (thread_reply_signal)
1246 m_thread_actions.SetSignalHandledForThread(tid);
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
1253 log->Printf("NativeProcessDarwin::%s(): failed to reply to "
1255 __FUNCTION__, error.AsCString());
1260 // Erase all exception message as we should have used and replied to them all
1262 m_exception_messages.clear();
1266 Status NativeProcessDarwin::ResumeTask() {
1268 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
1270 TaskPortForProcessID(error);
1273 log->Printf("NativeProcessDarwin::%s(): failed to get task port "
1274 "for process when attempting to resume: %s",
1275 __FUNCTION__, error.AsCString());
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");
1285 log->Printf("NativeProcessDarwin::%s(): requesting resume of task "
1287 __FUNCTION__, m_task);
1289 // Get the BasicInfo struct to verify that we're suspended before we try to
1291 struct task_basic_info task_info;
1292 error = GetTaskBasicInfo(m_task, &task_info);
1295 log->Printf("NativeProcessDarwin::%s(): failed to get task "
1296 "BasicInfo when attempting to resume: %s",
1297 __FUNCTION__, error.AsCString());
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);
1307 if (error.Success())
1308 log->Printf("::task_resume(target_task = 0x%4.4x): success", m_task);
1310 log->Printf("::task_resume(target_task = 0x%4.4x) error: %s", m_task,
1315 log->Printf("::task_resume(target_task = 0x%4.4x): ignored, "
1323 bool NativeProcessDarwin::IsTaskValid() const {
1324 if (m_task == TASK_NULL)
1327 struct task_basic_info task_info;
1328 return GetTaskBasicInfo(m_task, &task_info).Success();
1331 bool NativeProcessDarwin::IsTaskValid(task_t task) const {
1332 if (task == TASK_NULL)
1335 struct task_basic_info task_info;
1336 return GetTaskBasicInfo(task, &task_info).Success();
1339 mach_port_t NativeProcessDarwin::GetExceptionPort() const {
1340 return m_exception_port;
1343 bool NativeProcessDarwin::IsExceptionPortValid() const {
1344 return MACH_PORT_VALID(m_exception_port);
1348 NativeProcessDarwin::GetTaskBasicInfo(task_t task,
1349 struct task_basic_info *info) const {
1351 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
1355 error.SetErrorStringWithFormat("NativeProcessDarwin::%s(): mandatory "
1361 // Grab the task if we don't already have it.
1362 if (task == TASK_NULL) {
1363 error.SetErrorStringWithFormat("NativeProcessDarwin::%s(): given task "
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);
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());
1381 GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
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);
1396 Status NativeProcessDarwin::SuspendTask() {
1398 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
1400 if (m_task == TASK_NULL) {
1401 error.SetErrorString("task port is null, cannot suspend task");
1403 log->Printf("NativeProcessDarwin::%s() failed: %s", __FUNCTION__,
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);
1416 Status NativeProcessDarwin::Resume(const ResumeActionList &resume_actions) {
1418 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
1421 log->Printf("NativeProcessDarwin::%s() called", __FUNCTION__);
1424 m_thread_actions = resume_actions;
1425 error = PrivateResume();
1429 auto state = GetState();
1430 if (state == eStateRunning) {
1432 log->Printf("NativeProcessDarwin::%s(): task 0x%x is already "
1433 "running, ignoring...",
1434 __FUNCTION__, TaskPortForProcessID(error));
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));
1445 Status NativeProcessDarwin::Halt() {
1447 error.SetErrorString("TODO: implement");
1451 Status NativeProcessDarwin::Detach() {
1453 error.SetErrorString("TODO: implement");
1457 Status NativeProcessDarwin::Signal(int signo) {
1459 error.SetErrorString("TODO: implement");
1463 Status NativeProcessDarwin::Interrupt() {
1465 error.SetErrorString("TODO: implement");
1469 Status NativeProcessDarwin::Kill() {
1471 error.SetErrorString("TODO: implement");
1475 Status NativeProcessDarwin::GetMemoryRegionInfo(lldb::addr_t load_addr,
1476 MemoryRegionInfo &range_info) {
1478 error.SetErrorString("TODO: implement");
1482 Status NativeProcessDarwin::ReadMemory(lldb::addr_t addr, void *buf,
1483 size_t size, size_t &bytes_read) {
1485 error.SetErrorString("TODO: implement");
1489 Status NativeProcessDarwin::ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf,
1491 size_t &bytes_read) {
1493 error.SetErrorString("TODO: implement");
1497 Status NativeProcessDarwin::WriteMemory(lldb::addr_t addr, const void *buf,
1498 size_t size, size_t &bytes_written) {
1500 error.SetErrorString("TODO: implement");
1504 Status NativeProcessDarwin::AllocateMemory(size_t size, uint32_t permissions,
1505 lldb::addr_t &addr) {
1507 error.SetErrorString("TODO: implement");
1511 Status NativeProcessDarwin::DeallocateMemory(lldb::addr_t addr) {
1513 error.SetErrorString("TODO: implement");
1517 lldb::addr_t NativeProcessDarwin::GetSharedLibraryInfoAddress() {
1518 return LLDB_INVALID_ADDRESS;
1521 size_t NativeProcessDarwin::UpdateThreads() { return 0; }
1523 bool NativeProcessDarwin::GetArchitecture(ArchSpec &arch) const {
1527 Status NativeProcessDarwin::SetBreakpoint(lldb::addr_t addr, uint32_t size,
1530 error.SetErrorString("TODO: implement");
1534 void NativeProcessDarwin::DoStopIDBumped(uint32_t newBumpId) {}
1536 Status NativeProcessDarwin::GetLoadedModuleFileSpec(const char *module_path,
1537 FileSpec &file_spec) {
1539 error.SetErrorString("TODO: implement");
1543 Status NativeProcessDarwin::GetFileLoadAddress(const llvm::StringRef &file_name,
1544 lldb::addr_t &load_addr) {
1546 error.SetErrorString("TODO: implement");
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) {
1557 error.SetErrorString("TODO: implement");