1 //===-- SBThread.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/SBThread.h" 11 12 #include "lldb/API/SBSymbolContext.h" 13 #include "lldb/API/SBFileSpec.h" 14 #include "lldb/API/SBStream.h" 15 #include "lldb/Breakpoint/BreakpointLocation.h" 16 #include "lldb/Core/Debugger.h" 17 #include "lldb/Core/Stream.h" 18 #include "lldb/Core/StreamFile.h" 19 #include "lldb/Interpreter/CommandInterpreter.h" 20 #include "lldb/Target/Thread.h" 21 #include "lldb/Target/Process.h" 22 #include "lldb/Symbol/SymbolContext.h" 23 #include "lldb/Symbol/CompileUnit.h" 24 #include "lldb/Target/StopInfo.h" 25 #include "lldb/Target/Target.h" 26 #include "lldb/Target/ThreadPlan.h" 27 #include "lldb/Target/ThreadPlanStepInstruction.h" 28 #include "lldb/Target/ThreadPlanStepOut.h" 29 #include "lldb/Target/ThreadPlanStepRange.h" 30 #include "lldb/Target/ThreadPlanStepInRange.h" 31 32 33 #include "lldb/API/SBAddress.h" 34 #include "lldb/API/SBDebugger.h" 35 #include "lldb/API/SBFrame.h" 36 #include "lldb/API/SBProcess.h" 37 #include "lldb/API/SBValue.h" 38 39 using namespace lldb; 40 using namespace lldb_private; 41 42 //---------------------------------------------------------------------- 43 // Constructors 44 //---------------------------------------------------------------------- 45 SBThread::SBThread () : 46 m_opaque_wp () 47 { 48 } 49 50 SBThread::SBThread (const ThreadSP& lldb_object_sp) : 51 m_opaque_wp (lldb_object_sp) 52 { 53 } 54 55 SBThread::SBThread (const SBThread &rhs) : 56 m_opaque_wp (rhs.m_opaque_wp) 57 { 58 } 59 60 //---------------------------------------------------------------------- 61 // Assignment operator 62 //---------------------------------------------------------------------- 63 64 const lldb::SBThread & 65 SBThread::operator = (const SBThread &rhs) 66 { 67 if (this != &rhs) 68 m_opaque_wp = rhs.m_opaque_wp; 69 return *this; 70 } 71 72 //---------------------------------------------------------------------- 73 // Destructor 74 //---------------------------------------------------------------------- 75 SBThread::~SBThread() 76 { 77 } 78 79 bool 80 SBThread::IsValid() const 81 { 82 return !m_opaque_wp.expired(); 83 } 84 85 void 86 SBThread::Clear () 87 { 88 m_opaque_wp.reset(); 89 } 90 91 92 StopReason 93 SBThread::GetStopReason() 94 { 95 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 96 97 StopReason reason = eStopReasonInvalid; 98 ThreadSP thread_sp(m_opaque_wp.lock()); 99 if (thread_sp) 100 { 101 Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex()); 102 StopInfoSP stop_info_sp = thread_sp->GetStopInfo (); 103 if (stop_info_sp) 104 reason = stop_info_sp->GetStopReason(); 105 } 106 107 if (log) 108 log->Printf ("SBThread(%p)::GetStopReason () => %s", thread_sp.get(), 109 Thread::StopReasonAsCString (reason)); 110 111 return reason; 112 } 113 114 size_t 115 SBThread::GetStopReasonDataCount () 116 { 117 ThreadSP thread_sp(m_opaque_wp.lock()); 118 if (thread_sp) 119 { 120 Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex()); 121 StopInfoSP stop_info_sp = thread_sp->GetStopInfo (); 122 if (stop_info_sp) 123 { 124 StopReason reason = stop_info_sp->GetStopReason(); 125 switch (reason) 126 { 127 case eStopReasonInvalid: 128 case eStopReasonNone: 129 case eStopReasonTrace: 130 case eStopReasonPlanComplete: 131 // There is no data for these stop reasons. 132 return 0; 133 134 case eStopReasonBreakpoint: 135 { 136 break_id_t site_id = stop_info_sp->GetValue(); 137 lldb::BreakpointSiteSP bp_site_sp (thread_sp->GetProcess().GetBreakpointSiteList().FindByID (site_id)); 138 if (bp_site_sp) 139 return bp_site_sp->GetNumberOfOwners () * 2; 140 else 141 return 0; // Breakpoint must have cleared itself... 142 } 143 break; 144 145 case eStopReasonWatchpoint: 146 return 1; 147 148 case eStopReasonSignal: 149 return 1; 150 151 case eStopReasonException: 152 return 1; 153 } 154 } 155 } 156 return 0; 157 } 158 159 uint64_t 160 SBThread::GetStopReasonDataAtIndex (uint32_t idx) 161 { 162 ThreadSP thread_sp(m_opaque_wp.lock()); 163 if (thread_sp) 164 { 165 Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex()); 166 StopInfoSP stop_info_sp = thread_sp->GetStopInfo (); 167 if (stop_info_sp) 168 { 169 StopReason reason = stop_info_sp->GetStopReason(); 170 switch (reason) 171 { 172 case eStopReasonInvalid: 173 case eStopReasonNone: 174 case eStopReasonTrace: 175 case eStopReasonPlanComplete: 176 // There is no data for these stop reasons. 177 return 0; 178 179 case eStopReasonBreakpoint: 180 { 181 break_id_t site_id = stop_info_sp->GetValue(); 182 lldb::BreakpointSiteSP bp_site_sp (thread_sp->GetProcess().GetBreakpointSiteList().FindByID (site_id)); 183 if (bp_site_sp) 184 { 185 uint32_t bp_index = idx / 2; 186 BreakpointLocationSP bp_loc_sp (bp_site_sp->GetOwnerAtIndex (bp_index)); 187 if (bp_loc_sp) 188 { 189 if (bp_index & 1) 190 { 191 // Odd idx, return the breakpoint location ID 192 return bp_loc_sp->GetID(); 193 } 194 else 195 { 196 // Even idx, return the breakpoint ID 197 return bp_loc_sp->GetBreakpoint().GetID(); 198 } 199 } 200 } 201 return LLDB_INVALID_BREAK_ID; 202 } 203 break; 204 205 case eStopReasonWatchpoint: 206 return stop_info_sp->GetValue(); 207 208 case eStopReasonSignal: 209 return stop_info_sp->GetValue(); 210 211 case eStopReasonException: 212 return stop_info_sp->GetValue(); 213 } 214 } 215 } 216 return 0; 217 } 218 219 size_t 220 SBThread::GetStopDescription (char *dst, size_t dst_len) 221 { 222 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 223 224 ThreadSP thread_sp(m_opaque_wp.lock()); 225 if (thread_sp) 226 { 227 Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex()); 228 StopInfoSP stop_info_sp = thread_sp->GetStopInfo (); 229 if (stop_info_sp) 230 { 231 const char *stop_desc = stop_info_sp->GetDescription(); 232 if (stop_desc) 233 { 234 if (log) 235 log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => \"%s\"", 236 thread_sp.get(), stop_desc); 237 if (dst) 238 return ::snprintf (dst, dst_len, "%s", stop_desc); 239 else 240 { 241 // NULL dst passed in, return the length needed to contain the description 242 return ::strlen (stop_desc) + 1; // Include the NULL byte for size 243 } 244 } 245 else 246 { 247 size_t stop_desc_len = 0; 248 switch (stop_info_sp->GetStopReason()) 249 { 250 case eStopReasonTrace: 251 case eStopReasonPlanComplete: 252 { 253 static char trace_desc[] = "step"; 254 stop_desc = trace_desc; 255 stop_desc_len = sizeof(trace_desc); // Include the NULL byte for size 256 } 257 break; 258 259 case eStopReasonBreakpoint: 260 { 261 static char bp_desc[] = "breakpoint hit"; 262 stop_desc = bp_desc; 263 stop_desc_len = sizeof(bp_desc); // Include the NULL byte for size 264 } 265 break; 266 267 case eStopReasonWatchpoint: 268 { 269 static char wp_desc[] = "watchpoint hit"; 270 stop_desc = wp_desc; 271 stop_desc_len = sizeof(wp_desc); // Include the NULL byte for size 272 } 273 break; 274 275 case eStopReasonSignal: 276 { 277 stop_desc = thread_sp->GetProcess().GetUnixSignals ().GetSignalAsCString (stop_info_sp->GetValue()); 278 if (stop_desc == NULL || stop_desc[0] == '\0') 279 { 280 static char signal_desc[] = "signal"; 281 stop_desc = signal_desc; 282 stop_desc_len = sizeof(signal_desc); // Include the NULL byte for size 283 } 284 } 285 break; 286 287 case eStopReasonException: 288 { 289 char exc_desc[] = "exception"; 290 stop_desc = exc_desc; 291 stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size 292 } 293 break; 294 295 default: 296 break; 297 } 298 299 if (stop_desc && stop_desc[0]) 300 { 301 if (log) 302 log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => '%s'", 303 thread_sp.get(), stop_desc); 304 305 if (dst) 306 return ::snprintf (dst, dst_len, "%s", stop_desc) + 1; // Include the NULL byte 307 308 if (stop_desc_len == 0) 309 stop_desc_len = ::strlen (stop_desc) + 1; // Include the NULL byte 310 311 return stop_desc_len; 312 } 313 } 314 } 315 } 316 if (dst) 317 *dst = 0; 318 return 0; 319 } 320 321 SBValue 322 SBThread::GetStopReturnValue () 323 { 324 ValueObjectSP return_valobj_sp; 325 ThreadSP thread_sp(m_opaque_wp.lock()); 326 if (thread_sp) 327 { 328 Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex()); 329 StopInfoSP stop_info_sp = thread_sp->GetStopInfo (); 330 if (stop_info_sp) 331 { 332 return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp); 333 } 334 } 335 336 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 337 if (log) 338 log->Printf ("SBThread(%p)::GetStopReturnValue () => %s", thread_sp.get(), 339 return_valobj_sp.get() 340 ? return_valobj_sp->GetValueAsCString() 341 : "<no return value>"); 342 343 return SBValue (return_valobj_sp); 344 } 345 346 void 347 SBThread::SetThread (const ThreadSP& lldb_object_sp) 348 { 349 m_opaque_wp = lldb_object_sp; 350 } 351 352 353 lldb::tid_t 354 SBThread::GetThreadID () const 355 { 356 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 357 358 lldb::tid_t tid = LLDB_INVALID_THREAD_ID; 359 ThreadSP thread_sp(m_opaque_wp.lock()); 360 if (thread_sp) 361 tid = thread_sp->GetID(); 362 363 if (log) 364 log->Printf ("SBThread(%p)::GetThreadID () => 0x%4.4llx", thread_sp.get(), tid); 365 366 return tid; 367 } 368 369 uint32_t 370 SBThread::GetIndexID () const 371 { 372 ThreadSP thread_sp(m_opaque_wp.lock()); 373 if (thread_sp) 374 return thread_sp->GetIndexID(); 375 return LLDB_INVALID_INDEX32; 376 } 377 const char * 378 SBThread::GetName () const 379 { 380 const char *name = NULL; 381 ThreadSP thread_sp(m_opaque_wp.lock()); 382 if (thread_sp) 383 { 384 Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex()); 385 name = thread_sp->GetName(); 386 } 387 388 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 389 if (log) 390 log->Printf ("SBThread(%p)::GetName () => %s", thread_sp.get(), name ? name : "NULL"); 391 392 return name; 393 } 394 395 const char * 396 SBThread::GetQueueName () const 397 { 398 const char *name = NULL; 399 ThreadSP thread_sp(m_opaque_wp.lock()); 400 if (thread_sp) 401 { 402 Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex()); 403 name = thread_sp->GetQueueName(); 404 } 405 406 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 407 if (log) 408 log->Printf ("SBThread(%p)::GetQueueName () => %s", thread_sp.get(), name ? name : "NULL"); 409 410 return name; 411 } 412 413 414 void 415 SBThread::StepOver (lldb::RunMode stop_other_threads) 416 { 417 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 418 419 ThreadSP thread_sp(m_opaque_wp.lock()); 420 421 if (log) 422 log->Printf ("SBThread(%p)::StepOver (stop_other_threads='%s')", thread_sp.get(), 423 Thread::RunModeAsCString (stop_other_threads)); 424 425 if (thread_sp) 426 { 427 Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex()); 428 bool abort_other_plans = true; 429 StackFrameSP frame_sp(thread_sp->GetStackFrameAtIndex (0)); 430 431 if (frame_sp) 432 { 433 if (frame_sp->HasDebugInformation ()) 434 { 435 SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything)); 436 thread_sp->QueueThreadPlanForStepRange (abort_other_plans, 437 eStepTypeOver, 438 sc.line_entry.range, 439 sc, 440 stop_other_threads, 441 false); 442 443 } 444 else 445 { 446 thread_sp->QueueThreadPlanForStepSingleInstruction (true, 447 abort_other_plans, 448 stop_other_threads); 449 } 450 } 451 452 Process &process = thread_sp->GetProcess(); 453 // Why do we need to set the current thread by ID here??? 454 process.GetThreadList().SetSelectedThreadByID (thread_sp->GetID()); 455 Error error (process.Resume()); 456 if (error.Success()) 457 { 458 // If we are doing synchronous mode, then wait for the 459 // process to stop yet again! 460 if (process.GetTarget().GetDebugger().GetAsyncExecution () == false) 461 process.WaitForProcessToStop (NULL); 462 } 463 } 464 } 465 466 void 467 SBThread::StepInto (lldb::RunMode stop_other_threads) 468 { 469 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 470 471 472 ThreadSP thread_sp(m_opaque_wp.lock()); 473 474 if (log) 475 log->Printf ("SBThread(%p)::StepInto (stop_other_threads='%s')", thread_sp.get(), 476 Thread::RunModeAsCString (stop_other_threads)); 477 if (thread_sp) 478 { 479 Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex()); 480 bool abort_other_plans = true; 481 482 StackFrameSP frame_sp(thread_sp->GetStackFrameAtIndex (0)); 483 484 if (frame_sp && frame_sp->HasDebugInformation ()) 485 { 486 bool avoid_code_without_debug_info = true; 487 SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything)); 488 thread_sp->QueueThreadPlanForStepRange (abort_other_plans, 489 eStepTypeInto, 490 sc.line_entry.range, 491 sc, 492 stop_other_threads, 493 avoid_code_without_debug_info); 494 } 495 else 496 { 497 thread_sp->QueueThreadPlanForStepSingleInstruction (false, 498 abort_other_plans, 499 stop_other_threads); 500 } 501 502 Process &process = thread_sp->GetProcess(); 503 // Why do we need to set the current thread by ID here??? 504 process.GetThreadList().SetSelectedThreadByID (thread_sp->GetID()); 505 Error error (process.Resume()); 506 if (error.Success()) 507 { 508 // If we are doing synchronous mode, then wait for the 509 // process to stop yet again! 510 if (process.GetTarget().GetDebugger().GetAsyncExecution () == false) 511 process.WaitForProcessToStop (NULL); 512 } 513 } 514 } 515 516 void 517 SBThread::StepOut () 518 { 519 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 520 521 ThreadSP thread_sp(m_opaque_wp.lock()); 522 523 if (log) 524 log->Printf ("SBThread(%p)::StepOut ()", thread_sp.get()); 525 526 if (thread_sp) 527 { 528 Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex()); 529 bool abort_other_plans = true; 530 bool stop_other_threads = true; 531 532 thread_sp->QueueThreadPlanForStepOut (abort_other_plans, 533 NULL, 534 false, 535 stop_other_threads, 536 eVoteYes, 537 eVoteNoOpinion, 538 0); 539 540 Process &process = thread_sp->GetProcess(); 541 process.GetThreadList().SetSelectedThreadByID (thread_sp->GetID()); 542 Error error (process.Resume()); 543 if (error.Success()) 544 { 545 // If we are doing synchronous mode, then wait for the 546 // process to stop yet again! 547 if (process.GetTarget().GetDebugger().GetAsyncExecution () == false) 548 process.WaitForProcessToStop (NULL); 549 } 550 } 551 } 552 553 void 554 SBThread::StepOutOfFrame (lldb::SBFrame &sb_frame) 555 { 556 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 557 558 ThreadSP thread_sp(m_opaque_wp.lock()); 559 560 StackFrameSP frame_sp (sb_frame.GetFrameSP()); 561 if (log) 562 { 563 SBStream frame_desc_strm; 564 sb_frame.GetDescription (frame_desc_strm); 565 log->Printf ("SBThread(%p)::StepOutOfFrame (frame = SBFrame(%p): %s)", thread_sp.get(), frame_sp.get(), frame_desc_strm.GetData()); 566 } 567 568 if (thread_sp) 569 { 570 Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex()); 571 bool abort_other_plans = true; 572 bool stop_other_threads = true; 573 574 thread_sp->QueueThreadPlanForStepOut (abort_other_plans, 575 NULL, 576 false, 577 stop_other_threads, 578 eVoteYes, 579 eVoteNoOpinion, 580 frame_sp->GetFrameIndex()); 581 582 Process &process = thread_sp->GetProcess(); 583 process.GetThreadList().SetSelectedThreadByID (thread_sp->GetID()); 584 Error error (process.Resume()); 585 if (error.Success()) 586 { 587 // If we are doing synchronous mode, then wait for the 588 // process to stop yet again! 589 if (process.GetTarget().GetDebugger().GetAsyncExecution () == false) 590 process.WaitForProcessToStop (NULL); 591 } 592 } 593 } 594 595 void 596 SBThread::StepInstruction (bool step_over) 597 { 598 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 599 600 ThreadSP thread_sp(m_opaque_wp.lock()); 601 602 if (log) 603 log->Printf ("SBThread(%p)::StepInstruction (step_over=%i)", thread_sp.get(), step_over); 604 605 if (thread_sp) 606 { 607 Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex()); 608 thread_sp->QueueThreadPlanForStepSingleInstruction (step_over, true, true); 609 Process &process = thread_sp->GetProcess(); 610 process.GetThreadList().SetSelectedThreadByID (thread_sp->GetID()); 611 Error error (process.Resume()); 612 if (error.Success()) 613 { 614 // If we are doing synchronous mode, then wait for the 615 // process to stop yet again! 616 if (process.GetTarget().GetDebugger().GetAsyncExecution () == false) 617 process.WaitForProcessToStop (NULL); 618 } 619 } 620 } 621 622 void 623 SBThread::RunToAddress (lldb::addr_t addr) 624 { 625 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 626 627 ThreadSP thread_sp(m_opaque_wp.lock()); 628 629 if (log) 630 log->Printf ("SBThread(%p)::RunToAddress (addr=0x%llx)", thread_sp.get(), addr); 631 632 if (thread_sp) 633 { 634 bool abort_other_plans = true; 635 bool stop_other_threads = true; 636 637 Address target_addr (NULL, addr); 638 639 thread_sp->QueueThreadPlanForRunToAddress (abort_other_plans, target_addr, stop_other_threads); 640 Process &process = thread_sp->GetProcess(); 641 process.GetThreadList().SetSelectedThreadByID (thread_sp->GetID()); 642 Error error (process.Resume()); 643 if (error.Success()) 644 { 645 // If we are doing synchronous mode, then wait for the 646 // process to stop yet again! 647 if (process.GetTarget().GetDebugger().GetAsyncExecution () == false) 648 process.WaitForProcessToStop (NULL); 649 } 650 } 651 } 652 653 SBError 654 SBThread::StepOverUntil (lldb::SBFrame &sb_frame, 655 lldb::SBFileSpec &sb_file_spec, 656 uint32_t line) 657 { 658 SBError sb_error; 659 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 660 char path[PATH_MAX]; 661 662 ThreadSP thread_sp(m_opaque_wp.lock()); 663 StackFrameSP frame_sp (sb_frame.GetFrameSP()); 664 665 if (log) 666 { 667 SBStream frame_desc_strm; 668 sb_frame.GetDescription (frame_desc_strm); 669 sb_file_spec->GetPath (path, sizeof(path)); 670 log->Printf ("SBThread(%p)::StepOverUntil (frame = SBFrame(%p): %s, file+line = %s:%u)", 671 thread_sp.get(), 672 frame_sp.get(), 673 frame_desc_strm.GetData(), 674 path, line); 675 } 676 677 if (thread_sp) 678 { 679 Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex()); 680 681 if (line == 0) 682 { 683 sb_error.SetErrorString("invalid line argument"); 684 return sb_error; 685 } 686 687 StackFrameSP frame_sp; 688 if (!frame_sp) 689 { 690 frame_sp = thread_sp->GetSelectedFrame (); 691 if (!frame_sp) 692 frame_sp = thread_sp->GetStackFrameAtIndex (0); 693 } 694 695 SymbolContext frame_sc; 696 if (!frame_sp) 697 { 698 sb_error.SetErrorString("no valid frames in thread to step"); 699 return sb_error; 700 } 701 702 // If we have a frame, get its line 703 frame_sc = frame_sp->GetSymbolContext (eSymbolContextCompUnit | 704 eSymbolContextFunction | 705 eSymbolContextLineEntry | 706 eSymbolContextSymbol ); 707 708 if (frame_sc.comp_unit == NULL) 709 { 710 sb_error.SetErrorStringWithFormat("frame %u doesn't have debug information", frame_sp->GetFrameIndex()); 711 return sb_error; 712 } 713 714 FileSpec step_file_spec; 715 if (sb_file_spec.IsValid()) 716 { 717 // The file spec passed in was valid, so use it 718 step_file_spec = sb_file_spec.ref(); 719 } 720 else 721 { 722 if (frame_sc.line_entry.IsValid()) 723 step_file_spec = frame_sc.line_entry.file; 724 else 725 { 726 sb_error.SetErrorString("invalid file argument or no file for frame"); 727 return sb_error; 728 } 729 } 730 731 // Grab the current function, then we will make sure the "until" address is 732 // within the function. We discard addresses that are out of the current 733 // function, and then if there are no addresses remaining, give an appropriate 734 // error message. 735 736 bool all_in_function = true; 737 AddressRange fun_range = frame_sc.function->GetAddressRange(); 738 739 std::vector<addr_t> step_over_until_addrs; 740 const bool abort_other_plans = true; 741 const bool stop_other_threads = true; 742 const bool check_inlines = true; 743 const bool exact = false; 744 Target *target = &thread_sp->GetProcess().GetTarget(); 745 746 SymbolContextList sc_list; 747 const uint32_t num_matches = frame_sc.comp_unit->ResolveSymbolContext (step_file_spec, 748 line, 749 check_inlines, 750 exact, 751 eSymbolContextLineEntry, 752 sc_list); 753 if (num_matches > 0) 754 { 755 SymbolContext sc; 756 for (uint32_t i=0; i<num_matches; ++i) 757 { 758 if (sc_list.GetContextAtIndex(i, sc)) 759 { 760 addr_t step_addr = sc.line_entry.range.GetBaseAddress().GetLoadAddress(target); 761 if (step_addr != LLDB_INVALID_ADDRESS) 762 { 763 if (fun_range.ContainsLoadAddress(step_addr, target)) 764 step_over_until_addrs.push_back(step_addr); 765 else 766 all_in_function = false; 767 } 768 } 769 } 770 } 771 772 if (step_over_until_addrs.empty()) 773 { 774 if (all_in_function) 775 { 776 step_file_spec.GetPath (path, sizeof(path)); 777 sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path, line); 778 } 779 else 780 sb_error.SetErrorString ("step until target not in current function"); 781 } 782 else 783 { 784 thread_sp->QueueThreadPlanForStepUntil (abort_other_plans, 785 &step_over_until_addrs[0], 786 step_over_until_addrs.size(), 787 stop_other_threads, 788 frame_sp->GetFrameIndex()); 789 790 thread_sp->GetProcess().GetThreadList().SetSelectedThreadByID (thread_sp->GetID()); 791 sb_error.ref() = thread_sp->GetProcess().Resume(); 792 if (sb_error->Success()) 793 { 794 // If we are doing synchronous mode, then wait for the 795 // process to stop yet again! 796 if (thread_sp->GetProcess().GetTarget().GetDebugger().GetAsyncExecution () == false) 797 thread_sp->GetProcess().WaitForProcessToStop (NULL); 798 } 799 } 800 } 801 else 802 { 803 sb_error.SetErrorString("this SBThread object is invalid"); 804 } 805 return sb_error; 806 } 807 808 809 bool 810 SBThread::Suspend() 811 { 812 ThreadSP thread_sp(m_opaque_wp.lock()); 813 if (thread_sp) 814 { 815 thread_sp->SetResumeState (eStateSuspended); 816 return true; 817 } 818 return false; 819 } 820 821 bool 822 SBThread::Resume () 823 { 824 ThreadSP thread_sp(m_opaque_wp.lock()); 825 if (thread_sp) 826 { 827 thread_sp->SetResumeState (eStateRunning); 828 return true; 829 } 830 return false; 831 } 832 833 bool 834 SBThread::IsSuspended() 835 { 836 ThreadSP thread_sp(m_opaque_wp.lock()); 837 if (thread_sp) 838 return thread_sp->GetResumeState () == eStateSuspended; 839 return false; 840 } 841 842 SBProcess 843 SBThread::GetProcess () 844 { 845 846 SBProcess sb_process; 847 ProcessSP process_sp; 848 ThreadSP thread_sp(m_opaque_wp.lock()); 849 if (thread_sp) 850 { 851 // Have to go up to the target so we can get a shared pointer to our process... 852 process_sp = thread_sp->GetProcess().GetTarget().GetProcessSP(); 853 sb_process.SetSP (process_sp); 854 } 855 856 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 857 if (log) 858 { 859 SBStream frame_desc_strm; 860 sb_process.GetDescription (frame_desc_strm); 861 log->Printf ("SBThread(%p)::GetProcess () => SBProcess(%p): %s", thread_sp.get(), 862 process_sp.get(), frame_desc_strm.GetData()); 863 } 864 865 return sb_process; 866 } 867 868 uint32_t 869 SBThread::GetNumFrames () 870 { 871 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 872 873 uint32_t num_frames = 0; 874 ThreadSP thread_sp(m_opaque_wp.lock()); 875 if (thread_sp) 876 { 877 Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex()); 878 num_frames = thread_sp->GetStackFrameCount(); 879 } 880 881 if (log) 882 log->Printf ("SBThread(%p)::GetNumFrames () => %u", thread_sp.get(), num_frames); 883 884 return num_frames; 885 } 886 887 SBFrame 888 SBThread::GetFrameAtIndex (uint32_t idx) 889 { 890 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 891 892 SBFrame sb_frame; 893 StackFrameSP frame_sp; 894 ThreadSP thread_sp(m_opaque_wp.lock()); 895 if (thread_sp) 896 { 897 Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex()); 898 frame_sp = thread_sp->GetStackFrameAtIndex (idx); 899 sb_frame.SetFrameSP (frame_sp); 900 } 901 902 if (log) 903 { 904 SBStream frame_desc_strm; 905 sb_frame.GetDescription (frame_desc_strm); 906 log->Printf ("SBThread(%p)::GetFrameAtIndex (idx=%d) => SBFrame(%p): %s", 907 thread_sp.get(), idx, frame_sp.get(), frame_desc_strm.GetData()); 908 } 909 910 return sb_frame; 911 } 912 913 lldb::SBFrame 914 SBThread::GetSelectedFrame () 915 { 916 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 917 918 SBFrame sb_frame; 919 StackFrameSP frame_sp; 920 ThreadSP thread_sp(m_opaque_wp.lock()); 921 if (thread_sp) 922 { 923 Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex()); 924 frame_sp = thread_sp->GetSelectedFrame (); 925 sb_frame.SetFrameSP (frame_sp); 926 } 927 928 if (log) 929 { 930 SBStream frame_desc_strm; 931 sb_frame.GetDescription (frame_desc_strm); 932 log->Printf ("SBThread(%p)::GetSelectedFrame () => SBFrame(%p): %s", 933 thread_sp.get(), frame_sp.get(), frame_desc_strm.GetData()); 934 } 935 936 return sb_frame; 937 } 938 939 lldb::SBFrame 940 SBThread::SetSelectedFrame (uint32_t idx) 941 { 942 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 943 944 SBFrame sb_frame; 945 StackFrameSP frame_sp; 946 ThreadSP thread_sp(m_opaque_wp.lock()); 947 if (thread_sp) 948 { 949 Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex()); 950 frame_sp = thread_sp->GetStackFrameAtIndex (idx); 951 if (frame_sp) 952 { 953 thread_sp->SetSelectedFrame (frame_sp.get()); 954 sb_frame.SetFrameSP (frame_sp); 955 } 956 } 957 958 if (log) 959 { 960 SBStream frame_desc_strm; 961 sb_frame.GetDescription (frame_desc_strm); 962 log->Printf ("SBThread(%p)::SetSelectedFrame (idx=%u) => SBFrame(%p): %s", 963 thread_sp.get(), idx, frame_sp.get(), frame_desc_strm.GetData()); 964 } 965 return sb_frame; 966 } 967 968 969 bool 970 SBThread::operator == (const SBThread &rhs) const 971 { 972 return m_opaque_wp.lock().get() == rhs.m_opaque_wp.lock().get(); 973 } 974 975 bool 976 SBThread::operator != (const SBThread &rhs) const 977 { 978 return m_opaque_wp.lock().get() != rhs.m_opaque_wp.lock().get(); 979 } 980 981 bool 982 SBThread::GetDescription (SBStream &description) const 983 { 984 Stream &strm = description.ref(); 985 986 ThreadSP thread_sp(m_opaque_wp.lock()); 987 if (thread_sp) 988 { 989 strm.Printf("SBThread: tid = 0x%4.4llx", thread_sp->GetID()); 990 } 991 else 992 strm.PutCString ("No value"); 993 994 return true; 995 } 996