1 //===-- DarwinProcessLauncher.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 // 11 // DarwinProcessLauncher.cpp 12 // lldb 13 // 14 // Created by Todd Fiala on 8/30/16. 15 // 16 // 17 18 #include "DarwinProcessLauncher.h" 19 20 // C includes 21 #include <spawn.h> 22 #include <sys/ptrace.h> 23 #include <sys/stat.h> 24 #include <sys/sysctl.h> 25 26 #ifndef _POSIX_SPAWN_DISABLE_ASLR 27 #define _POSIX_SPAWN_DISABLE_ASLR 0x0100 28 #endif 29 30 // LLDB includes 31 #include "lldb/lldb-enumerations.h" 32 33 #include "lldb/Host/PseudoTerminal.h" 34 #include "lldb/Target/ProcessLaunchInfo.h" 35 #include "lldb/Utility/Log.h" 36 #include "lldb/Utility/Status.h" 37 #include "lldb/Utility/StreamString.h" 38 #include "llvm/Support/Errno.h" 39 40 #include "CFBundle.h" 41 #include "CFString.h" 42 43 using namespace lldb; 44 using namespace lldb_private; 45 using namespace lldb_private::process_darwin; 46 using namespace lldb_private::darwin_process_launcher; 47 48 namespace { 49 static LaunchFlavor g_launch_flavor = LaunchFlavor::Default; 50 } 51 52 namespace lldb_private { 53 namespace darwin_process_launcher { 54 55 static uint32_t GetCPUTypeForLocalProcess(::pid_t pid) { 56 int mib[CTL_MAXNAME] = { 57 0, 58 }; 59 size_t len = CTL_MAXNAME; 60 if (::sysctlnametomib("sysctl.proc_cputype", mib, &len)) 61 return 0; 62 63 mib[len] = pid; 64 len++; 65 66 cpu_type_t cpu; 67 size_t cpu_len = sizeof(cpu); 68 if (::sysctl(mib, static_cast<u_int>(len), &cpu, &cpu_len, 0, 0)) 69 cpu = 0; 70 return cpu; 71 } 72 73 static bool ResolveExecutablePath(const char *path, char *resolved_path, 74 size_t resolved_path_size) { 75 if (path == NULL || path[0] == '\0') 76 return false; 77 78 char max_path[PATH_MAX]; 79 std::string result; 80 CFString::GlobPath(path, result); 81 82 if (result.empty()) 83 result = path; 84 85 struct stat path_stat; 86 if (::stat(path, &path_stat) == 0) { 87 if ((path_stat.st_mode & S_IFMT) == S_IFDIR) { 88 CFBundle bundle(path); 89 CFReleaser<CFURLRef> url(bundle.CopyExecutableURL()); 90 if (url.get()) { 91 if (::CFURLGetFileSystemRepresentation( 92 url.get(), true, (UInt8 *)resolved_path, resolved_path_size)) 93 return true; 94 } 95 } 96 } 97 98 if (realpath(path, max_path)) { 99 // Found the path relatively... 100 ::strncpy(resolved_path, max_path, resolved_path_size); 101 return strlen(resolved_path) + 1 < resolved_path_size; 102 } else { 103 // Not a relative path, check the PATH environment variable if the 104 const char *PATH = getenv("PATH"); 105 if (PATH) { 106 const char *curr_path_start = PATH; 107 const char *curr_path_end; 108 while (curr_path_start && *curr_path_start) { 109 curr_path_end = strchr(curr_path_start, ':'); 110 if (curr_path_end == NULL) { 111 result.assign(curr_path_start); 112 curr_path_start = NULL; 113 } else if (curr_path_end > curr_path_start) { 114 size_t len = curr_path_end - curr_path_start; 115 result.assign(curr_path_start, len); 116 curr_path_start += len + 1; 117 } else 118 break; 119 120 result += '/'; 121 result += path; 122 struct stat s; 123 if (stat(result.c_str(), &s) == 0) { 124 ::strncpy(resolved_path, result.c_str(), resolved_path_size); 125 return result.size() + 1 < resolved_path_size; 126 } 127 } 128 } 129 } 130 return false; 131 } 132 133 // TODO check if we have a general purpose fork and exec. We may be 134 // able to get rid of this entirely. 135 static Status ForkChildForPTraceDebugging(const char *path, char const *argv[], 136 char const *envp[], ::pid_t *pid, 137 int *pty_fd) { 138 Status error; 139 if (!path || !argv || !envp || !pid || !pty_fd) { 140 error.SetErrorString("invalid arguments"); 141 return error; 142 } 143 144 // Use a fork that ties the child process's stdin/out/err to a pseudo 145 // terminal so we can read it in our MachProcess::STDIOThread as unbuffered 146 // io. 147 PseudoTerminal pty; 148 char fork_error[256]; 149 memset(fork_error, 0, sizeof(fork_error)); 150 *pid = static_cast<::pid_t>(pty.Fork(fork_error, sizeof(fork_error))); 151 if (*pid < 0) { 152 //-------------------------------------------------------------- 153 // Status during fork. 154 //-------------------------------------------------------------- 155 *pid = static_cast<::pid_t>(LLDB_INVALID_PROCESS_ID); 156 error.SetErrorStringWithFormat("%s(): fork failed: %s", __FUNCTION__, 157 fork_error); 158 return error; 159 } else if (pid == 0) { 160 //-------------------------------------------------------------- 161 // Child process 162 //-------------------------------------------------------------- 163 164 // Debug this process. 165 ::ptrace(PT_TRACE_ME, 0, 0, 0); 166 167 // Get BSD signals as mach exceptions. 168 ::ptrace(PT_SIGEXC, 0, 0, 0); 169 170 // If our parent is setgid, lets make sure we don't inherit those extra 171 // powers due to nepotism. 172 if (::setgid(getgid()) == 0) { 173 // Let the child have its own process group. We need to execute this call 174 // in both the child and parent to avoid a race condition between the two 175 // processes. 176 177 // Set the child process group to match its pid. 178 ::setpgid(0, 0); 179 180 // Sleep a bit to before the exec call. 181 ::sleep(1); 182 183 // Turn this process into the given executable. 184 ::execv(path, (char *const *)argv); 185 } 186 // Exit with error code. Child process should have taken over in above exec 187 // call and if the exec fails it will exit the child process below. 188 ::exit(127); 189 } else { 190 //-------------------------------------------------------------- 191 // Parent process 192 //-------------------------------------------------------------- 193 // Let the child have its own process group. We need to execute this call 194 // in both the child and parent to avoid a race condition between the two 195 // processes. 196 197 // Set the child process group to match its pid 198 ::setpgid(*pid, *pid); 199 if (pty_fd) { 200 // Release our master pty file descriptor so the pty class doesn't close 201 // it and so we can continue to use it in our STDIO thread 202 *pty_fd = pty.ReleaseMasterFileDescriptor(); 203 } 204 } 205 return error; 206 } 207 208 static Status 209 CreatePosixSpawnFileAction(const FileAction &action, 210 posix_spawn_file_actions_t *file_actions) { 211 Status error; 212 213 // Log it. 214 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); 215 if (log) { 216 StreamString stream; 217 stream.PutCString("converting file action for posix_spawn(): "); 218 action.Dump(stream); 219 stream.Flush(); 220 log->PutCString(stream.GetString().c_str()); 221 } 222 223 // Validate args. 224 if (!file_actions) { 225 error.SetErrorString("mandatory file_actions arg is null"); 226 return error; 227 } 228 229 // Build the posix file action. 230 switch (action.GetAction()) { 231 case FileAction::eFileActionOpen: { 232 const int error_code = ::posix_spawn_file_actions_addopen( 233 file_actions, action.GetFD(), action.GetPath(), 234 action.GetActionArgument(), 0); 235 if (error_code != 0) { 236 error.SetError(error_code, eErrorTypePOSIX); 237 return error; 238 } 239 break; 240 } 241 242 case FileAction::eFileActionClose: { 243 const int error_code = 244 ::posix_spawn_file_actions_addclose(file_actions, action.GetFD()); 245 if (error_code != 0) { 246 error.SetError(error_code, eErrorTypePOSIX); 247 return error; 248 } 249 break; 250 } 251 252 case FileAction::eFileActionDuplicate: { 253 const int error_code = ::posix_spawn_file_actions_adddup2( 254 file_actions, action.GetFD(), action.GetActionArgument()); 255 if (error_code != 0) { 256 error.SetError(error_code, eErrorTypePOSIX); 257 return error; 258 } 259 break; 260 } 261 262 case FileAction::eFileActionNone: 263 default: 264 if (log) 265 log->Printf("%s(): unsupported file action %u", __FUNCTION__, 266 action.GetAction()); 267 break; 268 } 269 270 return error; 271 } 272 273 static Status PosixSpawnChildForPTraceDebugging(const char *path, 274 ProcessLaunchInfo &launch_info, 275 ::pid_t *pid, 276 cpu_type_t *actual_cpu_type) { 277 Status error; 278 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); 279 280 if (!pid) { 281 error.SetErrorStringWithFormat("%s(): pid arg cannot be null", 282 __FUNCTION__); 283 return error; 284 } 285 286 posix_spawnattr_t attr; 287 short flags; 288 if (log) { 289 StreamString stream; 290 stream.Printf("%s(path='%s',...)\n", __FUNCTION__, path); 291 launch_info.Dump(stream, nullptr); 292 stream.Flush(); 293 log->PutCString(stream.GetString().c_str()); 294 } 295 296 int error_code; 297 if ((error_code = ::posix_spawnattr_init(&attr)) != 0) { 298 if (log) 299 log->Printf("::posix_spawnattr_init(&attr) failed"); 300 error.SetError(error_code, eErrorTypePOSIX); 301 return error; 302 } 303 304 // Ensure we clean up the spawnattr structure however we exit this function. 305 std::unique_ptr<posix_spawnattr_t, int (*)(posix_spawnattr_t *)> spawnattr_up( 306 &attr, ::posix_spawnattr_destroy); 307 308 flags = POSIX_SPAWN_START_SUSPENDED | POSIX_SPAWN_SETSIGDEF | 309 POSIX_SPAWN_SETSIGMASK; 310 if (launch_info.GetFlags().Test(eLaunchFlagDisableASLR)) 311 flags |= _POSIX_SPAWN_DISABLE_ASLR; 312 313 sigset_t no_signals; 314 sigset_t all_signals; 315 sigemptyset(&no_signals); 316 sigfillset(&all_signals); 317 ::posix_spawnattr_setsigmask(&attr, &no_signals); 318 ::posix_spawnattr_setsigdefault(&attr, &all_signals); 319 320 if ((error_code = ::posix_spawnattr_setflags(&attr, flags)) != 0) { 321 LLDB_LOG(log, 322 "::posix_spawnattr_setflags(&attr, " 323 "POSIX_SPAWN_START_SUSPENDED{0}) failed: {1}", 324 flags & _POSIX_SPAWN_DISABLE_ASLR ? " | _POSIX_SPAWN_DISABLE_ASLR" 325 : "", 326 llvm::sys::StrError(error_code)); 327 error.SetError(error_code, eErrorTypePOSIX); 328 return error; 329 } 330 331 #if !defined(__arm__) 332 333 // We don't need to do this for ARM, and we really shouldn't now that we have 334 // multiple CPU subtypes and no posix_spawnattr call that allows us to set 335 // which CPU subtype to launch... 336 cpu_type_t desired_cpu_type = launch_info.GetArchitecture().GetMachOCPUType(); 337 if (desired_cpu_type != LLDB_INVALID_CPUTYPE) { 338 size_t ocount = 0; 339 error_code = 340 ::posix_spawnattr_setbinpref_np(&attr, 1, &desired_cpu_type, &ocount); 341 if (error_code != 0) { 342 LLDB_LOG(log, 343 "::posix_spawnattr_setbinpref_np(&attr, 1, " 344 "cpu_type = {0:x8}, count => {1}): {2}", 345 desired_cpu_type, ocount, llvm::sys::StrError(error_code)); 346 error.SetError(error_code, eErrorTypePOSIX); 347 return error; 348 } 349 if (ocount != 1) { 350 error.SetErrorStringWithFormat("posix_spawnattr_setbinpref_np " 351 "did not set the expected number " 352 "of cpu_type entries: expected 1 " 353 "but was %zu", 354 ocount); 355 return error; 356 } 357 } 358 #endif 359 360 posix_spawn_file_actions_t file_actions; 361 if ((error_code = ::posix_spawn_file_actions_init(&file_actions)) != 0) { 362 LLDB_LOG(log, "::posix_spawn_file_actions_init(&file_actions) failed: {0}", 363 llvm::sys::StrError(error_code)); 364 error.SetError(error_code, eErrorTypePOSIX); 365 return error; 366 } 367 368 // Ensure we clean up file actions however we exit this. When the 369 // file_actions_up below goes out of scope, we'll get our file action 370 // cleanup. 371 std::unique_ptr<posix_spawn_file_actions_t, 372 int (*)(posix_spawn_file_actions_t *)> 373 file_actions_up(&file_actions, ::posix_spawn_file_actions_destroy); 374 375 // We assume the caller has setup the file actions appropriately. We are not 376 // in the business of figuring out what we really need here. lldb-server will 377 // have already called FinalizeFileActions() as well to button these up 378 // properly. 379 const size_t num_actions = launch_info.GetNumFileActions(); 380 for (size_t action_index = 0; action_index < num_actions; ++action_index) { 381 const FileAction *const action = 382 launch_info.GetFileActionAtIndex(action_index); 383 if (!action) 384 continue; 385 386 error = CreatePosixSpawnFileAction(*action, &file_actions); 387 if (!error.Success()) { 388 if (log) 389 log->Printf("%s(): error converting FileAction to posix_spawn " 390 "file action: %s", 391 __FUNCTION__, error.AsCString()); 392 return error; 393 } 394 } 395 396 // TODO: Verify if we can set the working directory back immediately 397 // after the posix_spawnp call without creating a race condition??? 398 const char *const working_directory = 399 launch_info.GetWorkingDirectory().GetCString(); 400 if (working_directory && working_directory[0]) 401 ::chdir(working_directory); 402 403 auto argv = launch_info.GetArguments().GetArgumentVector(); 404 auto envp = launch_info.GetEnvironmentEntries().GetArgumentVector(); 405 error_code = ::posix_spawnp(pid, path, &file_actions, &attr, 406 (char *const *)argv, (char *const *)envp); 407 if (error_code != 0) { 408 LLDB_LOG(log, 409 "::posix_spawnp(pid => {0}, path = '{1}', file_actions " 410 "= {2}, attr = {3}, argv = {4}, envp = {5}) failed: {6}", 411 pid, path, &file_actions, &attr, argv, envp, 412 llvm::sys::StrError(error_code)); 413 error.SetError(error_code, eErrorTypePOSIX); 414 return error; 415 } 416 417 // Validate we got a pid. 418 if (pid == LLDB_INVALID_PROCESS_ID) { 419 error.SetErrorString("posix_spawn() did not indicate a failure but it " 420 "failed to return a pid, aborting."); 421 return error; 422 } 423 424 if (actual_cpu_type) { 425 *actual_cpu_type = GetCPUTypeForLocalProcess(*pid); 426 if (log) 427 log->Printf("%s(): cpu type for launched process pid=%i: " 428 "cpu_type=0x%8.8x", 429 __FUNCTION__, *pid, *actual_cpu_type); 430 } 431 432 return error; 433 } 434 435 Status LaunchInferior(ProcessLaunchInfo &launch_info, int *pty_master_fd, 436 LaunchFlavor *launch_flavor) { 437 Status error; 438 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); 439 440 if (!launch_flavor) { 441 error.SetErrorString("mandatory launch_flavor field was null"); 442 return error; 443 } 444 445 if (log) { 446 StreamString stream; 447 stream.Printf("NativeProcessDarwin::%s(): launching with the " 448 "following launch info:", 449 __FUNCTION__); 450 launch_info.Dump(stream, nullptr); 451 stream.Flush(); 452 log->PutCString(stream.GetString().c_str()); 453 } 454 455 // Retrieve the binary name given to us. 456 char given_path[PATH_MAX]; 457 given_path[0] = '\0'; 458 launch_info.GetExecutableFile().GetPath(given_path, sizeof(given_path)); 459 460 // Determine the manner in which we'll launch. 461 *launch_flavor = g_launch_flavor; 462 if (*launch_flavor == LaunchFlavor::Default) { 463 // Our default launch method is posix spawn 464 *launch_flavor = LaunchFlavor::PosixSpawn; 465 #if defined WITH_FBS 466 // Check if we have an app bundle, if so launch using BackBoard Services. 467 if (strstr(given_path, ".app")) { 468 *launch_flavor = eLaunchFlavorFBS; 469 } 470 #elif defined WITH_BKS 471 // Check if we have an app bundle, if so launch using BackBoard Services. 472 if (strstr(given_path, ".app")) { 473 *launch_flavor = eLaunchFlavorBKS; 474 } 475 #elif defined WITH_SPRINGBOARD 476 // Check if we have an app bundle, if so launch using SpringBoard. 477 if (strstr(given_path, ".app")) { 478 *launch_flavor = eLaunchFlavorSpringBoard; 479 } 480 #endif 481 } 482 483 // Attempt to resolve the binary name to an absolute path. 484 char resolved_path[PATH_MAX]; 485 resolved_path[0] = '\0'; 486 487 if (log) 488 log->Printf("%s(): attempting to resolve given binary path: \"%s\"", 489 __FUNCTION__, given_path); 490 491 // If we fail to resolve the path to our executable, then just use what we 492 // were given and hope for the best 493 if (!ResolveExecutablePath(given_path, resolved_path, 494 sizeof(resolved_path))) { 495 if (log) 496 log->Printf("%s(): failed to resolve binary path, using " 497 "what was given verbatim and hoping for the best", 498 __FUNCTION__); 499 ::strncpy(resolved_path, given_path, sizeof(resolved_path)); 500 } else { 501 if (log) 502 log->Printf("%s(): resolved given binary path to: \"%s\"", __FUNCTION__, 503 resolved_path); 504 } 505 506 char launch_err_str[PATH_MAX]; 507 launch_err_str[0] = '\0'; 508 509 // TODO figure out how to handle QSetProcessEvent 510 // const char *process_event = ctx.GetProcessEvent(); 511 512 // Ensure the binary is there. 513 struct stat path_stat; 514 if (::stat(resolved_path, &path_stat) == -1) { 515 error.SetErrorToErrno(); 516 return error; 517 } 518 519 // Fork a child process for debugging 520 // state_callback(eStateLaunching); 521 522 const auto argv = launch_info.GetArguments().GetConstArgumentVector(); 523 const auto envp = 524 launch_info.GetEnvironmentEntries().GetConstArgumentVector(); 525 526 switch (*launch_flavor) { 527 case LaunchFlavor::ForkExec: { 528 ::pid_t pid = LLDB_INVALID_PROCESS_ID; 529 error = ForkChildForPTraceDebugging(resolved_path, argv, envp, &pid, 530 pty_master_fd); 531 if (error.Success()) { 532 launch_info.SetProcessID(static_cast<lldb::pid_t>(pid)); 533 } else { 534 // Reset any variables that might have been set during a failed launch 535 // attempt. 536 if (pty_master_fd) 537 *pty_master_fd = -1; 538 539 // We're done. 540 return error; 541 } 542 } break; 543 544 #ifdef WITH_FBS 545 case LaunchFlavor::FBS: { 546 const char *app_ext = strstr(path, ".app"); 547 if (app_ext && (app_ext[4] == '\0' || app_ext[4] == '/')) { 548 std::string app_bundle_path(path, app_ext + strlen(".app")); 549 m_flags |= eMachProcessFlagsUsingFBS; 550 if (BoardServiceLaunchForDebug(app_bundle_path.c_str(), argv, envp, 551 no_stdio, disable_aslr, event_data, 552 launch_err) != 0) 553 return m_pid; // A successful SBLaunchForDebug() returns and assigns a 554 // non-zero m_pid. 555 else 556 break; // We tried a FBS launch, but didn't succeed lets get out 557 } 558 } break; 559 #endif 560 561 #ifdef WITH_BKS 562 case LaunchFlavor::BKS: { 563 const char *app_ext = strstr(path, ".app"); 564 if (app_ext && (app_ext[4] == '\0' || app_ext[4] == '/')) { 565 std::string app_bundle_path(path, app_ext + strlen(".app")); 566 m_flags |= eMachProcessFlagsUsingBKS; 567 if (BoardServiceLaunchForDebug(app_bundle_path.c_str(), argv, envp, 568 no_stdio, disable_aslr, event_data, 569 launch_err) != 0) 570 return m_pid; // A successful SBLaunchForDebug() returns and assigns a 571 // non-zero m_pid. 572 else 573 break; // We tried a BKS launch, but didn't succeed lets get out 574 } 575 } break; 576 #endif 577 578 #ifdef WITH_SPRINGBOARD 579 case LaunchFlavor::SpringBoard: { 580 // .../whatever.app/whatever ? 581 // Or .../com.apple.whatever.app/whatever -- be careful of ".app" in 582 // "com.apple.whatever" here 583 const char *app_ext = strstr(path, ".app/"); 584 if (app_ext == NULL) { 585 // .../whatever.app ? 586 int len = strlen(path); 587 if (len > 5) { 588 if (strcmp(path + len - 4, ".app") == 0) { 589 app_ext = path + len - 4; 590 } 591 } 592 } 593 if (app_ext) { 594 std::string app_bundle_path(path, app_ext + strlen(".app")); 595 if (SBLaunchForDebug(app_bundle_path.c_str(), argv, envp, no_stdio, 596 disable_aslr, launch_err) != 0) 597 return m_pid; // A successful SBLaunchForDebug() returns and assigns a 598 // non-zero m_pid. 599 else 600 break; // We tried a springboard launch, but didn't succeed lets get out 601 } 602 } break; 603 #endif 604 605 case LaunchFlavor::PosixSpawn: { 606 ::pid_t pid = LLDB_INVALID_PROCESS_ID; 607 608 // Retrieve paths for stdin/stdout/stderr. 609 cpu_type_t actual_cpu_type = 0; 610 error = PosixSpawnChildForPTraceDebugging(resolved_path, launch_info, &pid, 611 &actual_cpu_type); 612 if (error.Success()) { 613 launch_info.SetProcessID(static_cast<lldb::pid_t>(pid)); 614 if (pty_master_fd) 615 *pty_master_fd = launch_info.GetPTY().ReleaseMasterFileDescriptor(); 616 } else { 617 // Reset any variables that might have been set during a failed launch 618 // attempt. 619 if (pty_master_fd) 620 *pty_master_fd = -1; 621 622 // We're done. 623 return error; 624 } 625 break; 626 } 627 628 default: 629 // Invalid launch flavor. 630 error.SetErrorStringWithFormat("NativeProcessDarwin::%s(): unknown " 631 "launch flavor %d", 632 __FUNCTION__, (int)*launch_flavor); 633 return error; 634 } 635 636 if (launch_info.GetProcessID() == LLDB_INVALID_PROCESS_ID) { 637 // If we don't have a valid process ID and no one has set the error, then 638 // return a generic error. 639 if (error.Success()) 640 error.SetErrorStringWithFormat("%s(): failed to launch, no reason " 641 "specified", 642 __FUNCTION__); 643 } 644 645 // We're done with the launch side of the operation. 646 return error; 647 } 648 } 649 } // namespaces 650