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