1 //===-- PlatformPOSIX.cpp ---------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "PlatformPOSIX.h" 11 12 // C Includes 13 // C++ Includes 14 // Other libraries and framework includes 15 // Project includes 16 17 #include "lldb/Core/DataBufferHeap.h" 18 #include "lldb/Core/Debugger.h" 19 #include "lldb/Core/Log.h" 20 #include "lldb/Core/Module.h" 21 #include "lldb/Core/StreamString.h" 22 #include "lldb/Host/File.h" 23 #include "lldb/Host/FileCache.h" 24 #include "lldb/Host/FileSpec.h" 25 #include "lldb/Host/FileSystem.h" 26 #include "lldb/Host/Host.h" 27 #include "lldb/Target/ProcessLaunchInfo.h" 28 29 using namespace lldb; 30 using namespace lldb_private; 31 32 33 //------------------------------------------------------------------ 34 /// Default Constructor 35 //------------------------------------------------------------------ 36 PlatformPOSIX::PlatformPOSIX (bool is_host) : 37 Platform(is_host), // This is the local host platform 38 m_remote_platform_sp () 39 { 40 } 41 42 //------------------------------------------------------------------ 43 /// Destructor. 44 /// 45 /// The destructor is virtual since this class is designed to be 46 /// inherited from by the plug-in instance. 47 //------------------------------------------------------------------ 48 PlatformPOSIX::~PlatformPOSIX() 49 { 50 } 51 52 lldb_private::OptionGroupOptions* 53 PlatformPOSIX::GetConnectionOptions (lldb_private::CommandInterpreter& interpreter) 54 { 55 if (m_options.get() == NULL) 56 { 57 m_options.reset(new OptionGroupOptions(interpreter)); 58 m_options->Append(new OptionGroupPlatformRSync()); 59 m_options->Append(new OptionGroupPlatformSSH()); 60 m_options->Append(new OptionGroupPlatformCaching()); 61 } 62 return m_options.get(); 63 } 64 65 bool 66 PlatformPOSIX::IsConnected () const 67 { 68 if (IsHost()) 69 return true; 70 else if (m_remote_platform_sp) 71 return m_remote_platform_sp->IsConnected(); 72 return false; 73 } 74 75 lldb_private::Error 76 PlatformPOSIX::RunShellCommand (const char *command, // Shouldn't be NULL 77 const char *working_dir, // Pass NULL to use the current working directory 78 int *status_ptr, // Pass NULL if you don't want the process exit status 79 int *signo_ptr, // Pass NULL if you don't want the signal that caused the process to exit 80 std::string *command_output, // Pass NULL if you don't want the command output 81 uint32_t timeout_sec) // Timeout in seconds to wait for shell program to finish 82 { 83 if (IsHost()) 84 return Host::RunShellCommand(command, working_dir, status_ptr, signo_ptr, command_output, timeout_sec); 85 else 86 { 87 if (m_remote_platform_sp) 88 return m_remote_platform_sp->RunShellCommand(command, working_dir, status_ptr, signo_ptr, command_output, timeout_sec); 89 else 90 return Error("unable to run a remote command without a platform"); 91 } 92 } 93 94 Error 95 PlatformPOSIX::MakeDirectory (const char *path, uint32_t file_permissions) 96 { 97 if (m_remote_platform_sp) 98 return m_remote_platform_sp->MakeDirectory(path, file_permissions); 99 else 100 return Platform::MakeDirectory(path ,file_permissions); 101 } 102 103 Error 104 PlatformPOSIX::GetFilePermissions (const char *path, uint32_t &file_permissions) 105 { 106 if (m_remote_platform_sp) 107 return m_remote_platform_sp->GetFilePermissions(path, file_permissions); 108 else 109 return Platform::GetFilePermissions(path ,file_permissions); 110 } 111 112 Error 113 PlatformPOSIX::SetFilePermissions (const char *path, uint32_t file_permissions) 114 { 115 if (m_remote_platform_sp) 116 return m_remote_platform_sp->SetFilePermissions(path, file_permissions); 117 else 118 return Platform::SetFilePermissions(path ,file_permissions); 119 } 120 121 lldb::user_id_t 122 PlatformPOSIX::OpenFile (const FileSpec& file_spec, 123 uint32_t flags, 124 uint32_t mode, 125 Error &error) 126 { 127 if (IsHost()) 128 return FileCache::GetInstance().OpenFile(file_spec, flags, mode, error); 129 else if (m_remote_platform_sp) 130 return m_remote_platform_sp->OpenFile(file_spec, flags, mode, error); 131 else 132 return Platform::OpenFile(file_spec, flags, mode, error); 133 } 134 135 bool 136 PlatformPOSIX::CloseFile (lldb::user_id_t fd, Error &error) 137 { 138 if (IsHost()) 139 return FileCache::GetInstance().CloseFile(fd, error); 140 else if (m_remote_platform_sp) 141 return m_remote_platform_sp->CloseFile(fd, error); 142 else 143 return Platform::CloseFile(fd, error); 144 } 145 146 uint64_t 147 PlatformPOSIX::ReadFile (lldb::user_id_t fd, 148 uint64_t offset, 149 void *dst, 150 uint64_t dst_len, 151 Error &error) 152 { 153 if (IsHost()) 154 return FileCache::GetInstance().ReadFile(fd, offset, dst, dst_len, error); 155 else if (m_remote_platform_sp) 156 return m_remote_platform_sp->ReadFile(fd, offset, dst, dst_len, error); 157 else 158 return Platform::ReadFile(fd, offset, dst, dst_len, error); 159 } 160 161 uint64_t 162 PlatformPOSIX::WriteFile (lldb::user_id_t fd, 163 uint64_t offset, 164 const void* src, 165 uint64_t src_len, 166 Error &error) 167 { 168 if (IsHost()) 169 return FileCache::GetInstance().WriteFile(fd, offset, src, src_len, error); 170 else if (m_remote_platform_sp) 171 return m_remote_platform_sp->WriteFile(fd, offset, src, src_len, error); 172 else 173 return Platform::WriteFile(fd, offset, src, src_len, error); 174 } 175 176 static uint32_t 177 chown_file(Platform *platform, 178 const char* path, 179 uint32_t uid = UINT32_MAX, 180 uint32_t gid = UINT32_MAX) 181 { 182 if (!platform || !path || *path == 0) 183 return UINT32_MAX; 184 185 if (uid == UINT32_MAX && gid == UINT32_MAX) 186 return 0; // pretend I did chown correctly - actually I just didn't care 187 188 StreamString command; 189 command.PutCString("chown "); 190 if (uid != UINT32_MAX) 191 command.Printf("%d",uid); 192 if (gid != UINT32_MAX) 193 command.Printf(":%d",gid); 194 command.Printf("%s",path); 195 int status; 196 platform->RunShellCommand(command.GetData(), 197 NULL, 198 &status, 199 NULL, 200 NULL, 201 10); 202 return status; 203 } 204 205 lldb_private::Error 206 PlatformPOSIX::PutFile (const lldb_private::FileSpec& source, 207 const lldb_private::FileSpec& destination, 208 uint32_t uid, 209 uint32_t gid) 210 { 211 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM)); 212 213 if (IsHost()) 214 { 215 if (FileSpec::Equal(source, destination, true)) 216 return Error(); 217 // cp src dst 218 // chown uid:gid dst 219 std::string src_path (source.GetPath()); 220 if (src_path.empty()) 221 return Error("unable to get file path for source"); 222 std::string dst_path (destination.GetPath()); 223 if (dst_path.empty()) 224 return Error("unable to get file path for destination"); 225 StreamString command; 226 command.Printf("cp %s %s", src_path.c_str(), dst_path.c_str()); 227 int status; 228 RunShellCommand(command.GetData(), 229 NULL, 230 &status, 231 NULL, 232 NULL, 233 10); 234 if (status != 0) 235 return Error("unable to perform copy"); 236 if (uid == UINT32_MAX && gid == UINT32_MAX) 237 return Error(); 238 if (chown_file(this,dst_path.c_str(),uid,gid) != 0) 239 return Error("unable to perform chown"); 240 return Error(); 241 } 242 else if (m_remote_platform_sp) 243 { 244 if (GetSupportsRSync()) 245 { 246 std::string src_path (source.GetPath()); 247 if (src_path.empty()) 248 return Error("unable to get file path for source"); 249 std::string dst_path (destination.GetPath()); 250 if (dst_path.empty()) 251 return Error("unable to get file path for destination"); 252 StreamString command; 253 if (GetIgnoresRemoteHostname()) 254 { 255 if (!GetRSyncPrefix()) 256 command.Printf("rsync %s %s %s", 257 GetRSyncOpts(), 258 src_path.c_str(), 259 dst_path.c_str()); 260 else 261 command.Printf("rsync %s %s %s%s", 262 GetRSyncOpts(), 263 src_path.c_str(), 264 GetRSyncPrefix(), 265 dst_path.c_str()); 266 } 267 else 268 command.Printf("rsync %s %s %s:%s", 269 GetRSyncOpts(), 270 src_path.c_str(), 271 GetHostname(), 272 dst_path.c_str()); 273 if (log) 274 log->Printf("[PutFile] Running command: %s\n", command.GetData()); 275 int retcode; 276 Host::RunShellCommand(command.GetData(), 277 NULL, 278 &retcode, 279 NULL, 280 NULL, 281 60); 282 if (retcode == 0) 283 { 284 // Don't chown a local file for a remote system 285 // if (chown_file(this,dst_path.c_str(),uid,gid) != 0) 286 // return Error("unable to perform chown"); 287 return Error(); 288 } 289 // if we are still here rsync has failed - let's try the slow way before giving up 290 } 291 } 292 return Platform::PutFile(source,destination,uid,gid); 293 } 294 295 lldb::user_id_t 296 PlatformPOSIX::GetFileSize (const FileSpec& file_spec) 297 { 298 if (IsHost()) 299 return FileSystem::GetFileSize(file_spec); 300 else if (m_remote_platform_sp) 301 return m_remote_platform_sp->GetFileSize(file_spec); 302 else 303 return Platform::GetFileSize(file_spec); 304 } 305 306 Error 307 PlatformPOSIX::CreateSymlink(const char *src, const char *dst) 308 { 309 if (IsHost()) 310 return FileSystem::Symlink(src, dst); 311 else if (m_remote_platform_sp) 312 return m_remote_platform_sp->CreateSymlink(src, dst); 313 else 314 return Platform::CreateSymlink(src, dst); 315 } 316 317 bool 318 PlatformPOSIX::GetFileExists (const FileSpec& file_spec) 319 { 320 if (IsHost()) 321 return file_spec.Exists(); 322 else if (m_remote_platform_sp) 323 return m_remote_platform_sp->GetFileExists(file_spec); 324 else 325 return Platform::GetFileExists(file_spec); 326 } 327 328 Error 329 PlatformPOSIX::Unlink (const char *path) 330 { 331 if (IsHost()) 332 return FileSystem::Unlink(path); 333 else if (m_remote_platform_sp) 334 return m_remote_platform_sp->Unlink(path); 335 else 336 return Platform::Unlink(path); 337 } 338 339 lldb_private::Error 340 PlatformPOSIX::GetFile (const lldb_private::FileSpec& source /* remote file path */, 341 const lldb_private::FileSpec& destination /* local file path */) 342 { 343 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM)); 344 345 // Check the args, first. 346 std::string src_path (source.GetPath()); 347 if (src_path.empty()) 348 return Error("unable to get file path for source"); 349 std::string dst_path (destination.GetPath()); 350 if (dst_path.empty()) 351 return Error("unable to get file path for destination"); 352 if (IsHost()) 353 { 354 if (FileSpec::Equal(source, destination, true)) 355 return Error("local scenario->source and destination are the same file path: no operation performed"); 356 // cp src dst 357 StreamString cp_command; 358 cp_command.Printf("cp %s %s", src_path.c_str(), dst_path.c_str()); 359 int status; 360 RunShellCommand(cp_command.GetData(), 361 NULL, 362 &status, 363 NULL, 364 NULL, 365 10); 366 if (status != 0) 367 return Error("unable to perform copy"); 368 return Error(); 369 } 370 else if (m_remote_platform_sp) 371 { 372 if (GetSupportsRSync()) 373 { 374 StreamString command; 375 if (GetIgnoresRemoteHostname()) 376 { 377 if (!GetRSyncPrefix()) 378 command.Printf("rsync %s %s %s", 379 GetRSyncOpts(), 380 src_path.c_str(), 381 dst_path.c_str()); 382 else 383 command.Printf("rsync %s %s%s %s", 384 GetRSyncOpts(), 385 GetRSyncPrefix(), 386 src_path.c_str(), 387 dst_path.c_str()); 388 } 389 else 390 command.Printf("rsync %s %s:%s %s", 391 GetRSyncOpts(), 392 m_remote_platform_sp->GetHostname(), 393 src_path.c_str(), 394 dst_path.c_str()); 395 if (log) 396 log->Printf("[GetFile] Running command: %s\n", command.GetData()); 397 int retcode; 398 Host::RunShellCommand(command.GetData(), 399 NULL, 400 &retcode, 401 NULL, 402 NULL, 403 60); 404 if (retcode == 0) 405 return Error(); 406 // If we are here, rsync has failed - let's try the slow way before giving up 407 } 408 // open src and dst 409 // read/write, read/write, read/write, ... 410 // close src 411 // close dst 412 if (log) 413 log->Printf("[GetFile] Using block by block transfer....\n"); 414 Error error; 415 user_id_t fd_src = OpenFile (source, 416 File::eOpenOptionRead, 417 lldb::eFilePermissionsFileDefault, 418 error); 419 420 if (fd_src == UINT64_MAX) 421 return Error("unable to open source file"); 422 423 uint32_t permissions = 0; 424 error = GetFilePermissions(source.GetPath().c_str(), permissions); 425 426 if (permissions == 0) 427 permissions = lldb::eFilePermissionsFileDefault; 428 429 user_id_t fd_dst = FileCache::GetInstance().OpenFile( 430 destination, File::eOpenOptionCanCreate | File::eOpenOptionWrite | File::eOpenOptionTruncate, permissions, 431 error); 432 433 if (fd_dst == UINT64_MAX) 434 { 435 if (error.Success()) 436 error.SetErrorString("unable to open destination file"); 437 } 438 439 if (error.Success()) 440 { 441 lldb::DataBufferSP buffer_sp(new DataBufferHeap(1024, 0)); 442 uint64_t offset = 0; 443 error.Clear(); 444 while (error.Success()) 445 { 446 const uint64_t n_read = ReadFile (fd_src, 447 offset, 448 buffer_sp->GetBytes(), 449 buffer_sp->GetByteSize(), 450 error); 451 if (error.Fail()) 452 break; 453 if (n_read == 0) 454 break; 455 if (FileCache::GetInstance().WriteFile(fd_dst, offset, buffer_sp->GetBytes(), n_read, error) != n_read) 456 { 457 if (!error.Fail()) 458 error.SetErrorString("unable to write to destination file"); 459 break; 460 } 461 offset += n_read; 462 } 463 } 464 // Ignore the close error of src. 465 if (fd_src != UINT64_MAX) 466 CloseFile(fd_src, error); 467 // And close the dst file descriptot. 468 if (fd_dst != UINT64_MAX && !FileCache::GetInstance().CloseFile(fd_dst, error)) 469 { 470 if (!error.Fail()) 471 error.SetErrorString("unable to close destination file"); 472 473 } 474 return error; 475 } 476 return Platform::GetFile(source,destination); 477 } 478 479 std::string 480 PlatformPOSIX::GetPlatformSpecificConnectionInformation() 481 { 482 StreamString stream; 483 if (GetSupportsRSync()) 484 { 485 stream.PutCString("rsync"); 486 if ( (GetRSyncOpts() && *GetRSyncOpts()) || 487 (GetRSyncPrefix() && *GetRSyncPrefix()) || 488 GetIgnoresRemoteHostname()) 489 { 490 stream.Printf(", options: "); 491 if (GetRSyncOpts() && *GetRSyncOpts()) 492 stream.Printf("'%s' ",GetRSyncOpts()); 493 stream.Printf(", prefix: "); 494 if (GetRSyncPrefix() && *GetRSyncPrefix()) 495 stream.Printf("'%s' ",GetRSyncPrefix()); 496 if (GetIgnoresRemoteHostname()) 497 stream.Printf("ignore remote-hostname "); 498 } 499 } 500 if (GetSupportsSSH()) 501 { 502 stream.PutCString("ssh"); 503 if (GetSSHOpts() && *GetSSHOpts()) 504 stream.Printf(", options: '%s' ",GetSSHOpts()); 505 } 506 if (GetLocalCacheDirectory() && *GetLocalCacheDirectory()) 507 stream.Printf("cache dir: %s",GetLocalCacheDirectory()); 508 if (stream.GetSize()) 509 return stream.GetData(); 510 else 511 return ""; 512 } 513 514 bool 515 PlatformPOSIX::CalculateMD5 (const FileSpec& file_spec, 516 uint64_t &low, 517 uint64_t &high) 518 { 519 if (IsHost()) 520 return Platform::CalculateMD5 (file_spec, low, high); 521 if (m_remote_platform_sp) 522 return m_remote_platform_sp->CalculateMD5(file_spec, low, high); 523 return false; 524 } 525 526 lldb_private::ConstString 527 PlatformPOSIX::GetRemoteWorkingDirectory() 528 { 529 if (IsRemote() && m_remote_platform_sp) 530 return m_remote_platform_sp->GetRemoteWorkingDirectory(); 531 else 532 return Platform::GetRemoteWorkingDirectory(); 533 } 534 535 bool 536 PlatformPOSIX::SetRemoteWorkingDirectory(const lldb_private::ConstString &path) 537 { 538 if (IsRemote() && m_remote_platform_sp) 539 return m_remote_platform_sp->SetRemoteWorkingDirectory(path); 540 else 541 return Platform::SetRemoteWorkingDirectory(path); 542 } 543 544 bool 545 PlatformPOSIX::GetRemoteOSVersion () 546 { 547 if (m_remote_platform_sp) 548 return m_remote_platform_sp->GetOSVersion (m_major_os_version, 549 m_minor_os_version, 550 m_update_os_version); 551 return false; 552 } 553 554 bool 555 PlatformPOSIX::GetRemoteOSBuildString (std::string &s) 556 { 557 if (m_remote_platform_sp) 558 return m_remote_platform_sp->GetRemoteOSBuildString (s); 559 s.clear(); 560 return false; 561 } 562 563 size_t 564 PlatformPOSIX::GetEnvironment (StringList &env) 565 { 566 if (IsRemote()) 567 { 568 if (m_remote_platform_sp) 569 return m_remote_platform_sp->GetEnvironment(env); 570 return 0; 571 } 572 return Host::GetEnvironment(env); 573 } 574 575 bool 576 PlatformPOSIX::GetRemoteOSKernelDescription (std::string &s) 577 { 578 if (m_remote_platform_sp) 579 return m_remote_platform_sp->GetRemoteOSKernelDescription (s); 580 s.clear(); 581 return false; 582 } 583 584 // Remote Platform subclasses need to override this function 585 ArchSpec 586 PlatformPOSIX::GetRemoteSystemArchitecture () 587 { 588 if (m_remote_platform_sp) 589 return m_remote_platform_sp->GetRemoteSystemArchitecture (); 590 return ArchSpec(); 591 } 592 593 const char * 594 PlatformPOSIX::GetHostname () 595 { 596 if (IsHost()) 597 return Platform::GetHostname(); 598 599 if (m_remote_platform_sp) 600 return m_remote_platform_sp->GetHostname (); 601 return NULL; 602 } 603 604 const char * 605 PlatformPOSIX::GetUserName (uint32_t uid) 606 { 607 // Check the cache in Platform in case we have already looked this uid up 608 const char *user_name = Platform::GetUserName(uid); 609 if (user_name) 610 return user_name; 611 612 if (IsRemote() && m_remote_platform_sp) 613 return m_remote_platform_sp->GetUserName(uid); 614 return NULL; 615 } 616 617 const char * 618 PlatformPOSIX::GetGroupName (uint32_t gid) 619 { 620 const char *group_name = Platform::GetGroupName(gid); 621 if (group_name) 622 return group_name; 623 624 if (IsRemote() && m_remote_platform_sp) 625 return m_remote_platform_sp->GetGroupName(gid); 626 return NULL; 627 } 628 629 Error 630 PlatformPOSIX::ConnectRemote (Args& args) 631 { 632 Error error; 633 if (IsHost()) 634 { 635 error.SetErrorStringWithFormat ("can't connect to the host platform '%s', always connected", GetPluginName().GetCString()); 636 } 637 else 638 { 639 if (!m_remote_platform_sp) 640 m_remote_platform_sp = Platform::Create (ConstString("remote-gdb-server"), error); 641 642 if (m_remote_platform_sp && error.Success()) 643 error = m_remote_platform_sp->ConnectRemote (args); 644 else 645 error.SetErrorString ("failed to create a 'remote-gdb-server' platform"); 646 647 if (error.Fail()) 648 m_remote_platform_sp.reset(); 649 } 650 651 if (error.Success() && m_remote_platform_sp) 652 { 653 if (m_options.get()) 654 { 655 OptionGroupOptions* options = m_options.get(); 656 OptionGroupPlatformRSync* m_rsync_options = (OptionGroupPlatformRSync*)options->GetGroupWithOption('r'); 657 OptionGroupPlatformSSH* m_ssh_options = (OptionGroupPlatformSSH*)options->GetGroupWithOption('s'); 658 OptionGroupPlatformCaching* m_cache_options = (OptionGroupPlatformCaching*)options->GetGroupWithOption('c'); 659 660 if (m_rsync_options->m_rsync) 661 { 662 SetSupportsRSync(true); 663 SetRSyncOpts(m_rsync_options->m_rsync_opts.c_str()); 664 SetRSyncPrefix(m_rsync_options->m_rsync_prefix.c_str()); 665 SetIgnoresRemoteHostname(m_rsync_options->m_ignores_remote_hostname); 666 } 667 if (m_ssh_options->m_ssh) 668 { 669 SetSupportsSSH(true); 670 SetSSHOpts(m_ssh_options->m_ssh_opts.c_str()); 671 } 672 SetLocalCacheDirectory(m_cache_options->m_cache_dir.c_str()); 673 } 674 } 675 676 return error; 677 } 678 679 Error 680 PlatformPOSIX::DisconnectRemote () 681 { 682 Error error; 683 684 if (IsHost()) 685 { 686 error.SetErrorStringWithFormat ("can't disconnect from the host platform '%s', always connected", GetPluginName().GetCString()); 687 } 688 else 689 { 690 if (m_remote_platform_sp) 691 error = m_remote_platform_sp->DisconnectRemote (); 692 else 693 error.SetErrorString ("the platform is not currently connected"); 694 } 695 return error; 696 } 697 698 Error 699 PlatformPOSIX::LaunchProcess (ProcessLaunchInfo &launch_info) 700 { 701 Error error; 702 703 if (IsHost()) 704 { 705 error = Platform::LaunchProcess (launch_info); 706 } 707 else 708 { 709 if (m_remote_platform_sp) 710 error = m_remote_platform_sp->LaunchProcess (launch_info); 711 else 712 error.SetErrorString ("the platform is not currently connected"); 713 } 714 return error; 715 } 716 717 lldb_private::Error 718 PlatformPOSIX::KillProcess (const lldb::pid_t pid) 719 { 720 if (IsHost()) 721 return Platform::KillProcess (pid); 722 723 if (m_remote_platform_sp) 724 return m_remote_platform_sp->KillProcess (pid); 725 726 return Error ("the platform is not currently connected"); 727 } 728 729 lldb::ProcessSP 730 PlatformPOSIX::Attach (ProcessAttachInfo &attach_info, 731 Debugger &debugger, 732 Target *target, 733 Error &error) 734 { 735 lldb::ProcessSP process_sp; 736 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM)); 737 738 if (IsHost()) 739 { 740 if (target == NULL) 741 { 742 TargetSP new_target_sp; 743 744 error = debugger.GetTargetList().CreateTarget (debugger, 745 NULL, 746 NULL, 747 false, 748 NULL, 749 new_target_sp); 750 target = new_target_sp.get(); 751 if (log) 752 log->Printf ("PlatformPOSIX::%s created new target", __FUNCTION__); 753 } 754 else 755 { 756 error.Clear(); 757 if (log) 758 log->Printf ("PlatformPOSIX::%s target already existed, setting target", __FUNCTION__); 759 } 760 761 if (target && error.Success()) 762 { 763 debugger.GetTargetList().SetSelectedTarget(target); 764 if (log) 765 { 766 ModuleSP exe_module_sp = target->GetExecutableModule (); 767 log->Printf ("PlatformPOSIX::%s set selected target to %p %s", __FUNCTION__, 768 target, 769 exe_module_sp ? exe_module_sp->GetFileSpec().GetPath().c_str () : "<null>" ); 770 } 771 772 773 process_sp = target->CreateProcess (attach_info.GetListenerForProcess(debugger), attach_info.GetProcessPluginName(), NULL); 774 775 if (process_sp) 776 { 777 // Set UnixSignals appropriately. 778 process_sp->SetUnixSignals (Host::GetUnixSignals ()); 779 780 auto listener_sp = attach_info.GetHijackListener(); 781 if (listener_sp == nullptr) 782 { 783 listener_sp.reset(new Listener("lldb.PlatformPOSIX.attach.hijack")); 784 attach_info.SetHijackListener(listener_sp); 785 } 786 process_sp->HijackProcessEvents(listener_sp.get()); 787 error = process_sp->Attach (attach_info); 788 } 789 } 790 } 791 else 792 { 793 if (m_remote_platform_sp) 794 process_sp = m_remote_platform_sp->Attach (attach_info, debugger, target, error); 795 else 796 error.SetErrorString ("the platform is not currently connected"); 797 } 798 return process_sp; 799 } 800 801 lldb::ProcessSP 802 PlatformPOSIX::DebugProcess (ProcessLaunchInfo &launch_info, 803 Debugger &debugger, 804 Target *target, // Can be NULL, if NULL create a new target, else use existing one 805 Error &error) 806 { 807 ProcessSP process_sp; 808 809 if (IsHost()) 810 { 811 // We are going to hand this process off to debugserver which will be in charge of setting the exit status. 812 // We still need to reap it from lldb but if we let the monitor thread also set the exit status, we set up a 813 // race between debugserver & us for who will find out about the debugged process's death. 814 launch_info.GetFlags().Set(eLaunchFlagDontSetExitStatus); 815 process_sp = Platform::DebugProcess (launch_info, debugger, target, error); 816 } 817 else 818 { 819 if (m_remote_platform_sp) 820 process_sp = m_remote_platform_sp->DebugProcess (launch_info, debugger, target, error); 821 else 822 error.SetErrorString ("the platform is not currently connected"); 823 } 824 return process_sp; 825 826 } 827 828 void 829 PlatformPOSIX::CalculateTrapHandlerSymbolNames () 830 { 831 m_trap_handlers.push_back (ConstString ("_sigtramp")); 832 } 833