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