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