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/SBFileSpec.h" 15 #include "lldb/API/SBModule.h" 16 #include "lldb/API/SBStream.h" 17 #include "lldb/Breakpoint/BreakpointID.h" 18 #include "lldb/Breakpoint/BreakpointIDList.h" 19 #include "lldb/Breakpoint/BreakpointList.h" 20 #include "lldb/Breakpoint/BreakpointLocation.h" 21 #include "lldb/Core/Address.h" 22 #include "lldb/Core/AddressResolver.h" 23 #include "lldb/Core/AddressResolverName.h" 24 #include "lldb/Interpreter/Args.h" 25 #include "lldb/Core/ArchSpec.h" 26 #include "lldb/Core/Debugger.h" 27 #include "lldb/Core/Disassembler.h" 28 #include "lldb/Host/FileSpec.h" 29 #include "lldb/Core/Log.h" 30 #include "lldb/Core/RegularExpression.h" 31 #include "lldb/Core/SearchFilter.h" 32 #include "lldb/Core/STLUtils.h" 33 #include "lldb/Host/Host.h" 34 #include "lldb/Target/Process.h" 35 #include "lldb/Target/Target.h" 36 #include "lldb/Target/TargetList.h" 37 38 #include "lldb/Interpreter/CommandReturnObject.h" 39 #include "../source/Commands/CommandObjectBreakpoint.h" 40 41 #include "lldb/API/SBDebugger.h" 42 #include "lldb/API/SBProcess.h" 43 #include "lldb/API/SBListener.h" 44 #include "lldb/API/SBBreakpoint.h" 45 46 using namespace lldb; 47 using namespace lldb_private; 48 49 #define DEFAULT_DISASM_BYTE_SIZE 32 50 51 //---------------------------------------------------------------------- 52 // SBTarget constructor 53 //---------------------------------------------------------------------- 54 SBTarget::SBTarget () : 55 m_opaque_sp () 56 { 57 } 58 59 SBTarget::SBTarget (const SBTarget& rhs) : 60 m_opaque_sp (rhs.m_opaque_sp) 61 { 62 } 63 64 SBTarget::SBTarget(const TargetSP& target_sp) : 65 m_opaque_sp (target_sp) 66 { 67 } 68 69 const SBTarget& 70 SBTarget::operator = (const SBTarget& rhs) 71 { 72 if (this != &rhs) 73 m_opaque_sp = rhs.m_opaque_sp; 74 return *this; 75 } 76 77 //---------------------------------------------------------------------- 78 // Destructor 79 //---------------------------------------------------------------------- 80 SBTarget::~SBTarget() 81 { 82 } 83 84 bool 85 SBTarget::IsValid () const 86 { 87 return m_opaque_sp.get() != NULL; 88 } 89 90 SBProcess 91 SBTarget::GetProcess () 92 { 93 94 SBProcess sb_process; 95 if (m_opaque_sp) 96 { 97 Mutex::Locker api_locker (m_opaque_sp->GetAPIMutex()); 98 sb_process.SetProcess (m_opaque_sp->GetProcessSP()); 99 } 100 101 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 102 if (log) 103 { 104 log->Printf ("SBTarget(%p)::GetProcess () => SBProcess(%p)", 105 m_opaque_sp.get(), sb_process.get()); 106 } 107 108 return sb_process; 109 } 110 111 SBDebugger 112 SBTarget::GetDebugger () const 113 { 114 SBDebugger debugger; 115 if (m_opaque_sp) 116 debugger.reset (m_opaque_sp->GetDebugger().GetSP()); 117 return debugger; 118 } 119 120 SBProcess 121 SBTarget::LaunchSimple 122 ( 123 char const **argv, 124 char const **envp, 125 const char *working_directory 126 ) 127 { 128 char *stdin_path = NULL; 129 char *stdout_path = NULL; 130 char *stderr_path = NULL; 131 uint32_t launch_flags = 0; 132 bool stop_at_entry = false; 133 SBError error; 134 SBListener listener = GetDebugger().GetListener(); 135 return Launch (listener, 136 argv, 137 envp, 138 stdin_path, 139 stdout_path, 140 stderr_path, 141 working_directory, 142 launch_flags, 143 stop_at_entry, 144 error); 145 } 146 147 SBProcess 148 SBTarget::Launch 149 ( 150 SBListener &listener, 151 char const **argv, 152 char const **envp, 153 const char *stdin_path, 154 const char *stdout_path, 155 const char *stderr_path, 156 const char *working_directory, 157 uint32_t launch_flags, // See LaunchFlags 158 bool stop_at_entry, 159 lldb::SBError& error 160 ) 161 { 162 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 163 164 if (log) 165 { 166 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))...", 167 m_opaque_sp.get(), 168 argv, 169 envp, 170 stdin_path ? stdin_path : "NULL", 171 stdout_path ? stdout_path : "NULL", 172 stderr_path ? stderr_path : "NULL", 173 working_directory ? working_directory : "NULL", 174 launch_flags, 175 stop_at_entry, 176 error.get()); 177 } 178 SBProcess sb_process; 179 if (m_opaque_sp) 180 { 181 Mutex::Locker api_locker (m_opaque_sp->GetAPIMutex()); 182 183 if (getenv("LLDB_LAUNCH_FLAG_DISABLE_ASLR")) 184 launch_flags |= eLaunchFlagDisableASLR; 185 186 StateType state = eStateInvalid; 187 sb_process.SetProcess (m_opaque_sp->GetProcessSP()); 188 if (sb_process.IsValid()) 189 { 190 state = sb_process->GetState(); 191 192 if (sb_process->IsAlive() && state != eStateConnected) 193 { 194 if (state == eStateAttaching) 195 error.SetErrorString ("process attach is in progress"); 196 else 197 error.SetErrorString ("a process is already being debugged"); 198 sb_process.Clear(); 199 return sb_process; 200 } 201 } 202 203 if (state == eStateConnected) 204 { 205 // If we are already connected, then we have already specified the 206 // listener, so if a valid listener is supplied, we need to error out 207 // to let the client know. 208 if (listener.IsValid()) 209 { 210 error.SetErrorString ("process is connected and already has a listener, pass empty listener"); 211 sb_process.Clear(); 212 return sb_process; 213 } 214 } 215 else 216 { 217 if (listener.IsValid()) 218 sb_process.SetProcess (m_opaque_sp->CreateProcess (listener.ref())); 219 else 220 sb_process.SetProcess (m_opaque_sp->CreateProcess (m_opaque_sp->GetDebugger().GetListener())); 221 } 222 223 if (sb_process.IsValid()) 224 { 225 if (getenv("LLDB_LAUNCH_FLAG_DISABLE_STDIO")) 226 launch_flags |= eLaunchFlagDisableSTDIO; 227 228 error.SetError (sb_process->Launch (argv, envp, launch_flags, stdin_path, stdout_path, stderr_path, working_directory)); 229 if (error.Success()) 230 { 231 // We we are stopping at the entry point, we can return now! 232 if (stop_at_entry) 233 return sb_process; 234 235 // Make sure we are stopped at the entry 236 StateType state = sb_process->WaitForProcessToStop (NULL); 237 if (state == eStateStopped) 238 { 239 // resume the process to skip the entry point 240 error.SetError (sb_process->Resume()); 241 if (error.Success()) 242 { 243 // If we are doing synchronous mode, then wait for the 244 // process to stop yet again! 245 if (m_opaque_sp->GetDebugger().GetAsyncExecution () == false) 246 sb_process->WaitForProcessToStop (NULL); 247 } 248 } 249 } 250 } 251 else 252 { 253 error.SetErrorString ("unable to create lldb_private::Process"); 254 } 255 } 256 else 257 { 258 error.SetErrorString ("SBTarget is invalid"); 259 } 260 261 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API); 262 if (log) 263 { 264 log->Printf ("SBTarget(%p)::Launch (...) => SBProceess(%p)", 265 m_opaque_sp.get(), sb_process.get()); 266 } 267 268 return sb_process; 269 } 270 271 272 lldb::SBProcess 273 SBTarget::AttachToProcessWithID 274 ( 275 SBListener &listener, 276 lldb::pid_t pid,// The process ID to attach to 277 SBError& error // An error explaining what went wrong if attach fails 278 ) 279 { 280 SBProcess sb_process; 281 if (m_opaque_sp) 282 { 283 Mutex::Locker api_locker (m_opaque_sp->GetAPIMutex()); 284 if (listener.IsValid()) 285 sb_process.SetProcess (m_opaque_sp->CreateProcess (listener.ref())); 286 else 287 sb_process.SetProcess (m_opaque_sp->CreateProcess (m_opaque_sp->GetDebugger().GetListener())); 288 289 290 if (sb_process.IsValid()) 291 { 292 error.SetError (sb_process->Attach (pid)); 293 } 294 else 295 { 296 error.SetErrorString ("unable to create lldb_private::Process"); 297 } 298 } 299 else 300 { 301 error.SetErrorString ("SBTarget is invalid"); 302 } 303 return sb_process; 304 305 } 306 307 lldb::SBProcess 308 SBTarget::AttachToProcessWithName 309 ( 310 SBListener &listener, 311 const char *name, // basename of process to attach to 312 bool wait_for, // if true wait for a new instance of "name" to be launched 313 SBError& error // An error explaining what went wrong if attach fails 314 ) 315 { 316 SBProcess sb_process; 317 if (m_opaque_sp) 318 { 319 Mutex::Locker api_locker (m_opaque_sp->GetAPIMutex()); 320 321 if (listener.IsValid()) 322 sb_process.SetProcess (m_opaque_sp->CreateProcess (listener.ref())); 323 else 324 sb_process.SetProcess (m_opaque_sp->CreateProcess (m_opaque_sp->GetDebugger().GetListener())); 325 326 if (sb_process.IsValid()) 327 { 328 error.SetError (sb_process->Attach (name, wait_for)); 329 } 330 else 331 { 332 error.SetErrorString ("unable to create lldb_private::Process"); 333 } 334 } 335 else 336 { 337 error.SetErrorString ("SBTarget is invalid"); 338 } 339 return sb_process; 340 341 } 342 343 lldb::SBProcess 344 SBTarget::ConnectRemote 345 ( 346 SBListener &listener, 347 const char *url, 348 const char *plugin_name, 349 SBError& error 350 ) 351 { 352 SBProcess sb_process; 353 if (m_opaque_sp) 354 { 355 Mutex::Locker api_locker (m_opaque_sp->GetAPIMutex()); 356 if (listener.IsValid()) 357 sb_process.SetProcess (m_opaque_sp->CreateProcess (listener.ref(), plugin_name)); 358 else 359 sb_process.SetProcess (m_opaque_sp->CreateProcess (m_opaque_sp->GetDebugger().GetListener(), plugin_name)); 360 361 362 if (sb_process.IsValid()) 363 { 364 error.SetError (sb_process->ConnectRemote (url)); 365 } 366 else 367 { 368 error.SetErrorString ("unable to create lldb_private::Process"); 369 } 370 } 371 else 372 { 373 error.SetErrorString ("SBTarget is invalid"); 374 } 375 return sb_process; 376 } 377 378 SBFileSpec 379 SBTarget::GetExecutable () 380 { 381 382 SBFileSpec exe_file_spec; 383 if (m_opaque_sp) 384 { 385 ModuleSP exe_module_sp (m_opaque_sp->GetExecutableModule ()); 386 if (exe_module_sp) 387 exe_file_spec.SetFileSpec (exe_module_sp->GetFileSpec()); 388 } 389 390 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 391 if (log) 392 { 393 log->Printf ("SBTarget(%p)::GetExecutable () => SBFileSpec(%p)", 394 m_opaque_sp.get(), exe_file_spec.get()); 395 } 396 397 return exe_file_spec; 398 } 399 400 401 bool 402 SBTarget::DeleteTargetFromList (TargetList *list) 403 { 404 if (m_opaque_sp) 405 return list->DeleteTarget (m_opaque_sp); 406 else 407 return false; 408 } 409 410 bool 411 SBTarget::operator == (const SBTarget &rhs) const 412 { 413 return m_opaque_sp.get() == rhs.m_opaque_sp.get(); 414 } 415 416 bool 417 SBTarget::operator != (const SBTarget &rhs) const 418 { 419 return m_opaque_sp.get() != rhs.m_opaque_sp.get(); 420 } 421 422 lldb_private::Target * 423 SBTarget::operator ->() const 424 { 425 return m_opaque_sp.get(); 426 } 427 428 lldb_private::Target * 429 SBTarget::get() const 430 { 431 return m_opaque_sp.get(); 432 } 433 434 void 435 SBTarget::reset (const lldb::TargetSP& target_sp) 436 { 437 m_opaque_sp = target_sp; 438 } 439 440 bool 441 SBTarget::ResolveLoadAddress (lldb::addr_t vm_addr, 442 lldb::SBAddress& addr) 443 { 444 if (m_opaque_sp) 445 { 446 Mutex::Locker api_locker (m_opaque_sp->GetAPIMutex()); 447 return m_opaque_sp->GetSectionLoadList().ResolveLoadAddress (vm_addr, *addr); 448 } 449 450 addr->Clear(); 451 return false; 452 } 453 454 SBSymbolContext 455 SBTarget::ResolveSymbolContextForAddress (const SBAddress& addr, uint32_t resolve_scope) 456 { 457 SBSymbolContext sc; 458 if (m_opaque_sp) 459 m_opaque_sp->GetImages().ResolveSymbolContextForAddress (*addr, resolve_scope, sc.ref()); 460 return sc; 461 } 462 463 464 SBBreakpoint 465 SBTarget::BreakpointCreateByLocation (const char *file, uint32_t line) 466 { 467 return SBBreakpoint(BreakpointCreateByLocation (SBFileSpec (file, false), line)); 468 } 469 470 SBBreakpoint 471 SBTarget::BreakpointCreateByLocation (const SBFileSpec &sb_file_spec, uint32_t line) 472 { 473 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 474 475 SBBreakpoint sb_bp; 476 if (m_opaque_sp.get() && line != 0) 477 { 478 Mutex::Locker api_locker (m_opaque_sp->GetAPIMutex()); 479 *sb_bp = m_opaque_sp->CreateBreakpoint (NULL, *sb_file_spec, line, true, false); 480 } 481 482 if (log) 483 { 484 SBStream sstr; 485 sb_bp.GetDescription (sstr); 486 char path[PATH_MAX]; 487 sb_file_spec->GetPath (path, sizeof(path)); 488 log->Printf ("SBTarget(%p)::BreakpointCreateByLocation ( %s:%u ) => SBBreakpoint(%p): %s", 489 m_opaque_sp.get(), 490 path, 491 line, 492 sb_bp.get(), 493 sstr.GetData()); 494 } 495 496 return sb_bp; 497 } 498 499 SBBreakpoint 500 SBTarget::BreakpointCreateByName (const char *symbol_name, const char *module_name) 501 { 502 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 503 504 SBBreakpoint sb_bp; 505 if (m_opaque_sp.get() && symbol_name && symbol_name[0]) 506 { 507 Mutex::Locker api_locker (m_opaque_sp->GetAPIMutex()); 508 if (module_name && module_name[0]) 509 { 510 FileSpec module_file_spec(module_name, false); 511 *sb_bp = m_opaque_sp->CreateBreakpoint (&module_file_spec, symbol_name, eFunctionNameTypeFull | eFunctionNameTypeBase, false); 512 } 513 else 514 { 515 *sb_bp = m_opaque_sp->CreateBreakpoint (NULL, symbol_name, eFunctionNameTypeFull | eFunctionNameTypeBase, false); 516 } 517 } 518 519 if (log) 520 { 521 log->Printf ("SBTarget(%p)::BreakpointCreateByName (symbol=\"%s\", module=\"%s\") => SBBreakpoint(%p)", 522 m_opaque_sp.get(), symbol_name, module_name, sb_bp.get()); 523 } 524 525 return sb_bp; 526 } 527 528 SBBreakpoint 529 SBTarget::BreakpointCreateByRegex (const char *symbol_name_regex, const char *module_name) 530 { 531 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 532 533 SBBreakpoint sb_bp; 534 if (m_opaque_sp.get() && symbol_name_regex && symbol_name_regex[0]) 535 { 536 Mutex::Locker api_locker (m_opaque_sp->GetAPIMutex()); 537 RegularExpression regexp(symbol_name_regex); 538 539 if (module_name && module_name[0]) 540 { 541 FileSpec module_file_spec(module_name, false); 542 543 *sb_bp = m_opaque_sp->CreateBreakpoint (&module_file_spec, regexp, false); 544 } 545 else 546 { 547 *sb_bp = m_opaque_sp->CreateBreakpoint (NULL, regexp, false); 548 } 549 } 550 551 if (log) 552 { 553 log->Printf ("SBTarget(%p)::BreakpointCreateByRegex (symbol_regex=\"%s\", module_name=\"%s\") => SBBreakpoint(%p)", 554 m_opaque_sp.get(), symbol_name_regex, module_name, sb_bp.get()); 555 } 556 557 return sb_bp; 558 } 559 560 561 562 SBBreakpoint 563 SBTarget::BreakpointCreateByAddress (addr_t address) 564 { 565 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 566 567 SBBreakpoint sb_bp; 568 if (m_opaque_sp.get()) 569 { 570 Mutex::Locker api_locker (m_opaque_sp->GetAPIMutex()); 571 *sb_bp = m_opaque_sp->CreateBreakpoint (address, false); 572 } 573 574 if (log) 575 { 576 log->Printf ("SBTarget(%p)::BreakpointCreateByAddress (%p, address=%p) => SBBreakpoint(%p)", m_opaque_sp.get(), address, sb_bp.get()); 577 } 578 579 return sb_bp; 580 } 581 582 SBBreakpoint 583 SBTarget::FindBreakpointByID (break_id_t bp_id) 584 { 585 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 586 587 SBBreakpoint sb_breakpoint; 588 if (m_opaque_sp && bp_id != LLDB_INVALID_BREAK_ID) 589 { 590 Mutex::Locker api_locker (m_opaque_sp->GetAPIMutex()); 591 *sb_breakpoint = m_opaque_sp->GetBreakpointByID (bp_id); 592 } 593 594 if (log) 595 { 596 log->Printf ("SBTarget(%p)::FindBreakpointByID (bp_id=%d) => SBBreakpoint(%p)", 597 m_opaque_sp.get(), (uint32_t) bp_id, sb_breakpoint.get()); 598 } 599 600 return sb_breakpoint; 601 } 602 603 uint32_t 604 SBTarget::GetNumBreakpoints () const 605 { 606 if (m_opaque_sp) 607 { 608 // The breakpoint list is thread safe, no need to lock 609 return m_opaque_sp->GetBreakpointList().GetSize(); 610 } 611 return 0; 612 } 613 614 SBBreakpoint 615 SBTarget::GetBreakpointAtIndex (uint32_t idx) const 616 { 617 SBBreakpoint sb_breakpoint; 618 if (m_opaque_sp) 619 { 620 // The breakpoint list is thread safe, no need to lock 621 *sb_breakpoint = m_opaque_sp->GetBreakpointList().GetBreakpointAtIndex(idx); 622 } 623 return sb_breakpoint; 624 } 625 626 bool 627 SBTarget::BreakpointDelete (break_id_t bp_id) 628 { 629 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 630 631 bool result = false; 632 if (m_opaque_sp) 633 { 634 Mutex::Locker api_locker (m_opaque_sp->GetAPIMutex()); 635 result = m_opaque_sp->RemoveBreakpointByID (bp_id); 636 } 637 638 if (log) 639 { 640 log->Printf ("SBTarget(%p)::BreakpointDelete (bp_id=%d) => %i", m_opaque_sp.get(), (uint32_t) bp_id, result); 641 } 642 643 return result; 644 } 645 646 bool 647 SBTarget::EnableAllBreakpoints () 648 { 649 if (m_opaque_sp) 650 { 651 Mutex::Locker api_locker (m_opaque_sp->GetAPIMutex()); 652 m_opaque_sp->EnableAllBreakpoints (); 653 return true; 654 } 655 return false; 656 } 657 658 bool 659 SBTarget::DisableAllBreakpoints () 660 { 661 if (m_opaque_sp) 662 { 663 Mutex::Locker api_locker (m_opaque_sp->GetAPIMutex()); 664 m_opaque_sp->DisableAllBreakpoints (); 665 return true; 666 } 667 return false; 668 } 669 670 bool 671 SBTarget::DeleteAllBreakpoints () 672 { 673 if (m_opaque_sp) 674 { 675 Mutex::Locker api_locker (m_opaque_sp->GetAPIMutex()); 676 m_opaque_sp->RemoveAllBreakpoints (); 677 return true; 678 } 679 return false; 680 } 681 682 683 uint32_t 684 SBTarget::GetNumModules () const 685 { 686 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 687 688 uint32_t num = 0; 689 if (m_opaque_sp) 690 { 691 // The module list is thread safe, no need to lock 692 num = m_opaque_sp->GetImages().GetSize(); 693 } 694 695 if (log) 696 log->Printf ("SBTarget(%p)::GetNumModules () => %d", m_opaque_sp.get(), num); 697 698 return num; 699 } 700 701 void 702 SBTarget::Clear () 703 { 704 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 705 706 if (log) 707 log->Printf ("SBTarget(%p)::Clear ()", m_opaque_sp.get()); 708 709 m_opaque_sp.reset(); 710 } 711 712 713 SBModule 714 SBTarget::FindModule (const SBFileSpec &sb_file_spec) 715 { 716 SBModule sb_module; 717 if (m_opaque_sp && sb_file_spec.IsValid()) 718 { 719 // The module list is thread safe, no need to lock 720 sb_module.SetModule (m_opaque_sp->GetImages().FindFirstModuleForFileSpec (*sb_file_spec, NULL, NULL)); 721 } 722 return sb_module; 723 } 724 725 SBModule 726 SBTarget::GetModuleAtIndex (uint32_t idx) 727 { 728 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 729 730 SBModule sb_module; 731 if (m_opaque_sp) 732 { 733 // The module list is thread safe, no need to lock 734 sb_module.SetModule(m_opaque_sp->GetImages().GetModuleAtIndex(idx)); 735 } 736 737 if (log) 738 { 739 log->Printf ("SBTarget(%p)::GetModuleAtIndex (idx=%d) => SBModule(%p)", 740 m_opaque_sp.get(), idx, sb_module.get()); 741 } 742 743 return sb_module; 744 } 745 746 747 SBBroadcaster 748 SBTarget::GetBroadcaster () const 749 { 750 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 751 752 SBBroadcaster broadcaster(m_opaque_sp.get(), false); 753 754 if (log) 755 log->Printf ("SBTarget(%p)::GetBroadcaster () => SBBroadcaster(%p)", 756 m_opaque_sp.get(), broadcaster.get()); 757 758 return broadcaster; 759 } 760 761 762 bool 763 SBTarget::GetDescription (SBStream &description, lldb::DescriptionLevel description_level) 764 { 765 if (m_opaque_sp) 766 { 767 description.ref(); 768 m_opaque_sp->Dump (description.get(), description_level); 769 } 770 else 771 description.Printf ("No value"); 772 773 return true; 774 } 775 776 bool 777 SBTarget::GetDescription (SBStream &description, lldb::DescriptionLevel description_level) const 778 { 779 if (m_opaque_sp) 780 { 781 description.ref(); 782 m_opaque_sp->Dump (description.get(), description_level); 783 } 784 else 785 description.Printf ("No value"); 786 787 return true; 788 } 789