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