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