1 //===-- DNB.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 //  Created by Greg Clayton on 3/23/07.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "DNB.h"
15 #include <inttypes.h>
16 #include <signal.h>
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <sys/resource.h>
20 #include <sys/stat.h>
21 #include <sys/types.h>
22 #include <sys/wait.h>
23 #include <unistd.h>
24 #include <sys/sysctl.h>
25 #include <map>
26 #include <vector>
27 #include <libproc.h>
28 
29 #include "MacOSX/MachProcess.h"
30 #include "MacOSX/MachTask.h"
31 #include "CFString.h"
32 #include "DNBLog.h"
33 #include "DNBDataRef.h"
34 #include "DNBThreadResumeActions.h"
35 #include "DNBTimer.h"
36 #include "CFBundle.h"
37 
38 
39 typedef std::shared_ptr<MachProcess> MachProcessSP;
40 typedef std::map<nub_process_t, MachProcessSP> ProcessMap;
41 typedef ProcessMap::iterator ProcessMapIter;
42 typedef ProcessMap::const_iterator ProcessMapConstIter;
43 
44 size_t GetAllInfos (std::vector<struct kinfo_proc>& proc_infos);
45 static size_t GetAllInfosMatchingName (const char *process_name, std::vector<struct kinfo_proc>& matching_proc_infos);
46 
47 //----------------------------------------------------------------------
48 // A Thread safe singleton to get a process map pointer.
49 //
50 // Returns a pointer to the existing process map, or a pointer to a
51 // newly created process map if CAN_CREATE is non-zero.
52 //----------------------------------------------------------------------
53 static ProcessMap*
54 GetProcessMap(bool can_create)
55 {
56     static ProcessMap* g_process_map_ptr = NULL;
57 
58     if (can_create && g_process_map_ptr == NULL)
59     {
60         static pthread_mutex_t g_process_map_mutex = PTHREAD_MUTEX_INITIALIZER;
61         PTHREAD_MUTEX_LOCKER (locker, &g_process_map_mutex);
62         if (g_process_map_ptr == NULL)
63             g_process_map_ptr = new ProcessMap;
64     }
65     return g_process_map_ptr;
66 }
67 
68 //----------------------------------------------------------------------
69 // Add PID to the shared process pointer map.
70 //
71 // Return non-zero value if we succeed in adding the process to the map.
72 // The only time this should fail is if we run out of memory and can't
73 // allocate a ProcessMap.
74 //----------------------------------------------------------------------
75 static nub_bool_t
76 AddProcessToMap (nub_process_t pid, MachProcessSP& procSP)
77 {
78     ProcessMap* process_map = GetProcessMap(true);
79     if (process_map)
80     {
81         process_map->insert(std::make_pair(pid, procSP));
82         return true;
83     }
84     return false;
85 }
86 
87 //----------------------------------------------------------------------
88 // Remove the shared pointer for PID from the process map.
89 //
90 // Returns the number of items removed from the process map.
91 //----------------------------------------------------------------------
92 static size_t
93 RemoveProcessFromMap (nub_process_t pid)
94 {
95     ProcessMap* process_map = GetProcessMap(false);
96     if (process_map)
97     {
98         return process_map->erase(pid);
99     }
100     return 0;
101 }
102 
103 //----------------------------------------------------------------------
104 // Get the shared pointer for PID from the existing process map.
105 //
106 // Returns true if we successfully find a shared pointer to a
107 // MachProcess object.
108 //----------------------------------------------------------------------
109 static nub_bool_t
110 GetProcessSP (nub_process_t pid, MachProcessSP& procSP)
111 {
112     ProcessMap* process_map = GetProcessMap(false);
113     if (process_map != NULL)
114     {
115         ProcessMapIter pos = process_map->find(pid);
116         if (pos != process_map->end())
117         {
118             procSP = pos->second;
119             return true;
120         }
121     }
122     procSP.reset();
123     return false;
124 }
125 
126 
127 static void *
128 waitpid_thread (void *arg)
129 {
130     const pid_t pid = (pid_t)(intptr_t)arg;
131     int status;
132     while (1)
133     {
134         pid_t child_pid = waitpid(pid, &status, 0);
135         DNBLogThreadedIf(LOG_PROCESS, "waitpid_thread (): waitpid (pid = %i, &status, 0) => %i, status = %i, errno = %i", pid, child_pid, status, errno);
136 
137         if (child_pid < 0)
138         {
139             if (errno == EINTR)
140                 continue;
141             break;
142         }
143         else
144         {
145             if (WIFSTOPPED(status))
146             {
147                 continue;
148             }
149             else// if (WIFEXITED(status) || WIFSIGNALED(status))
150             {
151                 DNBLogThreadedIf(LOG_PROCESS, "waitpid_thread (): setting exit status for pid = %i to %i", child_pid, status);
152                 DNBProcessSetExitStatus (child_pid, status);
153                 return NULL;
154             }
155         }
156     }
157 
158     // We should never exit as long as our child process is alive, so if we
159     // do something else went wrong and we should exit...
160     DNBLogThreadedIf(LOG_PROCESS, "waitpid_thread (): main loop exited, setting exit status to an invalid value (-1) for pid %i", pid);
161     DNBProcessSetExitStatus (pid, -1);
162     return NULL;
163 }
164 
165 static bool
166 spawn_waitpid_thread (pid_t pid)
167 {
168     pthread_t thread;
169     int ret = ::pthread_create (&thread, NULL, waitpid_thread, (void *)(intptr_t)pid);
170     // pthread_create returns 0 if successful
171     if (ret == 0)
172     {
173         ::pthread_detach (thread);
174         return true;
175     }
176     return false;
177 }
178 
179 nub_process_t
180 DNBProcessLaunch (const char *path,
181                   char const *argv[],
182                   const char *envp[],
183                   const char *working_directory, // NULL => dont' change, non-NULL => set working directory for inferior to this
184                   const char *stdin_path,
185                   const char *stdout_path,
186                   const char *stderr_path,
187                   bool no_stdio,
188                   nub_launch_flavor_t launch_flavor,
189                   int disable_aslr,
190                   char *err_str,
191                   size_t err_len)
192 {
193     DNBLogThreadedIf(LOG_PROCESS, "%s ( path='%s', argv = %p, envp = %p, working_dir=%s, stdin=%s, stdout=%s, stderr=%s, no-stdio=%i, launch_flavor = %u, disable_aslr = %d, err = %p, err_len = %llu) called...",
194                      __FUNCTION__,
195                      path,
196                      argv,
197                      envp,
198                      working_directory,
199                      stdin_path,
200                      stdout_path,
201                      stderr_path,
202                      no_stdio,
203                      launch_flavor,
204                      disable_aslr,
205                      err_str,
206                      (uint64_t)err_len);
207 
208     if (err_str && err_len > 0)
209         err_str[0] = '\0';
210     struct stat path_stat;
211     if (::stat(path, &path_stat) == -1)
212     {
213         char stat_error[256];
214         ::strerror_r (errno, stat_error, sizeof(stat_error));
215         snprintf(err_str, err_len, "%s (%s)", stat_error, path);
216         return INVALID_NUB_PROCESS;
217     }
218 
219     MachProcessSP processSP (new MachProcess);
220     if (processSP.get())
221     {
222         DNBError launch_err;
223         pid_t pid = processSP->LaunchForDebug (path,
224                                                argv,
225                                                envp,
226                                                working_directory,
227                                                stdin_path,
228                                                stdout_path,
229                                                stderr_path,
230                                                no_stdio,
231                                                launch_flavor,
232                                                disable_aslr,
233                                                launch_err);
234         if (err_str)
235         {
236             *err_str = '\0';
237             if (launch_err.Fail())
238             {
239                 const char *launch_err_str = launch_err.AsString();
240                 if (launch_err_str)
241                 {
242                     strncpy(err_str, launch_err_str, err_len-1);
243                     err_str[err_len-1] = '\0';  // Make sure the error string is terminated
244                 }
245             }
246         }
247 
248         DNBLogThreadedIf(LOG_PROCESS, "(DebugNub) new pid is %d...", pid);
249 
250         if (pid != INVALID_NUB_PROCESS)
251         {
252             // Spawn a thread to reap our child inferior process...
253             spawn_waitpid_thread (pid);
254 
255             if (processSP->Task().TaskPortForProcessID (launch_err) == TASK_NULL)
256             {
257                 // We failed to get the task for our process ID which is bad.
258                 // Kill our process otherwise it will be stopped at the entry
259                 // point and get reparented to someone else and never go away.
260                 DNBLog ("Could not get task port for process, sending SIGKILL and exiting.");
261                 kill (SIGKILL, pid);
262 
263                 if (err_str && err_len > 0)
264                 {
265                     if (launch_err.AsString())
266                     {
267                         ::snprintf (err_str, err_len, "failed to get the task for process %i (%s)", pid, launch_err.AsString());
268                     }
269                     else
270                     {
271                         ::snprintf (err_str, err_len, "failed to get the task for process %i", pid);
272                     }
273                 }
274             }
275             else
276             {
277                 bool res = AddProcessToMap(pid, processSP);
278                 assert(res && "Couldn't add process to map!");
279                 return pid;
280             }
281         }
282     }
283     return INVALID_NUB_PROCESS;
284 }
285 
286 nub_process_t
287 DNBProcessAttachByName (const char *name, struct timespec *timeout, char *err_str, size_t err_len)
288 {
289     if (err_str && err_len > 0)
290         err_str[0] = '\0';
291     std::vector<struct kinfo_proc> matching_proc_infos;
292     size_t num_matching_proc_infos = GetAllInfosMatchingName(name, matching_proc_infos);
293     if (num_matching_proc_infos == 0)
294     {
295         DNBLogError ("error: no processes match '%s'\n", name);
296         return INVALID_NUB_PROCESS;
297     }
298     else if (num_matching_proc_infos > 1)
299     {
300         DNBLogError ("error: %llu processes match '%s':\n", (uint64_t)num_matching_proc_infos, name);
301         size_t i;
302         for (i=0; i<num_matching_proc_infos; ++i)
303             DNBLogError ("%6u - %s\n", matching_proc_infos[i].kp_proc.p_pid, matching_proc_infos[i].kp_proc.p_comm);
304         return INVALID_NUB_PROCESS;
305     }
306 
307     return DNBProcessAttach (matching_proc_infos[0].kp_proc.p_pid, timeout, err_str, err_len);
308 }
309 
310 nub_process_t
311 DNBProcessAttach (nub_process_t attach_pid, struct timespec *timeout, char *err_str, size_t err_len)
312 {
313     if (err_str && err_len > 0)
314         err_str[0] = '\0';
315 
316     pid_t pid = INVALID_NUB_PROCESS;
317     MachProcessSP processSP(new MachProcess);
318     if (processSP.get())
319     {
320         DNBLogThreadedIf(LOG_PROCESS, "(DebugNub) attaching to pid %d...", attach_pid);
321         pid = processSP->AttachForDebug (attach_pid, err_str,  err_len);
322 
323         if (pid != INVALID_NUB_PROCESS)
324         {
325             bool res = AddProcessToMap(pid, processSP);
326             assert(res && "Couldn't add process to map!");
327             spawn_waitpid_thread(pid);
328         }
329     }
330 
331     while (pid != INVALID_NUB_PROCESS)
332     {
333         // Wait for process to start up and hit entry point
334         DNBLogThreadedIf (LOG_PROCESS,
335                           "%s DNBProcessWaitForEvent (%4.4x, eEventProcessRunningStateChanged | eEventProcessStoppedStateChanged, true, INFINITE)...",
336                           __FUNCTION__,
337                           pid);
338         nub_event_t set_events = DNBProcessWaitForEvents (pid,
339                                                           eEventProcessRunningStateChanged | eEventProcessStoppedStateChanged,
340                                                           true,
341                                                           timeout);
342 
343         DNBLogThreadedIf (LOG_PROCESS,
344                           "%s DNBProcessWaitForEvent (%4.4x, eEventProcessRunningStateChanged | eEventProcessStoppedStateChanged, true, INFINITE) => 0x%8.8x",
345                           __FUNCTION__,
346                           pid,
347                           set_events);
348 
349         if (set_events == 0)
350         {
351             if (err_str && err_len > 0)
352                 snprintf(err_str, err_len, "operation timed out");
353             pid = INVALID_NUB_PROCESS;
354         }
355         else
356         {
357             if (set_events & (eEventProcessRunningStateChanged | eEventProcessStoppedStateChanged))
358             {
359                 nub_state_t pid_state = DNBProcessGetState (pid);
360                 DNBLogThreadedIf (LOG_PROCESS, "%s process %4.4x state changed (eEventProcessStateChanged): %s",
361                         __FUNCTION__, pid, DNBStateAsString(pid_state));
362 
363                 switch (pid_state)
364                 {
365                     default:
366                     case eStateInvalid:
367                     case eStateUnloaded:
368                     case eStateAttaching:
369                     case eStateLaunching:
370                     case eStateSuspended:
371                         break;  // Ignore
372 
373                     case eStateRunning:
374                     case eStateStepping:
375                         // Still waiting to stop at entry point...
376                         break;
377 
378                     case eStateStopped:
379                     case eStateCrashed:
380                         return pid;
381 
382                     case eStateDetached:
383                     case eStateExited:
384                         if (err_str && err_len > 0)
385                             snprintf(err_str, err_len, "process exited");
386                         return INVALID_NUB_PROCESS;
387                 }
388             }
389 
390             DNBProcessResetEvents(pid, set_events);
391         }
392     }
393 
394     return INVALID_NUB_PROCESS;
395 }
396 
397 size_t
398 GetAllInfos (std::vector<struct kinfo_proc>& proc_infos)
399 {
400     size_t size = 0;
401     int name[] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL };
402     u_int namelen = sizeof(name)/sizeof(int);
403     int err;
404 
405     // Try to find out how many processes are around so we can
406     // size the buffer appropriately.  sysctl's man page specifically suggests
407     // this approach, and says it returns a bit larger size than needed to
408     // handle any new processes created between then and now.
409 
410     err = ::sysctl (name, namelen, NULL, &size, NULL, 0);
411 
412     if ((err < 0) && (err != ENOMEM))
413     {
414         proc_infos.clear();
415         perror("sysctl (mib, miblen, NULL, &num_processes, NULL, 0)");
416         return 0;
417     }
418 
419 
420     // Increase the size of the buffer by a few processes in case more have
421     // been spawned
422     proc_infos.resize (size / sizeof(struct kinfo_proc));
423     size = proc_infos.size() * sizeof(struct kinfo_proc);   // Make sure we don't exceed our resize...
424     err = ::sysctl (name, namelen, &proc_infos[0], &size, NULL, 0);
425     if (err < 0)
426     {
427         proc_infos.clear();
428         return 0;
429     }
430 
431     // Trim down our array to fit what we actually got back
432     proc_infos.resize(size / sizeof(struct kinfo_proc));
433     return proc_infos.size();
434 }
435 
436 static size_t
437 GetAllInfosMatchingName(const char *full_process_name, std::vector<struct kinfo_proc>& matching_proc_infos)
438 {
439 
440     matching_proc_infos.clear();
441     if (full_process_name && full_process_name[0])
442     {
443         // We only get the process name, not the full path, from the proc_info.  So just take the
444         // base name of the process name...
445         const char *process_name;
446         process_name = strrchr (full_process_name, '/');
447         if (process_name == NULL)
448             process_name = full_process_name;
449         else
450             process_name++;
451 
452         const int process_name_len = strlen(process_name);
453         std::vector<struct kinfo_proc> proc_infos;
454         const size_t num_proc_infos = GetAllInfos(proc_infos);
455         if (num_proc_infos > 0)
456         {
457             uint32_t i;
458             for (i=0; i<num_proc_infos; i++)
459             {
460                 // Skip zombie processes and processes with unset status
461                 if (proc_infos[i].kp_proc.p_stat == 0 || proc_infos[i].kp_proc.p_stat == SZOMB)
462                     continue;
463 
464                 // Check for process by name. We only check the first MAXCOMLEN
465                 // chars as that is all that kp_proc.p_comm holds.
466 
467                 if (::strncasecmp(process_name, proc_infos[i].kp_proc.p_comm, MAXCOMLEN) == 0)
468                 {
469                     if (process_name_len > MAXCOMLEN)
470                     {
471                         // We found a matching process name whose first MAXCOMLEN
472                         // characters match, but there is more to the name than
473                         // this. We need to get the full process name.  Use proc_pidpath, which will get
474                         // us the full path to the executed process.
475 
476                         char proc_path_buf[PATH_MAX];
477 
478                         int return_val = proc_pidpath (proc_infos[i].kp_proc.p_pid, proc_path_buf, PATH_MAX);
479                         if (return_val > 0)
480                         {
481                             // Okay, now search backwards from that to see if there is a
482                             // slash in the name.  Note, even though we got all the args we don't care
483                             // because the list data is just a bunch of concatenated null terminated strings
484                             // so strrchr will start from the end of argv0.
485 
486                             const char *argv_basename = strrchr(proc_path_buf, '/');
487                             if (argv_basename)
488                             {
489                                 // Skip the '/'
490                                 ++argv_basename;
491                             }
492                             else
493                             {
494                                 // We didn't find a directory delimiter in the process argv[0], just use what was in there
495                                 argv_basename = proc_path_buf;
496                             }
497 
498                             if (argv_basename)
499                             {
500                                 if (::strncasecmp(process_name, argv_basename, PATH_MAX) == 0)
501                                 {
502                                     matching_proc_infos.push_back(proc_infos[i]);
503                                 }
504                             }
505                         }
506                     }
507                     else
508                     {
509                         // We found a matching process, add it to our list
510                         matching_proc_infos.push_back(proc_infos[i]);
511                     }
512                 }
513             }
514         }
515     }
516     // return the newly added matches.
517     return matching_proc_infos.size();
518 }
519 
520 nub_process_t
521 DNBProcessAttachWait (const char *waitfor_process_name,
522                       nub_launch_flavor_t launch_flavor,
523                       bool ignore_existing,
524                       struct timespec *timeout_abstime,
525                       useconds_t waitfor_interval,
526                       char *err_str,
527                       size_t err_len,
528                       DNBShouldCancelCallback should_cancel_callback,
529                       void *callback_data)
530 {
531     DNBError prepare_error;
532     std::vector<struct kinfo_proc> exclude_proc_infos;
533     size_t num_exclude_proc_infos;
534 
535     // If the PrepareForAttach returns a valid token, use  MachProcess to check
536     // for the process, otherwise scan the process table.
537 
538     const void *attach_token = MachProcess::PrepareForAttach (waitfor_process_name, launch_flavor, true, prepare_error);
539 
540     if (prepare_error.Fail())
541     {
542         DNBLogError ("Error in PrepareForAttach: %s", prepare_error.AsString());
543         return INVALID_NUB_PROCESS;
544     }
545 
546     if (attach_token == NULL)
547     {
548         if (ignore_existing)
549             num_exclude_proc_infos = GetAllInfosMatchingName (waitfor_process_name, exclude_proc_infos);
550         else
551             num_exclude_proc_infos = 0;
552     }
553 
554     DNBLogThreadedIf (LOG_PROCESS, "Waiting for '%s' to appear...\n", waitfor_process_name);
555 
556     // Loop and try to find the process by name
557     nub_process_t waitfor_pid = INVALID_NUB_PROCESS;
558 
559     while (waitfor_pid == INVALID_NUB_PROCESS)
560     {
561         if (attach_token != NULL)
562         {
563             nub_process_t pid;
564             pid = MachProcess::CheckForProcess(attach_token);
565             if (pid != INVALID_NUB_PROCESS)
566             {
567                 waitfor_pid = pid;
568                 break;
569             }
570         }
571         else
572         {
573 
574             // Get the current process list, and check for matches that
575             // aren't in our original list. If anyone wants to attach
576             // to an existing process by name, they should do it with
577             // --attach=PROCNAME. Else we will wait for the first matching
578             // process that wasn't in our exclusion list.
579             std::vector<struct kinfo_proc> proc_infos;
580             const size_t num_proc_infos = GetAllInfosMatchingName (waitfor_process_name, proc_infos);
581             for (size_t i=0; i<num_proc_infos; i++)
582             {
583                 nub_process_t curr_pid = proc_infos[i].kp_proc.p_pid;
584                 for (size_t j=0; j<num_exclude_proc_infos; j++)
585                 {
586                     if (curr_pid == exclude_proc_infos[j].kp_proc.p_pid)
587                     {
588                         // This process was in our exclusion list, don't use it.
589                         curr_pid = INVALID_NUB_PROCESS;
590                         break;
591                     }
592                 }
593 
594                 // If we didn't find CURR_PID in our exclusion list, then use it.
595                 if (curr_pid != INVALID_NUB_PROCESS)
596                 {
597                     // We found our process!
598                     waitfor_pid = curr_pid;
599                     break;
600                 }
601             }
602         }
603 
604         // If we haven't found our process yet, check for a timeout
605         // and then sleep for a bit until we poll again.
606         if (waitfor_pid == INVALID_NUB_PROCESS)
607         {
608             if (timeout_abstime != NULL)
609             {
610                 // Check to see if we have a waitfor-duration option that
611                 // has timed out?
612                 if (DNBTimer::TimeOfDayLaterThan(*timeout_abstime))
613                 {
614                     if (err_str && err_len > 0)
615                         snprintf(err_str, err_len, "operation timed out");
616                     DNBLogError ("error: waiting for process '%s' timed out.\n", waitfor_process_name);
617                     return INVALID_NUB_PROCESS;
618                 }
619             }
620 
621             // Call the should cancel callback as well...
622 
623             if (should_cancel_callback != NULL
624                 && should_cancel_callback (callback_data))
625             {
626                 DNBLogThreadedIf (LOG_PROCESS, "DNBProcessAttachWait cancelled by should_cancel callback.");
627                 waitfor_pid = INVALID_NUB_PROCESS;
628                 break;
629             }
630 
631             ::usleep (waitfor_interval);    // Sleep for WAITFOR_INTERVAL, then poll again
632         }
633     }
634 
635     if (waitfor_pid != INVALID_NUB_PROCESS)
636     {
637         DNBLogThreadedIf (LOG_PROCESS, "Attaching to %s with pid %i...\n", waitfor_process_name, waitfor_pid);
638         waitfor_pid = DNBProcessAttach (waitfor_pid, timeout_abstime, err_str, err_len);
639     }
640 
641     bool success = waitfor_pid != INVALID_NUB_PROCESS;
642     MachProcess::CleanupAfterAttach (attach_token, success, prepare_error);
643 
644     return waitfor_pid;
645 }
646 
647 nub_bool_t
648 DNBProcessDetach (nub_process_t pid)
649 {
650     MachProcessSP procSP;
651     if (GetProcessSP (pid, procSP))
652     {
653         return procSP->Detach();
654     }
655     return false;
656 }
657 
658 nub_bool_t
659 DNBProcessKill (nub_process_t pid)
660 {
661     MachProcessSP procSP;
662     if (GetProcessSP (pid, procSP))
663     {
664         return procSP->Kill ();
665     }
666     return false;
667 }
668 
669 nub_bool_t
670 DNBProcessSignal (nub_process_t pid, int signal)
671 {
672     MachProcessSP procSP;
673     if (GetProcessSP (pid, procSP))
674     {
675         return procSP->Signal (signal);
676     }
677     return false;
678 }
679 
680 
681 nub_bool_t
682 DNBProcessIsAlive (nub_process_t pid)
683 {
684     MachProcessSP procSP;
685     if (GetProcessSP (pid, procSP))
686     {
687         return MachTask::IsValid (procSP->Task().TaskPort());
688     }
689     return eStateInvalid;
690 }
691 
692 //----------------------------------------------------------------------
693 // Process and Thread state information
694 //----------------------------------------------------------------------
695 nub_state_t
696 DNBProcessGetState (nub_process_t pid)
697 {
698     MachProcessSP procSP;
699     if (GetProcessSP (pid, procSP))
700     {
701         return procSP->GetState();
702     }
703     return eStateInvalid;
704 }
705 
706 //----------------------------------------------------------------------
707 // Process and Thread state information
708 //----------------------------------------------------------------------
709 nub_bool_t
710 DNBProcessGetExitStatus (nub_process_t pid, int* status)
711 {
712     MachProcessSP procSP;
713     if (GetProcessSP (pid, procSP))
714     {
715         return procSP->GetExitStatus(status);
716     }
717     return false;
718 }
719 
720 nub_bool_t
721 DNBProcessSetExitStatus (nub_process_t pid, int status)
722 {
723     MachProcessSP procSP;
724     if (GetProcessSP (pid, procSP))
725     {
726         procSP->SetExitStatus(status);
727         return true;
728     }
729     return false;
730 }
731 
732 
733 const char *
734 DNBThreadGetName (nub_process_t pid, nub_thread_t tid)
735 {
736     MachProcessSP procSP;
737     if (GetProcessSP (pid, procSP))
738         return procSP->ThreadGetName(tid);
739     return NULL;
740 }
741 
742 
743 nub_bool_t
744 DNBThreadGetIdentifierInfo (nub_process_t pid, nub_thread_t tid, thread_identifier_info_data_t *ident_info)
745 {
746     MachProcessSP procSP;
747     if (GetProcessSP (pid, procSP))
748         return procSP->GetThreadList().GetIdentifierInfo(tid, ident_info);
749     return false;
750 }
751 
752 nub_state_t
753 DNBThreadGetState (nub_process_t pid, nub_thread_t tid)
754 {
755     MachProcessSP procSP;
756     if (GetProcessSP (pid, procSP))
757     {
758         return procSP->ThreadGetState(tid);
759     }
760     return eStateInvalid;
761 }
762 
763 const char *
764 DNBStateAsString(nub_state_t state)
765 {
766     switch (state)
767     {
768     case eStateInvalid:     return "Invalid";
769     case eStateUnloaded:    return "Unloaded";
770     case eStateAttaching:   return "Attaching";
771     case eStateLaunching:   return "Launching";
772     case eStateStopped:     return "Stopped";
773     case eStateRunning:     return "Running";
774     case eStateStepping:    return "Stepping";
775     case eStateCrashed:     return "Crashed";
776     case eStateDetached:    return "Detached";
777     case eStateExited:      return "Exited";
778     case eStateSuspended:   return "Suspended";
779     }
780     return "nub_state_t ???";
781 }
782 
783 const char *
784 DNBProcessGetExecutablePath (nub_process_t pid)
785 {
786     MachProcessSP procSP;
787     if (GetProcessSP (pid, procSP))
788     {
789         return procSP->Path();
790     }
791     return NULL;
792 }
793 
794 nub_size_t
795 DNBProcessGetArgumentCount (nub_process_t pid)
796 {
797     MachProcessSP procSP;
798     if (GetProcessSP (pid, procSP))
799     {
800         return procSP->ArgumentCount();
801     }
802     return 0;
803 }
804 
805 const char *
806 DNBProcessGetArgumentAtIndex (nub_process_t pid, nub_size_t idx)
807 {
808     MachProcessSP procSP;
809     if (GetProcessSP (pid, procSP))
810     {
811         return procSP->ArgumentAtIndex (idx);
812     }
813     return NULL;
814 }
815 
816 
817 //----------------------------------------------------------------------
818 // Execution control
819 //----------------------------------------------------------------------
820 nub_bool_t
821 DNBProcessResume (nub_process_t pid, const DNBThreadResumeAction *actions, size_t num_actions)
822 {
823     DNBLogThreadedIf(LOG_PROCESS, "%s(pid = %4.4x)", __FUNCTION__, pid);
824     MachProcessSP procSP;
825     if (GetProcessSP (pid, procSP))
826     {
827         DNBThreadResumeActions thread_actions (actions, num_actions);
828 
829         // Below we add a default thread plan just in case one wasn't
830         // provided so all threads always know what they were supposed to do
831         if (thread_actions.IsEmpty())
832         {
833             // No thread plans were given, so the default it to run all threads
834             thread_actions.SetDefaultThreadActionIfNeeded (eStateRunning, 0);
835         }
836         else
837         {
838             // Some thread plans were given which means anything that wasn't
839             // specified should remain stopped.
840             thread_actions.SetDefaultThreadActionIfNeeded (eStateStopped, 0);
841         }
842         return procSP->Resume (thread_actions);
843     }
844     return false;
845 }
846 
847 nub_bool_t
848 DNBProcessHalt (nub_process_t pid)
849 {
850     DNBLogThreadedIf(LOG_PROCESS, "%s(pid = %4.4x)", __FUNCTION__, pid);
851     MachProcessSP procSP;
852     if (GetProcessSP (pid, procSP))
853         return procSP->Signal (SIGSTOP);
854     return false;
855 }
856 //
857 //nub_bool_t
858 //DNBThreadResume (nub_process_t pid, nub_thread_t tid, nub_bool_t step)
859 //{
860 //    DNBLogThreadedIf(LOG_THREAD, "%s(pid = %4.4x, tid = %4.4x, step = %u)", __FUNCTION__, pid, tid, (uint32_t)step);
861 //    MachProcessSP procSP;
862 //    if (GetProcessSP (pid, procSP))
863 //    {
864 //        return procSP->Resume(tid, step, 0);
865 //    }
866 //    return false;
867 //}
868 //
869 //nub_bool_t
870 //DNBThreadResumeWithSignal (nub_process_t pid, nub_thread_t tid, nub_bool_t step, int signal)
871 //{
872 //    DNBLogThreadedIf(LOG_THREAD, "%s(pid = %4.4x, tid = %4.4x, step = %u, signal = %i)", __FUNCTION__, pid, tid, (uint32_t)step, signal);
873 //    MachProcessSP procSP;
874 //    if (GetProcessSP (pid, procSP))
875 //    {
876 //        return procSP->Resume(tid, step, signal);
877 //    }
878 //    return false;
879 //}
880 
881 nub_event_t
882 DNBProcessWaitForEvents (nub_process_t pid, nub_event_t event_mask, bool wait_for_set, struct timespec* timeout)
883 {
884     nub_event_t result = 0;
885     MachProcessSP procSP;
886     if (GetProcessSP (pid, procSP))
887     {
888         if (wait_for_set)
889             result = procSP->Events().WaitForSetEvents(event_mask, timeout);
890         else
891             result = procSP->Events().WaitForEventsToReset(event_mask, timeout);
892     }
893     return result;
894 }
895 
896 void
897 DNBProcessResetEvents (nub_process_t pid, nub_event_t event_mask)
898 {
899     MachProcessSP procSP;
900     if (GetProcessSP (pid, procSP))
901         procSP->Events().ResetEvents(event_mask);
902 }
903 
904 // Breakpoints
905 nub_bool_t
906 DNBBreakpointSet (nub_process_t pid, nub_addr_t addr, nub_size_t size, nub_bool_t hardware)
907 {
908     MachProcessSP procSP;
909     if (GetProcessSP (pid, procSP))
910         return procSP->CreateBreakpoint(addr, size, hardware) != NULL;
911     return false;
912 }
913 
914 nub_bool_t
915 DNBBreakpointClear (nub_process_t pid, nub_addr_t addr)
916 {
917     MachProcessSP procSP;
918     if (GetProcessSP (pid, procSP))
919         return procSP->DisableBreakpoint(addr, true);
920     return false; // Failed
921 }
922 
923 
924 //----------------------------------------------------------------------
925 // Watchpoints
926 //----------------------------------------------------------------------
927 nub_bool_t
928 DNBWatchpointSet (nub_process_t pid, nub_addr_t addr, nub_size_t size, uint32_t watch_flags, nub_bool_t hardware)
929 {
930     MachProcessSP procSP;
931     if (GetProcessSP (pid, procSP))
932         return procSP->CreateWatchpoint(addr, size, watch_flags, hardware) != NULL;
933     return false;
934 }
935 
936 nub_bool_t
937 DNBWatchpointClear (nub_process_t pid, nub_addr_t addr)
938 {
939     MachProcessSP procSP;
940     if (GetProcessSP (pid, procSP))
941         return procSP->DisableWatchpoint(addr, true);
942     return false; // Failed
943 }
944 
945 //----------------------------------------------------------------------
946 // Return the number of supported hardware watchpoints.
947 //----------------------------------------------------------------------
948 uint32_t
949 DNBWatchpointGetNumSupportedHWP (nub_process_t pid)
950 {
951     MachProcessSP procSP;
952     if (GetProcessSP (pid, procSP))
953         return procSP->GetNumSupportedHardwareWatchpoints();
954     return 0;
955 }
956 
957 //----------------------------------------------------------------------
958 // Read memory in the address space of process PID. This call will take
959 // care of setting and restoring permissions and breaking up the memory
960 // read into multiple chunks as required.
961 //
962 // RETURNS: number of bytes actually read
963 //----------------------------------------------------------------------
964 nub_size_t
965 DNBProcessMemoryRead (nub_process_t pid, nub_addr_t addr, nub_size_t size, void *buf)
966 {
967     MachProcessSP procSP;
968     if (GetProcessSP (pid, procSP))
969         return procSP->ReadMemory(addr, size, buf);
970     return 0;
971 }
972 
973 //----------------------------------------------------------------------
974 // Write memory to the address space of process PID. This call will take
975 // care of setting and restoring permissions and breaking up the memory
976 // write into multiple chunks as required.
977 //
978 // RETURNS: number of bytes actually written
979 //----------------------------------------------------------------------
980 nub_size_t
981 DNBProcessMemoryWrite (nub_process_t pid, nub_addr_t addr, nub_size_t size, const void *buf)
982 {
983     MachProcessSP procSP;
984     if (GetProcessSP (pid, procSP))
985         return procSP->WriteMemory(addr, size, buf);
986     return 0;
987 }
988 
989 nub_addr_t
990 DNBProcessMemoryAllocate (nub_process_t pid, nub_size_t size, uint32_t permissions)
991 {
992     MachProcessSP procSP;
993     if (GetProcessSP (pid, procSP))
994         return procSP->Task().AllocateMemory (size, permissions);
995     return 0;
996 }
997 
998 nub_bool_t
999 DNBProcessMemoryDeallocate (nub_process_t pid, nub_addr_t addr)
1000 {
1001     MachProcessSP procSP;
1002     if (GetProcessSP (pid, procSP))
1003         return procSP->Task().DeallocateMemory (addr);
1004     return 0;
1005 }
1006 
1007 //----------------------------------------------------------------------
1008 // Find attributes of the memory region that contains ADDR for process PID,
1009 // if possible, and return a string describing those attributes.
1010 //
1011 // Returns 1 if we could find attributes for this region and OUTBUF can
1012 // be sent to the remote debugger.
1013 //
1014 // Returns 0 if we couldn't find the attributes for a region of memory at
1015 // that address and OUTBUF should not be sent.
1016 //
1017 // Returns -1 if this platform cannot look up information about memory regions
1018 // or if we do not yet have a valid launched process.
1019 //
1020 //----------------------------------------------------------------------
1021 int
1022 DNBProcessMemoryRegionInfo (nub_process_t pid, nub_addr_t addr, DNBRegionInfo *region_info)
1023 {
1024     MachProcessSP procSP;
1025     if (GetProcessSP (pid, procSP))
1026         return procSP->Task().GetMemoryRegionInfo (addr, region_info);
1027 
1028     return -1;
1029 }
1030 
1031 std::string
1032 DNBProcessGetProfileData (nub_process_t pid, DNBProfileDataScanType scanType)
1033 {
1034     MachProcessSP procSP;
1035     if (GetProcessSP (pid, procSP))
1036         return procSP->Task().GetProfileData(scanType);
1037 
1038     return std::string("");
1039 }
1040 
1041 nub_bool_t
1042 DNBProcessSetEnableAsyncProfiling (nub_process_t pid, nub_bool_t enable, uint64_t interval_usec, DNBProfileDataScanType scan_type)
1043 {
1044     MachProcessSP procSP;
1045     if (GetProcessSP (pid, procSP))
1046     {
1047         procSP->SetEnableAsyncProfiling(enable, interval_usec, scan_type);
1048         return true;
1049     }
1050 
1051     return false;
1052 }
1053 
1054 //----------------------------------------------------------------------
1055 // Formatted output that uses memory and registers from process and
1056 // thread in place of arguments.
1057 //----------------------------------------------------------------------
1058 nub_size_t
1059 DNBPrintf (nub_process_t pid, nub_thread_t tid, nub_addr_t base_addr, FILE *file, const char *format)
1060 {
1061     if (file == NULL)
1062         return 0;
1063     enum printf_flags
1064     {
1065         alternate_form          = (1 << 0),
1066         zero_padding            = (1 << 1),
1067         negative_field_width    = (1 << 2),
1068         blank_space             = (1 << 3),
1069         show_sign               = (1 << 4),
1070         show_thousands_separator= (1 << 5),
1071     };
1072 
1073     enum printf_length_modifiers
1074     {
1075         length_mod_h            = (1 << 0),
1076         length_mod_hh           = (1 << 1),
1077         length_mod_l            = (1 << 2),
1078         length_mod_ll           = (1 << 3),
1079         length_mod_L            = (1 << 4),
1080         length_mod_j            = (1 << 5),
1081         length_mod_t            = (1 << 6),
1082         length_mod_z            = (1 << 7),
1083         length_mod_q            = (1 << 8),
1084     };
1085 
1086     nub_addr_t addr = base_addr;
1087     char *end_format = (char*)format + strlen(format);
1088     char *end = NULL;    // For strtoXXXX calls;
1089     std::basic_string<uint8_t> buf;
1090     nub_size_t total_bytes_read = 0;
1091     DNBDataRef data;
1092     const char *f;
1093     for (f = format; *f != '\0' && f < end_format; f++)
1094     {
1095         char ch = *f;
1096         switch (ch)
1097         {
1098         case '%':
1099             {
1100                 f++;    // Skip the '%' character
1101 //                int min_field_width = 0;
1102 //                int precision = 0;
1103                 //uint32_t flags = 0;
1104                 uint32_t length_modifiers = 0;
1105                 uint32_t byte_size = 0;
1106                 uint32_t actual_byte_size = 0;
1107                 bool is_string = false;
1108                 bool is_register = false;
1109                 DNBRegisterValue register_value;
1110                 int64_t    register_offset = 0;
1111                 nub_addr_t register_addr = INVALID_NUB_ADDRESS;
1112 
1113                 // Create the format string to use for this conversion specification
1114                 // so we can remove and mprintf specific flags and formatters.
1115                 std::string fprintf_format("%");
1116 
1117                 // Decode any flags
1118                 switch (*f)
1119                 {
1120                 case '#': fprintf_format += *f++; break; //flags |= alternate_form;          break;
1121                 case '0': fprintf_format += *f++; break; //flags |= zero_padding;            break;
1122                 case '-': fprintf_format += *f++; break; //flags |= negative_field_width;    break;
1123                 case ' ': fprintf_format += *f++; break; //flags |= blank_space;             break;
1124                 case '+': fprintf_format += *f++; break; //flags |= show_sign;               break;
1125                 case ',': fprintf_format += *f++; break; //flags |= show_thousands_separator;break;
1126                 case '{':
1127                 case '[':
1128                     {
1129                         // We have a register name specification that can take two forms:
1130                         // ${regname} or ${regname+offset}
1131                         //        The action is to read the register value and add the signed offset
1132                         //        (if any) and use that as the value to format.
1133                         // $[regname] or $[regname+offset]
1134                         //        The action is to read the register value and add the signed offset
1135                         //        (if any) and use the result as an address to dereference. The size
1136                         //        of what is dereferenced is specified by the actual byte size that
1137                         //        follows the minimum field width and precision (see comments below).
1138                         switch (*f)
1139                         {
1140                         case '{':
1141                         case '[':
1142                             {
1143                                 char open_scope_ch = *f;
1144                                 f++;
1145                                 const char *reg_name = f;
1146                                 size_t reg_name_length = strcspn(f, "+-}]");
1147                                 if (reg_name_length > 0)
1148                                 {
1149                                     std::string register_name(reg_name, reg_name_length);
1150                                     f += reg_name_length;
1151                                     register_offset = strtoll(f, &end, 0);
1152                                     if (f < end)
1153                                         f = end;
1154                                     if ((open_scope_ch == '{' && *f != '}') || (open_scope_ch == '[' && *f != ']'))
1155                                     {
1156                                         fprintf(file, "error: Invalid register format string. Valid formats are %%{regname} or %%{regname+offset}, %%[regname] or %%[regname+offset]\n");
1157                                         return total_bytes_read;
1158                                     }
1159                                     else
1160                                     {
1161                                         f++;
1162                                         if (DNBThreadGetRegisterValueByName(pid, tid, REGISTER_SET_ALL, register_name.c_str(), &register_value))
1163                                         {
1164                                             // Set the address to dereference using the register value plus the offset
1165                                             switch (register_value.info.size)
1166                                             {
1167                                             default:
1168                                             case 0:
1169                                                 fprintf (file, "error: unsupported register size of %u.\n", register_value.info.size);
1170                                                 return total_bytes_read;
1171 
1172                                             case 1:        register_addr = register_value.value.uint8  + register_offset; break;
1173                                             case 2:        register_addr = register_value.value.uint16 + register_offset; break;
1174                                             case 4:        register_addr = register_value.value.uint32 + register_offset; break;
1175                                             case 8:        register_addr = register_value.value.uint64 + register_offset; break;
1176                                             case 16:
1177                                                 if (open_scope_ch == '[')
1178                                                 {
1179                                                     fprintf (file, "error: register size (%u) too large for address.\n", register_value.info.size);
1180                                                     return total_bytes_read;
1181                                                 }
1182                                                 break;
1183                                             }
1184 
1185                                             if (open_scope_ch == '{')
1186                                             {
1187                                                 byte_size = register_value.info.size;
1188                                                 is_register = true;    // value is in a register
1189 
1190                                             }
1191                                             else
1192                                             {
1193                                                 addr = register_addr;    // Use register value and offset as the address
1194                                             }
1195                                         }
1196                                         else
1197                                         {
1198                                             fprintf(file, "error: unable to read register '%s' for process %#.4x and thread %#.8" PRIx64 "\n", register_name.c_str(), pid, tid);
1199                                             return total_bytes_read;
1200                                         }
1201                                     }
1202                                 }
1203                             }
1204                             break;
1205 
1206                         default:
1207                             fprintf(file, "error: %%$ must be followed by (regname + n) or [regname + n]\n");
1208                             return total_bytes_read;
1209                         }
1210                     }
1211                     break;
1212                 }
1213 
1214                 // Check for a minimum field width
1215                 if (isdigit(*f))
1216                 {
1217                     //min_field_width = strtoul(f, &end, 10);
1218                     strtoul(f, &end, 10);
1219                     if (end > f)
1220                     {
1221                         fprintf_format.append(f, end - f);
1222                         f = end;
1223                     }
1224                 }
1225 
1226 
1227                 // Check for a precision
1228                 if (*f == '.')
1229                 {
1230                     f++;
1231                     if (isdigit(*f))
1232                     {
1233                         fprintf_format += '.';
1234                         //precision = strtoul(f, &end, 10);
1235                         strtoul(f, &end, 10);
1236                         if (end > f)
1237                         {
1238                             fprintf_format.append(f, end - f);
1239                             f = end;
1240                         }
1241                     }
1242                 }
1243 
1244 
1245                 // mprintf specific: read the optional actual byte size (abs)
1246                 // after the standard minimum field width (mfw) and precision (prec).
1247                 // Standard printf calls you can have "mfw.prec" or ".prec", but
1248                 // mprintf can have "mfw.prec.abs", ".prec.abs" or "..abs". This is nice
1249                 // for strings that may be in a fixed size buffer, but may not use all bytes
1250                 // in that buffer for printable characters.
1251                 if (*f == '.')
1252                 {
1253                     f++;
1254                     actual_byte_size = strtoul(f, &end, 10);
1255                     if (end > f)
1256                     {
1257                         byte_size = actual_byte_size;
1258                         f = end;
1259                     }
1260                 }
1261 
1262                 // Decode the length modifiers
1263                 switch (*f)
1264                 {
1265                 case 'h':    // h and hh length modifiers
1266                     fprintf_format += *f++;
1267                     length_modifiers |= length_mod_h;
1268                     if (*f == 'h')
1269                     {
1270                         fprintf_format += *f++;
1271                         length_modifiers |= length_mod_hh;
1272                     }
1273                     break;
1274 
1275                 case 'l': // l and ll length modifiers
1276                     fprintf_format += *f++;
1277                     length_modifiers |= length_mod_l;
1278                     if (*f == 'h')
1279                     {
1280                         fprintf_format += *f++;
1281                         length_modifiers |= length_mod_ll;
1282                     }
1283                     break;
1284 
1285                 case 'L':    fprintf_format += *f++;    length_modifiers |= length_mod_L;    break;
1286                 case 'j':    fprintf_format += *f++;    length_modifiers |= length_mod_j;    break;
1287                 case 't':    fprintf_format += *f++;    length_modifiers |= length_mod_t;    break;
1288                 case 'z':    fprintf_format += *f++;    length_modifiers |= length_mod_z;    break;
1289                 case 'q':    fprintf_format += *f++;    length_modifiers |= length_mod_q;    break;
1290                 }
1291 
1292                 // Decode the conversion specifier
1293                 switch (*f)
1294                 {
1295                 case '_':
1296                     // mprintf specific format items
1297                     {
1298                         ++f;    // Skip the '_' character
1299                         switch (*f)
1300                         {
1301                         case 'a':    // Print the current address
1302                             ++f;
1303                             fprintf_format += "ll";
1304                             fprintf_format += *f;    // actual format to show address with folows the 'a' ("%_ax")
1305                             fprintf (file, fprintf_format.c_str(), addr);
1306                             break;
1307                         case 'o':    // offset from base address
1308                             ++f;
1309                             fprintf_format += "ll";
1310                             fprintf_format += *f;    // actual format to show address with folows the 'a' ("%_ox")
1311                             fprintf(file, fprintf_format.c_str(), addr - base_addr);
1312                             break;
1313                         default:
1314                             fprintf (file, "error: unsupported mprintf specific format character '%c'.\n", *f);
1315                             break;
1316                         }
1317                         continue;
1318                     }
1319                     break;
1320 
1321                 case 'D':
1322                 case 'O':
1323                 case 'U':
1324                     fprintf_format += *f;
1325                     if (byte_size == 0)
1326                         byte_size = sizeof(long int);
1327                     break;
1328 
1329                 case 'd':
1330                 case 'i':
1331                 case 'o':
1332                 case 'u':
1333                 case 'x':
1334                 case 'X':
1335                     fprintf_format += *f;
1336                     if (byte_size == 0)
1337                     {
1338                         if (length_modifiers & length_mod_hh)
1339                             byte_size = sizeof(char);
1340                         else if (length_modifiers & length_mod_h)
1341                             byte_size = sizeof(short);
1342                         else if (length_modifiers & length_mod_ll)
1343                             byte_size = sizeof(long long);
1344                         else if (length_modifiers & length_mod_l)
1345                             byte_size = sizeof(long);
1346                         else
1347                             byte_size = sizeof(int);
1348                     }
1349                     break;
1350 
1351                 case 'a':
1352                 case 'A':
1353                 case 'f':
1354                 case 'F':
1355                 case 'e':
1356                 case 'E':
1357                 case 'g':
1358                 case 'G':
1359                     fprintf_format += *f;
1360                     if (byte_size == 0)
1361                     {
1362                         if (length_modifiers & length_mod_L)
1363                             byte_size = sizeof(long double);
1364                         else
1365                             byte_size = sizeof(double);
1366                     }
1367                     break;
1368 
1369                 case 'c':
1370                     if ((length_modifiers & length_mod_l) == 0)
1371                     {
1372                         fprintf_format += *f;
1373                         if (byte_size == 0)
1374                             byte_size = sizeof(char);
1375                         break;
1376                     }
1377                     // Fall through to 'C' modifier below...
1378 
1379                 case 'C':
1380                     fprintf_format += *f;
1381                     if (byte_size == 0)
1382                         byte_size = sizeof(wchar_t);
1383                     break;
1384 
1385                 case 's':
1386                     fprintf_format += *f;
1387                     if (is_register || byte_size == 0)
1388                         is_string = 1;
1389                     break;
1390 
1391                 case 'p':
1392                     fprintf_format += *f;
1393                     if (byte_size == 0)
1394                         byte_size = sizeof(void*);
1395                     break;
1396                 }
1397 
1398                 if (is_string)
1399                 {
1400                     std::string mem_string;
1401                     const size_t string_buf_len = 4;
1402                     char string_buf[string_buf_len+1];
1403                     char *string_buf_end = string_buf + string_buf_len;
1404                     string_buf[string_buf_len] = '\0';
1405                     nub_size_t bytes_read;
1406                     nub_addr_t str_addr = is_register ? register_addr : addr;
1407                     while ((bytes_read = DNBProcessMemoryRead(pid, str_addr, string_buf_len, &string_buf[0])) > 0)
1408                     {
1409                         // Did we get a NULL termination character yet?
1410                         if (strchr(string_buf, '\0') == string_buf_end)
1411                         {
1412                             // no NULL terminator yet, append as a std::string
1413                             mem_string.append(string_buf, string_buf_len);
1414                             str_addr += string_buf_len;
1415                         }
1416                         else
1417                         {
1418                             // yep
1419                             break;
1420                         }
1421                     }
1422                     // Append as a C-string so we don't get the extra NULL
1423                     // characters in the temp buffer (since it was resized)
1424                     mem_string += string_buf;
1425                     size_t mem_string_len = mem_string.size() + 1;
1426                     fprintf(file, fprintf_format.c_str(), mem_string.c_str());
1427                     if (mem_string_len > 0)
1428                     {
1429                         if (!is_register)
1430                         {
1431                             addr += mem_string_len;
1432                             total_bytes_read += mem_string_len;
1433                         }
1434                     }
1435                     else
1436                         return total_bytes_read;
1437                 }
1438                 else
1439                 if (byte_size > 0)
1440                 {
1441                     buf.resize(byte_size);
1442                     nub_size_t bytes_read = 0;
1443                     if (is_register)
1444                         bytes_read = register_value.info.size;
1445                     else
1446                         bytes_read = DNBProcessMemoryRead(pid, addr, buf.size(), &buf[0]);
1447                     if (bytes_read > 0)
1448                     {
1449                         if (!is_register)
1450                             total_bytes_read += bytes_read;
1451 
1452                         if (bytes_read == byte_size)
1453                         {
1454                             switch (*f)
1455                             {
1456                             case 'd':
1457                             case 'i':
1458                             case 'o':
1459                             case 'u':
1460                             case 'X':
1461                             case 'x':
1462                             case 'a':
1463                             case 'A':
1464                             case 'f':
1465                             case 'F':
1466                             case 'e':
1467                             case 'E':
1468                             case 'g':
1469                             case 'G':
1470                             case 'p':
1471                             case 'c':
1472                             case 'C':
1473                                 {
1474                                     if (is_register)
1475                                         data.SetData(&register_value.value.v_uint8[0], register_value.info.size);
1476                                     else
1477                                         data.SetData(&buf[0], bytes_read);
1478                                     DNBDataRef::offset_t data_offset = 0;
1479                                     if (byte_size <= 4)
1480                                     {
1481                                         uint32_t u32 = data.GetMax32(&data_offset, byte_size);
1482                                         // Show the actual byte width when displaying hex
1483                                         fprintf(file, fprintf_format.c_str(), u32);
1484                                     }
1485                                     else if (byte_size <= 8)
1486                                     {
1487                                         uint64_t u64 = data.GetMax64(&data_offset, byte_size);
1488                                         // Show the actual byte width when displaying hex
1489                                         fprintf(file, fprintf_format.c_str(), u64);
1490                                     }
1491                                     else
1492                                     {
1493                                         fprintf(file, "error: integer size not supported, must be 8 bytes or less (%u bytes).\n", byte_size);
1494                                     }
1495                                     if (!is_register)
1496                                         addr += byte_size;
1497                                 }
1498                                 break;
1499 
1500                             case 's':
1501                                 fprintf(file, fprintf_format.c_str(), buf.c_str());
1502                                 addr += byte_size;
1503                                 break;
1504 
1505                             default:
1506                                 fprintf(file, "error: unsupported conversion specifier '%c'.\n", *f);
1507                                 break;
1508                             }
1509                         }
1510                     }
1511                 }
1512                 else
1513                     return total_bytes_read;
1514             }
1515             break;
1516 
1517         case '\\':
1518             {
1519                 f++;
1520                 switch (*f)
1521                 {
1522                 case 'e': ch = '\e'; break;
1523                 case 'a': ch = '\a'; break;
1524                 case 'b': ch = '\b'; break;
1525                 case 'f': ch = '\f'; break;
1526                 case 'n': ch = '\n'; break;
1527                 case 'r': ch = '\r'; break;
1528                 case 't': ch = '\t'; break;
1529                 case 'v': ch = '\v'; break;
1530                 case '\'': ch = '\''; break;
1531                 case '\\': ch = '\\'; break;
1532                 case '0':
1533                 case '1':
1534                 case '2':
1535                 case '3':
1536                 case '4':
1537                 case '5':
1538                 case '6':
1539                 case '7':
1540                     ch = strtoul(f, &end, 8);
1541                     f = end;
1542                     break;
1543                 default:
1544                     ch = *f;
1545                     break;
1546                 }
1547                 fputc(ch, file);
1548             }
1549             break;
1550 
1551         default:
1552             fputc(ch, file);
1553             break;
1554         }
1555     }
1556     return total_bytes_read;
1557 }
1558 
1559 
1560 //----------------------------------------------------------------------
1561 // Get the number of threads for the specified process.
1562 //----------------------------------------------------------------------
1563 nub_size_t
1564 DNBProcessGetNumThreads (nub_process_t pid)
1565 {
1566     MachProcessSP procSP;
1567     if (GetProcessSP (pid, procSP))
1568         return procSP->GetNumThreads();
1569     return 0;
1570 }
1571 
1572 //----------------------------------------------------------------------
1573 // Get the thread ID of the current thread.
1574 //----------------------------------------------------------------------
1575 nub_thread_t
1576 DNBProcessGetCurrentThread (nub_process_t pid)
1577 {
1578     MachProcessSP procSP;
1579     if (GetProcessSP (pid, procSP))
1580         return procSP->GetCurrentThread();
1581     return 0;
1582 }
1583 
1584 //----------------------------------------------------------------------
1585 // Get the mach port number of the current thread.
1586 //----------------------------------------------------------------------
1587 nub_thread_t
1588 DNBProcessGetCurrentThreadMachPort (nub_process_t pid)
1589 {
1590     MachProcessSP procSP;
1591     if (GetProcessSP (pid, procSP))
1592         return procSP->GetCurrentThreadMachPort();
1593     return 0;
1594 }
1595 
1596 //----------------------------------------------------------------------
1597 // Change the current thread.
1598 //----------------------------------------------------------------------
1599 nub_thread_t
1600 DNBProcessSetCurrentThread (nub_process_t pid, nub_thread_t tid)
1601 {
1602     MachProcessSP procSP;
1603     if (GetProcessSP (pid, procSP))
1604         return procSP->SetCurrentThread (tid);
1605     return INVALID_NUB_THREAD;
1606 }
1607 
1608 
1609 //----------------------------------------------------------------------
1610 // Dump a string describing a thread's stop reason to the specified file
1611 // handle
1612 //----------------------------------------------------------------------
1613 nub_bool_t
1614 DNBThreadGetStopReason (nub_process_t pid, nub_thread_t tid, struct DNBThreadStopInfo *stop_info)
1615 {
1616     MachProcessSP procSP;
1617     if (GetProcessSP (pid, procSP))
1618         return procSP->GetThreadStoppedReason (tid, stop_info);
1619     return false;
1620 }
1621 
1622 //----------------------------------------------------------------------
1623 // Return string description for the specified thread.
1624 //
1625 // RETURNS: NULL if the thread isn't valid, else a NULL terminated C
1626 // string from a static buffer that must be copied prior to subsequent
1627 // calls.
1628 //----------------------------------------------------------------------
1629 const char *
1630 DNBThreadGetInfo (nub_process_t pid, nub_thread_t tid)
1631 {
1632     MachProcessSP procSP;
1633     if (GetProcessSP (pid, procSP))
1634         return procSP->GetThreadInfo (tid);
1635     return NULL;
1636 }
1637 
1638 //----------------------------------------------------------------------
1639 // Get the thread ID given a thread index.
1640 //----------------------------------------------------------------------
1641 nub_thread_t
1642 DNBProcessGetThreadAtIndex (nub_process_t pid, size_t thread_idx)
1643 {
1644     MachProcessSP procSP;
1645     if (GetProcessSP (pid, procSP))
1646         return procSP->GetThreadAtIndex (thread_idx);
1647     return INVALID_NUB_THREAD;
1648 }
1649 
1650 //----------------------------------------------------------------------
1651 // Do whatever is needed to sync the thread's register state with it's kernel values.
1652 //----------------------------------------------------------------------
1653 nub_bool_t
1654 DNBProcessSyncThreadState (nub_process_t pid, nub_thread_t tid)
1655 {
1656     MachProcessSP procSP;
1657     if (GetProcessSP (pid, procSP))
1658         return procSP->SyncThreadState (tid);
1659     return false;
1660 
1661 }
1662 
1663 nub_addr_t
1664 DNBProcessGetSharedLibraryInfoAddress (nub_process_t pid)
1665 {
1666     MachProcessSP procSP;
1667     DNBError err;
1668     if (GetProcessSP (pid, procSP))
1669         return procSP->Task().GetDYLDAllImageInfosAddress (err);
1670     return INVALID_NUB_ADDRESS;
1671 }
1672 
1673 
1674 nub_bool_t
1675 DNBProcessSharedLibrariesUpdated(nub_process_t pid)
1676 {
1677     MachProcessSP procSP;
1678     if (GetProcessSP (pid, procSP))
1679     {
1680         procSP->SharedLibrariesUpdated ();
1681         return true;
1682     }
1683     return false;
1684 }
1685 
1686 //----------------------------------------------------------------------
1687 // Get the current shared library information for a process. Only return
1688 // the shared libraries that have changed since the last shared library
1689 // state changed event if only_changed is non-zero.
1690 //----------------------------------------------------------------------
1691 nub_size_t
1692 DNBProcessGetSharedLibraryInfo (nub_process_t pid, nub_bool_t only_changed, struct DNBExecutableImageInfo **image_infos)
1693 {
1694     MachProcessSP procSP;
1695     if (GetProcessSP (pid, procSP))
1696         return procSP->CopyImageInfos (image_infos, only_changed);
1697 
1698     // If we have no process, then return NULL for the shared library info
1699     // and zero for shared library count
1700     *image_infos = NULL;
1701     return 0;
1702 }
1703 
1704 //----------------------------------------------------------------------
1705 // Get the register set information for a specific thread.
1706 //----------------------------------------------------------------------
1707 const DNBRegisterSetInfo *
1708 DNBGetRegisterSetInfo (nub_size_t *num_reg_sets)
1709 {
1710     return DNBArchProtocol::GetRegisterSetInfo (num_reg_sets);
1711 }
1712 
1713 
1714 //----------------------------------------------------------------------
1715 // Read a register value by register set and register index.
1716 //----------------------------------------------------------------------
1717 nub_bool_t
1718 DNBThreadGetRegisterValueByID (nub_process_t pid, nub_thread_t tid, uint32_t set, uint32_t reg, DNBRegisterValue *value)
1719 {
1720     MachProcessSP procSP;
1721     ::bzero (value, sizeof(DNBRegisterValue));
1722     if (GetProcessSP (pid, procSP))
1723     {
1724         if (tid != INVALID_NUB_THREAD)
1725             return procSP->GetRegisterValue (tid, set, reg, value);
1726     }
1727     return false;
1728 }
1729 
1730 nub_bool_t
1731 DNBThreadSetRegisterValueByID (nub_process_t pid, nub_thread_t tid, uint32_t set, uint32_t reg, const DNBRegisterValue *value)
1732 {
1733     if (tid != INVALID_NUB_THREAD)
1734     {
1735         MachProcessSP procSP;
1736         if (GetProcessSP (pid, procSP))
1737             return procSP->SetRegisterValue (tid, set, reg, value);
1738     }
1739     return false;
1740 }
1741 
1742 nub_size_t
1743 DNBThreadGetRegisterContext (nub_process_t pid, nub_thread_t tid, void *buf, size_t buf_len)
1744 {
1745     MachProcessSP procSP;
1746     if (GetProcessSP (pid, procSP))
1747     {
1748         if (tid != INVALID_NUB_THREAD)
1749             return procSP->GetThreadList().GetRegisterContext (tid, buf, buf_len);
1750     }
1751     ::bzero (buf, buf_len);
1752     return 0;
1753 
1754 }
1755 
1756 nub_size_t
1757 DNBThreadSetRegisterContext (nub_process_t pid, nub_thread_t tid, const void *buf, size_t buf_len)
1758 {
1759     MachProcessSP procSP;
1760     if (GetProcessSP (pid, procSP))
1761     {
1762         if (tid != INVALID_NUB_THREAD)
1763             return procSP->GetThreadList().SetRegisterContext (tid, buf, buf_len);
1764     }
1765     return 0;
1766 }
1767 
1768 uint32_t
1769 DNBThreadSaveRegisterState (nub_process_t pid, nub_thread_t tid)
1770 {
1771     if (tid != INVALID_NUB_THREAD)
1772     {
1773         MachProcessSP procSP;
1774         if (GetProcessSP (pid, procSP))
1775             return procSP->GetThreadList().SaveRegisterState (tid);
1776     }
1777     return 0;
1778 }
1779 nub_bool_t
1780 DNBThreadRestoreRegisterState (nub_process_t pid, nub_thread_t tid, uint32_t save_id)
1781 {
1782     if (tid != INVALID_NUB_THREAD)
1783     {
1784         MachProcessSP procSP;
1785         if (GetProcessSP (pid, procSP))
1786             return procSP->GetThreadList().RestoreRegisterState (tid, save_id);
1787     }
1788     return false;
1789 }
1790 
1791 
1792 
1793 //----------------------------------------------------------------------
1794 // Read a register value by name.
1795 //----------------------------------------------------------------------
1796 nub_bool_t
1797 DNBThreadGetRegisterValueByName (nub_process_t pid, nub_thread_t tid, uint32_t reg_set, const char *reg_name, DNBRegisterValue *value)
1798 {
1799     MachProcessSP procSP;
1800     ::bzero (value, sizeof(DNBRegisterValue));
1801     if (GetProcessSP (pid, procSP))
1802     {
1803         const struct DNBRegisterSetInfo *set_info;
1804         nub_size_t num_reg_sets = 0;
1805         set_info = DNBGetRegisterSetInfo (&num_reg_sets);
1806         if (set_info)
1807         {
1808             uint32_t set = reg_set;
1809             uint32_t reg;
1810             if (set == REGISTER_SET_ALL)
1811             {
1812                 for (set = 1; set < num_reg_sets; ++set)
1813                 {
1814                     for (reg = 0; reg < set_info[set].num_registers; ++reg)
1815                     {
1816                         if (strcasecmp(reg_name, set_info[set].registers[reg].name) == 0)
1817                             return procSP->GetRegisterValue (tid, set, reg, value);
1818                     }
1819                 }
1820             }
1821             else
1822             {
1823                 for (reg = 0; reg < set_info[set].num_registers; ++reg)
1824                 {
1825                     if (strcasecmp(reg_name, set_info[set].registers[reg].name) == 0)
1826                         return procSP->GetRegisterValue (tid, set, reg, value);
1827                 }
1828             }
1829         }
1830     }
1831     return false;
1832 }
1833 
1834 
1835 //----------------------------------------------------------------------
1836 // Read a register set and register number from the register name.
1837 //----------------------------------------------------------------------
1838 nub_bool_t
1839 DNBGetRegisterInfoByName (const char *reg_name, DNBRegisterInfo* info)
1840 {
1841     const struct DNBRegisterSetInfo *set_info;
1842     nub_size_t num_reg_sets = 0;
1843     set_info = DNBGetRegisterSetInfo (&num_reg_sets);
1844     if (set_info)
1845     {
1846         uint32_t set, reg;
1847         for (set = 1; set < num_reg_sets; ++set)
1848         {
1849             for (reg = 0; reg < set_info[set].num_registers; ++reg)
1850             {
1851                 if (strcasecmp(reg_name, set_info[set].registers[reg].name) == 0)
1852                 {
1853                     *info = set_info[set].registers[reg];
1854                     return true;
1855                 }
1856             }
1857         }
1858 
1859         for (set = 1; set < num_reg_sets; ++set)
1860         {
1861             uint32_t reg;
1862             for (reg = 0; reg < set_info[set].num_registers; ++reg)
1863             {
1864                 if (set_info[set].registers[reg].alt == NULL)
1865                     continue;
1866 
1867                 if (strcasecmp(reg_name, set_info[set].registers[reg].alt) == 0)
1868                 {
1869                     *info = set_info[set].registers[reg];
1870                     return true;
1871                 }
1872             }
1873         }
1874     }
1875 
1876     ::bzero (info, sizeof(DNBRegisterInfo));
1877     return false;
1878 }
1879 
1880 
1881 //----------------------------------------------------------------------
1882 // Set the name to address callback function that this nub can use
1883 // for any name to address lookups that are needed.
1884 //----------------------------------------------------------------------
1885 nub_bool_t
1886 DNBProcessSetNameToAddressCallback (nub_process_t pid, DNBCallbackNameToAddress callback, void *baton)
1887 {
1888     MachProcessSP procSP;
1889     if (GetProcessSP (pid, procSP))
1890     {
1891         procSP->SetNameToAddressCallback (callback, baton);
1892         return true;
1893     }
1894     return false;
1895 }
1896 
1897 
1898 //----------------------------------------------------------------------
1899 // Set the name to address callback function that this nub can use
1900 // for any name to address lookups that are needed.
1901 //----------------------------------------------------------------------
1902 nub_bool_t
1903 DNBProcessSetSharedLibraryInfoCallback (nub_process_t pid, DNBCallbackCopyExecutableImageInfos callback, void  *baton)
1904 {
1905     MachProcessSP procSP;
1906     if (GetProcessSP (pid, procSP))
1907     {
1908         procSP->SetSharedLibraryInfoCallback (callback, baton);
1909         return true;
1910     }
1911     return false;
1912 }
1913 
1914 nub_addr_t
1915 DNBProcessLookupAddress (nub_process_t pid, const char *name, const char *shlib)
1916 {
1917     MachProcessSP procSP;
1918     if (GetProcessSP (pid, procSP))
1919     {
1920         return procSP->LookupSymbol (name, shlib);
1921     }
1922     return INVALID_NUB_ADDRESS;
1923 }
1924 
1925 
1926 nub_size_t
1927 DNBProcessGetAvailableSTDOUT (nub_process_t pid, char *buf, nub_size_t buf_size)
1928 {
1929     MachProcessSP procSP;
1930     if (GetProcessSP (pid, procSP))
1931         return procSP->GetAvailableSTDOUT (buf, buf_size);
1932     return 0;
1933 }
1934 
1935 nub_size_t
1936 DNBProcessGetAvailableSTDERR (nub_process_t pid, char *buf, nub_size_t buf_size)
1937 {
1938     MachProcessSP procSP;
1939     if (GetProcessSP (pid, procSP))
1940         return procSP->GetAvailableSTDERR (buf, buf_size);
1941     return 0;
1942 }
1943 
1944 nub_size_t
1945 DNBProcessGetAvailableProfileData (nub_process_t pid, char *buf, nub_size_t buf_size)
1946 {
1947     MachProcessSP procSP;
1948     if (GetProcessSP (pid, procSP))
1949         return procSP->GetAsyncProfileData (buf, buf_size);
1950     return 0;
1951 }
1952 
1953 nub_size_t
1954 DNBProcessGetStopCount (nub_process_t pid)
1955 {
1956     MachProcessSP procSP;
1957     if (GetProcessSP (pid, procSP))
1958         return procSP->StopCount();
1959     return 0;
1960 }
1961 
1962 uint32_t
1963 DNBProcessGetCPUType (nub_process_t pid)
1964 {
1965     MachProcessSP procSP;
1966     if (GetProcessSP (pid, procSP))
1967         return procSP->GetCPUType ();
1968     return 0;
1969 
1970 }
1971 
1972 nub_bool_t
1973 DNBResolveExecutablePath (const char *path, char *resolved_path, size_t resolved_path_size)
1974 {
1975     if (path == NULL || path[0] == '\0')
1976         return false;
1977 
1978     char max_path[PATH_MAX];
1979     std::string result;
1980     CFString::GlobPath(path, result);
1981 
1982     if (result.empty())
1983         result = path;
1984 
1985     struct stat path_stat;
1986     if (::stat(path, &path_stat) == 0)
1987     {
1988         if ((path_stat.st_mode & S_IFMT) == S_IFDIR)
1989         {
1990             CFBundle bundle (path);
1991             CFReleaser<CFURLRef> url(bundle.CopyExecutableURL ());
1992             if (url.get())
1993             {
1994                 if (::CFURLGetFileSystemRepresentation (url.get(), true, (UInt8*)resolved_path, resolved_path_size))
1995                     return true;
1996             }
1997         }
1998     }
1999 
2000     if (realpath(path, max_path))
2001     {
2002         // Found the path relatively...
2003         ::strncpy(resolved_path, max_path, resolved_path_size);
2004         return strlen(resolved_path) + 1 < resolved_path_size;
2005     }
2006     else
2007     {
2008         // Not a relative path, check the PATH environment variable if the
2009         const char *PATH = getenv("PATH");
2010         if (PATH)
2011         {
2012             const char *curr_path_start = PATH;
2013             const char *curr_path_end;
2014             while (curr_path_start && *curr_path_start)
2015             {
2016                 curr_path_end = strchr(curr_path_start, ':');
2017                 if (curr_path_end == NULL)
2018                 {
2019                     result.assign(curr_path_start);
2020                     curr_path_start = NULL;
2021                 }
2022                 else if (curr_path_end > curr_path_start)
2023                 {
2024                     size_t len = curr_path_end - curr_path_start;
2025                     result.assign(curr_path_start, len);
2026                     curr_path_start += len + 1;
2027                 }
2028                 else
2029                     break;
2030 
2031                 result += '/';
2032                 result += path;
2033                 struct stat s;
2034                 if (stat(result.c_str(), &s) == 0)
2035                 {
2036                     ::strncpy(resolved_path, result.c_str(), resolved_path_size);
2037                     return result.size() + 1 < resolved_path_size;
2038                 }
2039             }
2040         }
2041     }
2042     return false;
2043 }
2044 
2045 
2046 void
2047 DNBInitialize()
2048 {
2049     DNBLogThreadedIf (LOG_PROCESS, "DNBInitialize ()");
2050 #if defined (__i386__) || defined (__x86_64__)
2051     DNBArchImplI386::Initialize();
2052     DNBArchImplX86_64::Initialize();
2053 #elif defined (__arm__)
2054     DNBArchMachARM::Initialize();
2055 #endif
2056 }
2057 
2058 void
2059 DNBTerminate()
2060 {
2061 }
2062 
2063 nub_bool_t
2064 DNBSetArchitecture (const char *arch)
2065 {
2066     if (arch && arch[0])
2067     {
2068         if (strcasecmp (arch, "i386") == 0)
2069             return DNBArchProtocol::SetArchitecture (CPU_TYPE_I386);
2070         else if (strcasecmp (arch, "x86_64") == 0)
2071             return DNBArchProtocol::SetArchitecture (CPU_TYPE_X86_64);
2072         else if (strstr (arch, "arm") == arch)
2073             return DNBArchProtocol::SetArchitecture (CPU_TYPE_ARM);
2074     }
2075     return false;
2076 }
2077