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