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