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