blob: f33bbb9adda5047dadd2ef1171fd09d4dfdbe47c [file] [log] [blame]
Todd Fialae77fce02016-09-04 00:18:56 +00001//===-- NativeProcessDarwin.cpp ---------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "NativeProcessDarwin.h"
11
12// C includes
13#include <mach/mach_init.h>
14#include <mach/mach_traps.h>
15#include <sys/ptrace.h>
16#include <sys/stat.h>
17#include <sys/sysctl.h>
18#include <sys/types.h>
19
20// C++ includes
21// LLDB includes
22#include "lldb/Core/Log.h"
23#include "lldb/Core/State.h"
Zachary Turner24ae6292017-02-16 19:38:21 +000024#include "lldb/Host/PseudoTerminal.h"
Todd Fialae77fce02016-09-04 00:18:56 +000025#include "lldb/Target/ProcessLaunchInfo.h"
Zachary Turnerbf9a7732017-02-02 21:39:50 +000026#include "lldb/Utility/StreamString.h"
Todd Fialae77fce02016-09-04 00:18:56 +000027
28#include "CFBundle.h"
29#include "CFString.h"
30#include "DarwinProcessLauncher.h"
31
32#include "MachException.h"
33
34using namespace lldb;
35using namespace lldb_private;
36using namespace lldb_private::process_darwin;
37using namespace lldb_private::darwin_process_launcher;
38
39// -----------------------------------------------------------------------------
40// Hidden Impl
41// -----------------------------------------------------------------------------
42
Kate Stoneb9c1b512016-09-06 20:57:50 +000043namespace {
44struct hack_task_dyld_info {
45 mach_vm_address_t all_image_info_addr;
46 mach_vm_size_t all_image_info_size;
47};
Todd Fialae77fce02016-09-04 00:18:56 +000048}
49
50// -----------------------------------------------------------------------------
51// Public Static Methods
52// -----------------------------------------------------------------------------
53
Kate Stoneb9c1b512016-09-06 20:57:50 +000054Error NativeProcessProtocol::Launch(
55 ProcessLaunchInfo &launch_info,
56 NativeProcessProtocol::NativeDelegate &native_delegate, MainLoop &mainloop,
57 NativeProcessProtocolSP &native_process_sp) {
58 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
Todd Fialae77fce02016-09-04 00:18:56 +000059
Kate Stoneb9c1b512016-09-06 20:57:50 +000060 Error error;
Todd Fialae77fce02016-09-04 00:18:56 +000061
Kate Stoneb9c1b512016-09-06 20:57:50 +000062 // Verify the working directory is valid if one was specified.
63 FileSpec working_dir(launch_info.GetWorkingDirectory());
64 if (working_dir &&
65 (!working_dir.ResolvePath() ||
66 working_dir.GetFileType() != FileSpec::eFileTypeDirectory)) {
67 error.SetErrorStringWithFormat("No such file or directory: %s",
68 working_dir.GetCString());
Todd Fialae77fce02016-09-04 00:18:56 +000069 return error;
Kate Stoneb9c1b512016-09-06 20:57:50 +000070 }
71
72 // Launch the inferior.
73 int pty_master_fd = -1;
74 LaunchFlavor launch_flavor = LaunchFlavor::Default;
75
76 error = LaunchInferior(launch_info, &pty_master_fd, &launch_flavor);
77
78 // Handle launch failure.
79 if (!error.Success()) {
80 if (log)
81 log->Printf("NativeProcessDarwin::%s() failed to launch process: "
82 "%s",
83 __FUNCTION__, error.AsCString());
84 return error;
85 }
86
87 // Handle failure to return a pid.
88 if (launch_info.GetProcessID() == LLDB_INVALID_PROCESS_ID) {
89 if (log)
90 log->Printf("NativeProcessDarwin::%s() launch succeeded but no "
91 "pid was returned! Aborting.",
92 __FUNCTION__);
93 return error;
94 }
95
96 // Create the Darwin native process impl.
97 std::shared_ptr<NativeProcessDarwin> np_darwin_sp(
98 new NativeProcessDarwin(launch_info.GetProcessID(), pty_master_fd));
99 if (!np_darwin_sp->RegisterNativeDelegate(native_delegate)) {
100 native_process_sp.reset();
101 error.SetErrorStringWithFormat("failed to register the native delegate");
102 return error;
103 }
104
105 // Finalize the processing needed to debug the launched process with
106 // a NativeProcessDarwin instance.
107 error = np_darwin_sp->FinalizeLaunch(launch_flavor, mainloop);
108 if (!error.Success()) {
109 if (log)
110 log->Printf("NativeProcessDarwin::%s() aborting, failed to finalize"
111 " the launching of the process: %s",
112 __FUNCTION__, error.AsCString());
113 return error;
114 }
115
116 // Return the process and process id to the caller through the launch args.
117 native_process_sp = np_darwin_sp;
118 return error;
Todd Fialae77fce02016-09-04 00:18:56 +0000119}
120
Kate Stoneb9c1b512016-09-06 20:57:50 +0000121Error NativeProcessProtocol::Attach(
122 lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &native_delegate,
123 MainLoop &mainloop, NativeProcessProtocolSP &native_process_sp) {
124 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
125 if (log)
126 log->Printf("NativeProcessDarwin::%s(pid = %" PRIi64 ")", __FUNCTION__,
127 pid);
Todd Fialae77fce02016-09-04 00:18:56 +0000128
Kate Stoneb9c1b512016-09-06 20:57:50 +0000129 // Retrieve the architecture for the running process.
130 ArchSpec process_arch;
131 Error error = ResolveProcessArchitecture(pid, process_arch);
132 if (!error.Success())
Todd Fialae77fce02016-09-04 00:18:56 +0000133 return error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000134
135 // TODO get attach to return this value.
136 const int pty_master_fd = -1;
137 std::shared_ptr<NativeProcessDarwin> native_process_darwin_sp(
138 new NativeProcessDarwin(pid, pty_master_fd));
139
140 if (!native_process_darwin_sp->RegisterNativeDelegate(native_delegate)) {
141 error.SetErrorStringWithFormat("failed to register the native "
142 "delegate");
143 return error;
144 }
145
146 native_process_darwin_sp->AttachToInferior(mainloop, pid, error);
147 if (!error.Success())
148 return error;
149
150 native_process_sp = native_process_darwin_sp;
151 return error;
Todd Fialae77fce02016-09-04 00:18:56 +0000152}
153
154// -----------------------------------------------------------------------------
155// ctor/dtor
156// -----------------------------------------------------------------------------
157
Kate Stoneb9c1b512016-09-06 20:57:50 +0000158NativeProcessDarwin::NativeProcessDarwin(lldb::pid_t pid, int pty_master_fd)
159 : NativeProcessProtocol(pid), m_task(TASK_NULL), m_did_exec(false),
160 m_cpu_type(0), m_exception_port(MACH_PORT_NULL), m_exc_port_info(),
161 m_exception_thread(nullptr), m_exception_messages_mutex(),
162 m_sent_interrupt_signo(0), m_auto_resume_signo(0), m_thread_list(),
163 m_thread_actions(), m_waitpid_pipe(), m_waitpid_thread(nullptr),
164 m_waitpid_reader_handle() {
165 // TODO add this to the NativeProcessProtocol constructor.
166 m_terminal_fd = pty_master_fd;
Todd Fialae77fce02016-09-04 00:18:56 +0000167}
168
Kate Stoneb9c1b512016-09-06 20:57:50 +0000169NativeProcessDarwin::~NativeProcessDarwin() {}
Todd Fialae77fce02016-09-04 00:18:56 +0000170
171// -----------------------------------------------------------------------------
172// Instance methods
173// -----------------------------------------------------------------------------
174
Kate Stoneb9c1b512016-09-06 20:57:50 +0000175Error NativeProcessDarwin::FinalizeLaunch(LaunchFlavor launch_flavor,
176 MainLoop &main_loop) {
177 Error error;
178 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
Todd Fialae77fce02016-09-04 00:18:56 +0000179
180#if 0
181 m_path = path;
182 size_t i;
183 char const *arg;
184 for (i=0; (arg = argv[i]) != NULL; i++)
185 m_args.push_back(arg);
186#endif
187
Kate Stoneb9c1b512016-09-06 20:57:50 +0000188 error = StartExceptionThread();
189 if (!error.Success()) {
Todd Fialae77fce02016-09-04 00:18:56 +0000190 if (log)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000191 log->Printf("NativeProcessDarwin::%s(): failure starting the "
192 "mach exception port monitor thread: %s",
193 __FUNCTION__, error.AsCString());
Todd Fialae77fce02016-09-04 00:18:56 +0000194
Kate Stoneb9c1b512016-09-06 20:57:50 +0000195 // Terminate the inferior process. There's nothing meaningful we can
196 // do if we can't receive signals and exceptions. Since we launched
197 // the process, it's fair game for us to kill it.
198 ::ptrace(PT_KILL, m_pid, 0, 0);
199 SetState(eStateExited);
Todd Fialae77fce02016-09-04 00:18:56 +0000200
Todd Fialae77fce02016-09-04 00:18:56 +0000201 return error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000202 }
203
204 StartSTDIOThread();
205
206 if (launch_flavor == LaunchFlavor::PosixSpawn) {
207 SetState(eStateAttaching);
208 errno = 0;
209 int err = ::ptrace(PT_ATTACHEXC, m_pid, 0, 0);
210 if (err == 0) {
211 // m_flags |= eMachProcessFlagsAttached;
212 if (log)
213 log->Printf("NativeProcessDarwin::%s(): successfully spawned "
214 "process with pid %" PRIu64,
215 __FUNCTION__, m_pid);
216 } else {
217 error.SetErrorToErrno();
218 SetState(eStateExited);
219 if (log)
220 log->Printf("NativeProcessDarwin::%s(): error: failed to "
221 "attach to spawned pid %" PRIu64 " (error=%d (%s))",
222 __FUNCTION__, m_pid, (int)error.GetError(),
223 error.AsCString());
224 return error;
225 }
226 }
227
228 if (log)
229 log->Printf("NativeProcessDarwin::%s(): new pid is %" PRIu64 "...",
230 __FUNCTION__, m_pid);
231
232 // Spawn a thread to reap our child inferior process...
233 error = StartWaitpidThread(main_loop);
234 if (error.Fail()) {
235 if (log)
236 log->Printf("NativeProcessDarwin::%s(): failed to start waitpid() "
237 "thread: %s",
238 __FUNCTION__, error.AsCString());
239 kill(SIGKILL, static_cast<::pid_t>(m_pid));
240 return error;
241 }
242
243 if (TaskPortForProcessID(error) == TASK_NULL) {
244 // We failed to get the task for our process ID which is bad.
245 // Kill our process; otherwise, it will be stopped at the entry
246 // point and get reparented to someone else and never go away.
247 if (log)
248 log->Printf("NativeProcessDarwin::%s(): could not get task port "
249 "for process, sending SIGKILL and exiting: %s",
250 __FUNCTION__, error.AsCString());
251 kill(SIGKILL, static_cast<::pid_t>(m_pid));
252 return error;
253 }
254
255 // Indicate that we're stopped, as we always launch suspended.
256 SetState(eStateStopped);
257
258 // Success.
259 return error;
Todd Fialae77fce02016-09-04 00:18:56 +0000260}
261
Kate Stoneb9c1b512016-09-06 20:57:50 +0000262Error NativeProcessDarwin::SaveExceptionPortInfo() {
263 return m_exc_port_info.Save(m_task);
Todd Fialae77fce02016-09-04 00:18:56 +0000264}
265
Kate Stoneb9c1b512016-09-06 20:57:50 +0000266bool NativeProcessDarwin::ProcessUsingSpringBoard() const {
267 // TODO implement flags
268 // return (m_flags & eMachProcessFlagsUsingSBS) != 0;
269 return false;
Todd Fialae77fce02016-09-04 00:18:56 +0000270}
271
Kate Stoneb9c1b512016-09-06 20:57:50 +0000272bool NativeProcessDarwin::ProcessUsingBackBoard() const {
273 // TODO implement flags
274 // return (m_flags & eMachProcessFlagsUsingBKS) != 0;
275 return false;
Todd Fialae77fce02016-09-04 00:18:56 +0000276}
277
278// Called by the exception thread when an exception has been received from
279// our process. The exception message is completely filled and the exception
280// data has already been copied.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000281void NativeProcessDarwin::ExceptionMessageReceived(
282 const MachException::Message &message) {
283 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
Todd Fialae77fce02016-09-04 00:18:56 +0000284
Kate Stoneb9c1b512016-09-06 20:57:50 +0000285 std::lock_guard<std::recursive_mutex> locker(m_exception_messages_mutex);
286 if (m_exception_messages.empty()) {
287 // Suspend the task the moment we receive our first exception message.
288 SuspendTask();
289 }
Todd Fialae77fce02016-09-04 00:18:56 +0000290
Kate Stoneb9c1b512016-09-06 20:57:50 +0000291 // Use a locker to automatically unlock our mutex in case of exceptions
292 // Add the exception to our internal exception stack
293 m_exception_messages.push_back(message);
Todd Fialae77fce02016-09-04 00:18:56 +0000294
Kate Stoneb9c1b512016-09-06 20:57:50 +0000295 if (log)
296 log->Printf("NativeProcessDarwin::%s(): new queued message count: %lu",
297 __FUNCTION__, m_exception_messages.size());
Todd Fialae77fce02016-09-04 00:18:56 +0000298}
299
Kate Stoneb9c1b512016-09-06 20:57:50 +0000300void *NativeProcessDarwin::ExceptionThread(void *arg) {
301 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
302 if (!arg) {
303 if (log)
304 log->Printf("NativeProcessDarwin::%s(): cannot run mach exception "
305 "thread, mandatory process arg was null",
306 __FUNCTION__);
307 return nullptr;
308 }
Todd Fialae77fce02016-09-04 00:18:56 +0000309
Kate Stoneb9c1b512016-09-06 20:57:50 +0000310 return reinterpret_cast<NativeProcessDarwin *>(arg)->DoExceptionThread();
Todd Fialae77fce02016-09-04 00:18:56 +0000311}
312
Kate Stoneb9c1b512016-09-06 20:57:50 +0000313void *NativeProcessDarwin::DoExceptionThread() {
314 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
Todd Fialae77fce02016-09-04 00:18:56 +0000315
Kate Stoneb9c1b512016-09-06 20:57:50 +0000316 if (log)
317 log->Printf("NativeProcessDarwin::%s(arg=%p) starting thread...",
318 __FUNCTION__, this);
319
320 pthread_setname_np("exception monitoring thread");
321
322 // Ensure we don't get CPU starved.
323 MaybeRaiseThreadPriority();
324
325 // We keep a count of the number of consecutive exceptions received so
326 // we know to grab all exceptions without a timeout. We do this to get a
327 // bunch of related exceptions on our exception port so we can process
328 // then together. When we have multiple threads, we can get an exception
329 // per thread and they will come in consecutively. The main loop in this
330 // thread can stop periodically if needed to service things related to this
331 // process.
332 //
333 // [did we lose some words here?]
334 //
335 // flag set in the options, so we will wait forever for an exception on
336 // 0 our exception port. After we get one exception, we then will use the
337 // MACH_RCV_TIMEOUT option with a zero timeout to grab all other current
338 // exceptions for our process. After we have received the last pending
339 // exception, we will get a timeout which enables us to then notify
340 // our main thread that we have an exception bundle available. We then wait
341 // for the main thread to tell this exception thread to start trying to get
342 // exceptions messages again and we start again with a mach_msg read with
343 // infinite timeout.
344 //
345 // We choose to park a thread on this, rather than polling, because the
346 // polling is expensive. On devices, we need to minimize overhead caused
347 // by the process monitor.
348 uint32_t num_exceptions_received = 0;
349 Error error;
350 task_t task = m_task;
351 mach_msg_timeout_t periodic_timeout = 0;
352
353#if defined(WITH_SPRINGBOARD) && !defined(WITH_BKS)
354 mach_msg_timeout_t watchdog_elapsed = 0;
355 mach_msg_timeout_t watchdog_timeout = 60 * 1000;
356 ::pid_t pid = (::pid_t)process->GetID();
357 CFReleaser<SBSWatchdogAssertionRef> watchdog;
358
359 if (process->ProcessUsingSpringBoard()) {
360 // Request a renewal for every 60 seconds if we attached using
361 // SpringBoard.
362 watchdog.reset(::SBSWatchdogAssertionCreateForPID(nullptr, pid, 60));
Todd Fialae77fce02016-09-04 00:18:56 +0000363 if (log)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000364 log->Printf("::SBSWatchdogAssertionCreateForPID(NULL, %4.4x, 60) "
365 "=> %p",
366 pid, watchdog.get());
Todd Fialae77fce02016-09-04 00:18:56 +0000367
Kate Stoneb9c1b512016-09-06 20:57:50 +0000368 if (watchdog.get()) {
369 ::SBSWatchdogAssertionRenew(watchdog.get());
Todd Fialae77fce02016-09-04 00:18:56 +0000370
Kate Stoneb9c1b512016-09-06 20:57:50 +0000371 CFTimeInterval watchdogRenewalInterval =
372 ::SBSWatchdogAssertionGetRenewalInterval(watchdog.get());
373 if (log)
374 log->Printf("::SBSWatchdogAssertionGetRenewalInterval(%p) => "
375 "%g seconds",
376 watchdog.get(), watchdogRenewalInterval);
377 if (watchdogRenewalInterval > 0.0) {
378 watchdog_timeout = (mach_msg_timeout_t)watchdogRenewalInterval * 1000;
379 if (watchdog_timeout > 3000) {
380 // Give us a second to renew our timeout.
381 watchdog_timeout -= 1000;
382 } else if (watchdog_timeout > 1000) {
383 // Give us a quarter of a second to renew our timeout.
384 watchdog_timeout -= 250;
Todd Fialae77fce02016-09-04 00:18:56 +0000385 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000386 }
Todd Fialae77fce02016-09-04 00:18:56 +0000387 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000388 if (periodic_timeout == 0 || periodic_timeout > watchdog_timeout)
389 periodic_timeout = watchdog_timeout;
390 }
391#endif // #if defined (WITH_SPRINGBOARD) && !defined (WITH_BKS)
Todd Fialae77fce02016-09-04 00:18:56 +0000392
393#ifdef WITH_BKS
Kate Stoneb9c1b512016-09-06 20:57:50 +0000394 CFReleaser<BKSWatchdogAssertionRef> watchdog;
395 if (process->ProcessUsingBackBoard()) {
396 ::pid_t pid = process->GetID();
397 CFAllocatorRef alloc = kCFAllocatorDefault;
398 watchdog.reset(::BKSWatchdogAssertionCreateForPID(alloc, pid));
399 }
Todd Fialae77fce02016-09-04 00:18:56 +0000400#endif // #ifdef WITH_BKS
401
Kate Stoneb9c1b512016-09-06 20:57:50 +0000402 // Do we want to use a weak pointer to the NativeProcessDarwin here, in
403 // which case we can guarantee we don't whack the process monitor if we
404 // race between this thread and the main one on shutdown?
405 while (IsExceptionPortValid()) {
406 ::pthread_testcancel();
Todd Fialae77fce02016-09-04 00:18:56 +0000407
Kate Stoneb9c1b512016-09-06 20:57:50 +0000408 MachException::Message exception_message;
Todd Fialae77fce02016-09-04 00:18:56 +0000409
Kate Stoneb9c1b512016-09-06 20:57:50 +0000410 if (num_exceptions_received > 0) {
411 // We don't want a timeout here, just receive as many exceptions as
412 // we can since we already have one. We want to get all currently
413 // available exceptions for this task at once.
414 error = exception_message.Receive(
415 GetExceptionPort(),
416 MACH_RCV_MSG | MACH_RCV_INTERRUPT | MACH_RCV_TIMEOUT, 0);
417 } else if (periodic_timeout > 0) {
418 // We need to stop periodically in this loop, so try and get a mach
419 // message with a valid timeout (ms).
420 error = exception_message.Receive(GetExceptionPort(),
421 MACH_RCV_MSG | MACH_RCV_INTERRUPT |
422 MACH_RCV_TIMEOUT,
423 periodic_timeout);
424 } else {
425 // We don't need to parse all current exceptions or stop
426 // periodically, just wait for an exception forever.
427 error = exception_message.Receive(GetExceptionPort(),
428 MACH_RCV_MSG | MACH_RCV_INTERRUPT, 0);
429 }
430
431 if (error.Success()) {
432 // We successfully received an exception.
433 if (exception_message.CatchExceptionRaise(task)) {
434 ++num_exceptions_received;
435 ExceptionMessageReceived(exception_message);
436 }
437 } else {
438 if (error.GetError() == MACH_RCV_INTERRUPTED) {
439 // We were interrupted.
440
441 // If we have no task port we should exit this thread, as it implies
442 // the inferior went down.
443 if (!IsExceptionPortValid()) {
444 if (log)
445 log->Printf("NativeProcessDarwin::%s(): the inferior "
446 "exception port is no longer valid, "
447 "canceling exception thread...",
448 __FUNCTION__);
449 // Should we be setting a process state here?
450 break;
Todd Fialae77fce02016-09-04 00:18:56 +0000451 }
452
Kate Stoneb9c1b512016-09-06 20:57:50 +0000453 // Make sure the inferior task is still valid.
454 if (IsTaskValid()) {
455 // Task is still ok.
456 if (log)
457 log->Printf("NativeProcessDarwin::%s(): interrupted, but "
458 "the inferior task iss till valid, "
459 "continuing...",
460 __FUNCTION__);
461 continue;
462 } else {
463 // The inferior task is no longer valid. Time to exit as
464 // the process has gone away.
465 if (log)
466 log->Printf("NativeProcessDarwin::%s(): the inferior task "
467 "has exited, and so will we...",
468 __FUNCTION__);
469 // Does this race at all with our waitpid()?
470 SetState(eStateExited);
471 break;
Todd Fialae77fce02016-09-04 00:18:56 +0000472 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000473 } else if (error.GetError() == MACH_RCV_TIMED_OUT) {
474 // We timed out when waiting for exceptions.
Todd Fialae77fce02016-09-04 00:18:56 +0000475
Kate Stoneb9c1b512016-09-06 20:57:50 +0000476 if (num_exceptions_received > 0) {
477 // We were receiving all current exceptions with a timeout of
478 // zero. It is time to go back to our normal looping mode.
479 num_exceptions_received = 0;
Todd Fialae77fce02016-09-04 00:18:56 +0000480
Kate Stoneb9c1b512016-09-06 20:57:50 +0000481 // Notify our main thread we have a complete exception message
482 // bundle available. Get the possibly updated task port back
483 // from the process in case we exec'ed and our task port
484 // changed.
485 task = ExceptionMessageBundleComplete();
Todd Fialae77fce02016-09-04 00:18:56 +0000486
Kate Stoneb9c1b512016-09-06 20:57:50 +0000487 // In case we use a timeout value when getting exceptions,
488 // make sure 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
498 // the 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 }
Todd Fialae77fce02016-09-04 00:18:56 +0000508
Kate Stoneb9c1b512016-09-06 20:57:50 +0000509#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 }
Todd Fialae77fce02016-09-04 00:18:56 +0000519#endif
Kate Stoneb9c1b512016-09-06 20:57:50 +0000520 } 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 }
Todd Fialae77fce02016-09-04 00:18:56 +0000527 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000528 }
Todd Fialae77fce02016-09-04 00:18:56 +0000529
Kate Stoneb9c1b512016-09-06 20:57:50 +0000530#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
536 // that will forward SBSWatchdogAssertionRelease to
537 // SBSWatchdogAssertionCancel for now
538 // so it should still build either way.
539 DNBLogThreadedIf(LOG_TASK, "::SBSWatchdogAssertionRelease(%p)",
540 watchdog.get());
541 ::SBSWatchdogAssertionRelease(watchdog.get());
542 }
543#endif // #if defined (WITH_SPRINGBOARD) && !defined (WITH_BKS)
544
545 if (log)
546 log->Printf("NativeProcessDarwin::%s(%p): thread exiting...", __FUNCTION__,
547 this);
548 return nullptr;
Todd Fialae77fce02016-09-04 00:18:56 +0000549}
550
Kate Stoneb9c1b512016-09-06 20:57:50 +0000551Error NativeProcessDarwin::StartExceptionThread() {
552 Error error;
553 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
554 if (log)
555 log->Printf("NativeProcessDarwin::%s() called", __FUNCTION__);
Todd Fialae77fce02016-09-04 00:18:56 +0000556
Kate Stoneb9c1b512016-09-06 20:57:50 +0000557 // Make sure we've looked up the inferior port.
558 TaskPortForProcessID(error);
Todd Fialae77fce02016-09-04 00:18:56 +0000559
Kate Stoneb9c1b512016-09-06 20:57:50 +0000560 // Ensure the inferior task is valid.
561 if (!IsTaskValid()) {
562 error.SetErrorStringWithFormat("cannot start exception thread: "
563 "task 0x%4.4x is not valid",
564 m_task);
Todd Fialae77fce02016-09-04 00:18:56 +0000565 return error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000566 }
567
568 // Get the mach port for the process monitor.
569 mach_port_t task_self = mach_task_self();
570
571 // Allocate an exception port that we will use to track our child process
572 auto mach_err = ::mach_port_allocate(task_self, MACH_PORT_RIGHT_RECEIVE,
573 &m_exception_port);
574 error.SetError(mach_err, eErrorTypeMachKernel);
575 if (error.Fail()) {
576 if (log)
577 log->Printf("NativeProcessDarwin::%s(): mach_port_allocate("
578 "task_self=0x%4.4x, MACH_PORT_RIGHT_RECEIVE, "
579 "&m_exception_port) failed: %u (%s)",
580 __FUNCTION__, task_self, error.GetError(), error.AsCString());
581 return error;
582 }
583
584 // Add the ability to send messages on the new exception port
585 mach_err = ::mach_port_insert_right(
586 task_self, m_exception_port, m_exception_port, MACH_MSG_TYPE_MAKE_SEND);
587 error.SetError(mach_err, eErrorTypeMachKernel);
588 if (error.Fail()) {
589 if (log)
590 log->Printf("NativeProcessDarwin::%s(): mach_port_insert_right("
591 "task_self=0x%4.4x, m_exception_port=0x%4.4x, "
592 "m_exception_port=0x%4.4x, MACH_MSG_TYPE_MAKE_SEND) "
593 "failed: %u (%s)",
594 __FUNCTION__, task_self, m_exception_port, m_exception_port,
595 error.GetError(), error.AsCString());
596 return error;
597 }
598
599 // Save the original state of the exception ports for our child process.
600 error = SaveExceptionPortInfo();
601 if (error.Fail() || (m_exc_port_info.mask == 0)) {
602 if (log)
603 log->Printf("NativeProcessDarwin::%s(): SaveExceptionPortInfo() "
604 "failed, cannot install exception handler: %s",
605 __FUNCTION__, error.AsCString());
606 return error;
607 }
608
609 // Set the ability to get all exceptions on this port.
610 mach_err = ::task_set_exception_ports(
611 m_task, m_exc_port_info.mask, m_exception_port,
612 EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES, THREAD_STATE_NONE);
613 error.SetError(mach_err, eErrorTypeMachKernel);
614 if (error.Fail()) {
615 if (log)
616 log->Printf("::task_set_exception_ports (task = 0x%4.4x, "
617 "exception_mask = 0x%8.8x, new_port = 0x%4.4x, "
618 "behavior = 0x%8.8x, new_flavor = 0x%8.8x) failed: "
619 "%u (%s)",
620 m_task, m_exc_port_info.mask, m_exception_port,
621 (EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES), THREAD_STATE_NONE,
622 error.GetError(), error.AsCString());
623 return error;
624 }
625
626 // Create the exception thread.
627 auto pthread_err =
628 ::pthread_create(&m_exception_thread, nullptr, ExceptionThread, this);
629 error.SetError(pthread_err, eErrorTypePOSIX);
630 if (error.Fail()) {
631 if (log)
632 log->Printf("NativeProcessDarwin::%s(): failed to create Mach "
633 "exception-handling thread: %u (%s)",
634 __FUNCTION__, error.GetError(), error.AsCString());
635 }
636
637 return error;
Todd Fialae77fce02016-09-04 00:18:56 +0000638}
639
640lldb::addr_t
Kate Stoneb9c1b512016-09-06 20:57:50 +0000641NativeProcessDarwin::GetDYLDAllImageInfosAddress(Error &error) const {
642 error.Clear();
Todd Fialae77fce02016-09-04 00:18:56 +0000643
Kate Stoneb9c1b512016-09-06 20:57:50 +0000644 struct hack_task_dyld_info dyld_info;
645 mach_msg_type_number_t count = TASK_DYLD_INFO_COUNT;
646 // Make sure that COUNT isn't bigger than our hacked up struct
647 // hack_task_dyld_info. If it is, then make COUNT smaller to match.
648 if (count > (sizeof(struct hack_task_dyld_info) / sizeof(natural_t))) {
649 count = (sizeof(struct hack_task_dyld_info) / sizeof(natural_t));
650 }
Todd Fialae77fce02016-09-04 00:18:56 +0000651
Kate Stoneb9c1b512016-09-06 20:57:50 +0000652 TaskPortForProcessID(error);
653 if (error.Fail())
Todd Fialae77fce02016-09-04 00:18:56 +0000654 return LLDB_INVALID_ADDRESS;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000655
656 auto mach_err =
657 ::task_info(m_task, TASK_DYLD_INFO, (task_info_t)&dyld_info, &count);
658 error.SetError(mach_err, eErrorTypeMachKernel);
659 if (error.Success()) {
660 // We now have the address of the all image infos structure.
661 return dyld_info.all_image_info_addr;
662 }
663
664 // We don't have it.
665 return LLDB_INVALID_ADDRESS;
Todd Fialae77fce02016-09-04 00:18:56 +0000666}
667
Kate Stoneb9c1b512016-09-06 20:57:50 +0000668uint32_t NativeProcessDarwin::GetCPUTypeForLocalProcess(::pid_t pid) {
669 int mib[CTL_MAXNAME] = {
670 0,
671 };
672 size_t len = CTL_MAXNAME;
Todd Fialae77fce02016-09-04 00:18:56 +0000673
Kate Stoneb9c1b512016-09-06 20:57:50 +0000674 if (::sysctlnametomib("sysctl.proc_cputype", mib, &len))
675 return 0;
Todd Fialae77fce02016-09-04 00:18:56 +0000676
Kate Stoneb9c1b512016-09-06 20:57:50 +0000677 mib[len] = pid;
678 len++;
Todd Fialae77fce02016-09-04 00:18:56 +0000679
Kate Stoneb9c1b512016-09-06 20:57:50 +0000680 cpu_type_t cpu;
681 size_t cpu_len = sizeof(cpu);
682 if (::sysctl(mib, static_cast<u_int>(len), &cpu, &cpu_len, 0, 0))
683 cpu = 0;
684 return cpu;
Todd Fialae77fce02016-09-04 00:18:56 +0000685}
686
Kate Stoneb9c1b512016-09-06 20:57:50 +0000687uint32_t NativeProcessDarwin::GetCPUType() const {
688 if (m_cpu_type == 0 && m_pid != 0)
689 m_cpu_type = GetCPUTypeForLocalProcess(m_pid);
690 return m_cpu_type;
Todd Fialae77fce02016-09-04 00:18:56 +0000691}
692
Kate Stoneb9c1b512016-09-06 20:57:50 +0000693task_t NativeProcessDarwin::ExceptionMessageBundleComplete() {
694 // We have a complete bundle of exceptions for our child process.
695 Error error;
696 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
Todd Fialae77fce02016-09-04 00:18:56 +0000697
Kate Stoneb9c1b512016-09-06 20:57:50 +0000698 std::lock_guard<std::recursive_mutex> locker(m_exception_messages_mutex);
699 if (log)
700 log->Printf("NativeProcessDarwin::%s(): processing %lu exception "
701 "messages.",
702 __FUNCTION__, m_exception_messages.size());
Todd Fialae77fce02016-09-04 00:18:56 +0000703
Kate Stoneb9c1b512016-09-06 20:57:50 +0000704 if (m_exception_messages.empty()) {
705 // Not particularly useful...
706 return m_task;
707 }
708
709 bool auto_resume = false;
710 m_did_exec = false;
711
712 // First check for any SIGTRAP and make sure we didn't exec
713 const task_t task = m_task;
714 size_t i;
715 if (m_pid != 0) {
716 bool received_interrupt = false;
717 uint32_t num_task_exceptions = 0;
718 for (i = 0; i < m_exception_messages.size(); ++i) {
719 if (m_exception_messages[i].state.task_port != task) {
720 // This is an exception that is not for our inferior, ignore.
721 continue;
722 }
723
724 // This is an exception for the inferior.
725 ++num_task_exceptions;
726 const int signo = m_exception_messages[i].state.SoftSignal();
727 if (signo == SIGTRAP) {
728 // SIGTRAP could mean that we exec'ed. We need to check the
729 // dyld all_image_infos.infoArray to see if it is NULL and if
730 // so, say that we exec'ed.
731 const addr_t aii_addr = GetDYLDAllImageInfosAddress(error);
732 if (aii_addr == LLDB_INVALID_ADDRESS)
733 break;
734
735 const addr_t info_array_count_addr = aii_addr + 4;
736 uint32_t info_array_count = 0;
737 size_t bytes_read = 0;
738 Error read_error;
739 read_error = ReadMemory(info_array_count_addr, // source addr
740 &info_array_count, // dest addr
741 4, // byte count
742 bytes_read); // #bytes read
743 if (read_error.Success() && (bytes_read == 4)) {
744 if (info_array_count == 0) {
745 // We got the all infos address, and there are zero
746 // entries. We think we exec'd.
747 m_did_exec = true;
748
749 // Force the task port to update itself in case the
750 // task port changed after exec
751 const task_t old_task = m_task;
752 const bool force_update = true;
753 const task_t new_task = TaskPortForProcessID(error, force_update);
754 if (old_task != new_task) {
755 if (log)
756 log->Printf("exec: inferior task port changed "
757 "from 0x%4.4x to 0x%4.4x",
758 old_task, new_task);
759 }
760 }
761 } else {
762 if (log)
763 log->Printf("NativeProcessDarwin::%s() warning: "
764 "failed to read all_image_infos."
765 "infoArrayCount from 0x%8.8llx",
766 __FUNCTION__, info_array_count_addr);
767 }
768 } else if ((m_sent_interrupt_signo != 0) &&
769 (signo == m_sent_interrupt_signo)) {
770 // We just received the interrupt that we sent to ourselves.
771 received_interrupt = true;
772 }
Todd Fialae77fce02016-09-04 00:18:56 +0000773 }
774
Kate Stoneb9c1b512016-09-06 20:57:50 +0000775 if (m_did_exec) {
776 cpu_type_t process_cpu_type = GetCPUTypeForLocalProcess(m_pid);
777 if (m_cpu_type != process_cpu_type) {
Todd Fialae77fce02016-09-04 00:18:56 +0000778 if (log)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000779 log->Printf("NativeProcessDarwin::%s(): arch changed from "
780 "0x%8.8x to 0x%8.8x",
781 __FUNCTION__, m_cpu_type, process_cpu_type);
782 m_cpu_type = process_cpu_type;
783 // TODO figure out if we need to do something here.
784 // DNBArchProtocol::SetArchitecture (process_cpu_type);
785 }
786 m_thread_list.Clear();
787
788 // TODO hook up breakpoints.
789 // m_breakpoints.DisableAll();
790 }
791
792 if (m_sent_interrupt_signo != 0) {
793 if (received_interrupt) {
794 if (log)
795 log->Printf("NativeProcessDarwin::%s(): process "
796 "successfully interrupted with signal %i",
797 __FUNCTION__, m_sent_interrupt_signo);
798
799 // Mark that we received the interrupt signal
800 m_sent_interrupt_signo = 0;
801 // Now check if we had a case where:
802 // 1 - We called NativeProcessDarwin::Interrupt() but we stopped
803 // for another reason.
804 // 2 - We called NativeProcessDarwin::Resume() (but still
805 // haven't gotten the interrupt signal).
806 // 3 - We are now incorrectly stopped because we are handling
807 // the interrupt signal we missed.
808 // 4 - We might need to resume if we stopped only with the
809 // interrupt signal that we never handled.
810 if (m_auto_resume_signo != 0) {
811 // Only auto_resume if we stopped with _only_ the interrupt
812 // signal.
813 if (num_task_exceptions == 1) {
814 auto_resume = true;
815 if (log)
816 log->Printf("NativeProcessDarwin::%s(): auto "
817 "resuming due to unhandled interrupt "
818 "signal %i",
819 __FUNCTION__, m_auto_resume_signo);
820 }
821 m_auto_resume_signo = 0;
Todd Fialae77fce02016-09-04 00:18:56 +0000822 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000823 } else {
824 if (log)
825 log->Printf("NativeProcessDarwin::%s(): didn't get signal "
826 "%i after MachProcess::Interrupt()",
827 __FUNCTION__, m_sent_interrupt_signo);
828 }
829 }
830 }
831
832 // Let all threads recover from stopping and do any clean up based
833 // on the previous thread state (if any).
834 m_thread_list.ProcessDidStop(*this);
835
836 // Let each thread know of any exceptions
837 for (i = 0; i < m_exception_messages.size(); ++i) {
838 // Let the thread list forward all exceptions on down to each thread.
839 if (m_exception_messages[i].state.task_port == task) {
840 // This exception is for our inferior.
841 m_thread_list.NotifyException(m_exception_messages[i].state);
Todd Fialae77fce02016-09-04 00:18:56 +0000842 }
843
Kate Stoneb9c1b512016-09-06 20:57:50 +0000844 if (log) {
845 StreamString stream;
846 m_exception_messages[i].Dump(stream);
847 stream.Flush();
848 log->PutCString(stream.GetString().c_str());
Todd Fialae77fce02016-09-04 00:18:56 +0000849 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000850 }
Todd Fialae77fce02016-09-04 00:18:56 +0000851
Kate Stoneb9c1b512016-09-06 20:57:50 +0000852 if (log) {
853 StreamString stream;
854 m_thread_list.Dump(stream);
855 stream.Flush();
856 log->PutCString(stream.GetString().c_str());
857 }
858
859 bool step_more = false;
860 if (m_thread_list.ShouldStop(step_more) && (auto_resume == false)) {
861// TODO - need to hook up event system here. !!!!
Todd Fialae77fce02016-09-04 00:18:56 +0000862#if 0
863 // Wait for the eEventProcessRunningStateChanged event to be reset
864 // before changing state to stopped to avoid race condition with
865 // very fast start/stops.
866 struct timespec timeout;
867
868 //DNBTimer::OffsetTimeOfDay(&timeout, 0, 250 * 1000); // Wait for 250 ms
869 DNBTimer::OffsetTimeOfDay(&timeout, 1, 0); // Wait for 250 ms
870 m_events.WaitForEventsToReset(eEventProcessRunningStateChanged,
871 &timeout);
872#endif
Kate Stoneb9c1b512016-09-06 20:57:50 +0000873 SetState(eStateStopped);
874 } else {
875 // Resume without checking our current state.
876 PrivateResume();
877 }
Todd Fialae77fce02016-09-04 00:18:56 +0000878
Kate Stoneb9c1b512016-09-06 20:57:50 +0000879 return m_task;
Todd Fialae77fce02016-09-04 00:18:56 +0000880}
881
Kate Stoneb9c1b512016-09-06 20:57:50 +0000882void NativeProcessDarwin::StartSTDIOThread() {
883 // TODO implement
Todd Fialae77fce02016-09-04 00:18:56 +0000884}
885
Kate Stoneb9c1b512016-09-06 20:57:50 +0000886Error NativeProcessDarwin::StartWaitpidThread(MainLoop &main_loop) {
887 Error error;
888 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
Todd Fialae77fce02016-09-04 00:18:56 +0000889
Kate Stoneb9c1b512016-09-06 20:57:50 +0000890 // Strategy: create a thread that sits on waitpid(), waiting for the
891 // inferior process to die, reaping it in the process. Arrange for
892 // the thread to have a pipe file descriptor that it can send a byte
893 // over when the waitpid completes. Have the main loop have a read
894 // object for the other side of the pipe, and have the callback for
895 // the read do the process termination message sending.
Todd Fialae77fce02016-09-04 00:18:56 +0000896
Kate Stoneb9c1b512016-09-06 20:57:50 +0000897 // Create a single-direction communication channel.
898 const bool child_inherits = false;
899 error = m_waitpid_pipe.CreateNew(child_inherits);
900 if (error.Fail()) {
901 if (log)
902 log->Printf("NativeProcessDarwin::%s(): failed to create waitpid "
903 "communication pipe: %s",
904 __FUNCTION__, error.AsCString());
Todd Fialae77fce02016-09-04 00:18:56 +0000905 return error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000906 }
907
908 // Hook up the waitpid reader callback.
909
910 // TODO make PipePOSIX derive from IOObject. This is goofy here.
911 const bool transfer_ownership = false;
912 auto io_sp = IOObjectSP(
913 new File(m_waitpid_pipe.GetReadFileDescriptor(), transfer_ownership));
914 m_waitpid_reader_handle = main_loop.RegisterReadObject(
915 io_sp, [this](MainLoopBase &) { HandleWaitpidResult(); }, error);
916
917 // Create the thread.
918 auto pthread_err =
919 ::pthread_create(&m_waitpid_thread, nullptr, WaitpidThread, this);
920 error.SetError(pthread_err, eErrorTypePOSIX);
921 if (error.Fail()) {
922 if (log)
923 log->Printf("NativeProcessDarwin::%s(): failed to create waitpid "
924 "handling thread: %u (%s)",
925 __FUNCTION__, error.GetError(), error.AsCString());
926 return error;
927 }
928
929 return error;
Todd Fialae77fce02016-09-04 00:18:56 +0000930}
931
Kate Stoneb9c1b512016-09-06 20:57:50 +0000932void *NativeProcessDarwin::WaitpidThread(void *arg) {
933 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
934 if (!arg) {
935 if (log)
936 log->Printf("NativeProcessDarwin::%s(): cannot run waitpid "
937 "thread, mandatory process arg was null",
938 __FUNCTION__);
939 return nullptr;
940 }
Todd Fialae77fce02016-09-04 00:18:56 +0000941
Kate Stoneb9c1b512016-09-06 20:57:50 +0000942 return reinterpret_cast<NativeProcessDarwin *>(arg)->DoWaitpidThread();
Todd Fialae77fce02016-09-04 00:18:56 +0000943}
944
Kate Stoneb9c1b512016-09-06 20:57:50 +0000945void NativeProcessDarwin::MaybeRaiseThreadPriority() {
946#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
947 struct sched_param thread_param;
948 int thread_sched_policy;
949 if (pthread_getschedparam(pthread_self(), &thread_sched_policy,
950 &thread_param) == 0) {
951 thread_param.sched_priority = 47;
952 pthread_setschedparam(pthread_self(), thread_sched_policy, &thread_param);
953 }
Todd Fialae77fce02016-09-04 00:18:56 +0000954#endif
955}
956
Kate Stoneb9c1b512016-09-06 20:57:50 +0000957void *NativeProcessDarwin::DoWaitpidThread() {
958 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
Todd Fialae77fce02016-09-04 00:18:56 +0000959
Kate Stoneb9c1b512016-09-06 20:57:50 +0000960 if (m_pid == LLDB_INVALID_PROCESS_ID) {
Todd Fialae77fce02016-09-04 00:18:56 +0000961 if (log)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000962 log->Printf("NativeProcessDarwin::%s(): inferior process ID is "
963 "not set, cannot waitpid on it",
964 __FUNCTION__);
Todd Fialae77fce02016-09-04 00:18:56 +0000965 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000966 }
Todd Fialae77fce02016-09-04 00:18:56 +0000967
Kate Stoneb9c1b512016-09-06 20:57:50 +0000968 // Name the thread.
969 pthread_setname_np("waitpid thread");
Todd Fialae77fce02016-09-04 00:18:56 +0000970
Kate Stoneb9c1b512016-09-06 20:57:50 +0000971 // Ensure we don't get CPU starved.
972 MaybeRaiseThreadPriority();
Todd Fialae77fce02016-09-04 00:18:56 +0000973
Kate Stoneb9c1b512016-09-06 20:57:50 +0000974 Error error;
975 int status = -1;
976
977 while (1) {
978 // Do a waitpid.
979 ::pid_t child_pid = ::waitpid(m_pid, &status, 0);
980 if (child_pid < 0)
981 error.SetErrorToErrno();
982 if (error.Fail()) {
983 if (error.GetError() == EINTR) {
984 // This is okay, we can keep going.
Todd Fialae77fce02016-09-04 00:18:56 +0000985 if (log)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000986 log->Printf("NativeProcessDarwin::%s(): waitpid(pid = %" PRIu64
987 ", &status, 0) interrupted, continuing",
988 __FUNCTION__, m_pid);
989 continue;
990 }
991
992 // This error is not okay, abort.
993 if (log)
994 log->Printf("NativeProcessDarwin::%s(): waitpid(pid = %" PRIu64
995 ", &status, 0) aborting due to error: %u (%s)",
996 __FUNCTION__, m_pid, error.GetError(), error.AsCString());
997 break;
Todd Fialae77fce02016-09-04 00:18:56 +0000998 }
999
Kate Stoneb9c1b512016-09-06 20:57:50 +00001000 // Log the successful result.
Todd Fialae77fce02016-09-04 00:18:56 +00001001 if (log)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001002 log->Printf("NativeProcessDarwin::%s(): waitpid(pid = %" PRIu64
1003 ", &status, 0) => %i, status = %i",
1004 __FUNCTION__, m_pid, child_pid, status);
Todd Fialae77fce02016-09-04 00:18:56 +00001005
Kate Stoneb9c1b512016-09-06 20:57:50 +00001006 // Handle the result.
1007 if (WIFSTOPPED(status)) {
1008 if (log)
1009 log->Printf("NativeProcessDarwin::%s(): waitpid(pid = %" PRIu64
1010 ") received a stop, continuing waitpid() loop",
1011 __FUNCTION__, m_pid);
1012 continue;
1013 } else // if (WIFEXITED(status) || WIFSIGNALED(status))
Todd Fialae77fce02016-09-04 00:18:56 +00001014 {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001015 if (log)
1016 log->Printf("NativeProcessDarwin::%s(pid = %" PRIu64 "): "
1017 "waitpid thread is setting exit status for pid = "
1018 "%i to %i",
1019 __FUNCTION__, m_pid, child_pid, status);
Todd Fialae77fce02016-09-04 00:18:56 +00001020
Kate Stoneb9c1b512016-09-06 20:57:50 +00001021 error = SendInferiorExitStatusToMainLoop(child_pid, status);
1022 return nullptr;
1023 }
1024 }
1025
1026 // We should never exit as long as our child process is alive. If we
1027 // get here, something completely unexpected went wrong and we should exit.
1028 if (log)
1029 log->Printf(
1030 "NativeProcessDarwin::%s(): internal error: waitpid thread "
1031 "exited out of its main loop in an unexpected way. pid = %" PRIu64
1032 ". Sending exit status of -1.",
1033 __FUNCTION__, m_pid);
1034
1035 error = SendInferiorExitStatusToMainLoop((::pid_t)m_pid, -1);
1036 return nullptr;
Todd Fialae77fce02016-09-04 00:18:56 +00001037}
1038
Kate Stoneb9c1b512016-09-06 20:57:50 +00001039Error NativeProcessDarwin::SendInferiorExitStatusToMainLoop(::pid_t pid,
1040 int status) {
1041 Error error;
1042 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
Todd Fialae77fce02016-09-04 00:18:56 +00001043
Kate Stoneb9c1b512016-09-06 20:57:50 +00001044 size_t bytes_written = 0;
Todd Fialae77fce02016-09-04 00:18:56 +00001045
Kate Stoneb9c1b512016-09-06 20:57:50 +00001046 // Send the pid.
1047 error = m_waitpid_pipe.Write(&pid, sizeof(pid), bytes_written);
1048 if (error.Fail() || (bytes_written < sizeof(pid))) {
Todd Fialae77fce02016-09-04 00:18:56 +00001049 if (log)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001050 log->Printf("NativeProcessDarwin::%s() - failed to write "
1051 "waitpid exiting pid to the pipe. Client will not "
1052 "hear about inferior exit status!",
1053 __FUNCTION__);
1054 return error;
1055 }
1056
1057 // Send the status.
1058 bytes_written = 0;
1059 error = m_waitpid_pipe.Write(&status, sizeof(status), bytes_written);
1060 if (error.Fail() || (bytes_written < sizeof(status))) {
1061 if (log)
1062 log->Printf("NativeProcessDarwin::%s() - failed to write "
1063 "waitpid exit result to the pipe. Client will not "
1064 "hear about inferior exit status!",
1065 __FUNCTION__);
1066 }
1067 return error;
1068}
1069
1070Error NativeProcessDarwin::HandleWaitpidResult() {
1071 Error error;
1072 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
1073
1074 // Read the pid.
1075 const bool notify_status = true;
1076
1077 ::pid_t pid = -1;
1078 size_t bytes_read = 0;
1079 error = m_waitpid_pipe.Read(&pid, sizeof(pid), bytes_read);
1080 if (error.Fail() || (bytes_read < sizeof(pid))) {
1081 if (log)
1082 log->Printf("NativeProcessDarwin::%s() - failed to read "
1083 "waitpid exiting pid from the pipe. Will notify "
1084 "as if parent process died with exit status -1.",
1085 __FUNCTION__);
1086 SetExitStatus(eExitTypeInvalid, -1, "failed to receive waitpid result",
1087 notify_status);
1088 return error;
1089 }
1090
1091 // Read the status.
1092 int status = -1;
1093 error = m_waitpid_pipe.Read(&status, sizeof(status), bytes_read);
1094 if (error.Fail() || (bytes_read < sizeof(status))) {
1095 if (log)
1096 log->Printf("NativeProcessDarwin::%s() - failed to read "
1097 "waitpid exit status from the pipe. Will notify "
1098 "as if parent process died with exit status -1.",
1099 __FUNCTION__);
1100 SetExitStatus(eExitTypeInvalid, -1, "failed to receive waitpid result",
1101 notify_status);
1102 return error;
1103 }
1104
1105 // Notify the monitor that our state has changed.
1106 if (log)
1107 log->Printf("NativeProcessDarwin::%s(): main loop received waitpid "
1108 "exit status info: pid=%i (%s), status=%i",
1109 __FUNCTION__, pid,
1110 (pid == m_pid) ? "the inferior" : "not the inferior", status);
1111
1112 ExitType exit_type = eExitTypeInvalid;
1113 int exit_status = -1;
1114
1115 if (WIFEXITED(status)) {
1116 exit_type = eExitTypeExit;
1117 exit_status = WEXITSTATUS(status);
1118 } else if (WIFSIGNALED(status)) {
1119 exit_type = eExitTypeSignal;
1120 exit_status = WTERMSIG(status);
1121 }
1122
1123 SetExitStatus(exit_type, exit_status, nullptr, notify_status);
1124 return error;
1125}
1126
1127task_t NativeProcessDarwin::TaskPortForProcessID(Error &error,
1128 bool force) const {
1129 if ((m_task == TASK_NULL) || force) {
1130 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
1131 if (m_pid == LLDB_INVALID_PROCESS_ID) {
1132 if (log)
1133 log->Printf("NativeProcessDarwin::%s(): cannot get task due "
1134 "to invalid pid",
1135 __FUNCTION__);
1136 return TASK_NULL;
Todd Fialae77fce02016-09-04 00:18:56 +00001137 }
1138
Kate Stoneb9c1b512016-09-06 20:57:50 +00001139 const uint32_t num_retries = 10;
1140 const uint32_t usec_interval = 10000;
1141
1142 mach_port_t task_self = mach_task_self();
1143 task_t task = TASK_NULL;
1144
1145 for (uint32_t i = 0; i < num_retries; i++) {
1146 kern_return_t err = ::task_for_pid(task_self, m_pid, &task);
1147 if (err == 0) {
1148 // Succeeded. Save and return it.
1149 error.Clear();
1150 m_task = task;
1151 log->Printf("NativeProcessDarwin::%s(): ::task_for_pid("
1152 "stub_port = 0x%4.4x, pid = %llu, &task) "
1153 "succeeded: inferior task port = 0x%4.4x",
1154 __FUNCTION__, task_self, m_pid, m_task);
1155 return m_task;
1156 } else {
1157 // Failed to get the task for the inferior process.
1158 error.SetError(err, eErrorTypeMachKernel);
1159 if (log) {
1160 log->Printf("NativeProcessDarwin::%s(): ::task_for_pid("
1161 "stub_port = 0x%4.4x, pid = %llu, &task) "
1162 "failed, err = 0x%8.8x (%s)",
1163 __FUNCTION__, task_self, m_pid, err, error.AsCString());
1164 }
1165 }
1166
1167 // Sleep a bit and try again
1168 ::usleep(usec_interval);
Todd Fialae77fce02016-09-04 00:18:56 +00001169 }
Todd Fialae77fce02016-09-04 00:18:56 +00001170
Kate Stoneb9c1b512016-09-06 20:57:50 +00001171 // We failed to get the task for the inferior process.
1172 // Ensure that it is cleared out.
1173 m_task = TASK_NULL;
1174 }
1175 return m_task;
1176}
Todd Fialae77fce02016-09-04 00:18:56 +00001177
Kate Stoneb9c1b512016-09-06 20:57:50 +00001178void NativeProcessDarwin::AttachToInferior(MainLoop &mainloop, lldb::pid_t pid,
1179 Error &error) {
1180 error.SetErrorString("TODO: implement");
1181}
1182
1183Error NativeProcessDarwin::PrivateResume() {
1184 Error error;
1185 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
1186
1187 std::lock_guard<std::recursive_mutex> locker(m_exception_messages_mutex);
1188 m_auto_resume_signo = m_sent_interrupt_signo;
1189
1190 if (log) {
1191 if (m_auto_resume_signo)
1192 log->Printf("NativeProcessDarwin::%s(): task 0x%x resuming (with "
1193 "unhandled interrupt signal %i)...",
1194 __FUNCTION__, m_task, m_auto_resume_signo);
Todd Fialae77fce02016-09-04 00:18:56 +00001195 else
Kate Stoneb9c1b512016-09-06 20:57:50 +00001196 log->Printf("NativeProcessDarwin::%s(): task 0x%x resuming...",
1197 __FUNCTION__, m_task);
1198 }
Todd Fialae77fce02016-09-04 00:18:56 +00001199
Kate Stoneb9c1b512016-09-06 20:57:50 +00001200 error = ReplyToAllExceptions();
1201 if (error.Fail()) {
Todd Fialae77fce02016-09-04 00:18:56 +00001202 if (log)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001203 log->Printf("NativeProcessDarwin::%s(): aborting, failed to "
1204 "reply to exceptions: %s",
1205 __FUNCTION__, error.AsCString());
Todd Fialae77fce02016-09-04 00:18:56 +00001206 return error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001207 }
1208 // bool stepOverBreakInstruction = step;
1209
1210 // Let the thread prepare to resume and see if any threads want us to
1211 // step over a breakpoint instruction (ProcessWillResume will modify
1212 // the value of stepOverBreakInstruction).
1213 m_thread_list.ProcessWillResume(*this, m_thread_actions);
1214
1215 // Set our state accordingly
1216 if (m_thread_actions.NumActionsWithState(eStateStepping))
1217 SetState(eStateStepping);
1218 else
1219 SetState(eStateRunning);
1220
1221 // Now resume our task.
1222 error = ResumeTask();
1223 return error;
Todd Fialae77fce02016-09-04 00:18:56 +00001224}
1225
Kate Stoneb9c1b512016-09-06 20:57:50 +00001226Error NativeProcessDarwin::ReplyToAllExceptions() {
1227 Error error;
1228 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
Todd Fialae77fce02016-09-04 00:18:56 +00001229
Kate Stoneb9c1b512016-09-06 20:57:50 +00001230 TaskPortForProcessID(error);
1231 if (error.Fail()) {
1232 if (log)
1233 log->Printf("NativeProcessDarwin::%s(): no task port, aborting",
1234 __FUNCTION__);
Todd Fialae77fce02016-09-04 00:18:56 +00001235 return error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001236 }
Todd Fialae77fce02016-09-04 00:18:56 +00001237
Kate Stoneb9c1b512016-09-06 20:57:50 +00001238 std::lock_guard<std::recursive_mutex> locker(m_exception_messages_mutex);
1239 if (m_exception_messages.empty()) {
1240 // We're done.
1241 return error;
1242 }
Todd Fialae77fce02016-09-04 00:18:56 +00001243
Kate Stoneb9c1b512016-09-06 20:57:50 +00001244 size_t index = 0;
1245 for (auto &message : m_exception_messages) {
1246 if (log) {
1247 log->Printf("NativeProcessDarwin::%s(): replying to exception "
1248 "%zu...",
1249 __FUNCTION__, index++);
Todd Fialae77fce02016-09-04 00:18:56 +00001250 }
1251
Kate Stoneb9c1b512016-09-06 20:57:50 +00001252 int thread_reply_signal = 0;
1253
1254 const tid_t tid =
1255 m_thread_list.GetThreadIDByMachPortNumber(message.state.thread_port);
1256 const ResumeAction *action = nullptr;
1257 if (tid != LLDB_INVALID_THREAD_ID)
1258 action = m_thread_actions.GetActionForThread(tid, false);
1259
1260 if (action) {
1261 thread_reply_signal = action->signal;
1262 if (thread_reply_signal)
1263 m_thread_actions.SetSignalHandledForThread(tid);
1264 }
1265
1266 error = message.Reply(m_pid, m_task, thread_reply_signal);
1267 if (error.Fail() && log) {
1268 // We log any error here, but we don't stop the exception
1269 // response handling.
1270 log->Printf("NativeProcessDarwin::%s(): failed to reply to "
1271 "exception: %s",
1272 __FUNCTION__, error.AsCString());
1273 error.Clear();
1274 }
1275 }
1276
1277 // Erase all exception message as we should have used and replied
1278 // to them all already.
1279 m_exception_messages.clear();
1280 return error;
1281}
1282
1283Error NativeProcessDarwin::ResumeTask() {
1284 Error error;
1285 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
1286
1287 TaskPortForProcessID(error);
1288 if (error.Fail()) {
1289 if (log)
1290 log->Printf("NativeProcessDarwin::%s(): failed to get task port "
1291 "for process when attempting to resume: %s",
1292 __FUNCTION__, error.AsCString());
1293 return error;
1294 }
1295 if (m_task == TASK_NULL) {
1296 error.SetErrorString("task port retrieval succeeded but task port is "
1297 "null when attempting to resume the task");
1298 return error;
1299 }
1300
1301 if (log)
1302 log->Printf("NativeProcessDarwin::%s(): requesting resume of task "
1303 "0x%4.4x",
1304 __FUNCTION__, m_task);
1305
1306 // Get the BasicInfo struct to verify that we're suspended before we try
1307 // to resume the task.
1308 struct task_basic_info task_info;
1309 error = GetTaskBasicInfo(m_task, &task_info);
1310 if (error.Fail()) {
1311 if (log)
1312 log->Printf("NativeProcessDarwin::%s(): failed to get task "
1313 "BasicInfo when attempting to resume: %s",
1314 __FUNCTION__, error.AsCString());
1315 return error;
1316 }
1317
1318 // task_resume isn't counted like task_suspend calls are, so if the
1319 // task is not suspended, don't try and resume it since it is already
1320 // running
1321 if (task_info.suspend_count > 0) {
1322 auto mach_err = ::task_resume(m_task);
Todd Fialae77fce02016-09-04 00:18:56 +00001323 error.SetError(mach_err, eErrorTypeMachKernel);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001324 if (log) {
1325 if (error.Success())
1326 log->Printf("::task_resume(target_task = 0x%4.4x): success", m_task);
1327 else
1328 log->Printf("::task_resume(target_task = 0x%4.4x) error: %s", m_task,
1329 error.AsCString());
1330 }
1331 } else {
Todd Fialae77fce02016-09-04 00:18:56 +00001332 if (log)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001333 log->Printf("::task_resume(target_task = 0x%4.4x): ignored, "
1334 "already running",
1335 m_task);
1336 }
Todd Fialae77fce02016-09-04 00:18:56 +00001337
Kate Stoneb9c1b512016-09-06 20:57:50 +00001338 return error;
Todd Fialae77fce02016-09-04 00:18:56 +00001339}
1340
Kate Stoneb9c1b512016-09-06 20:57:50 +00001341bool NativeProcessDarwin::IsTaskValid() const {
1342 if (m_task == TASK_NULL)
Todd Fialae77fce02016-09-04 00:18:56 +00001343 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001344
1345 struct task_basic_info task_info;
1346 return GetTaskBasicInfo(m_task, &task_info).Success();
Todd Fialae77fce02016-09-04 00:18:56 +00001347}
1348
Kate Stoneb9c1b512016-09-06 20:57:50 +00001349bool NativeProcessDarwin::IsTaskValid(task_t task) const {
1350 if (task == TASK_NULL)
1351 return false;
1352
1353 struct task_basic_info task_info;
1354 return GetTaskBasicInfo(task, &task_info).Success();
1355}
1356
1357mach_port_t NativeProcessDarwin::GetExceptionPort() const {
1358 return m_exception_port;
1359}
1360
1361bool NativeProcessDarwin::IsExceptionPortValid() const {
1362 return MACH_PORT_VALID(m_exception_port);
1363}
1364
1365Error NativeProcessDarwin::GetTaskBasicInfo(
1366 task_t task, struct task_basic_info *info) const {
1367 Error error;
1368 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
1369
1370 // Validate args.
1371 if (info == NULL) {
1372 error.SetErrorStringWithFormat("NativeProcessDarwin::%s(): mandatory "
1373 "info arg is null",
1374 __FUNCTION__);
Todd Fialae77fce02016-09-04 00:18:56 +00001375 return error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001376 }
Todd Fialae77fce02016-09-04 00:18:56 +00001377
Kate Stoneb9c1b512016-09-06 20:57:50 +00001378 // Grab the task if we don't already have it.
1379 if (task == TASK_NULL) {
1380 error.SetErrorStringWithFormat("NativeProcessDarwin::%s(): given task "
1381 "is invalid",
1382 __FUNCTION__);
1383 }
Todd Fialae77fce02016-09-04 00:18:56 +00001384
Kate Stoneb9c1b512016-09-06 20:57:50 +00001385 mach_msg_type_number_t count = TASK_BASIC_INFO_COUNT;
1386 auto err = ::task_info(m_task, TASK_BASIC_INFO, (task_info_t)info, &count);
1387 error.SetError(err, eErrorTypeMachKernel);
1388 if (error.Fail()) {
1389 if (log)
1390 log->Printf("::task_info(target_task = 0x%4.4x, "
1391 "flavor = TASK_BASIC_INFO, task_info_out => %p, "
1392 "task_info_outCnt => %u) failed: %u (%s)",
1393 m_task, info, count, error.GetError(), error.AsCString());
Todd Fialae77fce02016-09-04 00:18:56 +00001394 return error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001395 }
1396
1397 Log *verbose_log(
1398 GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
1399 if (verbose_log) {
1400 float user = (float)info->user_time.seconds +
1401 (float)info->user_time.microseconds / 1000000.0f;
1402 float system = (float)info->user_time.seconds +
1403 (float)info->user_time.microseconds / 1000000.0f;
1404 verbose_log->Printf("task_basic_info = { suspend_count = %i, "
1405 "virtual_size = 0x%8.8llx, resident_size = "
1406 "0x%8.8llx, user_time = %f, system_time = %f }",
1407 info->suspend_count, (uint64_t)info->virtual_size,
1408 (uint64_t)info->resident_size, user, system);
1409 }
1410 return error;
Todd Fialae77fce02016-09-04 00:18:56 +00001411}
1412
Kate Stoneb9c1b512016-09-06 20:57:50 +00001413Error NativeProcessDarwin::SuspendTask() {
1414 Error error;
1415 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
1416
1417 if (m_task == TASK_NULL) {
1418 error.SetErrorString("task port is null, cannot suspend task");
1419 if (log)
1420 log->Printf("NativeProcessDarwin::%s() failed: %s", __FUNCTION__,
1421 error.AsCString());
Todd Fialae77fce02016-09-04 00:18:56 +00001422 return error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001423 }
1424
1425 auto mach_err = ::task_suspend(m_task);
1426 error.SetError(mach_err, eErrorTypeMachKernel);
1427 if (error.Fail() && log)
1428 log->Printf("::task_suspend(target_task = 0x%4.4x)", m_task);
1429
1430 return error;
1431}
1432
1433Error NativeProcessDarwin::Resume(const ResumeActionList &resume_actions) {
1434 Error error;
1435 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
1436
1437 if (log)
1438 log->Printf("NativeProcessDarwin::%s() called", __FUNCTION__);
1439
1440 if (CanResume()) {
1441 m_thread_actions = resume_actions;
1442 error = PrivateResume();
1443 return error;
1444 }
1445
1446 auto state = GetState();
1447 if (state == eStateRunning) {
1448 if (log)
1449 log->Printf("NativeProcessDarwin::%s(): task 0x%x is already "
1450 "running, ignoring...",
1451 __FUNCTION__, TaskPortForProcessID(error));
1452 return error;
1453 }
1454
1455 // We can't resume from this state.
1456 error.SetErrorStringWithFormat("task 0x%x has state %s, can't resume",
1457 TaskPortForProcessID(error),
1458 StateAsCString(state));
1459 return error;
1460}
1461
1462Error NativeProcessDarwin::Halt() {
1463 Error error;
1464 error.SetErrorString("TODO: implement");
1465 return error;
1466}
1467
1468Error NativeProcessDarwin::Detach() {
1469 Error error;
1470 error.SetErrorString("TODO: implement");
1471 return error;
1472}
1473
1474Error NativeProcessDarwin::Signal(int signo) {
1475 Error error;
1476 error.SetErrorString("TODO: implement");
1477 return error;
1478}
1479
1480Error NativeProcessDarwin::Interrupt() {
1481 Error error;
1482 error.SetErrorString("TODO: implement");
1483 return error;
1484}
1485
1486Error NativeProcessDarwin::Kill() {
1487 Error error;
1488 error.SetErrorString("TODO: implement");
1489 return error;
1490}
1491
1492Error NativeProcessDarwin::GetMemoryRegionInfo(lldb::addr_t load_addr,
1493 MemoryRegionInfo &range_info) {
1494 Error error;
1495 error.SetErrorString("TODO: implement");
1496 return error;
1497}
1498
1499Error NativeProcessDarwin::ReadMemory(lldb::addr_t addr, void *buf, size_t size,
1500 size_t &bytes_read) {
1501 Error error;
1502 error.SetErrorString("TODO: implement");
1503 return error;
1504}
1505
1506Error NativeProcessDarwin::ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf,
1507 size_t size,
1508 size_t &bytes_read) {
1509 Error error;
1510 error.SetErrorString("TODO: implement");
1511 return error;
1512}
1513
1514Error NativeProcessDarwin::WriteMemory(lldb::addr_t addr, const void *buf,
1515 size_t size, size_t &bytes_written) {
1516 Error error;
1517 error.SetErrorString("TODO: implement");
1518 return error;
1519}
1520
1521Error NativeProcessDarwin::AllocateMemory(size_t size, uint32_t permissions,
1522 lldb::addr_t &addr) {
1523 Error error;
1524 error.SetErrorString("TODO: implement");
1525 return error;
1526}
1527
1528Error NativeProcessDarwin::DeallocateMemory(lldb::addr_t addr) {
1529 Error error;
1530 error.SetErrorString("TODO: implement");
1531 return error;
1532}
1533
1534lldb::addr_t NativeProcessDarwin::GetSharedLibraryInfoAddress() {
1535 return LLDB_INVALID_ADDRESS;
1536}
1537
1538size_t NativeProcessDarwin::UpdateThreads() { return 0; }
1539
1540bool NativeProcessDarwin::GetArchitecture(ArchSpec &arch) const {
1541 return false;
1542}
1543
1544Error NativeProcessDarwin::SetBreakpoint(lldb::addr_t addr, uint32_t size,
1545 bool hardware) {
1546 Error error;
1547 error.SetErrorString("TODO: implement");
1548 return error;
1549}
1550
1551void NativeProcessDarwin::DoStopIDBumped(uint32_t newBumpId) {}
1552
1553Error NativeProcessDarwin::GetLoadedModuleFileSpec(const char *module_path,
1554 FileSpec &file_spec) {
1555 Error error;
1556 error.SetErrorString("TODO: implement");
1557 return error;
1558}
1559
1560Error NativeProcessDarwin::GetFileLoadAddress(const llvm::StringRef &file_name,
1561 lldb::addr_t &load_addr) {
1562 Error error;
1563 error.SetErrorString("TODO: implement");
1564 return error;
Todd Fialae77fce02016-09-04 00:18:56 +00001565}
1566
1567// -----------------------------------------------------------------
1568// NativeProcessProtocol protected interface
1569// -----------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +00001570Error NativeProcessDarwin::GetSoftwareBreakpointTrapOpcode(
1571 size_t trap_opcode_size_hint, size_t &actual_opcode_size,
1572 const uint8_t *&trap_opcode_bytes) {
1573 Error error;
1574 error.SetErrorString("TODO: implement");
1575 return error;
Todd Fialae77fce02016-09-04 00:18:56 +00001576}