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