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