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