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