1 //===-- SBTarget.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 "lldb/API/SBTarget.h" 11 12 #include "lldb/lldb-public.h" 13 14 #include "lldb/API/SBDebugger.h" 15 #include "lldb/API/SBBreakpoint.h" 16 #include "lldb/API/SBFileSpec.h" 17 #include "lldb/API/SBListener.h" 18 #include "lldb/API/SBModule.h" 19 #include "lldb/API/SBSourceManager.h" 20 #include "lldb/API/SBProcess.h" 21 #include "lldb/API/SBStream.h" 22 #include "lldb/API/SBSymbolContextList.h" 23 #include "lldb/Breakpoint/BreakpointID.h" 24 #include "lldb/Breakpoint/BreakpointIDList.h" 25 #include "lldb/Breakpoint/BreakpointList.h" 26 #include "lldb/Breakpoint/BreakpointLocation.h" 27 #include "lldb/Core/Address.h" 28 #include "lldb/Core/AddressResolver.h" 29 #include "lldb/Core/AddressResolverName.h" 30 #include "lldb/Core/ArchSpec.h" 31 #include "lldb/Core/Debugger.h" 32 #include "lldb/Core/Disassembler.h" 33 #include "lldb/Core/Log.h" 34 #include "lldb/Core/RegularExpression.h" 35 #include "lldb/Core/SearchFilter.h" 36 #include "lldb/Core/STLUtils.h" 37 #include "lldb/Core/ValueObjectList.h" 38 #include "lldb/Core/ValueObjectVariable.h" 39 #include "lldb/Host/FileSpec.h" 40 #include "lldb/Host/Host.h" 41 #include "lldb/Interpreter/Args.h" 42 #include "lldb/Symbol/SymbolVendor.h" 43 #include "lldb/Symbol/VariableList.h" 44 #include "lldb/Target/LanguageRuntime.h" 45 #include "lldb/Target/Process.h" 46 #include "lldb/Target/Target.h" 47 #include "lldb/Target/TargetList.h" 48 49 #include "lldb/Interpreter/CommandReturnObject.h" 50 #include "../source/Commands/CommandObjectBreakpoint.h" 51 52 53 using namespace lldb; 54 using namespace lldb_private; 55 56 #define DEFAULT_DISASM_BYTE_SIZE 32 57 58 SBLaunchInfo::SBLaunchInfo (const char **argv) : 59 m_opaque_sp(new ProcessLaunchInfo()) 60 { 61 m_opaque_sp->GetFlags().Reset (eLaunchFlagDebug | eLaunchFlagDisableASLR); 62 if (argv && argv[0]) 63 m_opaque_sp->GetArguments().SetArguments(argv); 64 } 65 66 SBLaunchInfo::~SBLaunchInfo() 67 { 68 } 69 70 lldb_private::ProcessLaunchInfo & 71 SBLaunchInfo::ref () 72 { 73 return *m_opaque_sp; 74 } 75 76 77 uint32_t 78 SBLaunchInfo::GetUserID() 79 { 80 return m_opaque_sp->GetUserID(); 81 } 82 83 uint32_t 84 SBLaunchInfo::GetGroupID() 85 { 86 return m_opaque_sp->GetGroupID(); 87 } 88 89 bool 90 SBLaunchInfo::UserIDIsValid () 91 { 92 return m_opaque_sp->UserIDIsValid(); 93 } 94 95 bool 96 SBLaunchInfo::GroupIDIsValid () 97 { 98 return m_opaque_sp->GroupIDIsValid(); 99 } 100 101 void 102 SBLaunchInfo::SetUserID (uint32_t uid) 103 { 104 m_opaque_sp->SetUserID (uid); 105 } 106 107 void 108 SBLaunchInfo::SetGroupID (uint32_t gid) 109 { 110 m_opaque_sp->SetGroupID (gid); 111 } 112 113 uint32_t 114 SBLaunchInfo::GetNumArguments () 115 { 116 return m_opaque_sp->GetArguments().GetArgumentCount(); 117 } 118 119 const char * 120 SBLaunchInfo::GetArgumentAtIndex (uint32_t idx) 121 { 122 return m_opaque_sp->GetArguments().GetArgumentAtIndex(idx); 123 } 124 125 void 126 SBLaunchInfo::SetArguments (const char **argv, bool append) 127 { 128 if (append) 129 { 130 if (argv) 131 m_opaque_sp->GetArguments().AppendArguments(argv); 132 } 133 else 134 { 135 if (argv) 136 m_opaque_sp->GetArguments().SetArguments(argv); 137 else 138 m_opaque_sp->GetArguments().Clear(); 139 } 140 } 141 142 uint32_t 143 SBLaunchInfo::GetNumEnvironmentEntries () 144 { 145 return m_opaque_sp->GetEnvironmentEntries().GetArgumentCount(); 146 } 147 148 const char * 149 SBLaunchInfo::GetEnvironmentEntryAtIndex (uint32_t idx) 150 { 151 return m_opaque_sp->GetEnvironmentEntries().GetArgumentAtIndex(idx); 152 } 153 154 void 155 SBLaunchInfo::SetEnvironmentEntries (const char **envp, bool append) 156 { 157 if (append) 158 { 159 if (envp) 160 m_opaque_sp->GetEnvironmentEntries().AppendArguments(envp); 161 } 162 else 163 { 164 if (envp) 165 m_opaque_sp->GetEnvironmentEntries().SetArguments(envp); 166 else 167 m_opaque_sp->GetEnvironmentEntries().Clear(); 168 } 169 } 170 171 void 172 SBLaunchInfo::Clear () 173 { 174 m_opaque_sp->Clear(); 175 } 176 177 const char * 178 SBLaunchInfo::GetWorkingDirectory () const 179 { 180 return m_opaque_sp->GetWorkingDirectory(); 181 } 182 183 void 184 SBLaunchInfo::SetWorkingDirectory (const char *working_dir) 185 { 186 m_opaque_sp->SetWorkingDirectory(working_dir); 187 } 188 189 uint32_t 190 SBLaunchInfo::GetLaunchFlags () 191 { 192 return m_opaque_sp->GetFlags().Get(); 193 } 194 195 void 196 SBLaunchInfo::SetLaunchFlags (uint32_t flags) 197 { 198 m_opaque_sp->GetFlags().Reset(flags); 199 } 200 201 const char * 202 SBLaunchInfo::GetProcessPluginName () 203 { 204 return m_opaque_sp->GetProcessPluginName(); 205 } 206 207 void 208 SBLaunchInfo::SetProcessPluginName (const char *plugin_name) 209 { 210 return m_opaque_sp->SetProcessPluginName (plugin_name); 211 } 212 213 const char * 214 SBLaunchInfo::GetShell () 215 { 216 return m_opaque_sp->GetShell(); 217 } 218 219 void 220 SBLaunchInfo::SetShell (const char * path) 221 { 222 m_opaque_sp->SetShell (path); 223 } 224 225 uint32_t 226 SBLaunchInfo::GetResumeCount () 227 { 228 return m_opaque_sp->GetResumeCount(); 229 } 230 231 void 232 SBLaunchInfo::SetResumeCount (uint32_t c) 233 { 234 m_opaque_sp->SetResumeCount (c); 235 } 236 237 bool 238 SBLaunchInfo::AddCloseFileAction (int fd) 239 { 240 return m_opaque_sp->AppendCloseFileAction(fd); 241 } 242 243 bool 244 SBLaunchInfo::AddDuplicateFileAction (int fd, int dup_fd) 245 { 246 return m_opaque_sp->AppendDuplicateFileAction(fd, dup_fd); 247 } 248 249 bool 250 SBLaunchInfo::AddOpenFileAction (int fd, const char *path, bool read, bool write) 251 { 252 return m_opaque_sp->AppendOpenFileAction(fd, path, read, write); 253 } 254 255 bool 256 SBLaunchInfo::AddSuppressFileAction (int fd, bool read, bool write) 257 { 258 return m_opaque_sp->AppendSuppressFileAction(fd, read, write); 259 } 260 261 262 SBAttachInfo::SBAttachInfo () : 263 m_opaque_sp (new ProcessAttachInfo()) 264 { 265 } 266 267 SBAttachInfo::SBAttachInfo (lldb::pid_t pid) : 268 m_opaque_sp (new ProcessAttachInfo()) 269 { 270 m_opaque_sp->SetProcessID (pid); 271 } 272 273 SBAttachInfo::SBAttachInfo (const char *path, bool wait_for) : 274 m_opaque_sp (new ProcessAttachInfo()) 275 { 276 if (path && path[0]) 277 m_opaque_sp->GetExecutableFile().SetFile(path, false); 278 m_opaque_sp->SetWaitForLaunch (wait_for); 279 } 280 281 SBAttachInfo::SBAttachInfo (const SBAttachInfo &rhs) : 282 m_opaque_sp (new ProcessAttachInfo()) 283 { 284 *m_opaque_sp = *rhs.m_opaque_sp; 285 } 286 287 SBAttachInfo::~SBAttachInfo() 288 { 289 } 290 291 lldb_private::ProcessAttachInfo & 292 SBAttachInfo::ref () 293 { 294 return *m_opaque_sp; 295 } 296 297 SBAttachInfo & 298 SBAttachInfo::operator = (const SBAttachInfo &rhs) 299 { 300 if (this != &rhs) 301 *m_opaque_sp = *rhs.m_opaque_sp; 302 return *this; 303 } 304 305 lldb::pid_t 306 SBAttachInfo::GetProcessID () 307 { 308 return m_opaque_sp->GetProcessID(); 309 } 310 311 void 312 SBAttachInfo::SetProcessID (lldb::pid_t pid) 313 { 314 m_opaque_sp->SetProcessID (pid); 315 } 316 317 318 uint32_t 319 SBAttachInfo::GetResumeCount () 320 { 321 return m_opaque_sp->GetResumeCount(); 322 } 323 324 void 325 SBAttachInfo::SetResumeCount (uint32_t c) 326 { 327 m_opaque_sp->SetResumeCount (c); 328 } 329 330 const char * 331 SBAttachInfo::GetProcessPluginName () 332 { 333 return m_opaque_sp->GetProcessPluginName(); 334 } 335 336 void 337 SBAttachInfo::SetProcessPluginName (const char *plugin_name) 338 { 339 return m_opaque_sp->SetProcessPluginName (plugin_name); 340 } 341 342 void 343 SBAttachInfo::SetExecutable (const char *path) 344 { 345 if (path && path[0]) 346 m_opaque_sp->GetExecutableFile().SetFile(path, false); 347 else 348 m_opaque_sp->GetExecutableFile().Clear(); 349 } 350 351 void 352 SBAttachInfo::SetExecutable (SBFileSpec exe_file) 353 { 354 if (exe_file.IsValid()) 355 m_opaque_sp->GetExecutableFile() = exe_file.ref(); 356 else 357 m_opaque_sp->GetExecutableFile().Clear(); 358 } 359 360 bool 361 SBAttachInfo::GetWaitForLaunch () 362 { 363 return m_opaque_sp->GetWaitForLaunch(); 364 } 365 366 void 367 SBAttachInfo::SetWaitForLaunch (bool b) 368 { 369 m_opaque_sp->SetWaitForLaunch (b); 370 } 371 372 uint32_t 373 SBAttachInfo::GetUserID() 374 { 375 return m_opaque_sp->GetUserID(); 376 } 377 378 uint32_t 379 SBAttachInfo::GetGroupID() 380 { 381 return m_opaque_sp->GetGroupID(); 382 } 383 384 bool 385 SBAttachInfo::UserIDIsValid () 386 { 387 return m_opaque_sp->UserIDIsValid(); 388 } 389 390 bool 391 SBAttachInfo::GroupIDIsValid () 392 { 393 return m_opaque_sp->GroupIDIsValid(); 394 } 395 396 void 397 SBAttachInfo::SetUserID (uint32_t uid) 398 { 399 m_opaque_sp->SetUserID (uid); 400 } 401 402 void 403 SBAttachInfo::SetGroupID (uint32_t gid) 404 { 405 m_opaque_sp->SetGroupID (gid); 406 } 407 408 uint32_t 409 SBAttachInfo::GetEffectiveUserID() 410 { 411 return m_opaque_sp->GetEffectiveUserID(); 412 } 413 414 uint32_t 415 SBAttachInfo::GetEffectiveGroupID() 416 { 417 return m_opaque_sp->GetEffectiveGroupID(); 418 } 419 420 bool 421 SBAttachInfo::EffectiveUserIDIsValid () 422 { 423 return m_opaque_sp->EffectiveUserIDIsValid(); 424 } 425 426 bool 427 SBAttachInfo::EffectiveGroupIDIsValid () 428 { 429 return m_opaque_sp->EffectiveGroupIDIsValid (); 430 } 431 432 void 433 SBAttachInfo::SetEffectiveUserID (uint32_t uid) 434 { 435 m_opaque_sp->SetEffectiveUserID(uid); 436 } 437 438 void 439 SBAttachInfo::SetEffectiveGroupID (uint32_t gid) 440 { 441 m_opaque_sp->SetEffectiveGroupID(gid); 442 } 443 444 lldb::pid_t 445 SBAttachInfo::GetParentProcessID () 446 { 447 return m_opaque_sp->GetParentProcessID(); 448 } 449 450 void 451 SBAttachInfo::SetParentProcessID (lldb::pid_t pid) 452 { 453 m_opaque_sp->SetParentProcessID (pid); 454 } 455 456 bool 457 SBAttachInfo::ParentProcessIDIsValid() 458 { 459 return m_opaque_sp->ParentProcessIDIsValid(); 460 } 461 462 463 //---------------------------------------------------------------------- 464 // SBTarget constructor 465 //---------------------------------------------------------------------- 466 SBTarget::SBTarget () : 467 m_opaque_sp () 468 { 469 } 470 471 SBTarget::SBTarget (const SBTarget& rhs) : 472 m_opaque_sp (rhs.m_opaque_sp) 473 { 474 } 475 476 SBTarget::SBTarget(const TargetSP& target_sp) : 477 m_opaque_sp (target_sp) 478 { 479 } 480 481 const SBTarget& 482 SBTarget::operator = (const SBTarget& rhs) 483 { 484 if (this != &rhs) 485 m_opaque_sp = rhs.m_opaque_sp; 486 return *this; 487 } 488 489 //---------------------------------------------------------------------- 490 // Destructor 491 //---------------------------------------------------------------------- 492 SBTarget::~SBTarget() 493 { 494 } 495 496 const char * 497 SBTarget::GetBroadcasterClassName () 498 { 499 return Target::GetStaticBroadcasterClass().AsCString(); 500 } 501 502 bool 503 SBTarget::IsValid () const 504 { 505 return m_opaque_sp.get() != NULL && m_opaque_sp->IsValid(); 506 } 507 508 SBProcess 509 SBTarget::GetProcess () 510 { 511 SBProcess sb_process; 512 ProcessSP process_sp; 513 TargetSP target_sp(GetSP()); 514 if (target_sp) 515 { 516 process_sp = target_sp->GetProcessSP(); 517 sb_process.SetSP (process_sp); 518 } 519 520 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 521 if (log) 522 { 523 log->Printf ("SBTarget(%p)::GetProcess () => SBProcess(%p)", 524 target_sp.get(), process_sp.get()); 525 } 526 527 return sb_process; 528 } 529 530 SBDebugger 531 SBTarget::GetDebugger () const 532 { 533 SBDebugger debugger; 534 TargetSP target_sp(GetSP()); 535 if (target_sp) 536 debugger.reset (target_sp->GetDebugger().shared_from_this()); 537 return debugger; 538 } 539 540 SBProcess 541 SBTarget::LaunchSimple 542 ( 543 char const **argv, 544 char const **envp, 545 const char *working_directory 546 ) 547 { 548 char *stdin_path = NULL; 549 char *stdout_path = NULL; 550 char *stderr_path = NULL; 551 uint32_t launch_flags = 0; 552 bool stop_at_entry = false; 553 SBError error; 554 SBListener listener = GetDebugger().GetListener(); 555 return Launch (listener, 556 argv, 557 envp, 558 stdin_path, 559 stdout_path, 560 stderr_path, 561 working_directory, 562 launch_flags, 563 stop_at_entry, 564 error); 565 } 566 567 SBProcess 568 SBTarget::Launch 569 ( 570 SBListener &listener, 571 char const **argv, 572 char const **envp, 573 const char *stdin_path, 574 const char *stdout_path, 575 const char *stderr_path, 576 const char *working_directory, 577 uint32_t launch_flags, // See LaunchFlags 578 bool stop_at_entry, 579 lldb::SBError& error 580 ) 581 { 582 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 583 584 SBProcess sb_process; 585 ProcessSP process_sp; 586 TargetSP target_sp(GetSP()); 587 588 if (log) 589 { 590 log->Printf ("SBTarget(%p)::Launch (argv=%p, envp=%p, stdin=%s, stdout=%s, stderr=%s, working-dir=%s, launch_flags=0x%x, stop_at_entry=%i, &error (%p))...", 591 target_sp.get(), 592 argv, 593 envp, 594 stdin_path ? stdin_path : "NULL", 595 stdout_path ? stdout_path : "NULL", 596 stderr_path ? stderr_path : "NULL", 597 working_directory ? working_directory : "NULL", 598 launch_flags, 599 stop_at_entry, 600 error.get()); 601 } 602 603 if (target_sp) 604 { 605 Mutex::Locker api_locker (target_sp->GetAPIMutex()); 606 607 if (getenv("LLDB_LAUNCH_FLAG_DISABLE_ASLR")) 608 launch_flags |= eLaunchFlagDisableASLR; 609 610 StateType state = eStateInvalid; 611 process_sp = target_sp->GetProcessSP(); 612 if (process_sp) 613 { 614 state = process_sp->GetState(); 615 616 if (process_sp->IsAlive() && state != eStateConnected) 617 { 618 if (state == eStateAttaching) 619 error.SetErrorString ("process attach is in progress"); 620 else 621 error.SetErrorString ("a process is already being debugged"); 622 return sb_process; 623 } 624 } 625 626 if (state == eStateConnected) 627 { 628 // If we are already connected, then we have already specified the 629 // listener, so if a valid listener is supplied, we need to error out 630 // to let the client know. 631 if (listener.IsValid()) 632 { 633 error.SetErrorString ("process is connected and already has a listener, pass empty listener"); 634 return sb_process; 635 } 636 } 637 else 638 { 639 if (listener.IsValid()) 640 process_sp = target_sp->CreateProcess (listener.ref(), NULL, NULL); 641 else 642 process_sp = target_sp->CreateProcess (target_sp->GetDebugger().GetListener(), NULL, NULL); 643 } 644 645 if (process_sp) 646 { 647 sb_process.SetSP (process_sp); 648 if (getenv("LLDB_LAUNCH_FLAG_DISABLE_STDIO")) 649 launch_flags |= eLaunchFlagDisableSTDIO; 650 651 ProcessLaunchInfo launch_info (stdin_path, stdout_path, stderr_path, working_directory, launch_flags); 652 653 Module *exe_module = target_sp->GetExecutableModulePointer(); 654 if (exe_module) 655 launch_info.SetExecutableFile(exe_module->GetPlatformFileSpec(), true); 656 if (argv) 657 launch_info.GetArguments().AppendArguments (argv); 658 if (envp) 659 launch_info.GetEnvironmentEntries ().SetArguments (envp); 660 661 error.SetError (process_sp->Launch (launch_info)); 662 if (error.Success()) 663 { 664 // We we are stopping at the entry point, we can return now! 665 if (stop_at_entry) 666 return sb_process; 667 668 // Make sure we are stopped at the entry 669 StateType state = process_sp->WaitForProcessToStop (NULL); 670 if (state == eStateStopped) 671 { 672 // resume the process to skip the entry point 673 error.SetError (process_sp->Resume()); 674 if (error.Success()) 675 { 676 // If we are doing synchronous mode, then wait for the 677 // process to stop yet again! 678 if (target_sp->GetDebugger().GetAsyncExecution () == false) 679 process_sp->WaitForProcessToStop (NULL); 680 } 681 } 682 } 683 } 684 else 685 { 686 error.SetErrorString ("unable to create lldb_private::Process"); 687 } 688 } 689 else 690 { 691 error.SetErrorString ("SBTarget is invalid"); 692 } 693 694 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API); 695 if (log) 696 { 697 log->Printf ("SBTarget(%p)::Launch (...) => SBProceess(%p)", 698 target_sp.get(), process_sp.get()); 699 } 700 701 return sb_process; 702 } 703 704 SBProcess 705 SBTarget::Launch (SBLaunchInfo &sb_launch_info, SBError& error) 706 { 707 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 708 709 SBProcess sb_process; 710 ProcessSP process_sp; 711 TargetSP target_sp(GetSP()); 712 713 if (log) 714 { 715 log->Printf ("SBTarget(%p)::Launch (launch_info, error)...", target_sp.get()); 716 } 717 718 if (target_sp) 719 { 720 Mutex::Locker api_locker (target_sp->GetAPIMutex()); 721 StateType state = eStateInvalid; 722 process_sp = target_sp->GetProcessSP(); 723 if (process_sp) 724 { 725 state = process_sp->GetState(); 726 727 if (process_sp->IsAlive() && state != eStateConnected) 728 { 729 if (state == eStateAttaching) 730 error.SetErrorString ("process attach is in progress"); 731 else 732 error.SetErrorString ("a process is already being debugged"); 733 return sb_process; 734 } 735 } 736 737 if (state != eStateConnected) 738 process_sp = target_sp->CreateProcess (target_sp->GetDebugger().GetListener(), NULL, NULL); 739 740 if (process_sp) 741 { 742 sb_process.SetSP (process_sp); 743 lldb_private::ProcessLaunchInfo &launch_info = sb_launch_info.ref(); 744 745 Module *exe_module = target_sp->GetExecutableModulePointer(); 746 if (exe_module) 747 launch_info.SetExecutableFile(exe_module->GetPlatformFileSpec(), true); 748 749 const ArchSpec &arch_spec = target_sp->GetArchitecture(); 750 if (arch_spec.IsValid()) 751 launch_info.GetArchitecture () = arch_spec; 752 753 error.SetError (process_sp->Launch (launch_info)); 754 const bool synchronous_execution = target_sp->GetDebugger().GetAsyncExecution () == false; 755 if (error.Success()) 756 { 757 if (launch_info.GetFlags().Test(eLaunchFlagStopAtEntry)) 758 { 759 // If we are doing synchronous mode, then wait for the initial 760 // stop to happen, else, return and let the caller watch for 761 // the stop 762 if (synchronous_execution) 763 process_sp->WaitForProcessToStop (NULL); 764 // We we are stopping at the entry point, we can return now! 765 return sb_process; 766 } 767 768 // Make sure we are stopped at the entry 769 StateType state = process_sp->WaitForProcessToStop (NULL); 770 if (state == eStateStopped) 771 { 772 // resume the process to skip the entry point 773 error.SetError (process_sp->Resume()); 774 if (error.Success()) 775 { 776 // If we are doing synchronous mode, then wait for the 777 // process to stop yet again! 778 if (synchronous_execution) 779 process_sp->WaitForProcessToStop (NULL); 780 } 781 } 782 } 783 } 784 else 785 { 786 error.SetErrorString ("unable to create lldb_private::Process"); 787 } 788 } 789 else 790 { 791 error.SetErrorString ("SBTarget is invalid"); 792 } 793 794 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API); 795 if (log) 796 { 797 log->Printf ("SBTarget(%p)::Launch (...) => SBProceess(%p)", 798 target_sp.get(), process_sp.get()); 799 } 800 801 return sb_process; 802 } 803 804 lldb::SBProcess 805 SBTarget::Attach (SBAttachInfo &sb_attach_info, SBError& error) 806 { 807 SBProcess sb_process; 808 ProcessSP process_sp; 809 TargetSP target_sp(GetSP()); 810 if (target_sp) 811 { 812 Mutex::Locker api_locker (target_sp->GetAPIMutex()); 813 814 StateType state = eStateInvalid; 815 process_sp = target_sp->GetProcessSP(); 816 if (process_sp) 817 { 818 state = process_sp->GetState(); 819 820 if (process_sp->IsAlive() && state != eStateConnected) 821 { 822 if (state == eStateAttaching) 823 error.SetErrorString ("process attach is in progress"); 824 else 825 error.SetErrorString ("a process is already being debugged"); 826 return sb_process; 827 } 828 } 829 830 if (state != eStateConnected) 831 process_sp = target_sp->CreateProcess (target_sp->GetDebugger().GetListener(), NULL, NULL); 832 833 if (process_sp) 834 { 835 ProcessAttachInfo &attach_info = sb_attach_info.ref(); 836 lldb::pid_t attach_pid = attach_info.GetProcessID(); 837 if (attach_pid != LLDB_INVALID_PROCESS_ID) 838 { 839 PlatformSP platform_sp = target_sp->GetPlatform(); 840 ProcessInstanceInfo instance_info; 841 if (platform_sp->GetProcessInfo(attach_pid, instance_info)) 842 { 843 attach_info.SetUserID(instance_info.GetEffectiveUserID()); 844 } 845 } 846 error.SetError (process_sp->Attach (attach_info)); 847 if (error.Success()) 848 { 849 sb_process.SetSP (process_sp); 850 // If we are doing synchronous mode, then wait for the 851 // process to stop! 852 if (target_sp->GetDebugger().GetAsyncExecution () == false) 853 process_sp->WaitForProcessToStop (NULL); 854 } 855 } 856 else 857 { 858 error.SetErrorString ("unable to create lldb_private::Process"); 859 } 860 } 861 else 862 { 863 error.SetErrorString ("SBTarget is invalid"); 864 } 865 return sb_process; 866 } 867 868 869 #if defined(__APPLE__) 870 871 lldb::SBProcess 872 SBTarget::AttachToProcessWithID (SBListener &listener, 873 ::pid_t pid, 874 lldb::SBError& error) 875 { 876 return AttachToProcessWithID (listener, (lldb::pid_t)pid, error); 877 } 878 879 #endif // #if defined(__APPLE__) 880 881 lldb::SBProcess 882 SBTarget::AttachToProcessWithID 883 ( 884 SBListener &listener, 885 lldb::pid_t pid,// The process ID to attach to 886 SBError& error // An error explaining what went wrong if attach fails 887 ) 888 { 889 SBProcess sb_process; 890 ProcessSP process_sp; 891 TargetSP target_sp(GetSP()); 892 if (target_sp) 893 { 894 Mutex::Locker api_locker (target_sp->GetAPIMutex()); 895 896 StateType state = eStateInvalid; 897 process_sp = target_sp->GetProcessSP(); 898 if (process_sp) 899 { 900 state = process_sp->GetState(); 901 902 if (process_sp->IsAlive() && state != eStateConnected) 903 { 904 if (state == eStateAttaching) 905 error.SetErrorString ("process attach is in progress"); 906 else 907 error.SetErrorString ("a process is already being debugged"); 908 return sb_process; 909 } 910 } 911 912 if (state == eStateConnected) 913 { 914 // If we are already connected, then we have already specified the 915 // listener, so if a valid listener is supplied, we need to error out 916 // to let the client know. 917 if (listener.IsValid()) 918 { 919 error.SetErrorString ("process is connected and already has a listener, pass empty listener"); 920 return sb_process; 921 } 922 } 923 else 924 { 925 if (listener.IsValid()) 926 process_sp = target_sp->CreateProcess (listener.ref(), NULL, NULL); 927 else 928 process_sp = target_sp->CreateProcess (target_sp->GetDebugger().GetListener(), NULL, NULL); 929 } 930 if (process_sp) 931 { 932 sb_process.SetSP (process_sp); 933 934 ProcessAttachInfo attach_info; 935 attach_info.SetProcessID (pid); 936 937 PlatformSP platform_sp = target_sp->GetPlatform(); 938 ProcessInstanceInfo instance_info; 939 if (platform_sp->GetProcessInfo(pid, instance_info)) 940 { 941 attach_info.SetUserID(instance_info.GetEffectiveUserID()); 942 } 943 error.SetError (process_sp->Attach (attach_info)); 944 // If we are doing synchronous mode, then wait for the 945 // process to stop! 946 if (target_sp->GetDebugger().GetAsyncExecution () == false) 947 process_sp->WaitForProcessToStop (NULL); 948 } 949 else 950 { 951 error.SetErrorString ("unable to create lldb_private::Process"); 952 } 953 } 954 else 955 { 956 error.SetErrorString ("SBTarget is invalid"); 957 } 958 return sb_process; 959 960 } 961 962 lldb::SBProcess 963 SBTarget::AttachToProcessWithName 964 ( 965 SBListener &listener, 966 const char *name, // basename of process to attach to 967 bool wait_for, // if true wait for a new instance of "name" to be launched 968 SBError& error // An error explaining what went wrong if attach fails 969 ) 970 { 971 SBProcess sb_process; 972 ProcessSP process_sp; 973 TargetSP target_sp(GetSP()); 974 if (name && target_sp) 975 { 976 Mutex::Locker api_locker (target_sp->GetAPIMutex()); 977 978 StateType state = eStateInvalid; 979 process_sp = target_sp->GetProcessSP(); 980 if (process_sp) 981 { 982 state = process_sp->GetState(); 983 984 if (process_sp->IsAlive() && state != eStateConnected) 985 { 986 if (state == eStateAttaching) 987 error.SetErrorString ("process attach is in progress"); 988 else 989 error.SetErrorString ("a process is already being debugged"); 990 return sb_process; 991 } 992 } 993 994 if (state == eStateConnected) 995 { 996 // If we are already connected, then we have already specified the 997 // listener, so if a valid listener is supplied, we need to error out 998 // to let the client know. 999 if (listener.IsValid()) 1000 { 1001 error.SetErrorString ("process is connected and already has a listener, pass empty listener"); 1002 return sb_process; 1003 } 1004 } 1005 else 1006 { 1007 if (listener.IsValid()) 1008 process_sp = target_sp->CreateProcess (listener.ref(), NULL, NULL); 1009 else 1010 process_sp = target_sp->CreateProcess (target_sp->GetDebugger().GetListener(), NULL, NULL); 1011 } 1012 1013 if (process_sp) 1014 { 1015 sb_process.SetSP (process_sp); 1016 ProcessAttachInfo attach_info; 1017 attach_info.GetExecutableFile().SetFile(name, false); 1018 attach_info.SetWaitForLaunch(wait_for); 1019 error.SetError (process_sp->Attach (attach_info)); 1020 // If we are doing synchronous mode, then wait for the 1021 // process to stop! 1022 if (target_sp->GetDebugger().GetAsyncExecution () == false) 1023 process_sp->WaitForProcessToStop (NULL); 1024 } 1025 else 1026 { 1027 error.SetErrorString ("unable to create lldb_private::Process"); 1028 } 1029 } 1030 else 1031 { 1032 error.SetErrorString ("SBTarget is invalid"); 1033 } 1034 return sb_process; 1035 1036 } 1037 1038 lldb::SBProcess 1039 SBTarget::ConnectRemote 1040 ( 1041 SBListener &listener, 1042 const char *url, 1043 const char *plugin_name, 1044 SBError& error 1045 ) 1046 { 1047 SBProcess sb_process; 1048 ProcessSP process_sp; 1049 TargetSP target_sp(GetSP()); 1050 if (target_sp) 1051 { 1052 Mutex::Locker api_locker (target_sp->GetAPIMutex()); 1053 if (listener.IsValid()) 1054 process_sp = target_sp->CreateProcess (listener.ref(), plugin_name, NULL); 1055 else 1056 process_sp = target_sp->CreateProcess (target_sp->GetDebugger().GetListener(), plugin_name, NULL); 1057 1058 1059 if (process_sp) 1060 { 1061 sb_process.SetSP (process_sp); 1062 error.SetError (process_sp->ConnectRemote (url)); 1063 } 1064 else 1065 { 1066 error.SetErrorString ("unable to create lldb_private::Process"); 1067 } 1068 } 1069 else 1070 { 1071 error.SetErrorString ("SBTarget is invalid"); 1072 } 1073 return sb_process; 1074 } 1075 1076 SBFileSpec 1077 SBTarget::GetExecutable () 1078 { 1079 1080 SBFileSpec exe_file_spec; 1081 TargetSP target_sp(GetSP()); 1082 if (target_sp) 1083 { 1084 Module *exe_module = target_sp->GetExecutableModulePointer(); 1085 if (exe_module) 1086 exe_file_spec.SetFileSpec (exe_module->GetFileSpec()); 1087 } 1088 1089 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1090 if (log) 1091 { 1092 log->Printf ("SBTarget(%p)::GetExecutable () => SBFileSpec(%p)", 1093 target_sp.get(), exe_file_spec.get()); 1094 } 1095 1096 return exe_file_spec; 1097 } 1098 1099 bool 1100 SBTarget::operator == (const SBTarget &rhs) const 1101 { 1102 return m_opaque_sp.get() == rhs.m_opaque_sp.get(); 1103 } 1104 1105 bool 1106 SBTarget::operator != (const SBTarget &rhs) const 1107 { 1108 return m_opaque_sp.get() != rhs.m_opaque_sp.get(); 1109 } 1110 1111 lldb::TargetSP 1112 SBTarget::GetSP () const 1113 { 1114 return m_opaque_sp; 1115 } 1116 1117 void 1118 SBTarget::SetSP (const lldb::TargetSP& target_sp) 1119 { 1120 m_opaque_sp = target_sp; 1121 } 1122 1123 lldb::SBAddress 1124 SBTarget::ResolveLoadAddress (lldb::addr_t vm_addr) 1125 { 1126 lldb::SBAddress sb_addr; 1127 Address &addr = sb_addr.ref(); 1128 TargetSP target_sp(GetSP()); 1129 if (target_sp) 1130 { 1131 Mutex::Locker api_locker (target_sp->GetAPIMutex()); 1132 if (target_sp->GetSectionLoadList().ResolveLoadAddress (vm_addr, addr)) 1133 return sb_addr; 1134 } 1135 1136 // We have a load address that isn't in a section, just return an address 1137 // with the offset filled in (the address) and the section set to NULL 1138 addr.SetRawAddress(vm_addr); 1139 return sb_addr; 1140 } 1141 1142 SBSymbolContext 1143 SBTarget::ResolveSymbolContextForAddress (const SBAddress& addr, uint32_t resolve_scope) 1144 { 1145 SBSymbolContext sc; 1146 if (addr.IsValid()) 1147 { 1148 TargetSP target_sp(GetSP()); 1149 if (target_sp) 1150 target_sp->GetImages().ResolveSymbolContextForAddress (addr.ref(), resolve_scope, sc.ref()); 1151 } 1152 return sc; 1153 } 1154 1155 1156 SBBreakpoint 1157 SBTarget::BreakpointCreateByLocation (const char *file, uint32_t line) 1158 { 1159 return SBBreakpoint(BreakpointCreateByLocation (SBFileSpec (file, false), line)); 1160 } 1161 1162 SBBreakpoint 1163 SBTarget::BreakpointCreateByLocation (const SBFileSpec &sb_file_spec, uint32_t line) 1164 { 1165 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1166 1167 SBBreakpoint sb_bp; 1168 TargetSP target_sp(GetSP()); 1169 if (target_sp && line != 0) 1170 { 1171 Mutex::Locker api_locker (target_sp->GetAPIMutex()); 1172 1173 const bool check_inlines = true; 1174 const bool internal = false; 1175 const LazyBool skip_prologue = eLazyBoolCalculate; 1176 *sb_bp = target_sp->CreateBreakpoint (NULL, *sb_file_spec, line, check_inlines, skip_prologue, internal); 1177 } 1178 1179 if (log) 1180 { 1181 SBStream sstr; 1182 sb_bp.GetDescription (sstr); 1183 char path[PATH_MAX]; 1184 sb_file_spec->GetPath (path, sizeof(path)); 1185 log->Printf ("SBTarget(%p)::BreakpointCreateByLocation ( %s:%u ) => SBBreakpoint(%p): %s", 1186 target_sp.get(), 1187 path, 1188 line, 1189 sb_bp.get(), 1190 sstr.GetData()); 1191 } 1192 1193 return sb_bp; 1194 } 1195 1196 SBBreakpoint 1197 SBTarget::BreakpointCreateByName (const char *symbol_name, const char *module_name) 1198 { 1199 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1200 1201 SBBreakpoint sb_bp; 1202 TargetSP target_sp(GetSP()); 1203 if (target_sp.get()) 1204 { 1205 Mutex::Locker api_locker (target_sp->GetAPIMutex()); 1206 1207 const bool internal = false; 1208 const LazyBool skip_prologue = eLazyBoolCalculate; 1209 if (module_name && module_name[0]) 1210 { 1211 FileSpecList module_spec_list; 1212 module_spec_list.Append (FileSpec (module_name, false)); 1213 *sb_bp = target_sp->CreateBreakpoint (&module_spec_list, NULL, symbol_name, eFunctionNameTypeAuto, skip_prologue, internal); 1214 } 1215 else 1216 { 1217 *sb_bp = target_sp->CreateBreakpoint (NULL, NULL, symbol_name, eFunctionNameTypeAuto, skip_prologue, internal); 1218 } 1219 } 1220 1221 if (log) 1222 { 1223 log->Printf ("SBTarget(%p)::BreakpointCreateByName (symbol=\"%s\", module=\"%s\") => SBBreakpoint(%p)", 1224 target_sp.get(), symbol_name, module_name, sb_bp.get()); 1225 } 1226 1227 return sb_bp; 1228 } 1229 1230 lldb::SBBreakpoint 1231 SBTarget::BreakpointCreateByName (const char *symbol_name, 1232 const SBFileSpecList &module_list, 1233 const SBFileSpecList &comp_unit_list) 1234 { 1235 uint32_t name_type_mask = eFunctionNameTypeAuto; 1236 return BreakpointCreateByName (symbol_name, name_type_mask, module_list, comp_unit_list); 1237 } 1238 1239 lldb::SBBreakpoint 1240 SBTarget::BreakpointCreateByName (const char *symbol_name, 1241 uint32_t name_type_mask, 1242 const SBFileSpecList &module_list, 1243 const SBFileSpecList &comp_unit_list) 1244 { 1245 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1246 1247 SBBreakpoint sb_bp; 1248 TargetSP target_sp(GetSP()); 1249 if (target_sp && symbol_name && symbol_name[0]) 1250 { 1251 const bool internal = false; 1252 const LazyBool skip_prologue = eLazyBoolCalculate; 1253 Mutex::Locker api_locker (target_sp->GetAPIMutex()); 1254 *sb_bp = target_sp->CreateBreakpoint (module_list.get(), 1255 comp_unit_list.get(), 1256 symbol_name, 1257 name_type_mask, 1258 skip_prologue, 1259 internal); 1260 } 1261 1262 if (log) 1263 { 1264 log->Printf ("SBTarget(%p)::BreakpointCreateByName (symbol=\"%s\", name_type: %d) => SBBreakpoint(%p)", 1265 target_sp.get(), symbol_name, name_type_mask, sb_bp.get()); 1266 } 1267 1268 return sb_bp; 1269 } 1270 1271 lldb::SBBreakpoint 1272 SBTarget::BreakpointCreateByNames (const char *symbol_names[], 1273 uint32_t num_names, 1274 uint32_t name_type_mask, 1275 const SBFileSpecList &module_list, 1276 const SBFileSpecList &comp_unit_list) 1277 { 1278 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1279 1280 SBBreakpoint sb_bp; 1281 TargetSP target_sp(GetSP()); 1282 if (target_sp && num_names > 0) 1283 { 1284 Mutex::Locker api_locker (target_sp->GetAPIMutex()); 1285 const bool internal = false; 1286 const LazyBool skip_prologue = eLazyBoolCalculate; 1287 *sb_bp = target_sp->CreateBreakpoint (module_list.get(), 1288 comp_unit_list.get(), 1289 symbol_names, 1290 num_names, 1291 name_type_mask, 1292 skip_prologue, 1293 internal); 1294 } 1295 1296 if (log) 1297 { 1298 log->Printf ("SBTarget(%p)::BreakpointCreateByName (symbols={", target_sp.get()); 1299 for (uint32_t i = 0 ; i < num_names; i++) 1300 { 1301 char sep; 1302 if (i < num_names - 1) 1303 sep = ','; 1304 else 1305 sep = '}'; 1306 if (symbol_names[i] != NULL) 1307 log->Printf ("\"%s\"%c ", symbol_names[i], sep); 1308 else 1309 log->Printf ("\"<NULL>\"%c ", sep); 1310 1311 } 1312 log->Printf ("name_type: %d) => SBBreakpoint(%p)", name_type_mask, sb_bp.get()); 1313 } 1314 1315 return sb_bp; 1316 } 1317 1318 SBBreakpoint 1319 SBTarget::BreakpointCreateByRegex (const char *symbol_name_regex, const char *module_name) 1320 { 1321 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1322 1323 SBBreakpoint sb_bp; 1324 TargetSP target_sp(GetSP()); 1325 if (target_sp && symbol_name_regex && symbol_name_regex[0]) 1326 { 1327 Mutex::Locker api_locker (target_sp->GetAPIMutex()); 1328 RegularExpression regexp(symbol_name_regex); 1329 const bool internal = false; 1330 const LazyBool skip_prologue = eLazyBoolCalculate; 1331 1332 if (module_name && module_name[0]) 1333 { 1334 FileSpecList module_spec_list; 1335 module_spec_list.Append (FileSpec (module_name, false)); 1336 1337 *sb_bp = target_sp->CreateFuncRegexBreakpoint (&module_spec_list, NULL, regexp, skip_prologue, internal); 1338 } 1339 else 1340 { 1341 *sb_bp = target_sp->CreateFuncRegexBreakpoint (NULL, NULL, regexp, skip_prologue, internal); 1342 } 1343 } 1344 1345 if (log) 1346 { 1347 log->Printf ("SBTarget(%p)::BreakpointCreateByRegex (symbol_regex=\"%s\", module_name=\"%s\") => SBBreakpoint(%p)", 1348 target_sp.get(), symbol_name_regex, module_name, sb_bp.get()); 1349 } 1350 1351 return sb_bp; 1352 } 1353 1354 lldb::SBBreakpoint 1355 SBTarget::BreakpointCreateByRegex (const char *symbol_name_regex, 1356 const SBFileSpecList &module_list, 1357 const SBFileSpecList &comp_unit_list) 1358 { 1359 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1360 1361 SBBreakpoint sb_bp; 1362 TargetSP target_sp(GetSP()); 1363 if (target_sp && symbol_name_regex && symbol_name_regex[0]) 1364 { 1365 Mutex::Locker api_locker (target_sp->GetAPIMutex()); 1366 RegularExpression regexp(symbol_name_regex); 1367 const bool internal = false; 1368 const LazyBool skip_prologue = eLazyBoolCalculate; 1369 1370 *sb_bp = target_sp->CreateFuncRegexBreakpoint (module_list.get(), comp_unit_list.get(), regexp, skip_prologue, internal); 1371 } 1372 1373 if (log) 1374 { 1375 log->Printf ("SBTarget(%p)::BreakpointCreateByRegex (symbol_regex=\"%s\") => SBBreakpoint(%p)", 1376 target_sp.get(), symbol_name_regex, sb_bp.get()); 1377 } 1378 1379 return sb_bp; 1380 } 1381 1382 SBBreakpoint 1383 SBTarget::BreakpointCreateByAddress (addr_t address) 1384 { 1385 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1386 1387 SBBreakpoint sb_bp; 1388 TargetSP target_sp(GetSP()); 1389 if (target_sp) 1390 { 1391 Mutex::Locker api_locker (target_sp->GetAPIMutex()); 1392 *sb_bp = target_sp->CreateBreakpoint (address, false); 1393 } 1394 1395 if (log) 1396 { 1397 log->Printf ("SBTarget(%p)::BreakpointCreateByAddress (address=%llu) => SBBreakpoint(%p)", target_sp.get(), (uint64_t) address, sb_bp.get()); 1398 } 1399 1400 return sb_bp; 1401 } 1402 1403 lldb::SBBreakpoint 1404 SBTarget::BreakpointCreateBySourceRegex (const char *source_regex, const lldb::SBFileSpec &source_file, const char *module_name) 1405 { 1406 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1407 1408 SBBreakpoint sb_bp; 1409 TargetSP target_sp(GetSP()); 1410 if (target_sp && source_regex && source_regex[0]) 1411 { 1412 Mutex::Locker api_locker (target_sp->GetAPIMutex()); 1413 RegularExpression regexp(source_regex); 1414 FileSpecList source_file_spec_list; 1415 source_file_spec_list.Append (source_file.ref()); 1416 1417 if (module_name && module_name[0]) 1418 { 1419 FileSpecList module_spec_list; 1420 module_spec_list.Append (FileSpec (module_name, false)); 1421 1422 *sb_bp = target_sp->CreateSourceRegexBreakpoint (&module_spec_list, &source_file_spec_list, regexp, false); 1423 } 1424 else 1425 { 1426 *sb_bp = target_sp->CreateSourceRegexBreakpoint (NULL, &source_file_spec_list, regexp, false); 1427 } 1428 } 1429 1430 if (log) 1431 { 1432 char path[PATH_MAX]; 1433 source_file->GetPath (path, sizeof(path)); 1434 log->Printf ("SBTarget(%p)::BreakpointCreateByRegex (source_regex=\"%s\", file=\"%s\", module_name=\"%s\") => SBBreakpoint(%p)", 1435 target_sp.get(), source_regex, path, module_name, sb_bp.get()); 1436 } 1437 1438 return sb_bp; 1439 } 1440 1441 lldb::SBBreakpoint 1442 SBTarget::BreakpointCreateBySourceRegex (const char *source_regex, 1443 const SBFileSpecList &module_list, 1444 const lldb::SBFileSpecList &source_file_list) 1445 { 1446 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1447 1448 SBBreakpoint sb_bp; 1449 TargetSP target_sp(GetSP()); 1450 if (target_sp && source_regex && source_regex[0]) 1451 { 1452 Mutex::Locker api_locker (target_sp->GetAPIMutex()); 1453 RegularExpression regexp(source_regex); 1454 *sb_bp = target_sp->CreateSourceRegexBreakpoint (module_list.get(), source_file_list.get(), regexp, false); 1455 } 1456 1457 if (log) 1458 { 1459 log->Printf ("SBTarget(%p)::BreakpointCreateByRegex (source_regex=\"%s\") => SBBreakpoint(%p)", 1460 target_sp.get(), source_regex, sb_bp.get()); 1461 } 1462 1463 return sb_bp; 1464 } 1465 1466 lldb::SBBreakpoint 1467 SBTarget::BreakpointCreateForException (lldb::LanguageType language, 1468 bool catch_bp, 1469 bool throw_bp) 1470 { 1471 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1472 1473 SBBreakpoint sb_bp; 1474 TargetSP target_sp(GetSP()); 1475 if (target_sp) 1476 { 1477 Mutex::Locker api_locker (target_sp->GetAPIMutex()); 1478 *sb_bp = target_sp->CreateExceptionBreakpoint (language, catch_bp, throw_bp); 1479 } 1480 1481 if (log) 1482 { 1483 log->Printf ("SBTarget(%p)::BreakpointCreateByRegex (Language: %s, catch: %s throw: %s) => SBBreakpoint(%p)", 1484 target_sp.get(), 1485 LanguageRuntime::GetNameForLanguageType(language), 1486 catch_bp ? "on" : "off", 1487 throw_bp ? "on" : "off", 1488 sb_bp.get()); 1489 } 1490 1491 return sb_bp; 1492 } 1493 1494 uint32_t 1495 SBTarget::GetNumBreakpoints () const 1496 { 1497 TargetSP target_sp(GetSP()); 1498 if (target_sp) 1499 { 1500 // The breakpoint list is thread safe, no need to lock 1501 return target_sp->GetBreakpointList().GetSize(); 1502 } 1503 return 0; 1504 } 1505 1506 SBBreakpoint 1507 SBTarget::GetBreakpointAtIndex (uint32_t idx) const 1508 { 1509 SBBreakpoint sb_breakpoint; 1510 TargetSP target_sp(GetSP()); 1511 if (target_sp) 1512 { 1513 // The breakpoint list is thread safe, no need to lock 1514 *sb_breakpoint = target_sp->GetBreakpointList().GetBreakpointAtIndex(idx); 1515 } 1516 return sb_breakpoint; 1517 } 1518 1519 bool 1520 SBTarget::BreakpointDelete (break_id_t bp_id) 1521 { 1522 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1523 1524 bool result = false; 1525 TargetSP target_sp(GetSP()); 1526 if (target_sp) 1527 { 1528 Mutex::Locker api_locker (target_sp->GetAPIMutex()); 1529 result = target_sp->RemoveBreakpointByID (bp_id); 1530 } 1531 1532 if (log) 1533 { 1534 log->Printf ("SBTarget(%p)::BreakpointDelete (bp_id=%d) => %i", target_sp.get(), (uint32_t) bp_id, result); 1535 } 1536 1537 return result; 1538 } 1539 1540 SBBreakpoint 1541 SBTarget::FindBreakpointByID (break_id_t bp_id) 1542 { 1543 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1544 1545 SBBreakpoint sb_breakpoint; 1546 TargetSP target_sp(GetSP()); 1547 if (target_sp && bp_id != LLDB_INVALID_BREAK_ID) 1548 { 1549 Mutex::Locker api_locker (target_sp->GetAPIMutex()); 1550 *sb_breakpoint = target_sp->GetBreakpointByID (bp_id); 1551 } 1552 1553 if (log) 1554 { 1555 log->Printf ("SBTarget(%p)::FindBreakpointByID (bp_id=%d) => SBBreakpoint(%p)", 1556 target_sp.get(), (uint32_t) bp_id, sb_breakpoint.get()); 1557 } 1558 1559 return sb_breakpoint; 1560 } 1561 1562 bool 1563 SBTarget::EnableAllBreakpoints () 1564 { 1565 TargetSP target_sp(GetSP()); 1566 if (target_sp) 1567 { 1568 Mutex::Locker api_locker (target_sp->GetAPIMutex()); 1569 target_sp->EnableAllBreakpoints (); 1570 return true; 1571 } 1572 return false; 1573 } 1574 1575 bool 1576 SBTarget::DisableAllBreakpoints () 1577 { 1578 TargetSP target_sp(GetSP()); 1579 if (target_sp) 1580 { 1581 Mutex::Locker api_locker (target_sp->GetAPIMutex()); 1582 target_sp->DisableAllBreakpoints (); 1583 return true; 1584 } 1585 return false; 1586 } 1587 1588 bool 1589 SBTarget::DeleteAllBreakpoints () 1590 { 1591 TargetSP target_sp(GetSP()); 1592 if (target_sp) 1593 { 1594 Mutex::Locker api_locker (target_sp->GetAPIMutex()); 1595 target_sp->RemoveAllBreakpoints (); 1596 return true; 1597 } 1598 return false; 1599 } 1600 1601 uint32_t 1602 SBTarget::GetNumWatchpoints () const 1603 { 1604 TargetSP target_sp(GetSP()); 1605 if (target_sp) 1606 { 1607 // The watchpoint list is thread safe, no need to lock 1608 return target_sp->GetWatchpointList().GetSize(); 1609 } 1610 return 0; 1611 } 1612 1613 SBWatchpoint 1614 SBTarget::GetWatchpointAtIndex (uint32_t idx) const 1615 { 1616 SBWatchpoint sb_watchpoint; 1617 TargetSP target_sp(GetSP()); 1618 if (target_sp) 1619 { 1620 // The watchpoint list is thread safe, no need to lock 1621 sb_watchpoint.SetSP (target_sp->GetWatchpointList().GetByIndex(idx)); 1622 } 1623 return sb_watchpoint; 1624 } 1625 1626 bool 1627 SBTarget::DeleteWatchpoint (watch_id_t wp_id) 1628 { 1629 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1630 1631 bool result = false; 1632 TargetSP target_sp(GetSP()); 1633 if (target_sp) 1634 { 1635 Mutex::Locker api_locker (target_sp->GetAPIMutex()); 1636 Mutex::Locker locker; 1637 target_sp->GetWatchpointList().GetListMutex(locker); 1638 result = target_sp->RemoveWatchpointByID (wp_id); 1639 } 1640 1641 if (log) 1642 { 1643 log->Printf ("SBTarget(%p)::WatchpointDelete (wp_id=%d) => %i", target_sp.get(), (uint32_t) wp_id, result); 1644 } 1645 1646 return result; 1647 } 1648 1649 SBWatchpoint 1650 SBTarget::FindWatchpointByID (lldb::watch_id_t wp_id) 1651 { 1652 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1653 1654 SBWatchpoint sb_watchpoint; 1655 lldb::WatchpointSP watchpoint_sp; 1656 TargetSP target_sp(GetSP()); 1657 if (target_sp && wp_id != LLDB_INVALID_WATCH_ID) 1658 { 1659 Mutex::Locker api_locker (target_sp->GetAPIMutex()); 1660 Mutex::Locker locker; 1661 target_sp->GetWatchpointList().GetListMutex(locker); 1662 watchpoint_sp = target_sp->GetWatchpointList().FindByID(wp_id); 1663 sb_watchpoint.SetSP (watchpoint_sp); 1664 } 1665 1666 if (log) 1667 { 1668 log->Printf ("SBTarget(%p)::FindWatchpointByID (bp_id=%d) => SBWatchpoint(%p)", 1669 target_sp.get(), (uint32_t) wp_id, watchpoint_sp.get()); 1670 } 1671 1672 return sb_watchpoint; 1673 } 1674 1675 lldb::SBWatchpoint 1676 SBTarget::WatchAddress (lldb::addr_t addr, size_t size, bool read, bool write, SBError &error) 1677 { 1678 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1679 1680 SBWatchpoint sb_watchpoint; 1681 lldb::WatchpointSP watchpoint_sp; 1682 TargetSP target_sp(GetSP()); 1683 if (target_sp && (read || write) && addr != LLDB_INVALID_ADDRESS && size > 0) 1684 { 1685 Mutex::Locker api_locker (target_sp->GetAPIMutex()); 1686 uint32_t watch_type = 0; 1687 if (read) 1688 watch_type |= LLDB_WATCH_TYPE_READ; 1689 if (write) 1690 watch_type |= LLDB_WATCH_TYPE_WRITE; 1691 // Target::CreateWatchpoint() is thread safe. 1692 Error cw_error; 1693 watchpoint_sp = target_sp->CreateWatchpoint(addr, size, watch_type, cw_error); 1694 error.SetError(cw_error); 1695 sb_watchpoint.SetSP (watchpoint_sp); 1696 } 1697 1698 if (log) 1699 { 1700 log->Printf ("SBTarget(%p)::WatchAddress (addr=0x%llx, 0x%u) => SBWatchpoint(%p)", 1701 target_sp.get(), addr, (uint32_t) size, watchpoint_sp.get()); 1702 } 1703 1704 return sb_watchpoint; 1705 } 1706 1707 bool 1708 SBTarget::EnableAllWatchpoints () 1709 { 1710 TargetSP target_sp(GetSP()); 1711 if (target_sp) 1712 { 1713 Mutex::Locker api_locker (target_sp->GetAPIMutex()); 1714 Mutex::Locker locker; 1715 target_sp->GetWatchpointList().GetListMutex(locker); 1716 target_sp->EnableAllWatchpoints (); 1717 return true; 1718 } 1719 return false; 1720 } 1721 1722 bool 1723 SBTarget::DisableAllWatchpoints () 1724 { 1725 TargetSP target_sp(GetSP()); 1726 if (target_sp) 1727 { 1728 Mutex::Locker api_locker (target_sp->GetAPIMutex()); 1729 Mutex::Locker locker; 1730 target_sp->GetWatchpointList().GetListMutex(locker); 1731 target_sp->DisableAllWatchpoints (); 1732 return true; 1733 } 1734 return false; 1735 } 1736 1737 bool 1738 SBTarget::DeleteAllWatchpoints () 1739 { 1740 TargetSP target_sp(GetSP()); 1741 if (target_sp) 1742 { 1743 Mutex::Locker api_locker (target_sp->GetAPIMutex()); 1744 Mutex::Locker locker; 1745 target_sp->GetWatchpointList().GetListMutex(locker); 1746 target_sp->RemoveAllWatchpoints (); 1747 return true; 1748 } 1749 return false; 1750 } 1751 1752 1753 lldb::SBModule 1754 SBTarget::AddModule (const char *path, 1755 const char *triple, 1756 const char *uuid_cstr) 1757 { 1758 return AddModule (path, triple, uuid_cstr, NULL); 1759 } 1760 1761 lldb::SBModule 1762 SBTarget::AddModule (const char *path, 1763 const char *triple, 1764 const char *uuid_cstr, 1765 const char *symfile) 1766 { 1767 lldb::SBModule sb_module; 1768 TargetSP target_sp(GetSP()); 1769 if (target_sp) 1770 { 1771 ModuleSpec module_spec; 1772 if (path) 1773 module_spec.GetFileSpec().SetFile(path, false); 1774 1775 if (uuid_cstr) 1776 module_spec.GetUUID().SetfromCString(uuid_cstr); 1777 1778 if (triple) 1779 module_spec.GetArchitecture().SetTriple (triple, target_sp->GetPlatform ().get()); 1780 1781 if (symfile) 1782 module_spec.GetSymbolFileSpec ().SetFile(symfile, false); 1783 1784 sb_module.SetSP(target_sp->GetSharedModule (module_spec)); 1785 } 1786 return sb_module; 1787 } 1788 1789 bool 1790 SBTarget::AddModule (lldb::SBModule &module) 1791 { 1792 TargetSP target_sp(GetSP()); 1793 if (target_sp) 1794 { 1795 target_sp->GetImages().AppendIfNeeded (module.GetSP()); 1796 return true; 1797 } 1798 return false; 1799 } 1800 1801 uint32_t 1802 SBTarget::GetNumModules () const 1803 { 1804 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1805 1806 uint32_t num = 0; 1807 TargetSP target_sp(GetSP()); 1808 if (target_sp) 1809 { 1810 // The module list is thread safe, no need to lock 1811 num = target_sp->GetImages().GetSize(); 1812 } 1813 1814 if (log) 1815 log->Printf ("SBTarget(%p)::GetNumModules () => %d", target_sp.get(), num); 1816 1817 return num; 1818 } 1819 1820 void 1821 SBTarget::Clear () 1822 { 1823 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1824 1825 if (log) 1826 log->Printf ("SBTarget(%p)::Clear ()", m_opaque_sp.get()); 1827 1828 m_opaque_sp.reset(); 1829 } 1830 1831 1832 SBModule 1833 SBTarget::FindModule (const SBFileSpec &sb_file_spec) 1834 { 1835 SBModule sb_module; 1836 TargetSP target_sp(GetSP()); 1837 if (target_sp && sb_file_spec.IsValid()) 1838 { 1839 ModuleSpec module_spec(*sb_file_spec); 1840 // The module list is thread safe, no need to lock 1841 sb_module.SetSP (target_sp->GetImages().FindFirstModule (module_spec)); 1842 } 1843 return sb_module; 1844 } 1845 1846 lldb::ByteOrder 1847 SBTarget::GetByteOrder () 1848 { 1849 TargetSP target_sp(GetSP()); 1850 if (target_sp) 1851 return target_sp->GetArchitecture().GetByteOrder(); 1852 return eByteOrderInvalid; 1853 } 1854 1855 const char * 1856 SBTarget::GetTriple () 1857 { 1858 TargetSP target_sp(GetSP()); 1859 if (target_sp) 1860 { 1861 std::string triple (target_sp->GetArchitecture().GetTriple().str()); 1862 // Unique the string so we don't run into ownership issues since 1863 // the const strings put the string into the string pool once and 1864 // the strings never comes out 1865 ConstString const_triple (triple.c_str()); 1866 return const_triple.GetCString(); 1867 } 1868 return NULL; 1869 } 1870 1871 uint32_t 1872 SBTarget::GetAddressByteSize() 1873 { 1874 TargetSP target_sp(GetSP()); 1875 if (target_sp) 1876 return target_sp->GetArchitecture().GetAddressByteSize(); 1877 return sizeof(void*); 1878 } 1879 1880 1881 SBModule 1882 SBTarget::GetModuleAtIndex (uint32_t idx) 1883 { 1884 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1885 1886 SBModule sb_module; 1887 ModuleSP module_sp; 1888 TargetSP target_sp(GetSP()); 1889 if (target_sp) 1890 { 1891 // The module list is thread safe, no need to lock 1892 module_sp = target_sp->GetImages().GetModuleAtIndex(idx); 1893 sb_module.SetSP (module_sp); 1894 } 1895 1896 if (log) 1897 { 1898 log->Printf ("SBTarget(%p)::GetModuleAtIndex (idx=%d) => SBModule(%p)", 1899 target_sp.get(), idx, module_sp.get()); 1900 } 1901 1902 return sb_module; 1903 } 1904 1905 bool 1906 SBTarget::RemoveModule (lldb::SBModule module) 1907 { 1908 TargetSP target_sp(GetSP()); 1909 if (target_sp) 1910 return target_sp->GetImages().Remove(module.GetSP()); 1911 return false; 1912 } 1913 1914 1915 SBBroadcaster 1916 SBTarget::GetBroadcaster () const 1917 { 1918 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1919 1920 TargetSP target_sp(GetSP()); 1921 SBBroadcaster broadcaster(target_sp.get(), false); 1922 1923 if (log) 1924 log->Printf ("SBTarget(%p)::GetBroadcaster () => SBBroadcaster(%p)", 1925 target_sp.get(), broadcaster.get()); 1926 1927 return broadcaster; 1928 } 1929 1930 bool 1931 SBTarget::GetDescription (SBStream &description, lldb::DescriptionLevel description_level) 1932 { 1933 Stream &strm = description.ref(); 1934 1935 TargetSP target_sp(GetSP()); 1936 if (target_sp) 1937 { 1938 target_sp->Dump (&strm, description_level); 1939 } 1940 else 1941 strm.PutCString ("No value"); 1942 1943 return true; 1944 } 1945 1946 lldb::SBSymbolContextList 1947 SBTarget::FindFunctions (const char *name, uint32_t name_type_mask) 1948 { 1949 lldb::SBSymbolContextList sb_sc_list; 1950 if (name && name[0]) 1951 { 1952 TargetSP target_sp(GetSP()); 1953 if (target_sp) 1954 { 1955 const bool symbols_ok = true; 1956 const bool inlines_ok = true; 1957 const bool append = true; 1958 target_sp->GetImages().FindFunctions (ConstString(name), 1959 name_type_mask, 1960 symbols_ok, 1961 inlines_ok, 1962 append, 1963 *sb_sc_list); 1964 } 1965 } 1966 return sb_sc_list; 1967 } 1968 1969 lldb::SBType 1970 SBTarget::FindFirstType (const char* type) 1971 { 1972 TargetSP target_sp(GetSP()); 1973 if (type && target_sp) 1974 { 1975 size_t count = target_sp->GetImages().GetSize(); 1976 for (size_t idx = 0; idx < count; idx++) 1977 { 1978 SBType found_at_idx = GetModuleAtIndex(idx).FindFirstType(type); 1979 1980 if (found_at_idx.IsValid()) 1981 return found_at_idx; 1982 } 1983 } 1984 return SBType(); 1985 } 1986 1987 lldb::SBTypeList 1988 SBTarget::FindTypes (const char* type) 1989 { 1990 1991 SBTypeList retval; 1992 1993 TargetSP target_sp(GetSP()); 1994 if (type && target_sp) 1995 { 1996 ModuleList& images = target_sp->GetImages(); 1997 ConstString name_const(type); 1998 bool exact_match = false; 1999 SymbolContext sc; 2000 TypeList type_list; 2001 2002 uint32_t num_matches = images.FindTypes (sc, 2003 name_const, 2004 exact_match, 2005 UINT32_MAX, 2006 type_list); 2007 2008 for (size_t idx = 0; idx < num_matches; idx++) 2009 { 2010 TypeSP type_sp (type_list.GetTypeAtIndex(idx)); 2011 if (type_sp) 2012 retval.Append(SBType(type_sp)); 2013 } 2014 } 2015 return retval; 2016 } 2017 2018 SBValueList 2019 SBTarget::FindGlobalVariables (const char *name, uint32_t max_matches) 2020 { 2021 SBValueList sb_value_list; 2022 2023 TargetSP target_sp(GetSP()); 2024 if (name && target_sp) 2025 { 2026 VariableList variable_list; 2027 const bool append = true; 2028 const uint32_t match_count = target_sp->GetImages().FindGlobalVariables (ConstString (name), 2029 append, 2030 max_matches, 2031 variable_list); 2032 2033 if (match_count > 0) 2034 { 2035 ExecutionContextScope *exe_scope = target_sp->GetProcessSP().get(); 2036 if (exe_scope == NULL) 2037 exe_scope = target_sp.get(); 2038 ValueObjectList &value_object_list = sb_value_list.ref(); 2039 for (uint32_t i=0; i<match_count; ++i) 2040 { 2041 lldb::ValueObjectSP valobj_sp (ValueObjectVariable::Create (exe_scope, variable_list.GetVariableAtIndex(i))); 2042 if (valobj_sp) 2043 value_object_list.Append(valobj_sp); 2044 } 2045 } 2046 } 2047 2048 return sb_value_list; 2049 } 2050 2051 SBSourceManager 2052 SBTarget::GetSourceManager() 2053 { 2054 SBSourceManager source_manager (*this); 2055 return source_manager; 2056 } 2057 2058 lldb::SBInstructionList 2059 SBTarget::ReadInstructions (lldb::SBAddress base_addr, uint32_t count) 2060 { 2061 SBInstructionList sb_instructions; 2062 2063 TargetSP target_sp(GetSP()); 2064 if (target_sp) 2065 { 2066 Address *addr_ptr = base_addr.get(); 2067 2068 if (addr_ptr) 2069 { 2070 DataBufferHeap data (target_sp->GetArchitecture().GetMaximumOpcodeByteSize() * count, 0); 2071 bool prefer_file_cache = false; 2072 lldb_private::Error error; 2073 const size_t bytes_read = target_sp->ReadMemory(*addr_ptr, prefer_file_cache, data.GetBytes(), data.GetByteSize(), error); 2074 sb_instructions.SetDisassembler (Disassembler::DisassembleBytes (target_sp->GetArchitecture(), 2075 NULL, 2076 *addr_ptr, 2077 data.GetBytes(), 2078 bytes_read, 2079 count)); 2080 } 2081 } 2082 2083 return sb_instructions; 2084 2085 } 2086 2087 lldb::SBInstructionList 2088 SBTarget::GetInstructions (lldb::SBAddress base_addr, const void *buf, size_t size) 2089 { 2090 SBInstructionList sb_instructions; 2091 2092 TargetSP target_sp(GetSP()); 2093 if (target_sp) 2094 { 2095 Address addr; 2096 2097 if (base_addr.get()) 2098 addr = *base_addr.get(); 2099 2100 sb_instructions.SetDisassembler (Disassembler::DisassembleBytes (target_sp->GetArchitecture(), 2101 NULL, 2102 addr, 2103 buf, 2104 size)); 2105 } 2106 2107 return sb_instructions; 2108 } 2109 2110 lldb::SBInstructionList 2111 SBTarget::GetInstructions (lldb::addr_t base_addr, const void *buf, size_t size) 2112 { 2113 return GetInstructions (ResolveLoadAddress(base_addr), buf, size); 2114 } 2115 2116 SBError 2117 SBTarget::SetSectionLoadAddress (lldb::SBSection section, 2118 lldb::addr_t section_base_addr) 2119 { 2120 SBError sb_error; 2121 TargetSP target_sp(GetSP()); 2122 if (target_sp) 2123 { 2124 if (!section.IsValid()) 2125 { 2126 sb_error.SetErrorStringWithFormat ("invalid section"); 2127 } 2128 else 2129 { 2130 SectionSP section_sp (section.GetSP()); 2131 if (section_sp) 2132 { 2133 if (section_sp->IsThreadSpecific()) 2134 { 2135 sb_error.SetErrorString ("thread specific sections are not yet supported"); 2136 } 2137 else 2138 { 2139 target_sp->GetSectionLoadList().SetSectionLoadAddress (section_sp, section_base_addr); 2140 } 2141 } 2142 } 2143 } 2144 else 2145 { 2146 sb_error.SetErrorString ("invalid target"); 2147 } 2148 return sb_error; 2149 } 2150 2151 SBError 2152 SBTarget::ClearSectionLoadAddress (lldb::SBSection section) 2153 { 2154 SBError sb_error; 2155 2156 TargetSP target_sp(GetSP()); 2157 if (target_sp) 2158 { 2159 if (!section.IsValid()) 2160 { 2161 sb_error.SetErrorStringWithFormat ("invalid section"); 2162 } 2163 else 2164 { 2165 target_sp->GetSectionLoadList().SetSectionUnloaded (section.GetSP()); 2166 } 2167 } 2168 else 2169 { 2170 sb_error.SetErrorStringWithFormat ("invalid target"); 2171 } 2172 return sb_error; 2173 } 2174 2175 SBError 2176 SBTarget::SetModuleLoadAddress (lldb::SBModule module, int64_t slide_offset) 2177 { 2178 SBError sb_error; 2179 2180 TargetSP target_sp(GetSP()); 2181 if (target_sp) 2182 { 2183 ModuleSP module_sp (module.GetSP()); 2184 if (module_sp) 2185 { 2186 bool changed = false; 2187 if (module_sp->SetLoadAddress (*target_sp, slide_offset, changed)) 2188 { 2189 // The load was successful, make sure that at least some sections 2190 // changed before we notify that our module was loaded. 2191 if (changed) 2192 { 2193 ModuleList module_list; 2194 module_list.Append(module_sp); 2195 target_sp->ModulesDidLoad (module_list); 2196 } 2197 } 2198 } 2199 else 2200 { 2201 sb_error.SetErrorStringWithFormat ("invalid module"); 2202 } 2203 2204 } 2205 else 2206 { 2207 sb_error.SetErrorStringWithFormat ("invalid target"); 2208 } 2209 return sb_error; 2210 } 2211 2212 SBError 2213 SBTarget::ClearModuleLoadAddress (lldb::SBModule module) 2214 { 2215 SBError sb_error; 2216 2217 char path[PATH_MAX]; 2218 TargetSP target_sp(GetSP()); 2219 if (target_sp) 2220 { 2221 ModuleSP module_sp (module.GetSP()); 2222 if (module_sp) 2223 { 2224 ObjectFile *objfile = module_sp->GetObjectFile(); 2225 if (objfile) 2226 { 2227 SectionList *section_list = objfile->GetSectionList(); 2228 if (section_list) 2229 { 2230 const size_t num_sections = section_list->GetSize(); 2231 for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) 2232 { 2233 SectionSP section_sp (section_list->GetSectionAtIndex(sect_idx)); 2234 if (section_sp) 2235 target_sp->GetSectionLoadList().SetSectionUnloaded (section_sp); 2236 } 2237 } 2238 else 2239 { 2240 module_sp->GetFileSpec().GetPath (path, sizeof(path)); 2241 sb_error.SetErrorStringWithFormat ("no sections in object file '%s'", path); 2242 } 2243 } 2244 else 2245 { 2246 module_sp->GetFileSpec().GetPath (path, sizeof(path)); 2247 sb_error.SetErrorStringWithFormat ("no object file for module '%s'", path); 2248 } 2249 } 2250 else 2251 { 2252 sb_error.SetErrorStringWithFormat ("invalid module"); 2253 } 2254 } 2255 else 2256 { 2257 sb_error.SetErrorStringWithFormat ("invalid target"); 2258 } 2259 return sb_error; 2260 } 2261 2262 2263