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