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