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 GetPrivateStopReason () != NULL; 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 QueueThreadPlan (thread_plan_sp, abort_other_plans); 979 return thread_plan_sp.get(); 980 } 981 982 ThreadPlan * 983 Thread::QueueThreadPlanForStepThrough (StackID &return_stack_id, bool abort_other_plans, bool stop_other_threads) 984 { 985 ThreadPlanSP thread_plan_sp(new ThreadPlanStepThrough (*this, return_stack_id, stop_other_threads)); 986 if (!thread_plan_sp || !thread_plan_sp->ValidatePlan (NULL)) 987 return NULL; 988 989 QueueThreadPlan (thread_plan_sp, abort_other_plans); 990 return thread_plan_sp.get(); 991 } 992 993 ThreadPlan * 994 Thread::QueueThreadPlanForCallFunction (bool abort_other_plans, 995 Address& function, 996 lldb::addr_t arg, 997 bool stop_other_threads, 998 bool discard_on_error) 999 { 1000 ThreadPlanSP thread_plan_sp (new ThreadPlanCallFunction (*this, function, ClangASTType(), arg, stop_other_threads, discard_on_error)); 1001 QueueThreadPlan (thread_plan_sp, abort_other_plans); 1002 return thread_plan_sp.get(); 1003 } 1004 1005 ThreadPlan * 1006 Thread::QueueThreadPlanForRunToAddress (bool abort_other_plans, 1007 Address &target_addr, 1008 bool stop_other_threads) 1009 { 1010 ThreadPlanSP thread_plan_sp (new ThreadPlanRunToAddress (*this, target_addr, stop_other_threads)); 1011 QueueThreadPlan (thread_plan_sp, abort_other_plans); 1012 return thread_plan_sp.get(); 1013 } 1014 1015 ThreadPlan * 1016 Thread::QueueThreadPlanForStepUntil (bool abort_other_plans, 1017 lldb::addr_t *address_list, 1018 size_t num_addresses, 1019 bool stop_other_threads, 1020 uint32_t frame_idx) 1021 { 1022 ThreadPlanSP thread_plan_sp (new ThreadPlanStepUntil (*this, address_list, num_addresses, stop_other_threads, frame_idx)); 1023 QueueThreadPlan (thread_plan_sp, abort_other_plans); 1024 return thread_plan_sp.get(); 1025 1026 } 1027 1028 uint32_t 1029 Thread::GetIndexID () const 1030 { 1031 return m_index_id; 1032 } 1033 1034 void 1035 Thread::DumpThreadPlans (lldb_private::Stream *s) const 1036 { 1037 uint32_t stack_size = m_plan_stack.size(); 1038 int i; 1039 s->Indent(); 1040 s->Printf ("Plan Stack for thread #%u: tid = 0x%4.4llx, stack_size = %d\n", GetIndexID(), GetID(), stack_size); 1041 for (i = stack_size - 1; i >= 0; i--) 1042 { 1043 s->IndentMore(); 1044 s->Indent(); 1045 s->Printf ("Element %d: ", i); 1046 m_plan_stack[i]->GetDescription (s, eDescriptionLevelFull); 1047 s->EOL(); 1048 s->IndentLess(); 1049 } 1050 1051 stack_size = m_completed_plan_stack.size(); 1052 if (stack_size > 0) 1053 { 1054 s->Indent(); 1055 s->Printf ("Completed Plan Stack: %d elements.\n", stack_size); 1056 for (i = stack_size - 1; i >= 0; i--) 1057 { 1058 s->IndentMore(); 1059 s->Indent(); 1060 s->Printf ("Element %d: ", i); 1061 m_completed_plan_stack[i]->GetDescription (s, eDescriptionLevelFull); 1062 s->EOL(); 1063 s->IndentLess(); 1064 } 1065 } 1066 1067 stack_size = m_discarded_plan_stack.size(); 1068 if (stack_size > 0) 1069 { 1070 s->Indent(); 1071 s->Printf ("Discarded Plan Stack: %d elements.\n", stack_size); 1072 for (i = stack_size - 1; i >= 0; i--) 1073 { 1074 s->IndentMore(); 1075 s->Indent(); 1076 s->Printf ("Element %d: ", i); 1077 m_discarded_plan_stack[i]->GetDescription (s, eDescriptionLevelFull); 1078 s->EOL(); 1079 s->IndentLess(); 1080 } 1081 } 1082 1083 } 1084 1085 TargetSP 1086 Thread::CalculateTarget () 1087 { 1088 TargetSP target_sp; 1089 ProcessSP process_sp(GetProcess()); 1090 if (process_sp) 1091 target_sp = process_sp->CalculateTarget(); 1092 return target_sp; 1093 1094 } 1095 1096 ProcessSP 1097 Thread::CalculateProcess () 1098 { 1099 return GetProcess(); 1100 } 1101 1102 ThreadSP 1103 Thread::CalculateThread () 1104 { 1105 return shared_from_this(); 1106 } 1107 1108 StackFrameSP 1109 Thread::CalculateStackFrame () 1110 { 1111 return StackFrameSP(); 1112 } 1113 1114 void 1115 Thread::CalculateExecutionContext (ExecutionContext &exe_ctx) 1116 { 1117 exe_ctx.SetContext (shared_from_this()); 1118 } 1119 1120 1121 StackFrameListSP 1122 Thread::GetStackFrameList () 1123 { 1124 StackFrameListSP frame_list_sp; 1125 Mutex::Locker locker(m_frame_mutex); 1126 if (m_curr_frames_sp) 1127 { 1128 frame_list_sp = m_curr_frames_sp; 1129 } 1130 else 1131 { 1132 frame_list_sp.reset(new StackFrameList (*this, m_prev_frames_sp, true)); 1133 m_curr_frames_sp = frame_list_sp; 1134 } 1135 return frame_list_sp; 1136 } 1137 1138 void 1139 Thread::ClearStackFrames () 1140 { 1141 Mutex::Locker locker(m_frame_mutex); 1142 1143 // Only store away the old "reference" StackFrameList if we got all its frames: 1144 // FIXME: At some point we can try to splice in the frames we have fetched into 1145 // the new frame as we make it, but let's not try that now. 1146 if (m_curr_frames_sp && m_curr_frames_sp->GetAllFramesFetched()) 1147 m_prev_frames_sp.swap (m_curr_frames_sp); 1148 m_curr_frames_sp.reset(); 1149 } 1150 1151 lldb::StackFrameSP 1152 Thread::GetFrameWithConcreteFrameIndex (uint32_t unwind_idx) 1153 { 1154 return GetStackFrameList()->GetFrameWithConcreteFrameIndex (unwind_idx); 1155 } 1156 1157 void 1158 Thread::DumpUsingSettingsFormat (Stream &strm, uint32_t frame_idx) 1159 { 1160 ExecutionContext exe_ctx (shared_from_this()); 1161 Process *process = exe_ctx.GetProcessPtr(); 1162 if (process == NULL) 1163 return; 1164 1165 StackFrameSP frame_sp; 1166 SymbolContext frame_sc; 1167 if (frame_idx != LLDB_INVALID_INDEX32) 1168 { 1169 frame_sp = GetStackFrameAtIndex (frame_idx); 1170 if (frame_sp) 1171 { 1172 exe_ctx.SetFrameSP(frame_sp); 1173 frame_sc = frame_sp->GetSymbolContext(eSymbolContextEverything); 1174 } 1175 } 1176 1177 const char *thread_format = exe_ctx.GetTargetRef().GetDebugger().GetThreadFormat(); 1178 assert (thread_format); 1179 const char *end = NULL; 1180 Debugger::FormatPrompt (thread_format, 1181 frame_sp ? &frame_sc : NULL, 1182 &exe_ctx, 1183 NULL, 1184 strm, 1185 &end); 1186 } 1187 1188 void 1189 Thread::SettingsInitialize () 1190 { 1191 UserSettingsController::InitializeSettingsController (GetSettingsController(), 1192 SettingsController::global_settings_table, 1193 SettingsController::instance_settings_table); 1194 1195 // Now call SettingsInitialize() on each 'child' setting of Thread. 1196 // Currently there are none. 1197 } 1198 1199 void 1200 Thread::SettingsTerminate () 1201 { 1202 // Must call SettingsTerminate() on each 'child' setting of Thread before terminating Thread settings. 1203 // Currently there are none. 1204 1205 // Now terminate Thread Settings. 1206 1207 UserSettingsControllerSP &usc = GetSettingsController(); 1208 UserSettingsController::FinalizeSettingsController (usc); 1209 usc.reset(); 1210 } 1211 1212 UserSettingsControllerSP & 1213 Thread::GetSettingsController () 1214 { 1215 static UserSettingsControllerSP g_settings_controller_sp; 1216 if (!g_settings_controller_sp) 1217 { 1218 g_settings_controller_sp.reset (new Thread::SettingsController); 1219 // The first shared pointer to Target::SettingsController in 1220 // g_settings_controller_sp must be fully created above so that 1221 // the TargetInstanceSettings can use a weak_ptr to refer back 1222 // to the master setttings controller 1223 InstanceSettingsSP default_instance_settings_sp (new ThreadInstanceSettings (g_settings_controller_sp, 1224 false, 1225 InstanceSettings::GetDefaultName().AsCString())); 1226 1227 g_settings_controller_sp->SetDefaultInstanceSettings (default_instance_settings_sp); 1228 } 1229 return g_settings_controller_sp; 1230 } 1231 1232 void 1233 Thread::UpdateInstanceName () 1234 { 1235 StreamString sstr; 1236 const char *name = GetName(); 1237 1238 if (name && name[0] != '\0') 1239 sstr.Printf ("%s", name); 1240 else if ((GetIndexID() != 0) || (GetID() != 0)) 1241 sstr.Printf ("0x%4.4x", GetIndexID()); 1242 1243 if (sstr.GetSize() > 0) 1244 Thread::GetSettingsController()->RenameInstanceSettings (GetInstanceName().AsCString(), sstr.GetData()); 1245 } 1246 1247 lldb::StackFrameSP 1248 Thread::GetStackFrameSPForStackFramePtr (StackFrame *stack_frame_ptr) 1249 { 1250 return GetStackFrameList()->GetStackFrameSPForStackFramePtr (stack_frame_ptr); 1251 } 1252 1253 const char * 1254 Thread::StopReasonAsCString (lldb::StopReason reason) 1255 { 1256 switch (reason) 1257 { 1258 case eStopReasonInvalid: return "invalid"; 1259 case eStopReasonNone: return "none"; 1260 case eStopReasonTrace: return "trace"; 1261 case eStopReasonBreakpoint: return "breakpoint"; 1262 case eStopReasonWatchpoint: return "watchpoint"; 1263 case eStopReasonSignal: return "signal"; 1264 case eStopReasonException: return "exception"; 1265 case eStopReasonPlanComplete: return "plan complete"; 1266 } 1267 1268 1269 static char unknown_state_string[64]; 1270 snprintf(unknown_state_string, sizeof (unknown_state_string), "StopReason = %i", reason); 1271 return unknown_state_string; 1272 } 1273 1274 const char * 1275 Thread::RunModeAsCString (lldb::RunMode mode) 1276 { 1277 switch (mode) 1278 { 1279 case eOnlyThisThread: return "only this thread"; 1280 case eAllThreads: return "all threads"; 1281 case eOnlyDuringStepping: return "only during stepping"; 1282 } 1283 1284 static char unknown_state_string[64]; 1285 snprintf(unknown_state_string, sizeof (unknown_state_string), "RunMode = %i", mode); 1286 return unknown_state_string; 1287 } 1288 1289 size_t 1290 Thread::GetStatus (Stream &strm, uint32_t start_frame, uint32_t num_frames, uint32_t num_frames_with_source) 1291 { 1292 ExecutionContext exe_ctx (shared_from_this()); 1293 Target *target = exe_ctx.GetTargetPtr(); 1294 Process *process = exe_ctx.GetProcessPtr(); 1295 size_t num_frames_shown = 0; 1296 strm.Indent(); 1297 bool is_selected = false; 1298 if (process) 1299 { 1300 if (process->GetThreadList().GetSelectedThread().get() == this) 1301 is_selected = true; 1302 } 1303 strm.Printf("%c ", is_selected ? '*' : ' '); 1304 if (target && target->GetDebugger().GetUseExternalEditor()) 1305 { 1306 StackFrameSP frame_sp = GetStackFrameAtIndex(start_frame); 1307 if (frame_sp) 1308 { 1309 SymbolContext frame_sc(frame_sp->GetSymbolContext (eSymbolContextLineEntry)); 1310 if (frame_sc.line_entry.line != 0 && frame_sc.line_entry.file) 1311 { 1312 Host::OpenFileInExternalEditor (frame_sc.line_entry.file, frame_sc.line_entry.line); 1313 } 1314 } 1315 } 1316 1317 DumpUsingSettingsFormat (strm, start_frame); 1318 1319 if (num_frames > 0) 1320 { 1321 strm.IndentMore(); 1322 1323 const bool show_frame_info = true; 1324 strm.IndentMore (); 1325 num_frames_shown = GetStackFrameList ()->GetStatus (strm, 1326 start_frame, 1327 num_frames, 1328 show_frame_info, 1329 num_frames_with_source); 1330 strm.IndentLess(); 1331 strm.IndentLess(); 1332 } 1333 return num_frames_shown; 1334 } 1335 1336 size_t 1337 Thread::GetStackFrameStatus (Stream& strm, 1338 uint32_t first_frame, 1339 uint32_t num_frames, 1340 bool show_frame_info, 1341 uint32_t num_frames_with_source) 1342 { 1343 return GetStackFrameList()->GetStatus (strm, 1344 first_frame, 1345 num_frames, 1346 show_frame_info, 1347 num_frames_with_source); 1348 } 1349 1350 bool 1351 Thread::SaveFrameZeroState (RegisterCheckpoint &checkpoint) 1352 { 1353 lldb::StackFrameSP frame_sp(GetStackFrameAtIndex (0)); 1354 if (frame_sp) 1355 { 1356 checkpoint.SetStackID(frame_sp->GetStackID()); 1357 return frame_sp->GetRegisterContext()->ReadAllRegisterValues (checkpoint.GetData()); 1358 } 1359 return false; 1360 } 1361 1362 bool 1363 Thread::RestoreSaveFrameZero (const RegisterCheckpoint &checkpoint) 1364 { 1365 lldb::StackFrameSP frame_sp(GetStackFrameAtIndex (0)); 1366 if (frame_sp) 1367 { 1368 bool ret = frame_sp->GetRegisterContext()->WriteAllRegisterValues (checkpoint.GetData()); 1369 1370 // Clear out all stack frames as our world just changed. 1371 ClearStackFrames(); 1372 frame_sp->GetRegisterContext()->InvalidateIfNeeded(true); 1373 1374 return ret; 1375 } 1376 return false; 1377 } 1378 1379 Unwind * 1380 Thread::GetUnwinder () 1381 { 1382 if (m_unwinder_ap.get() == NULL) 1383 { 1384 const ArchSpec target_arch (CalculateTarget()->GetArchitecture ()); 1385 const llvm::Triple::ArchType machine = target_arch.GetMachine(); 1386 switch (machine) 1387 { 1388 case llvm::Triple::x86_64: 1389 case llvm::Triple::x86: 1390 case llvm::Triple::arm: 1391 case llvm::Triple::thumb: 1392 m_unwinder_ap.reset (new UnwindLLDB (*this)); 1393 break; 1394 1395 default: 1396 if (target_arch.GetTriple().getVendor() == llvm::Triple::Apple) 1397 m_unwinder_ap.reset (new UnwindMacOSXFrameBackchain (*this)); 1398 break; 1399 } 1400 } 1401 return m_unwinder_ap.get(); 1402 } 1403 1404 1405 void 1406 Thread::Flush () 1407 { 1408 ClearStackFrames (); 1409 m_reg_context_sp.reset(); 1410 } 1411 1412 1413 #pragma mark "Thread::SettingsController" 1414 //-------------------------------------------------------------- 1415 // class Thread::SettingsController 1416 //-------------------------------------------------------------- 1417 1418 Thread::SettingsController::SettingsController () : 1419 UserSettingsController ("thread", Process::GetSettingsController()) 1420 { 1421 } 1422 1423 Thread::SettingsController::~SettingsController () 1424 { 1425 } 1426 1427 lldb::InstanceSettingsSP 1428 Thread::SettingsController::CreateInstanceSettings (const char *instance_name) 1429 { 1430 lldb::InstanceSettingsSP new_settings_sp (new ThreadInstanceSettings (GetSettingsController(), 1431 false, 1432 instance_name)); 1433 return new_settings_sp; 1434 } 1435 1436 #pragma mark "ThreadInstanceSettings" 1437 //-------------------------------------------------------------- 1438 // class ThreadInstanceSettings 1439 //-------------------------------------------------------------- 1440 1441 ThreadInstanceSettings::ThreadInstanceSettings (const UserSettingsControllerSP &owner_sp, bool live_instance, const char *name) : 1442 InstanceSettings (owner_sp, name ? name : InstanceSettings::InvalidName().AsCString(), live_instance), 1443 m_avoid_regexp_ap (), 1444 m_trace_enabled (false) 1445 { 1446 // CopyInstanceSettings is a pure virtual function in InstanceSettings; it therefore cannot be called 1447 // until the vtables for ThreadInstanceSettings are properly set up, i.e. AFTER all the initializers. 1448 // For this reason it has to be called here, rather than in the initializer or in the parent constructor. 1449 // This is true for CreateInstanceName() too. 1450 1451 if (GetInstanceName() == InstanceSettings::InvalidName()) 1452 { 1453 ChangeInstanceName (std::string (CreateInstanceName().AsCString())); 1454 owner_sp->RegisterInstanceSettings (this); 1455 } 1456 1457 if (live_instance) 1458 { 1459 CopyInstanceSettings (owner_sp->FindPendingSettings (m_instance_name),false); 1460 } 1461 } 1462 1463 ThreadInstanceSettings::ThreadInstanceSettings (const ThreadInstanceSettings &rhs) : 1464 InstanceSettings (Thread::GetSettingsController(), CreateInstanceName().AsCString()), 1465 m_avoid_regexp_ap (), 1466 m_trace_enabled (rhs.m_trace_enabled) 1467 { 1468 if (m_instance_name != InstanceSettings::GetDefaultName()) 1469 { 1470 UserSettingsControllerSP owner_sp (m_owner_wp.lock()); 1471 if (owner_sp) 1472 { 1473 CopyInstanceSettings (owner_sp->FindPendingSettings (m_instance_name), false); 1474 owner_sp->RemovePendingSettings (m_instance_name); 1475 } 1476 } 1477 if (rhs.m_avoid_regexp_ap.get() != NULL) 1478 m_avoid_regexp_ap.reset(new RegularExpression(rhs.m_avoid_regexp_ap->GetText())); 1479 } 1480 1481 ThreadInstanceSettings::~ThreadInstanceSettings () 1482 { 1483 } 1484 1485 ThreadInstanceSettings& 1486 ThreadInstanceSettings::operator= (const ThreadInstanceSettings &rhs) 1487 { 1488 if (this != &rhs) 1489 { 1490 if (rhs.m_avoid_regexp_ap.get() != NULL) 1491 m_avoid_regexp_ap.reset(new RegularExpression(rhs.m_avoid_regexp_ap->GetText())); 1492 else 1493 m_avoid_regexp_ap.reset(NULL); 1494 } 1495 m_trace_enabled = rhs.m_trace_enabled; 1496 return *this; 1497 } 1498 1499 1500 void 1501 ThreadInstanceSettings::UpdateInstanceSettingsVariable (const ConstString &var_name, 1502 const char *index_value, 1503 const char *value, 1504 const ConstString &instance_name, 1505 const SettingEntry &entry, 1506 VarSetOperationType op, 1507 Error &err, 1508 bool pending) 1509 { 1510 if (var_name == StepAvoidRegexpVarName()) 1511 { 1512 std::string regexp_text; 1513 if (m_avoid_regexp_ap.get() != NULL) 1514 regexp_text.append (m_avoid_regexp_ap->GetText()); 1515 UserSettingsController::UpdateStringVariable (op, regexp_text, value, err); 1516 if (regexp_text.empty()) 1517 m_avoid_regexp_ap.reset(); 1518 else 1519 { 1520 m_avoid_regexp_ap.reset(new RegularExpression(regexp_text.c_str())); 1521 1522 } 1523 } 1524 else if (var_name == GetTraceThreadVarName()) 1525 { 1526 bool success; 1527 bool result = Args::StringToBoolean(value, false, &success); 1528 1529 if (success) 1530 { 1531 m_trace_enabled = result; 1532 if (!pending) 1533 { 1534 Thread *myself = static_cast<Thread *> (this); 1535 myself->EnableTracer(m_trace_enabled, true); 1536 } 1537 } 1538 else 1539 { 1540 err.SetErrorStringWithFormat ("Bad value \"%s\" for trace-thread, should be Boolean.", value); 1541 } 1542 1543 } 1544 } 1545 1546 void 1547 ThreadInstanceSettings::CopyInstanceSettings (const lldb::InstanceSettingsSP &new_settings, 1548 bool pending) 1549 { 1550 if (new_settings.get() == NULL) 1551 return; 1552 1553 ThreadInstanceSettings *new_process_settings = (ThreadInstanceSettings *) new_settings.get(); 1554 if (new_process_settings->GetSymbolsToAvoidRegexp() != NULL) 1555 m_avoid_regexp_ap.reset (new RegularExpression (new_process_settings->GetSymbolsToAvoidRegexp()->GetText())); 1556 else 1557 m_avoid_regexp_ap.reset (); 1558 } 1559 1560 bool 1561 ThreadInstanceSettings::GetInstanceSettingsValue (const SettingEntry &entry, 1562 const ConstString &var_name, 1563 StringList &value, 1564 Error *err) 1565 { 1566 if (var_name == StepAvoidRegexpVarName()) 1567 { 1568 if (m_avoid_regexp_ap.get() != NULL) 1569 { 1570 std::string regexp_text("\""); 1571 regexp_text.append(m_avoid_regexp_ap->GetText()); 1572 regexp_text.append ("\""); 1573 value.AppendString (regexp_text.c_str()); 1574 } 1575 1576 } 1577 else if (var_name == GetTraceThreadVarName()) 1578 { 1579 value.AppendString(m_trace_enabled ? "true" : "false"); 1580 } 1581 else 1582 { 1583 if (err) 1584 err->SetErrorStringWithFormat ("unrecognized variable name '%s'", var_name.AsCString()); 1585 return false; 1586 } 1587 return true; 1588 } 1589 1590 const ConstString 1591 ThreadInstanceSettings::CreateInstanceName () 1592 { 1593 static int instance_count = 1; 1594 StreamString sstr; 1595 1596 sstr.Printf ("thread_%d", instance_count); 1597 ++instance_count; 1598 1599 const ConstString ret_val (sstr.GetData()); 1600 return ret_val; 1601 } 1602 1603 const ConstString & 1604 ThreadInstanceSettings::StepAvoidRegexpVarName () 1605 { 1606 static ConstString step_avoid_var_name ("step-avoid-regexp"); 1607 1608 return step_avoid_var_name; 1609 } 1610 1611 const ConstString & 1612 ThreadInstanceSettings::GetTraceThreadVarName () 1613 { 1614 static ConstString trace_thread_var_name ("trace-thread"); 1615 1616 return trace_thread_var_name; 1617 } 1618 1619 //-------------------------------------------------- 1620 // SettingsController Variable Tables 1621 //-------------------------------------------------- 1622 1623 SettingEntry 1624 Thread::SettingsController::global_settings_table[] = 1625 { 1626 //{ "var-name", var-type , "default", enum-table, init'd, hidden, "help-text"}, 1627 { NULL, eSetVarTypeNone, NULL, NULL, 0, 0, NULL } 1628 }; 1629 1630 1631 SettingEntry 1632 Thread::SettingsController::instance_settings_table[] = 1633 { 1634 //{ "var-name", var-type, "default", enum-table, init'd, hidden, "help-text"}, 1635 { "step-avoid-regexp", eSetVarTypeString, "", NULL, false, false, "A regular expression defining functions step-in won't stop in." }, 1636 { "trace-thread", eSetVarTypeBoolean, "false", NULL, false, false, "If true, this thread will single-step and log execution." }, 1637 { NULL, eSetVarTypeNone, NULL, NULL, 0, 0, NULL } 1638 }; 1639