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