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