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