1 //===-- Thread.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-private-log.h" 11 #include "lldb/Breakpoint/BreakpointLocation.h" 12 #include "lldb/Core/Debugger.h" 13 #include "lldb/Core/Log.h" 14 #include "lldb/Core/Stream.h" 15 #include "lldb/Core/StreamString.h" 16 #include "lldb/Core/RegularExpression.h" 17 #include "lldb/Host/Host.h" 18 #include "lldb/Target/DynamicLoader.h" 19 #include "lldb/Target/ExecutionContext.h" 20 #include "lldb/Target/ObjCLanguageRuntime.h" 21 #include "lldb/Target/Process.h" 22 #include "lldb/Target/RegisterContext.h" 23 #include "lldb/Target/StopInfo.h" 24 #include "lldb/Target/Target.h" 25 #include "lldb/Target/Thread.h" 26 #include "lldb/Target/ThreadPlan.h" 27 #include "lldb/Target/ThreadPlanCallFunction.h" 28 #include "lldb/Target/ThreadPlanBase.h" 29 #include "lldb/Target/ThreadPlanStepInstruction.h" 30 #include "lldb/Target/ThreadPlanStepOut.h" 31 #include "lldb/Target/ThreadPlanStepOverBreakpoint.h" 32 #include "lldb/Target/ThreadPlanStepThrough.h" 33 #include "lldb/Target/ThreadPlanStepInRange.h" 34 #include "lldb/Target/ThreadPlanStepOverRange.h" 35 #include "lldb/Target/ThreadPlanRunToAddress.h" 36 #include "lldb/Target/ThreadPlanStepUntil.h" 37 #include "lldb/Target/ThreadSpec.h" 38 #include "lldb/Target/Unwind.h" 39 #include "Plugins/Process/Utility/UnwindLLDB.h" 40 #include "UnwindMacOSXFrameBackchain.h" 41 42 43 using namespace lldb; 44 using namespace lldb_private; 45 46 Thread::Thread (const ProcessSP &process_sp, lldb::tid_t tid) : 47 UserID (tid), 48 ThreadInstanceSettings (GetSettingsController()), 49 m_process_wp (process_sp), 50 m_actual_stop_info_sp (), 51 m_index_id (process_sp->GetNextThreadIndexID ()), 52 m_reg_context_sp (), 53 m_state (eStateUnloaded), 54 m_state_mutex (Mutex::eMutexTypeRecursive), 55 m_plan_stack (), 56 m_completed_plan_stack(), 57 m_frame_mutex (Mutex::eMutexTypeRecursive), 58 m_curr_frames_sp (), 59 m_prev_frames_sp (), 60 m_resume_signal (LLDB_INVALID_SIGNAL_NUMBER), 61 m_resume_state (eStateRunning), 62 m_temporary_resume_state (eStateRunning), 63 m_unwinder_ap (), 64 m_destroy_called (false), 65 m_thread_stop_reason_stop_id (0) 66 67 { 68 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT)); 69 if (log) 70 log->Printf ("%p Thread::Thread(tid = 0x%4.4llx)", this, GetID()); 71 72 QueueFundamentalPlan(true); 73 UpdateInstanceName(); 74 } 75 76 77 Thread::~Thread() 78 { 79 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT)); 80 if (log) 81 log->Printf ("%p Thread::~Thread(tid = 0x%4.4llx)", this, GetID()); 82 /// If you hit this assert, it means your derived class forgot to call DoDestroy in its destructor. 83 assert (m_destroy_called); 84 } 85 86 void 87 Thread::DestroyThread () 88 { 89 m_plan_stack.clear(); 90 m_discarded_plan_stack.clear(); 91 m_completed_plan_stack.clear(); 92 m_actual_stop_info_sp.reset(); 93 m_destroy_called = true; 94 } 95 96 lldb::StopInfoSP 97 Thread::GetStopInfo () 98 { 99 ThreadPlanSP plan_sp (GetCompletedPlan()); 100 if (plan_sp && plan_sp->PlanSucceeded()) 101 return StopInfo::CreateStopReasonWithPlan (plan_sp, GetReturnValueObject()); 102 else 103 { 104 ProcessSP process_sp (GetProcess()); 105 if (process_sp 106 && m_actual_stop_info_sp 107 && m_actual_stop_info_sp->IsValid() 108 && m_thread_stop_reason_stop_id == process_sp->GetStopID()) 109 return m_actual_stop_info_sp; 110 else 111 return GetPrivateStopReason (); 112 } 113 } 114 115 void 116 Thread::SetStopInfo (const lldb::StopInfoSP &stop_info_sp) 117 { 118 m_actual_stop_info_sp = stop_info_sp; 119 if (m_actual_stop_info_sp) 120 m_actual_stop_info_sp->MakeStopInfoValid(); 121 ProcessSP process_sp (GetProcess()); 122 if (process_sp) 123 m_thread_stop_reason_stop_id = process_sp->GetStopID(); 124 else 125 m_thread_stop_reason_stop_id = UINT32_MAX; 126 } 127 128 void 129 Thread::SetStopInfoToNothing() 130 { 131 // Note, we can't just NULL out the private reason, or the native thread implementation will try to 132 // go calculate it again. For now, just set it to a Unix Signal with an invalid signal number. 133 SetStopInfo (StopInfo::CreateStopReasonWithSignal (*this, LLDB_INVALID_SIGNAL_NUMBER)); 134 } 135 136 bool 137 Thread::ThreadStoppedForAReason (void) 138 { 139 return (bool) GetPrivateStopReason (); 140 } 141 142 bool 143 Thread::CheckpointThreadState (ThreadStateCheckpoint &saved_state) 144 { 145 if (!SaveFrameZeroState(saved_state.register_backup)) 146 return false; 147 148 saved_state.stop_info_sp = GetStopInfo(); 149 ProcessSP process_sp (GetProcess()); 150 if (process_sp) 151 saved_state.orig_stop_id = process_sp->GetStopID(); 152 return true; 153 } 154 155 bool 156 Thread::RestoreThreadStateFromCheckpoint (ThreadStateCheckpoint &saved_state) 157 { 158 RestoreSaveFrameZero(saved_state.register_backup); 159 if (saved_state.stop_info_sp) 160 saved_state.stop_info_sp->MakeStopInfoValid(); 161 SetStopInfo(saved_state.stop_info_sp); 162 return true; 163 } 164 165 StateType 166 Thread::GetState() const 167 { 168 // If any other threads access this we will need a mutex for it 169 Mutex::Locker locker(m_state_mutex); 170 return m_state; 171 } 172 173 void 174 Thread::SetState(StateType state) 175 { 176 Mutex::Locker locker(m_state_mutex); 177 m_state = state; 178 } 179 180 void 181 Thread::WillStop() 182 { 183 ThreadPlan *current_plan = GetCurrentPlan(); 184 185 // FIXME: I may decide to disallow threads with no plans. In which 186 // case this should go to an assert. 187 188 if (!current_plan) 189 return; 190 191 current_plan->WillStop(); 192 } 193 194 void 195 Thread::SetupForResume () 196 { 197 if (GetResumeState() != eStateSuspended) 198 { 199 200 // If we're at a breakpoint push the step-over breakpoint plan. Do this before 201 // telling the current plan it will resume, since we might change what the current 202 // plan is. 203 204 lldb::addr_t pc = GetRegisterContext()->GetPC(); 205 BreakpointSiteSP bp_site_sp = GetProcess()->GetBreakpointSiteList().FindByAddress(pc); 206 if (bp_site_sp && bp_site_sp->IsEnabled()) 207 { 208 // Note, don't assume there's a ThreadPlanStepOverBreakpoint, the target may not require anything 209 // special to step over a breakpoint. 210 211 ThreadPlan *cur_plan = GetCurrentPlan(); 212 213 if (cur_plan->GetKind() != ThreadPlan::eKindStepOverBreakpoint) 214 { 215 ThreadPlanStepOverBreakpoint *step_bp_plan = new ThreadPlanStepOverBreakpoint (*this); 216 if (step_bp_plan) 217 { 218 ThreadPlanSP step_bp_plan_sp; 219 step_bp_plan->SetPrivate (true); 220 221 if (GetCurrentPlan()->RunState() != eStateStepping) 222 { 223 step_bp_plan->SetAutoContinue(true); 224 } 225 step_bp_plan_sp.reset (step_bp_plan); 226 QueueThreadPlan (step_bp_plan_sp, false); 227 } 228 } 229 } 230 } 231 } 232 233 bool 234 Thread::WillResume (StateType resume_state) 235 { 236 // At this point clear the completed plan stack. 237 m_completed_plan_stack.clear(); 238 m_discarded_plan_stack.clear(); 239 240 SetTemporaryResumeState(resume_state); 241 242 // This is a little dubious, but we are trying to limit how often we actually fetch stop info from 243 // the target, 'cause that slows down single stepping. So assume that if we got to the point where 244 // we're about to resume, and we haven't yet had to fetch the stop reason, then it doesn't need to know 245 // about the fact that we are resuming... 246 const uint32_t process_stop_id = GetProcess()->GetStopID(); 247 if (m_thread_stop_reason_stop_id == process_stop_id && 248 (m_actual_stop_info_sp && m_actual_stop_info_sp->IsValid())) 249 { 250 StopInfo *stop_info = GetPrivateStopReason().get(); 251 if (stop_info) 252 stop_info->WillResume (resume_state); 253 } 254 255 // Tell all the plans that we are about to resume in case they need to clear any state. 256 // We distinguish between the plan on the top of the stack and the lower 257 // plans in case a plan needs to do any special business before it runs. 258 259 ThreadPlan *plan_ptr = GetCurrentPlan(); 260 plan_ptr->WillResume(resume_state, true); 261 262 while ((plan_ptr = GetPreviousPlan(plan_ptr)) != NULL) 263 { 264 plan_ptr->WillResume (resume_state, false); 265 } 266 267 m_actual_stop_info_sp.reset(); 268 return true; 269 } 270 271 void 272 Thread::DidResume () 273 { 274 SetResumeSignal (LLDB_INVALID_SIGNAL_NUMBER); 275 } 276 277 bool 278 Thread::ShouldStop (Event* event_ptr) 279 { 280 ThreadPlan *current_plan = GetCurrentPlan(); 281 bool should_stop = true; 282 283 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 284 285 if (GetResumeState () == eStateSuspended) 286 { 287 if (log) 288 log->Printf ("Thread::%s for tid = 0x%4.4llx, should_stop = 0 (ignore since thread was suspended)", 289 __FUNCTION__, 290 GetID ()); 291 // log->Printf ("Thread::%s for tid = 0x%4.4llx, pc = 0x%16.16llx, should_stop = 0 (ignore since thread was suspended)", 292 // __FUNCTION__, 293 // GetID (), 294 // GetRegisterContext()->GetPC()); 295 return false; 296 } 297 298 if (GetTemporaryResumeState () == eStateSuspended) 299 { 300 if (log) 301 log->Printf ("Thread::%s for tid = 0x%4.4llx, should_stop = 0 (ignore since thread was suspended)", 302 __FUNCTION__, 303 GetID ()); 304 // log->Printf ("Thread::%s for tid = 0x%4.4llx, pc = 0x%16.16llx, should_stop = 0 (ignore since thread was suspended)", 305 // __FUNCTION__, 306 // GetID (), 307 // GetRegisterContext()->GetPC()); 308 return false; 309 } 310 311 if (ThreadStoppedForAReason() == false) 312 { 313 if (log) 314 log->Printf ("Thread::%s for tid = 0x%4.4llx, pc = 0x%16.16llx, should_stop = 0 (ignore since no stop reason)", 315 __FUNCTION__, 316 GetID (), 317 GetRegisterContext()->GetPC()); 318 return false; 319 } 320 321 if (log) 322 { 323 log->Printf ("Thread::%s for tid = 0x%4.4llx, pc = 0x%16.16llx", 324 __FUNCTION__, 325 GetID (), 326 GetRegisterContext()->GetPC()); 327 log->Printf ("^^^^^^^^ Thread::ShouldStop Begin ^^^^^^^^"); 328 StreamString s; 329 s.IndentMore(); 330 DumpThreadPlans(&s); 331 log->Printf ("Plan stack initial state:\n%s", s.GetData()); 332 } 333 334 // The top most plan always gets to do the trace log... 335 current_plan->DoTraceLog (); 336 337 // First query the stop info's ShouldStopSynchronous. This handles "synchronous" stop reasons, for example the breakpoint 338 // command on internal breakpoints. If a synchronous stop reason says we should not stop, then we don't have to 339 // do any more work on this stop. 340 StopInfoSP private_stop_info (GetPrivateStopReason()); 341 if (private_stop_info && private_stop_info->ShouldStopSynchronous(event_ptr) == false) 342 { 343 if (log) 344 log->Printf ("StopInfo::ShouldStop async callback says we should not stop, returning ShouldStop of false."); 345 return false; 346 } 347 348 // If the base plan doesn't understand why we stopped, then we have to find a plan that does. 349 // If that plan is still working, then we don't need to do any more work. If the plan that explains 350 // the stop is done, then we should pop all the plans below it, and pop it, and then let the plans above it decide 351 // whether they still need to do more work. 352 353 bool done_processing_current_plan = false; 354 355 if (!current_plan->PlanExplainsStop()) 356 { 357 if (current_plan->TracerExplainsStop()) 358 { 359 done_processing_current_plan = true; 360 should_stop = false; 361 } 362 else 363 { 364 // If the current plan doesn't explain the stop, then find one that 365 // does and let it handle the situation. 366 ThreadPlan *plan_ptr = current_plan; 367 while ((plan_ptr = GetPreviousPlan(plan_ptr)) != NULL) 368 { 369 if (plan_ptr->PlanExplainsStop()) 370 { 371 should_stop = plan_ptr->ShouldStop (event_ptr); 372 373 // plan_ptr explains the stop, next check whether plan_ptr is done, if so, then we should take it 374 // and all the plans below it off the stack. 375 376 if (plan_ptr->MischiefManaged()) 377 { 378 // We're going to pop the plans up to and including the plan that explains the stop. 379 ThreadPlan *prev_plan_ptr = GetPreviousPlan (plan_ptr); 380 381 do 382 { 383 if (should_stop) 384 current_plan->WillStop(); 385 PopPlan(); 386 } 387 while ((current_plan = GetCurrentPlan()) != prev_plan_ptr); 388 // Now, if the responsible plan was not "Okay to discard" then we're done, 389 // otherwise we forward this to the next plan in the stack below. 390 if (plan_ptr->IsMasterPlan() && !plan_ptr->OkayToDiscard()) 391 done_processing_current_plan = true; 392 else 393 done_processing_current_plan = false; 394 } 395 else 396 done_processing_current_plan = true; 397 398 break; 399 } 400 401 } 402 } 403 } 404 405 if (!done_processing_current_plan) 406 { 407 bool over_ride_stop = current_plan->ShouldAutoContinue(event_ptr); 408 409 if (log) 410 log->Printf("Plan %s explains stop, auto-continue %i.", current_plan->GetName(), over_ride_stop); 411 412 // We're starting from the base plan, so just let it decide; 413 if (PlanIsBasePlan(current_plan)) 414 { 415 should_stop = current_plan->ShouldStop (event_ptr); 416 if (log) 417 log->Printf("Base plan says should stop: %i.", should_stop); 418 } 419 else 420 { 421 // Otherwise, don't let the base plan override what the other plans say to do, since 422 // presumably if there were other plans they would know what to do... 423 while (1) 424 { 425 if (PlanIsBasePlan(current_plan)) 426 break; 427 428 should_stop = current_plan->ShouldStop(event_ptr); 429 if (log) 430 log->Printf("Plan %s should stop: %d.", current_plan->GetName(), should_stop); 431 if (current_plan->MischiefManaged()) 432 { 433 if (should_stop) 434 current_plan->WillStop(); 435 436 // If a Master Plan wants to stop, and wants to stick on the stack, we let it. 437 // Otherwise, see if the plan's parent wants to stop. 438 439 if (should_stop && current_plan->IsMasterPlan() && !current_plan->OkayToDiscard()) 440 { 441 PopPlan(); 442 break; 443 } 444 else 445 { 446 447 PopPlan(); 448 449 current_plan = GetCurrentPlan(); 450 if (current_plan == NULL) 451 { 452 break; 453 } 454 } 455 } 456 else 457 { 458 break; 459 } 460 } 461 } 462 463 if (over_ride_stop) 464 should_stop = false; 465 466 // One other potential problem is that we set up a master plan, then stop in before it is complete - for instance 467 // by hitting a breakpoint during a step-over - then do some step/finish/etc operations that wind up 468 // past the end point condition of the initial plan. We don't want to strand the original plan on the stack, 469 // This code clears stale plans off the stack. 470 471 if (should_stop) 472 { 473 ThreadPlan *plan_ptr = GetCurrentPlan(); 474 while (!PlanIsBasePlan(plan_ptr)) 475 { 476 bool stale = plan_ptr->IsPlanStale (); 477 ThreadPlan *examined_plan = plan_ptr; 478 plan_ptr = GetPreviousPlan (examined_plan); 479 480 if (stale) 481 { 482 if (log) 483 log->Printf("Plan %s being discarded in cleanup, it says it is already done.", examined_plan->GetName()); 484 DiscardThreadPlansUpToPlan(examined_plan); 485 } 486 } 487 } 488 489 } 490 491 if (log) 492 { 493 StreamString s; 494 s.IndentMore(); 495 DumpThreadPlans(&s); 496 log->Printf ("Plan stack final state:\n%s", s.GetData()); 497 log->Printf ("vvvvvvvv Thread::ShouldStop End (returning %i) vvvvvvvv", should_stop); 498 } 499 return should_stop; 500 } 501 502 Vote 503 Thread::ShouldReportStop (Event* event_ptr) 504 { 505 StateType thread_state = GetResumeState (); 506 StateType temp_thread_state = GetTemporaryResumeState(); 507 508 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 509 510 if (thread_state == eStateSuspended || thread_state == eStateInvalid) 511 { 512 if (log) 513 log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4llx: returning vote %i (state was suspended or invalid)\n", GetID(), eVoteNoOpinion); 514 return eVoteNoOpinion; 515 } 516 517 if (temp_thread_state == eStateSuspended || temp_thread_state == eStateInvalid) 518 { 519 if (log) 520 log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4llx: returning vote %i (temporary state was suspended or invalid)\n", GetID(), eVoteNoOpinion); 521 return eVoteNoOpinion; 522 } 523 524 if (!ThreadStoppedForAReason()) 525 { 526 if (log) 527 log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4llx: returning vote %i (thread didn't stop for a reason.)\n", GetID(), eVoteNoOpinion); 528 return eVoteNoOpinion; 529 } 530 531 if (m_completed_plan_stack.size() > 0) 532 { 533 // Don't use GetCompletedPlan here, since that suppresses private plans. 534 if (log) 535 log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4llx: returning vote for complete stack's back plan\n", GetID()); 536 return m_completed_plan_stack.back()->ShouldReportStop (event_ptr); 537 } 538 else 539 { 540 if (log) 541 log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4llx: returning vote for current plan\n", GetID()); 542 return GetCurrentPlan()->ShouldReportStop (event_ptr); 543 } 544 } 545 546 Vote 547 Thread::ShouldReportRun (Event* event_ptr) 548 { 549 StateType thread_state = GetResumeState (); 550 551 if (thread_state == eStateSuspended 552 || thread_state == eStateInvalid) 553 { 554 return eVoteNoOpinion; 555 } 556 557 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 558 if (m_completed_plan_stack.size() > 0) 559 { 560 // Don't use GetCompletedPlan here, since that suppresses private plans. 561 if (log) 562 log->Printf ("Current Plan for thread %d (0x%4.4llx): %s being asked whether we should report run.", 563 GetIndexID(), 564 GetID(), 565 m_completed_plan_stack.back()->GetName()); 566 567 return m_completed_plan_stack.back()->ShouldReportRun (event_ptr); 568 } 569 else 570 { 571 if (log) 572 log->Printf ("Current Plan for thread %d (0x%4.4llx): %s being asked whether we should report run.", 573 GetIndexID(), 574 GetID(), 575 GetCurrentPlan()->GetName()); 576 577 return GetCurrentPlan()->ShouldReportRun (event_ptr); 578 } 579 } 580 581 bool 582 Thread::MatchesSpec (const ThreadSpec *spec) 583 { 584 if (spec == NULL) 585 return true; 586 587 return spec->ThreadPassesBasicTests(*this); 588 } 589 590 void 591 Thread::PushPlan (ThreadPlanSP &thread_plan_sp) 592 { 593 if (thread_plan_sp) 594 { 595 // If the thread plan doesn't already have a tracer, give it its parent's tracer: 596 if (!thread_plan_sp->GetThreadPlanTracer()) 597 thread_plan_sp->SetThreadPlanTracer(m_plan_stack.back()->GetThreadPlanTracer()); 598 m_plan_stack.push_back (thread_plan_sp); 599 600 thread_plan_sp->DidPush(); 601 602 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 603 if (log) 604 { 605 StreamString s; 606 thread_plan_sp->GetDescription (&s, lldb::eDescriptionLevelFull); 607 log->Printf("Pushing plan: \"%s\", tid = 0x%4.4llx.", 608 s.GetData(), 609 thread_plan_sp->GetThread().GetID()); 610 } 611 } 612 } 613 614 void 615 Thread::PopPlan () 616 { 617 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 618 619 if (m_plan_stack.empty()) 620 return; 621 else 622 { 623 ThreadPlanSP &plan = m_plan_stack.back(); 624 if (log) 625 { 626 log->Printf("Popping plan: \"%s\", tid = 0x%4.4llx.", plan->GetName(), plan->GetThread().GetID()); 627 } 628 m_completed_plan_stack.push_back (plan); 629 plan->WillPop(); 630 m_plan_stack.pop_back(); 631 } 632 } 633 634 void 635 Thread::DiscardPlan () 636 { 637 if (m_plan_stack.size() > 1) 638 { 639 ThreadPlanSP &plan = m_plan_stack.back(); 640 m_discarded_plan_stack.push_back (plan); 641 plan->WillPop(); 642 m_plan_stack.pop_back(); 643 } 644 } 645 646 ThreadPlan * 647 Thread::GetCurrentPlan () 648 { 649 // There will always be at least the base plan. If somebody is mucking with a 650 // thread with an empty plan stack, we should assert right away. 651 assert (!m_plan_stack.empty()); 652 653 return m_plan_stack.back().get(); 654 } 655 656 ThreadPlanSP 657 Thread::GetCompletedPlan () 658 { 659 ThreadPlanSP empty_plan_sp; 660 if (!m_completed_plan_stack.empty()) 661 { 662 for (int i = m_completed_plan_stack.size() - 1; i >= 0; i--) 663 { 664 ThreadPlanSP completed_plan_sp; 665 completed_plan_sp = m_completed_plan_stack[i]; 666 if (!completed_plan_sp->GetPrivate ()) 667 return completed_plan_sp; 668 } 669 } 670 return empty_plan_sp; 671 } 672 673 ValueObjectSP 674 Thread::GetReturnValueObject () 675 { 676 if (!m_completed_plan_stack.empty()) 677 { 678 for (int i = m_completed_plan_stack.size() - 1; i >= 0; i--) 679 { 680 ValueObjectSP return_valobj_sp; 681 return_valobj_sp = m_completed_plan_stack[i]->GetReturnValueObject(); 682 if (return_valobj_sp) 683 return return_valobj_sp; 684 } 685 } 686 return ValueObjectSP(); 687 } 688 689 bool 690 Thread::IsThreadPlanDone (ThreadPlan *plan) 691 { 692 if (!m_completed_plan_stack.empty()) 693 { 694 for (int i = m_completed_plan_stack.size() - 1; i >= 0; i--) 695 { 696 if (m_completed_plan_stack[i].get() == plan) 697 return true; 698 } 699 } 700 return false; 701 } 702 703 bool 704 Thread::WasThreadPlanDiscarded (ThreadPlan *plan) 705 { 706 if (!m_discarded_plan_stack.empty()) 707 { 708 for (int i = m_discarded_plan_stack.size() - 1; i >= 0; i--) 709 { 710 if (m_discarded_plan_stack[i].get() == plan) 711 return true; 712 } 713 } 714 return false; 715 } 716 717 ThreadPlan * 718 Thread::GetPreviousPlan (ThreadPlan *current_plan) 719 { 720 if (current_plan == NULL) 721 return NULL; 722 723 int stack_size = m_completed_plan_stack.size(); 724 for (int i = stack_size - 1; i > 0; i--) 725 { 726 if (current_plan == m_completed_plan_stack[i].get()) 727 return m_completed_plan_stack[i-1].get(); 728 } 729 730 if (stack_size > 0 && m_completed_plan_stack[0].get() == current_plan) 731 { 732 if (m_plan_stack.size() > 0) 733 return m_plan_stack.back().get(); 734 else 735 return NULL; 736 } 737 738 stack_size = m_plan_stack.size(); 739 for (int i = stack_size - 1; i > 0; i--) 740 { 741 if (current_plan == m_plan_stack[i].get()) 742 return m_plan_stack[i-1].get(); 743 } 744 return NULL; 745 } 746 747 void 748 Thread::QueueThreadPlan (ThreadPlanSP &thread_plan_sp, bool abort_other_plans) 749 { 750 if (abort_other_plans) 751 DiscardThreadPlans(true); 752 753 PushPlan (thread_plan_sp); 754 } 755 756 757 void 758 Thread::EnableTracer (bool value, bool single_stepping) 759 { 760 int stack_size = m_plan_stack.size(); 761 for (int i = 0; i < stack_size; i++) 762 { 763 if (m_plan_stack[i]->GetThreadPlanTracer()) 764 { 765 m_plan_stack[i]->GetThreadPlanTracer()->EnableTracing(value); 766 m_plan_stack[i]->GetThreadPlanTracer()->EnableSingleStep(single_stepping); 767 } 768 } 769 } 770 771 void 772 Thread::SetTracer (lldb::ThreadPlanTracerSP &tracer_sp) 773 { 774 int stack_size = m_plan_stack.size(); 775 for (int i = 0; i < stack_size; i++) 776 m_plan_stack[i]->SetThreadPlanTracer(tracer_sp); 777 } 778 779 void 780 Thread::DiscardThreadPlansUpToPlan (lldb::ThreadPlanSP &up_to_plan_sp) 781 { 782 DiscardThreadPlansUpToPlan (up_to_plan_sp.get()); 783 } 784 785 void 786 Thread::DiscardThreadPlansUpToPlan (ThreadPlan *up_to_plan_ptr) 787 { 788 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 789 if (log) 790 { 791 log->Printf("Discarding thread plans for thread tid = 0x%4.4llx, up to %p", GetID(), up_to_plan_ptr); 792 } 793 794 int stack_size = m_plan_stack.size(); 795 796 // If the input plan is NULL, discard all plans. Otherwise make sure this plan is in the 797 // stack, and if so discard up to and including it. 798 799 if (up_to_plan_ptr == NULL) 800 { 801 for (int i = stack_size - 1; i > 0; i--) 802 DiscardPlan(); 803 } 804 else 805 { 806 bool found_it = false; 807 for (int i = stack_size - 1; i > 0; i--) 808 { 809 if (m_plan_stack[i].get() == up_to_plan_ptr) 810 found_it = true; 811 } 812 if (found_it) 813 { 814 bool last_one = false; 815 for (int i = stack_size - 1; i > 0 && !last_one ; i--) 816 { 817 if (GetCurrentPlan() == up_to_plan_ptr) 818 last_one = true; 819 DiscardPlan(); 820 } 821 } 822 } 823 return; 824 } 825 826 void 827 Thread::DiscardThreadPlans(bool force) 828 { 829 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 830 if (log) 831 { 832 log->Printf("Discarding thread plans for thread (tid = 0x%4.4llx, force %d)", GetID(), force); 833 } 834 835 if (force) 836 { 837 int stack_size = m_plan_stack.size(); 838 for (int i = stack_size - 1; i > 0; i--) 839 { 840 DiscardPlan(); 841 } 842 return; 843 } 844 845 while (1) 846 { 847 848 int master_plan_idx; 849 bool discard; 850 851 // Find the first master plan, see if it wants discarding, and if yes discard up to it. 852 for (master_plan_idx = m_plan_stack.size() - 1; master_plan_idx >= 0; master_plan_idx--) 853 { 854 if (m_plan_stack[master_plan_idx]->IsMasterPlan()) 855 { 856 discard = m_plan_stack[master_plan_idx]->OkayToDiscard(); 857 break; 858 } 859 } 860 861 if (discard) 862 { 863 // First pop all the dependent plans: 864 for (int i = m_plan_stack.size() - 1; i > master_plan_idx; i--) 865 { 866 867 // FIXME: Do we need a finalize here, or is the rule that "PrepareForStop" 868 // for the plan leaves it in a state that it is safe to pop the plan 869 // with no more notice? 870 DiscardPlan(); 871 } 872 873 // Now discard the master plan itself. 874 // The bottom-most plan never gets discarded. "OkayToDiscard" for it means 875 // discard it's dependent plans, but not it... 876 if (master_plan_idx > 0) 877 { 878 DiscardPlan(); 879 } 880 } 881 else 882 { 883 // If the master plan doesn't want to get discarded, then we're done. 884 break; 885 } 886 887 } 888 } 889 890 bool 891 Thread::PlanIsBasePlan (ThreadPlan *plan_ptr) 892 { 893 if (plan_ptr->IsBasePlan()) 894 return true; 895 else if (m_plan_stack.size() == 0) 896 return false; 897 else 898 return m_plan_stack[0].get() == plan_ptr; 899 } 900 901 ThreadPlan * 902 Thread::QueueFundamentalPlan (bool abort_other_plans) 903 { 904 ThreadPlanSP thread_plan_sp (new ThreadPlanBase(*this)); 905 QueueThreadPlan (thread_plan_sp, abort_other_plans); 906 return thread_plan_sp.get(); 907 } 908 909 ThreadPlan * 910 Thread::QueueThreadPlanForStepSingleInstruction 911 ( 912 bool step_over, 913 bool abort_other_plans, 914 bool stop_other_threads 915 ) 916 { 917 ThreadPlanSP thread_plan_sp (new ThreadPlanStepInstruction (*this, step_over, stop_other_threads, eVoteNoOpinion, eVoteNoOpinion)); 918 QueueThreadPlan (thread_plan_sp, abort_other_plans); 919 return thread_plan_sp.get(); 920 } 921 922 ThreadPlan * 923 Thread::QueueThreadPlanForStepRange 924 ( 925 bool abort_other_plans, 926 StepType type, 927 const AddressRange &range, 928 const SymbolContext &addr_context, 929 lldb::RunMode stop_other_threads, 930 bool avoid_code_without_debug_info 931 ) 932 { 933 ThreadPlanSP thread_plan_sp; 934 if (type == eStepTypeInto) 935 { 936 ThreadPlanStepInRange *plan = new ThreadPlanStepInRange (*this, range, addr_context, stop_other_threads); 937 if (avoid_code_without_debug_info) 938 plan->GetFlags().Set (ThreadPlanShouldStopHere::eAvoidNoDebug); 939 else 940 plan->GetFlags().Clear (ThreadPlanShouldStopHere::eAvoidNoDebug); 941 thread_plan_sp.reset (plan); 942 } 943 else 944 thread_plan_sp.reset (new ThreadPlanStepOverRange (*this, range, addr_context, stop_other_threads)); 945 946 QueueThreadPlan (thread_plan_sp, abort_other_plans); 947 return thread_plan_sp.get(); 948 } 949 950 951 ThreadPlan * 952 Thread::QueueThreadPlanForStepOverBreakpointPlan (bool abort_other_plans) 953 { 954 ThreadPlanSP thread_plan_sp (new ThreadPlanStepOverBreakpoint (*this)); 955 QueueThreadPlan (thread_plan_sp, abort_other_plans); 956 return thread_plan_sp.get(); 957 } 958 959 ThreadPlan * 960 Thread::QueueThreadPlanForStepOut 961 ( 962 bool abort_other_plans, 963 SymbolContext *addr_context, 964 bool first_insn, 965 bool stop_other_threads, 966 Vote stop_vote, 967 Vote run_vote, 968 uint32_t frame_idx 969 ) 970 { 971 ThreadPlanSP thread_plan_sp (new ThreadPlanStepOut (*this, 972 addr_context, 973 first_insn, 974 stop_other_threads, 975 stop_vote, 976 run_vote, 977 frame_idx)); 978 979 if (thread_plan_sp->ValidatePlan(NULL)) 980 { 981 QueueThreadPlan (thread_plan_sp, abort_other_plans); 982 return thread_plan_sp.get(); 983 } 984 else 985 { 986 return NULL; 987 } 988 } 989 990 ThreadPlan * 991 Thread::QueueThreadPlanForStepThrough (StackID &return_stack_id, bool abort_other_plans, bool stop_other_threads) 992 { 993 ThreadPlanSP thread_plan_sp(new ThreadPlanStepThrough (*this, return_stack_id, stop_other_threads)); 994 if (!thread_plan_sp || !thread_plan_sp->ValidatePlan (NULL)) 995 return NULL; 996 997 QueueThreadPlan (thread_plan_sp, abort_other_plans); 998 return thread_plan_sp.get(); 999 } 1000 1001 ThreadPlan * 1002 Thread::QueueThreadPlanForCallFunction (bool abort_other_plans, 1003 Address& function, 1004 lldb::addr_t arg, 1005 bool stop_other_threads, 1006 bool discard_on_error) 1007 { 1008 ThreadPlanSP thread_plan_sp (new ThreadPlanCallFunction (*this, function, ClangASTType(), arg, stop_other_threads, discard_on_error)); 1009 QueueThreadPlan (thread_plan_sp, abort_other_plans); 1010 return thread_plan_sp.get(); 1011 } 1012 1013 ThreadPlan * 1014 Thread::QueueThreadPlanForRunToAddress (bool abort_other_plans, 1015 Address &target_addr, 1016 bool stop_other_threads) 1017 { 1018 ThreadPlanSP thread_plan_sp (new ThreadPlanRunToAddress (*this, target_addr, stop_other_threads)); 1019 QueueThreadPlan (thread_plan_sp, abort_other_plans); 1020 return thread_plan_sp.get(); 1021 } 1022 1023 ThreadPlan * 1024 Thread::QueueThreadPlanForStepUntil (bool abort_other_plans, 1025 lldb::addr_t *address_list, 1026 size_t num_addresses, 1027 bool stop_other_threads, 1028 uint32_t frame_idx) 1029 { 1030 ThreadPlanSP thread_plan_sp (new ThreadPlanStepUntil (*this, address_list, num_addresses, stop_other_threads, frame_idx)); 1031 QueueThreadPlan (thread_plan_sp, abort_other_plans); 1032 return thread_plan_sp.get(); 1033 1034 } 1035 1036 uint32_t 1037 Thread::GetIndexID () const 1038 { 1039 return m_index_id; 1040 } 1041 1042 void 1043 Thread::DumpThreadPlans (lldb_private::Stream *s) const 1044 { 1045 uint32_t stack_size = m_plan_stack.size(); 1046 int i; 1047 s->Indent(); 1048 s->Printf ("Plan Stack for thread #%u: tid = 0x%4.4llx, stack_size = %d\n", GetIndexID(), GetID(), stack_size); 1049 for (i = stack_size - 1; i >= 0; i--) 1050 { 1051 s->IndentMore(); 1052 s->Indent(); 1053 s->Printf ("Element %d: ", i); 1054 m_plan_stack[i]->GetDescription (s, eDescriptionLevelFull); 1055 s->EOL(); 1056 s->IndentLess(); 1057 } 1058 1059 stack_size = m_completed_plan_stack.size(); 1060 if (stack_size > 0) 1061 { 1062 s->Indent(); 1063 s->Printf ("Completed Plan Stack: %d elements.\n", stack_size); 1064 for (i = stack_size - 1; i >= 0; i--) 1065 { 1066 s->IndentMore(); 1067 s->Indent(); 1068 s->Printf ("Element %d: ", i); 1069 m_completed_plan_stack[i]->GetDescription (s, eDescriptionLevelFull); 1070 s->EOL(); 1071 s->IndentLess(); 1072 } 1073 } 1074 1075 stack_size = m_discarded_plan_stack.size(); 1076 if (stack_size > 0) 1077 { 1078 s->Indent(); 1079 s->Printf ("Discarded Plan Stack: %d elements.\n", stack_size); 1080 for (i = stack_size - 1; i >= 0; i--) 1081 { 1082 s->IndentMore(); 1083 s->Indent(); 1084 s->Printf ("Element %d: ", i); 1085 m_discarded_plan_stack[i]->GetDescription (s, eDescriptionLevelFull); 1086 s->EOL(); 1087 s->IndentLess(); 1088 } 1089 } 1090 1091 } 1092 1093 TargetSP 1094 Thread::CalculateTarget () 1095 { 1096 TargetSP target_sp; 1097 ProcessSP process_sp(GetProcess()); 1098 if (process_sp) 1099 target_sp = process_sp->CalculateTarget(); 1100 return target_sp; 1101 1102 } 1103 1104 ProcessSP 1105 Thread::CalculateProcess () 1106 { 1107 return GetProcess(); 1108 } 1109 1110 ThreadSP 1111 Thread::CalculateThread () 1112 { 1113 return shared_from_this(); 1114 } 1115 1116 StackFrameSP 1117 Thread::CalculateStackFrame () 1118 { 1119 return StackFrameSP(); 1120 } 1121 1122 void 1123 Thread::CalculateExecutionContext (ExecutionContext &exe_ctx) 1124 { 1125 exe_ctx.SetContext (shared_from_this()); 1126 } 1127 1128 1129 StackFrameListSP 1130 Thread::GetStackFrameList () 1131 { 1132 StackFrameListSP frame_list_sp; 1133 Mutex::Locker locker(m_frame_mutex); 1134 if (m_curr_frames_sp) 1135 { 1136 frame_list_sp = m_curr_frames_sp; 1137 } 1138 else 1139 { 1140 frame_list_sp.reset(new StackFrameList (*this, m_prev_frames_sp, true)); 1141 m_curr_frames_sp = frame_list_sp; 1142 } 1143 return frame_list_sp; 1144 } 1145 1146 void 1147 Thread::ClearStackFrames () 1148 { 1149 Mutex::Locker locker(m_frame_mutex); 1150 1151 // Only store away the old "reference" StackFrameList if we got all its frames: 1152 // FIXME: At some point we can try to splice in the frames we have fetched into 1153 // the new frame as we make it, but let's not try that now. 1154 if (m_curr_frames_sp && m_curr_frames_sp->GetAllFramesFetched()) 1155 m_prev_frames_sp.swap (m_curr_frames_sp); 1156 m_curr_frames_sp.reset(); 1157 } 1158 1159 lldb::StackFrameSP 1160 Thread::GetFrameWithConcreteFrameIndex (uint32_t unwind_idx) 1161 { 1162 return GetStackFrameList()->GetFrameWithConcreteFrameIndex (unwind_idx); 1163 } 1164 1165 void 1166 Thread::DumpUsingSettingsFormat (Stream &strm, uint32_t frame_idx) 1167 { 1168 ExecutionContext exe_ctx (shared_from_this()); 1169 Process *process = exe_ctx.GetProcessPtr(); 1170 if (process == NULL) 1171 return; 1172 1173 StackFrameSP frame_sp; 1174 SymbolContext frame_sc; 1175 if (frame_idx != LLDB_INVALID_INDEX32) 1176 { 1177 frame_sp = GetStackFrameAtIndex (frame_idx); 1178 if (frame_sp) 1179 { 1180 exe_ctx.SetFrameSP(frame_sp); 1181 frame_sc = frame_sp->GetSymbolContext(eSymbolContextEverything); 1182 } 1183 } 1184 1185 const char *thread_format = exe_ctx.GetTargetRef().GetDebugger().GetThreadFormat(); 1186 assert (thread_format); 1187 const char *end = NULL; 1188 Debugger::FormatPrompt (thread_format, 1189 frame_sp ? &frame_sc : NULL, 1190 &exe_ctx, 1191 NULL, 1192 strm, 1193 &end); 1194 } 1195 1196 void 1197 Thread::SettingsInitialize () 1198 { 1199 UserSettingsController::InitializeSettingsController (GetSettingsController(), 1200 SettingsController::global_settings_table, 1201 SettingsController::instance_settings_table); 1202 1203 // Now call SettingsInitialize() on each 'child' setting of Thread. 1204 // Currently there are none. 1205 } 1206 1207 void 1208 Thread::SettingsTerminate () 1209 { 1210 // Must call SettingsTerminate() on each 'child' setting of Thread before terminating Thread settings. 1211 // Currently there are none. 1212 1213 // Now terminate Thread Settings. 1214 1215 UserSettingsControllerSP &usc = GetSettingsController(); 1216 UserSettingsController::FinalizeSettingsController (usc); 1217 usc.reset(); 1218 } 1219 1220 UserSettingsControllerSP & 1221 Thread::GetSettingsController () 1222 { 1223 static UserSettingsControllerSP g_settings_controller_sp; 1224 if (!g_settings_controller_sp) 1225 { 1226 g_settings_controller_sp.reset (new Thread::SettingsController); 1227 // The first shared pointer to Target::SettingsController in 1228 // g_settings_controller_sp must be fully created above so that 1229 // the TargetInstanceSettings can use a weak_ptr to refer back 1230 // to the master setttings controller 1231 InstanceSettingsSP default_instance_settings_sp (new ThreadInstanceSettings (g_settings_controller_sp, 1232 false, 1233 InstanceSettings::GetDefaultName().AsCString())); 1234 1235 g_settings_controller_sp->SetDefaultInstanceSettings (default_instance_settings_sp); 1236 } 1237 return g_settings_controller_sp; 1238 } 1239 1240 void 1241 Thread::UpdateInstanceName () 1242 { 1243 StreamString sstr; 1244 const char *name = GetName(); 1245 1246 if (name && name[0] != '\0') 1247 sstr.Printf ("%s", name); 1248 else if ((GetIndexID() != 0) || (GetID() != 0)) 1249 sstr.Printf ("0x%4.4x", GetIndexID()); 1250 1251 if (sstr.GetSize() > 0) 1252 Thread::GetSettingsController()->RenameInstanceSettings (GetInstanceName().AsCString(), sstr.GetData()); 1253 } 1254 1255 lldb::StackFrameSP 1256 Thread::GetStackFrameSPForStackFramePtr (StackFrame *stack_frame_ptr) 1257 { 1258 return GetStackFrameList()->GetStackFrameSPForStackFramePtr (stack_frame_ptr); 1259 } 1260 1261 const char * 1262 Thread::StopReasonAsCString (lldb::StopReason reason) 1263 { 1264 switch (reason) 1265 { 1266 case eStopReasonInvalid: return "invalid"; 1267 case eStopReasonNone: return "none"; 1268 case eStopReasonTrace: return "trace"; 1269 case eStopReasonBreakpoint: return "breakpoint"; 1270 case eStopReasonWatchpoint: return "watchpoint"; 1271 case eStopReasonSignal: return "signal"; 1272 case eStopReasonException: return "exception"; 1273 case eStopReasonPlanComplete: return "plan complete"; 1274 } 1275 1276 1277 static char unknown_state_string[64]; 1278 snprintf(unknown_state_string, sizeof (unknown_state_string), "StopReason = %i", reason); 1279 return unknown_state_string; 1280 } 1281 1282 const char * 1283 Thread::RunModeAsCString (lldb::RunMode mode) 1284 { 1285 switch (mode) 1286 { 1287 case eOnlyThisThread: return "only this thread"; 1288 case eAllThreads: return "all threads"; 1289 case eOnlyDuringStepping: return "only during stepping"; 1290 } 1291 1292 static char unknown_state_string[64]; 1293 snprintf(unknown_state_string, sizeof (unknown_state_string), "RunMode = %i", mode); 1294 return unknown_state_string; 1295 } 1296 1297 size_t 1298 Thread::GetStatus (Stream &strm, uint32_t start_frame, uint32_t num_frames, uint32_t num_frames_with_source) 1299 { 1300 ExecutionContext exe_ctx (shared_from_this()); 1301 Target *target = exe_ctx.GetTargetPtr(); 1302 Process *process = exe_ctx.GetProcessPtr(); 1303 size_t num_frames_shown = 0; 1304 strm.Indent(); 1305 bool is_selected = false; 1306 if (process) 1307 { 1308 if (process->GetThreadList().GetSelectedThread().get() == this) 1309 is_selected = true; 1310 } 1311 strm.Printf("%c ", is_selected ? '*' : ' '); 1312 if (target && target->GetDebugger().GetUseExternalEditor()) 1313 { 1314 StackFrameSP frame_sp = GetStackFrameAtIndex(start_frame); 1315 if (frame_sp) 1316 { 1317 SymbolContext frame_sc(frame_sp->GetSymbolContext (eSymbolContextLineEntry)); 1318 if (frame_sc.line_entry.line != 0 && frame_sc.line_entry.file) 1319 { 1320 Host::OpenFileInExternalEditor (frame_sc.line_entry.file, frame_sc.line_entry.line); 1321 } 1322 } 1323 } 1324 1325 DumpUsingSettingsFormat (strm, start_frame); 1326 1327 if (num_frames > 0) 1328 { 1329 strm.IndentMore(); 1330 1331 const bool show_frame_info = true; 1332 strm.IndentMore (); 1333 num_frames_shown = GetStackFrameList ()->GetStatus (strm, 1334 start_frame, 1335 num_frames, 1336 show_frame_info, 1337 num_frames_with_source); 1338 strm.IndentLess(); 1339 strm.IndentLess(); 1340 } 1341 return num_frames_shown; 1342 } 1343 1344 size_t 1345 Thread::GetStackFrameStatus (Stream& strm, 1346 uint32_t first_frame, 1347 uint32_t num_frames, 1348 bool show_frame_info, 1349 uint32_t num_frames_with_source) 1350 { 1351 return GetStackFrameList()->GetStatus (strm, 1352 first_frame, 1353 num_frames, 1354 show_frame_info, 1355 num_frames_with_source); 1356 } 1357 1358 bool 1359 Thread::SaveFrameZeroState (RegisterCheckpoint &checkpoint) 1360 { 1361 lldb::StackFrameSP frame_sp(GetStackFrameAtIndex (0)); 1362 if (frame_sp) 1363 { 1364 checkpoint.SetStackID(frame_sp->GetStackID()); 1365 return frame_sp->GetRegisterContext()->ReadAllRegisterValues (checkpoint.GetData()); 1366 } 1367 return false; 1368 } 1369 1370 bool 1371 Thread::RestoreSaveFrameZero (const RegisterCheckpoint &checkpoint) 1372 { 1373 lldb::StackFrameSP frame_sp(GetStackFrameAtIndex (0)); 1374 if (frame_sp) 1375 { 1376 bool ret = frame_sp->GetRegisterContext()->WriteAllRegisterValues (checkpoint.GetData()); 1377 1378 // Clear out all stack frames as our world just changed. 1379 ClearStackFrames(); 1380 frame_sp->GetRegisterContext()->InvalidateIfNeeded(true); 1381 1382 return ret; 1383 } 1384 return false; 1385 } 1386 1387 Unwind * 1388 Thread::GetUnwinder () 1389 { 1390 if (m_unwinder_ap.get() == NULL) 1391 { 1392 const ArchSpec target_arch (CalculateTarget()->GetArchitecture ()); 1393 const llvm::Triple::ArchType machine = target_arch.GetMachine(); 1394 switch (machine) 1395 { 1396 case llvm::Triple::x86_64: 1397 case llvm::Triple::x86: 1398 case llvm::Triple::arm: 1399 case llvm::Triple::thumb: 1400 m_unwinder_ap.reset (new UnwindLLDB (*this)); 1401 break; 1402 1403 default: 1404 if (target_arch.GetTriple().getVendor() == llvm::Triple::Apple) 1405 m_unwinder_ap.reset (new UnwindMacOSXFrameBackchain (*this)); 1406 break; 1407 } 1408 } 1409 return m_unwinder_ap.get(); 1410 } 1411 1412 1413 void 1414 Thread::Flush () 1415 { 1416 ClearStackFrames (); 1417 m_reg_context_sp.reset(); 1418 } 1419 1420 1421 #pragma mark "Thread::SettingsController" 1422 //-------------------------------------------------------------- 1423 // class Thread::SettingsController 1424 //-------------------------------------------------------------- 1425 1426 Thread::SettingsController::SettingsController () : 1427 UserSettingsController ("thread", Process::GetSettingsController()) 1428 { 1429 } 1430 1431 Thread::SettingsController::~SettingsController () 1432 { 1433 } 1434 1435 lldb::InstanceSettingsSP 1436 Thread::SettingsController::CreateInstanceSettings (const char *instance_name) 1437 { 1438 lldb::InstanceSettingsSP new_settings_sp (new ThreadInstanceSettings (GetSettingsController(), 1439 false, 1440 instance_name)); 1441 return new_settings_sp; 1442 } 1443 1444 #pragma mark "ThreadInstanceSettings" 1445 //-------------------------------------------------------------- 1446 // class ThreadInstanceSettings 1447 //-------------------------------------------------------------- 1448 1449 ThreadInstanceSettings::ThreadInstanceSettings (const UserSettingsControllerSP &owner_sp, bool live_instance, const char *name) : 1450 InstanceSettings (owner_sp, name ? name : InstanceSettings::InvalidName().AsCString(), live_instance), 1451 m_avoid_regexp_ap (), 1452 m_trace_enabled (false) 1453 { 1454 // CopyInstanceSettings is a pure virtual function in InstanceSettings; it therefore cannot be called 1455 // until the vtables for ThreadInstanceSettings are properly set up, i.e. AFTER all the initializers. 1456 // For this reason it has to be called here, rather than in the initializer or in the parent constructor. 1457 // This is true for CreateInstanceName() too. 1458 1459 if (GetInstanceName() == InstanceSettings::InvalidName()) 1460 { 1461 ChangeInstanceName (std::string (CreateInstanceName().AsCString())); 1462 owner_sp->RegisterInstanceSettings (this); 1463 } 1464 1465 if (live_instance) 1466 { 1467 CopyInstanceSettings (owner_sp->FindPendingSettings (m_instance_name),false); 1468 } 1469 } 1470 1471 ThreadInstanceSettings::ThreadInstanceSettings (const ThreadInstanceSettings &rhs) : 1472 InstanceSettings (Thread::GetSettingsController(), CreateInstanceName().AsCString()), 1473 m_avoid_regexp_ap (), 1474 m_trace_enabled (rhs.m_trace_enabled) 1475 { 1476 if (m_instance_name != InstanceSettings::GetDefaultName()) 1477 { 1478 UserSettingsControllerSP owner_sp (m_owner_wp.lock()); 1479 if (owner_sp) 1480 { 1481 CopyInstanceSettings (owner_sp->FindPendingSettings (m_instance_name), false); 1482 owner_sp->RemovePendingSettings (m_instance_name); 1483 } 1484 } 1485 if (rhs.m_avoid_regexp_ap.get() != NULL) 1486 m_avoid_regexp_ap.reset(new RegularExpression(rhs.m_avoid_regexp_ap->GetText())); 1487 } 1488 1489 ThreadInstanceSettings::~ThreadInstanceSettings () 1490 { 1491 } 1492 1493 ThreadInstanceSettings& 1494 ThreadInstanceSettings::operator= (const ThreadInstanceSettings &rhs) 1495 { 1496 if (this != &rhs) 1497 { 1498 if (rhs.m_avoid_regexp_ap.get() != NULL) 1499 m_avoid_regexp_ap.reset(new RegularExpression(rhs.m_avoid_regexp_ap->GetText())); 1500 else 1501 m_avoid_regexp_ap.reset(NULL); 1502 } 1503 m_trace_enabled = rhs.m_trace_enabled; 1504 return *this; 1505 } 1506 1507 1508 void 1509 ThreadInstanceSettings::UpdateInstanceSettingsVariable (const ConstString &var_name, 1510 const char *index_value, 1511 const char *value, 1512 const ConstString &instance_name, 1513 const SettingEntry &entry, 1514 VarSetOperationType op, 1515 Error &err, 1516 bool pending) 1517 { 1518 if (var_name == StepAvoidRegexpVarName()) 1519 { 1520 std::string regexp_text; 1521 if (m_avoid_regexp_ap.get() != NULL) 1522 regexp_text.append (m_avoid_regexp_ap->GetText()); 1523 UserSettingsController::UpdateStringVariable (op, regexp_text, value, err); 1524 if (regexp_text.empty()) 1525 m_avoid_regexp_ap.reset(); 1526 else 1527 { 1528 m_avoid_regexp_ap.reset(new RegularExpression(regexp_text.c_str())); 1529 1530 } 1531 } 1532 else if (var_name == GetTraceThreadVarName()) 1533 { 1534 bool success; 1535 bool result = Args::StringToBoolean(value, false, &success); 1536 1537 if (success) 1538 { 1539 m_trace_enabled = result; 1540 if (!pending) 1541 { 1542 Thread *myself = static_cast<Thread *> (this); 1543 myself->EnableTracer(m_trace_enabled, true); 1544 } 1545 } 1546 else 1547 { 1548 err.SetErrorStringWithFormat ("Bad value \"%s\" for trace-thread, should be Boolean.", value); 1549 } 1550 1551 } 1552 } 1553 1554 void 1555 ThreadInstanceSettings::CopyInstanceSettings (const lldb::InstanceSettingsSP &new_settings, 1556 bool pending) 1557 { 1558 if (new_settings.get() == NULL) 1559 return; 1560 1561 ThreadInstanceSettings *new_process_settings = (ThreadInstanceSettings *) new_settings.get(); 1562 if (new_process_settings->GetSymbolsToAvoidRegexp() != NULL) 1563 m_avoid_regexp_ap.reset (new RegularExpression (new_process_settings->GetSymbolsToAvoidRegexp()->GetText())); 1564 else 1565 m_avoid_regexp_ap.reset (); 1566 } 1567 1568 bool 1569 ThreadInstanceSettings::GetInstanceSettingsValue (const SettingEntry &entry, 1570 const ConstString &var_name, 1571 StringList &value, 1572 Error *err) 1573 { 1574 if (var_name == StepAvoidRegexpVarName()) 1575 { 1576 if (m_avoid_regexp_ap.get() != NULL) 1577 { 1578 std::string regexp_text("\""); 1579 regexp_text.append(m_avoid_regexp_ap->GetText()); 1580 regexp_text.append ("\""); 1581 value.AppendString (regexp_text.c_str()); 1582 } 1583 1584 } 1585 else if (var_name == GetTraceThreadVarName()) 1586 { 1587 value.AppendString(m_trace_enabled ? "true" : "false"); 1588 } 1589 else 1590 { 1591 if (err) 1592 err->SetErrorStringWithFormat ("unrecognized variable name '%s'", var_name.AsCString()); 1593 return false; 1594 } 1595 return true; 1596 } 1597 1598 const ConstString 1599 ThreadInstanceSettings::CreateInstanceName () 1600 { 1601 static int instance_count = 1; 1602 StreamString sstr; 1603 1604 sstr.Printf ("thread_%d", instance_count); 1605 ++instance_count; 1606 1607 const ConstString ret_val (sstr.GetData()); 1608 return ret_val; 1609 } 1610 1611 const ConstString & 1612 ThreadInstanceSettings::StepAvoidRegexpVarName () 1613 { 1614 static ConstString step_avoid_var_name ("step-avoid-regexp"); 1615 1616 return step_avoid_var_name; 1617 } 1618 1619 const ConstString & 1620 ThreadInstanceSettings::GetTraceThreadVarName () 1621 { 1622 static ConstString trace_thread_var_name ("trace-thread"); 1623 1624 return trace_thread_var_name; 1625 } 1626 1627 //-------------------------------------------------- 1628 // SettingsController Variable Tables 1629 //-------------------------------------------------- 1630 1631 SettingEntry 1632 Thread::SettingsController::global_settings_table[] = 1633 { 1634 //{ "var-name", var-type , "default", enum-table, init'd, hidden, "help-text"}, 1635 { NULL, eSetVarTypeNone, NULL, NULL, 0, 0, NULL } 1636 }; 1637 1638 1639 SettingEntry 1640 Thread::SettingsController::instance_settings_table[] = 1641 { 1642 //{ "var-name", var-type, "default", enum-table, init'd, hidden, "help-text"}, 1643 { "step-avoid-regexp", eSetVarTypeString, "", NULL, false, false, "A regular expression defining functions step-in won't stop in." }, 1644 { "trace-thread", eSetVarTypeBoolean, "false", NULL, false, false, "If true, this thread will single-step and log execution." }, 1645 { NULL, eSetVarTypeNone, NULL, NULL, 0, 0, NULL } 1646 }; 1647