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 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()) != plan_ptr); 388 done_processing_current_plan = false; 389 } 390 else 391 done_processing_current_plan = true; 392 393 break; 394 } 395 396 } 397 } 398 } 399 400 if (!done_processing_current_plan) 401 { 402 bool over_ride_stop = current_plan->ShouldAutoContinue(event_ptr); 403 404 if (log) 405 log->Printf("Plan %s explains stop, auto-continue %i.", current_plan->GetName(), over_ride_stop); 406 407 // We're starting from the base plan, so just let it decide; 408 if (PlanIsBasePlan(current_plan)) 409 { 410 should_stop = current_plan->ShouldStop (event_ptr); 411 if (log) 412 log->Printf("Base plan says should stop: %i.", should_stop); 413 } 414 else 415 { 416 // Otherwise, don't let the base plan override what the other plans say to do, since 417 // presumably if there were other plans they would know what to do... 418 while (1) 419 { 420 if (PlanIsBasePlan(current_plan)) 421 break; 422 423 should_stop = current_plan->ShouldStop(event_ptr); 424 if (log) 425 log->Printf("Plan %s should stop: %d.", current_plan->GetName(), should_stop); 426 if (current_plan->MischiefManaged()) 427 { 428 if (should_stop) 429 current_plan->WillStop(); 430 431 // If a Master Plan wants to stop, and wants to stick on the stack, we let it. 432 // Otherwise, see if the plan's parent wants to stop. 433 434 if (should_stop && current_plan->IsMasterPlan() && !current_plan->OkayToDiscard()) 435 { 436 PopPlan(); 437 break; 438 } 439 else 440 { 441 442 PopPlan(); 443 444 current_plan = GetCurrentPlan(); 445 if (current_plan == NULL) 446 { 447 break; 448 } 449 } 450 451 } 452 else 453 { 454 break; 455 } 456 } 457 } 458 if (over_ride_stop) 459 should_stop = false; 460 } 461 462 if (log) 463 { 464 StreamString s; 465 s.IndentMore(); 466 DumpThreadPlans(&s); 467 log->Printf ("Plan stack final state:\n%s", s.GetData()); 468 log->Printf ("vvvvvvvv Thread::ShouldStop End (returning %i) vvvvvvvv", should_stop); 469 } 470 return should_stop; 471 } 472 473 Vote 474 Thread::ShouldReportStop (Event* event_ptr) 475 { 476 StateType thread_state = GetResumeState (); 477 StateType temp_thread_state = GetTemporaryResumeState(); 478 479 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 480 481 if (thread_state == eStateSuspended || thread_state == eStateInvalid) 482 { 483 if (log) 484 log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4llx: returning vote %i (state was suspended or invalid)\n", GetID(), eVoteNoOpinion); 485 return eVoteNoOpinion; 486 } 487 488 if (temp_thread_state == eStateSuspended || temp_thread_state == eStateInvalid) 489 { 490 if (log) 491 log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4llx: returning vote %i (temporary state was suspended or invalid)\n", GetID(), eVoteNoOpinion); 492 return eVoteNoOpinion; 493 } 494 495 if (!ThreadStoppedForAReason()) 496 { 497 if (log) 498 log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4llx: returning vote %i (thread didn't stop for a reason.)\n", GetID(), eVoteNoOpinion); 499 return eVoteNoOpinion; 500 } 501 502 if (m_completed_plan_stack.size() > 0) 503 { 504 // Don't use GetCompletedPlan here, since that suppresses private plans. 505 if (log) 506 log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4llx: returning vote for complete stack's back plan\n", GetID()); 507 return m_completed_plan_stack.back()->ShouldReportStop (event_ptr); 508 } 509 else 510 { 511 if (log) 512 log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4llx: returning vote for current plan\n", GetID()); 513 return GetCurrentPlan()->ShouldReportStop (event_ptr); 514 } 515 } 516 517 Vote 518 Thread::ShouldReportRun (Event* event_ptr) 519 { 520 StateType thread_state = GetResumeState (); 521 522 if (thread_state == eStateSuspended 523 || thread_state == eStateInvalid) 524 { 525 return eVoteNoOpinion; 526 } 527 528 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 529 if (m_completed_plan_stack.size() > 0) 530 { 531 // Don't use GetCompletedPlan here, since that suppresses private plans. 532 if (log) 533 log->Printf ("Current Plan for thread %d (0x%4.4llx): %s being asked whether we should report run.", 534 GetIndexID(), 535 GetID(), 536 m_completed_plan_stack.back()->GetName()); 537 538 return m_completed_plan_stack.back()->ShouldReportRun (event_ptr); 539 } 540 else 541 { 542 if (log) 543 log->Printf ("Current Plan for thread %d (0x%4.4llx): %s being asked whether we should report run.", 544 GetIndexID(), 545 GetID(), 546 GetCurrentPlan()->GetName()); 547 548 return GetCurrentPlan()->ShouldReportRun (event_ptr); 549 } 550 } 551 552 bool 553 Thread::MatchesSpec (const ThreadSpec *spec) 554 { 555 if (spec == NULL) 556 return true; 557 558 return spec->ThreadPassesBasicTests(*this); 559 } 560 561 void 562 Thread::PushPlan (ThreadPlanSP &thread_plan_sp) 563 { 564 if (thread_plan_sp) 565 { 566 // If the thread plan doesn't already have a tracer, give it its parent's tracer: 567 if (!thread_plan_sp->GetThreadPlanTracer()) 568 thread_plan_sp->SetThreadPlanTracer(m_plan_stack.back()->GetThreadPlanTracer()); 569 m_plan_stack.push_back (thread_plan_sp); 570 571 thread_plan_sp->DidPush(); 572 573 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 574 if (log) 575 { 576 StreamString s; 577 thread_plan_sp->GetDescription (&s, lldb::eDescriptionLevelFull); 578 log->Printf("Pushing plan: \"%s\", tid = 0x%4.4llx.", 579 s.GetData(), 580 thread_plan_sp->GetThread().GetID()); 581 } 582 } 583 } 584 585 void 586 Thread::PopPlan () 587 { 588 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 589 590 if (m_plan_stack.empty()) 591 return; 592 else 593 { 594 ThreadPlanSP &plan = m_plan_stack.back(); 595 if (log) 596 { 597 log->Printf("Popping plan: \"%s\", tid = 0x%4.4llx.", plan->GetName(), plan->GetThread().GetID()); 598 } 599 m_completed_plan_stack.push_back (plan); 600 plan->WillPop(); 601 m_plan_stack.pop_back(); 602 } 603 } 604 605 void 606 Thread::DiscardPlan () 607 { 608 if (m_plan_stack.size() > 1) 609 { 610 ThreadPlanSP &plan = m_plan_stack.back(); 611 m_discarded_plan_stack.push_back (plan); 612 plan->WillPop(); 613 m_plan_stack.pop_back(); 614 } 615 } 616 617 ThreadPlan * 618 Thread::GetCurrentPlan () 619 { 620 // There will always be at least the base plan. If somebody is mucking with a 621 // thread with an empty plan stack, we should assert right away. 622 assert (!m_plan_stack.empty()); 623 624 return m_plan_stack.back().get(); 625 } 626 627 ThreadPlanSP 628 Thread::GetCompletedPlan () 629 { 630 ThreadPlanSP empty_plan_sp; 631 if (!m_completed_plan_stack.empty()) 632 { 633 for (int i = m_completed_plan_stack.size() - 1; i >= 0; i--) 634 { 635 ThreadPlanSP completed_plan_sp; 636 completed_plan_sp = m_completed_plan_stack[i]; 637 if (!completed_plan_sp->GetPrivate ()) 638 return completed_plan_sp; 639 } 640 } 641 return empty_plan_sp; 642 } 643 644 ValueObjectSP 645 Thread::GetReturnValueObject () 646 { 647 if (!m_completed_plan_stack.empty()) 648 { 649 for (int i = m_completed_plan_stack.size() - 1; i >= 0; i--) 650 { 651 ValueObjectSP return_valobj_sp; 652 return_valobj_sp = m_completed_plan_stack[i]->GetReturnValueObject(); 653 if (return_valobj_sp) 654 return return_valobj_sp; 655 } 656 } 657 return ValueObjectSP(); 658 } 659 660 bool 661 Thread::IsThreadPlanDone (ThreadPlan *plan) 662 { 663 if (!m_completed_plan_stack.empty()) 664 { 665 for (int i = m_completed_plan_stack.size() - 1; i >= 0; i--) 666 { 667 if (m_completed_plan_stack[i].get() == plan) 668 return true; 669 } 670 } 671 return false; 672 } 673 674 bool 675 Thread::WasThreadPlanDiscarded (ThreadPlan *plan) 676 { 677 if (!m_discarded_plan_stack.empty()) 678 { 679 for (int i = m_discarded_plan_stack.size() - 1; i >= 0; i--) 680 { 681 if (m_discarded_plan_stack[i].get() == plan) 682 return true; 683 } 684 } 685 return false; 686 } 687 688 ThreadPlan * 689 Thread::GetPreviousPlan (ThreadPlan *current_plan) 690 { 691 if (current_plan == NULL) 692 return NULL; 693 694 int stack_size = m_completed_plan_stack.size(); 695 for (int i = stack_size - 1; i > 0; i--) 696 { 697 if (current_plan == m_completed_plan_stack[i].get()) 698 return m_completed_plan_stack[i-1].get(); 699 } 700 701 if (stack_size > 0 && m_completed_plan_stack[0].get() == current_plan) 702 { 703 if (m_plan_stack.size() > 0) 704 return m_plan_stack.back().get(); 705 else 706 return NULL; 707 } 708 709 stack_size = m_plan_stack.size(); 710 for (int i = stack_size - 1; i > 0; i--) 711 { 712 if (current_plan == m_plan_stack[i].get()) 713 return m_plan_stack[i-1].get(); 714 } 715 return NULL; 716 } 717 718 void 719 Thread::QueueThreadPlan (ThreadPlanSP &thread_plan_sp, bool abort_other_plans) 720 { 721 if (abort_other_plans) 722 DiscardThreadPlans(true); 723 724 PushPlan (thread_plan_sp); 725 } 726 727 728 void 729 Thread::EnableTracer (bool value, bool single_stepping) 730 { 731 int stack_size = m_plan_stack.size(); 732 for (int i = 0; i < stack_size; i++) 733 { 734 if (m_plan_stack[i]->GetThreadPlanTracer()) 735 { 736 m_plan_stack[i]->GetThreadPlanTracer()->EnableTracing(value); 737 m_plan_stack[i]->GetThreadPlanTracer()->EnableSingleStep(single_stepping); 738 } 739 } 740 } 741 742 void 743 Thread::SetTracer (lldb::ThreadPlanTracerSP &tracer_sp) 744 { 745 int stack_size = m_plan_stack.size(); 746 for (int i = 0; i < stack_size; i++) 747 m_plan_stack[i]->SetThreadPlanTracer(tracer_sp); 748 } 749 750 void 751 Thread::DiscardThreadPlansUpToPlan (lldb::ThreadPlanSP &up_to_plan_sp) 752 { 753 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 754 if (log) 755 { 756 log->Printf("Discarding thread plans for thread tid = 0x%4.4llx, up to %p", GetID(), up_to_plan_sp.get()); 757 } 758 759 int stack_size = m_plan_stack.size(); 760 761 // If the input plan is NULL, discard all plans. Otherwise make sure this plan is in the 762 // stack, and if so discard up to and including it. 763 764 if (up_to_plan_sp.get() == NULL) 765 { 766 for (int i = stack_size - 1; i > 0; i--) 767 DiscardPlan(); 768 } 769 else 770 { 771 bool found_it = false; 772 for (int i = stack_size - 1; i > 0; i--) 773 { 774 if (m_plan_stack[i] == up_to_plan_sp) 775 found_it = true; 776 } 777 if (found_it) 778 { 779 bool last_one = false; 780 for (int i = stack_size - 1; i > 0 && !last_one ; i--) 781 { 782 if (GetCurrentPlan() == up_to_plan_sp.get()) 783 last_one = true; 784 DiscardPlan(); 785 } 786 } 787 } 788 return; 789 } 790 791 void 792 Thread::DiscardThreadPlans(bool force) 793 { 794 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 795 if (log) 796 { 797 log->Printf("Discarding thread plans for thread (tid = 0x%4.4llx, force %d)", GetID(), force); 798 } 799 800 if (force) 801 { 802 int stack_size = m_plan_stack.size(); 803 for (int i = stack_size - 1; i > 0; i--) 804 { 805 DiscardPlan(); 806 } 807 return; 808 } 809 810 while (1) 811 { 812 813 int master_plan_idx; 814 bool discard; 815 816 // Find the first master plan, see if it wants discarding, and if yes discard up to it. 817 for (master_plan_idx = m_plan_stack.size() - 1; master_plan_idx >= 0; master_plan_idx--) 818 { 819 if (m_plan_stack[master_plan_idx]->IsMasterPlan()) 820 { 821 discard = m_plan_stack[master_plan_idx]->OkayToDiscard(); 822 break; 823 } 824 } 825 826 if (discard) 827 { 828 // First pop all the dependent plans: 829 for (int i = m_plan_stack.size() - 1; i > master_plan_idx; i--) 830 { 831 832 // FIXME: Do we need a finalize here, or is the rule that "PrepareForStop" 833 // for the plan leaves it in a state that it is safe to pop the plan 834 // with no more notice? 835 DiscardPlan(); 836 } 837 838 // Now discard the master plan itself. 839 // The bottom-most plan never gets discarded. "OkayToDiscard" for it means 840 // discard it's dependent plans, but not it... 841 if (master_plan_idx > 0) 842 { 843 DiscardPlan(); 844 } 845 } 846 else 847 { 848 // If the master plan doesn't want to get discarded, then we're done. 849 break; 850 } 851 852 } 853 } 854 855 bool 856 Thread::PlanIsBasePlan (ThreadPlan *plan_ptr) 857 { 858 if (plan_ptr->IsBasePlan()) 859 return true; 860 else if (m_plan_stack.size() == 0) 861 return false; 862 else 863 return m_plan_stack[0].get() == plan_ptr; 864 } 865 866 ThreadPlan * 867 Thread::QueueFundamentalPlan (bool abort_other_plans) 868 { 869 ThreadPlanSP thread_plan_sp (new ThreadPlanBase(*this)); 870 QueueThreadPlan (thread_plan_sp, abort_other_plans); 871 return thread_plan_sp.get(); 872 } 873 874 ThreadPlan * 875 Thread::QueueThreadPlanForStepSingleInstruction 876 ( 877 bool step_over, 878 bool abort_other_plans, 879 bool stop_other_threads 880 ) 881 { 882 ThreadPlanSP thread_plan_sp (new ThreadPlanStepInstruction (*this, step_over, stop_other_threads, eVoteNoOpinion, eVoteNoOpinion)); 883 QueueThreadPlan (thread_plan_sp, abort_other_plans); 884 return thread_plan_sp.get(); 885 } 886 887 ThreadPlan * 888 Thread::QueueThreadPlanForStepRange 889 ( 890 bool abort_other_plans, 891 StepType type, 892 const AddressRange &range, 893 const SymbolContext &addr_context, 894 lldb::RunMode stop_other_threads, 895 bool avoid_code_without_debug_info 896 ) 897 { 898 ThreadPlanSP thread_plan_sp; 899 if (type == eStepTypeInto) 900 { 901 ThreadPlanStepInRange *plan = new ThreadPlanStepInRange (*this, range, addr_context, stop_other_threads); 902 if (avoid_code_without_debug_info) 903 plan->GetFlags().Set (ThreadPlanShouldStopHere::eAvoidNoDebug); 904 else 905 plan->GetFlags().Clear (ThreadPlanShouldStopHere::eAvoidNoDebug); 906 thread_plan_sp.reset (plan); 907 } 908 else 909 thread_plan_sp.reset (new ThreadPlanStepOverRange (*this, range, addr_context, stop_other_threads)); 910 911 QueueThreadPlan (thread_plan_sp, abort_other_plans); 912 return thread_plan_sp.get(); 913 } 914 915 916 ThreadPlan * 917 Thread::QueueThreadPlanForStepOverBreakpointPlan (bool abort_other_plans) 918 { 919 ThreadPlanSP thread_plan_sp (new ThreadPlanStepOverBreakpoint (*this)); 920 QueueThreadPlan (thread_plan_sp, abort_other_plans); 921 return thread_plan_sp.get(); 922 } 923 924 ThreadPlan * 925 Thread::QueueThreadPlanForStepOut 926 ( 927 bool abort_other_plans, 928 SymbolContext *addr_context, 929 bool first_insn, 930 bool stop_other_threads, 931 Vote stop_vote, 932 Vote run_vote, 933 uint32_t frame_idx 934 ) 935 { 936 ThreadPlanSP thread_plan_sp (new ThreadPlanStepOut (*this, 937 addr_context, 938 first_insn, 939 stop_other_threads, 940 stop_vote, 941 run_vote, 942 frame_idx)); 943 QueueThreadPlan (thread_plan_sp, abort_other_plans); 944 return thread_plan_sp.get(); 945 } 946 947 ThreadPlan * 948 Thread::QueueThreadPlanForStepThrough (bool abort_other_plans, bool stop_other_threads) 949 { 950 ThreadPlanSP thread_plan_sp(new ThreadPlanStepThrough (*this, stop_other_threads)); 951 if (!thread_plan_sp || !thread_plan_sp->ValidatePlan (NULL)) 952 return NULL; 953 954 QueueThreadPlan (thread_plan_sp, abort_other_plans); 955 return thread_plan_sp.get(); 956 } 957 958 ThreadPlan * 959 Thread::QueueThreadPlanForCallFunction (bool abort_other_plans, 960 Address& function, 961 lldb::addr_t arg, 962 bool stop_other_threads, 963 bool discard_on_error) 964 { 965 ThreadPlanSP thread_plan_sp (new ThreadPlanCallFunction (*this, function, ClangASTType(), arg, stop_other_threads, discard_on_error)); 966 QueueThreadPlan (thread_plan_sp, abort_other_plans); 967 return thread_plan_sp.get(); 968 } 969 970 ThreadPlan * 971 Thread::QueueThreadPlanForRunToAddress (bool abort_other_plans, 972 Address &target_addr, 973 bool stop_other_threads) 974 { 975 ThreadPlanSP thread_plan_sp (new ThreadPlanRunToAddress (*this, target_addr, stop_other_threads)); 976 QueueThreadPlan (thread_plan_sp, abort_other_plans); 977 return thread_plan_sp.get(); 978 } 979 980 ThreadPlan * 981 Thread::QueueThreadPlanForStepUntil (bool abort_other_plans, 982 lldb::addr_t *address_list, 983 size_t num_addresses, 984 bool stop_other_threads, 985 uint32_t frame_idx) 986 { 987 ThreadPlanSP thread_plan_sp (new ThreadPlanStepUntil (*this, address_list, num_addresses, stop_other_threads, frame_idx)); 988 QueueThreadPlan (thread_plan_sp, abort_other_plans); 989 return thread_plan_sp.get(); 990 991 } 992 993 uint32_t 994 Thread::GetIndexID () const 995 { 996 return m_index_id; 997 } 998 999 void 1000 Thread::DumpThreadPlans (lldb_private::Stream *s) const 1001 { 1002 uint32_t stack_size = m_plan_stack.size(); 1003 int i; 1004 s->Indent(); 1005 s->Printf ("Plan Stack for thread #%u: tid = 0x%4.4llx, stack_size = %d\n", GetIndexID(), GetID(), stack_size); 1006 for (i = stack_size - 1; i >= 0; i--) 1007 { 1008 s->IndentMore(); 1009 s->Indent(); 1010 s->Printf ("Element %d: ", i); 1011 m_plan_stack[i]->GetDescription (s, eDescriptionLevelFull); 1012 s->EOL(); 1013 s->IndentLess(); 1014 } 1015 1016 stack_size = m_completed_plan_stack.size(); 1017 if (stack_size > 0) 1018 { 1019 s->Indent(); 1020 s->Printf ("Completed Plan Stack: %d elements.\n", stack_size); 1021 for (i = stack_size - 1; i >= 0; i--) 1022 { 1023 s->IndentMore(); 1024 s->Indent(); 1025 s->Printf ("Element %d: ", i); 1026 m_completed_plan_stack[i]->GetDescription (s, eDescriptionLevelFull); 1027 s->EOL(); 1028 s->IndentLess(); 1029 } 1030 } 1031 1032 stack_size = m_discarded_plan_stack.size(); 1033 if (stack_size > 0) 1034 { 1035 s->Indent(); 1036 s->Printf ("Discarded Plan Stack: %d elements.\n", stack_size); 1037 for (i = stack_size - 1; i >= 0; i--) 1038 { 1039 s->IndentMore(); 1040 s->Indent(); 1041 s->Printf ("Element %d: ", i); 1042 m_discarded_plan_stack[i]->GetDescription (s, eDescriptionLevelFull); 1043 s->EOL(); 1044 s->IndentLess(); 1045 } 1046 } 1047 1048 } 1049 1050 TargetSP 1051 Thread::CalculateTarget () 1052 { 1053 TargetSP target_sp; 1054 ProcessSP process_sp(GetProcess()); 1055 if (process_sp) 1056 target_sp = process_sp->CalculateTarget(); 1057 return target_sp; 1058 1059 } 1060 1061 ProcessSP 1062 Thread::CalculateProcess () 1063 { 1064 return GetProcess(); 1065 } 1066 1067 ThreadSP 1068 Thread::CalculateThread () 1069 { 1070 return shared_from_this(); 1071 } 1072 1073 StackFrameSP 1074 Thread::CalculateStackFrame () 1075 { 1076 return StackFrameSP(); 1077 } 1078 1079 void 1080 Thread::CalculateExecutionContext (ExecutionContext &exe_ctx) 1081 { 1082 exe_ctx.SetContext (shared_from_this()); 1083 } 1084 1085 1086 StackFrameListSP 1087 Thread::GetStackFrameList () 1088 { 1089 StackFrameListSP frame_list_sp; 1090 Mutex::Locker locker(m_frame_mutex); 1091 if (m_curr_frames_sp) 1092 { 1093 frame_list_sp = m_curr_frames_sp; 1094 } 1095 else 1096 { 1097 frame_list_sp.reset(new StackFrameList (*this, m_prev_frames_sp, true)); 1098 m_curr_frames_sp = frame_list_sp; 1099 } 1100 return frame_list_sp; 1101 } 1102 1103 void 1104 Thread::ClearStackFrames () 1105 { 1106 Mutex::Locker locker(m_frame_mutex); 1107 1108 // Only store away the old "reference" StackFrameList if we got all its frames: 1109 // FIXME: At some point we can try to splice in the frames we have fetched into 1110 // the new frame as we make it, but let's not try that now. 1111 if (m_curr_frames_sp && m_curr_frames_sp->GetAllFramesFetched()) 1112 m_prev_frames_sp.swap (m_curr_frames_sp); 1113 m_curr_frames_sp.reset(); 1114 } 1115 1116 lldb::StackFrameSP 1117 Thread::GetFrameWithConcreteFrameIndex (uint32_t unwind_idx) 1118 { 1119 return GetStackFrameList()->GetFrameWithConcreteFrameIndex (unwind_idx); 1120 } 1121 1122 void 1123 Thread::DumpUsingSettingsFormat (Stream &strm, uint32_t frame_idx) 1124 { 1125 ExecutionContext exe_ctx (shared_from_this()); 1126 Process *process = exe_ctx.GetProcessPtr(); 1127 if (process == NULL) 1128 return; 1129 1130 StackFrameSP frame_sp; 1131 SymbolContext frame_sc; 1132 if (frame_idx != LLDB_INVALID_INDEX32) 1133 { 1134 frame_sp = GetStackFrameAtIndex (frame_idx); 1135 if (frame_sp) 1136 { 1137 exe_ctx.SetFrameSP(frame_sp); 1138 frame_sc = frame_sp->GetSymbolContext(eSymbolContextEverything); 1139 } 1140 } 1141 1142 const char *thread_format = exe_ctx.GetTargetRef().GetDebugger().GetThreadFormat(); 1143 assert (thread_format); 1144 const char *end = NULL; 1145 Debugger::FormatPrompt (thread_format, 1146 frame_sp ? &frame_sc : NULL, 1147 &exe_ctx, 1148 NULL, 1149 strm, 1150 &end); 1151 } 1152 1153 void 1154 Thread::SettingsInitialize () 1155 { 1156 UserSettingsController::InitializeSettingsController (GetSettingsController(), 1157 SettingsController::global_settings_table, 1158 SettingsController::instance_settings_table); 1159 1160 // Now call SettingsInitialize() on each 'child' setting of Thread. 1161 // Currently there are none. 1162 } 1163 1164 void 1165 Thread::SettingsTerminate () 1166 { 1167 // Must call SettingsTerminate() on each 'child' setting of Thread before terminating Thread settings. 1168 // Currently there are none. 1169 1170 // Now terminate Thread Settings. 1171 1172 UserSettingsControllerSP &usc = GetSettingsController(); 1173 UserSettingsController::FinalizeSettingsController (usc); 1174 usc.reset(); 1175 } 1176 1177 UserSettingsControllerSP & 1178 Thread::GetSettingsController () 1179 { 1180 static UserSettingsControllerSP g_settings_controller_sp; 1181 if (!g_settings_controller_sp) 1182 { 1183 g_settings_controller_sp.reset (new Thread::SettingsController); 1184 // The first shared pointer to Target::SettingsController in 1185 // g_settings_controller_sp must be fully created above so that 1186 // the TargetInstanceSettings can use a weak_ptr to refer back 1187 // to the master setttings controller 1188 InstanceSettingsSP default_instance_settings_sp (new ThreadInstanceSettings (g_settings_controller_sp, 1189 false, 1190 InstanceSettings::GetDefaultName().AsCString())); 1191 1192 g_settings_controller_sp->SetDefaultInstanceSettings (default_instance_settings_sp); 1193 } 1194 return g_settings_controller_sp; 1195 } 1196 1197 void 1198 Thread::UpdateInstanceName () 1199 { 1200 StreamString sstr; 1201 const char *name = GetName(); 1202 1203 if (name && name[0] != '\0') 1204 sstr.Printf ("%s", name); 1205 else if ((GetIndexID() != 0) || (GetID() != 0)) 1206 sstr.Printf ("0x%4.4x", GetIndexID()); 1207 1208 if (sstr.GetSize() > 0) 1209 Thread::GetSettingsController()->RenameInstanceSettings (GetInstanceName().AsCString(), sstr.GetData()); 1210 } 1211 1212 lldb::StackFrameSP 1213 Thread::GetStackFrameSPForStackFramePtr (StackFrame *stack_frame_ptr) 1214 { 1215 return GetStackFrameList()->GetStackFrameSPForStackFramePtr (stack_frame_ptr); 1216 } 1217 1218 const char * 1219 Thread::StopReasonAsCString (lldb::StopReason reason) 1220 { 1221 switch (reason) 1222 { 1223 case eStopReasonInvalid: return "invalid"; 1224 case eStopReasonNone: return "none"; 1225 case eStopReasonTrace: return "trace"; 1226 case eStopReasonBreakpoint: return "breakpoint"; 1227 case eStopReasonWatchpoint: return "watchpoint"; 1228 case eStopReasonSignal: return "signal"; 1229 case eStopReasonException: return "exception"; 1230 case eStopReasonPlanComplete: return "plan complete"; 1231 } 1232 1233 1234 static char unknown_state_string[64]; 1235 snprintf(unknown_state_string, sizeof (unknown_state_string), "StopReason = %i", reason); 1236 return unknown_state_string; 1237 } 1238 1239 const char * 1240 Thread::RunModeAsCString (lldb::RunMode mode) 1241 { 1242 switch (mode) 1243 { 1244 case eOnlyThisThread: return "only this thread"; 1245 case eAllThreads: return "all threads"; 1246 case eOnlyDuringStepping: return "only during stepping"; 1247 } 1248 1249 static char unknown_state_string[64]; 1250 snprintf(unknown_state_string, sizeof (unknown_state_string), "RunMode = %i", mode); 1251 return unknown_state_string; 1252 } 1253 1254 size_t 1255 Thread::GetStatus (Stream &strm, uint32_t start_frame, uint32_t num_frames, uint32_t num_frames_with_source) 1256 { 1257 ExecutionContext exe_ctx (shared_from_this()); 1258 Target *target = exe_ctx.GetTargetPtr(); 1259 Process *process = exe_ctx.GetProcessPtr(); 1260 size_t num_frames_shown = 0; 1261 strm.Indent(); 1262 bool is_selected = false; 1263 if (process) 1264 { 1265 if (process->GetThreadList().GetSelectedThread().get() == this) 1266 is_selected = true; 1267 } 1268 strm.Printf("%c ", is_selected ? '*' : ' '); 1269 if (target && target->GetDebugger().GetUseExternalEditor()) 1270 { 1271 StackFrameSP frame_sp = GetStackFrameAtIndex(start_frame); 1272 if (frame_sp) 1273 { 1274 SymbolContext frame_sc(frame_sp->GetSymbolContext (eSymbolContextLineEntry)); 1275 if (frame_sc.line_entry.line != 0 && frame_sc.line_entry.file) 1276 { 1277 Host::OpenFileInExternalEditor (frame_sc.line_entry.file, frame_sc.line_entry.line); 1278 } 1279 } 1280 } 1281 1282 DumpUsingSettingsFormat (strm, start_frame); 1283 1284 if (num_frames > 0) 1285 { 1286 strm.IndentMore(); 1287 1288 const bool show_frame_info = true; 1289 const uint32_t source_lines_before = 3; 1290 const uint32_t source_lines_after = 3; 1291 strm.IndentMore (); 1292 num_frames_shown = GetStackFrameList ()->GetStatus (strm, 1293 start_frame, 1294 num_frames, 1295 show_frame_info, 1296 num_frames_with_source, 1297 source_lines_before, 1298 source_lines_after); 1299 strm.IndentLess(); 1300 strm.IndentLess(); 1301 } 1302 return num_frames_shown; 1303 } 1304 1305 size_t 1306 Thread::GetStackFrameStatus (Stream& strm, 1307 uint32_t first_frame, 1308 uint32_t num_frames, 1309 bool show_frame_info, 1310 uint32_t num_frames_with_source, 1311 uint32_t source_lines_before, 1312 uint32_t source_lines_after) 1313 { 1314 return GetStackFrameList()->GetStatus (strm, 1315 first_frame, 1316 num_frames, 1317 show_frame_info, 1318 num_frames_with_source, 1319 source_lines_before, 1320 source_lines_after); 1321 } 1322 1323 bool 1324 Thread::SaveFrameZeroState (RegisterCheckpoint &checkpoint) 1325 { 1326 lldb::StackFrameSP frame_sp(GetStackFrameAtIndex (0)); 1327 if (frame_sp) 1328 { 1329 checkpoint.SetStackID(frame_sp->GetStackID()); 1330 return frame_sp->GetRegisterContext()->ReadAllRegisterValues (checkpoint.GetData()); 1331 } 1332 return false; 1333 } 1334 1335 bool 1336 Thread::RestoreSaveFrameZero (const RegisterCheckpoint &checkpoint) 1337 { 1338 lldb::StackFrameSP frame_sp(GetStackFrameAtIndex (0)); 1339 if (frame_sp) 1340 { 1341 bool ret = frame_sp->GetRegisterContext()->WriteAllRegisterValues (checkpoint.GetData()); 1342 1343 // Clear out all stack frames as our world just changed. 1344 ClearStackFrames(); 1345 frame_sp->GetRegisterContext()->InvalidateIfNeeded(true); 1346 1347 return ret; 1348 } 1349 return false; 1350 } 1351 1352 Unwind * 1353 Thread::GetUnwinder () 1354 { 1355 if (m_unwinder_ap.get() == NULL) 1356 { 1357 const ArchSpec target_arch (CalculateTarget()->GetArchitecture ()); 1358 const llvm::Triple::ArchType machine = target_arch.GetMachine(); 1359 switch (machine) 1360 { 1361 case llvm::Triple::x86_64: 1362 case llvm::Triple::x86: 1363 case llvm::Triple::arm: 1364 case llvm::Triple::thumb: 1365 m_unwinder_ap.reset (new UnwindLLDB (*this)); 1366 break; 1367 1368 default: 1369 if (target_arch.GetTriple().getVendor() == llvm::Triple::Apple) 1370 m_unwinder_ap.reset (new UnwindMacOSXFrameBackchain (*this)); 1371 break; 1372 } 1373 } 1374 return m_unwinder_ap.get(); 1375 } 1376 1377 1378 #pragma mark "Thread::SettingsController" 1379 //-------------------------------------------------------------- 1380 // class Thread::SettingsController 1381 //-------------------------------------------------------------- 1382 1383 Thread::SettingsController::SettingsController () : 1384 UserSettingsController ("thread", Process::GetSettingsController()) 1385 { 1386 } 1387 1388 Thread::SettingsController::~SettingsController () 1389 { 1390 } 1391 1392 lldb::InstanceSettingsSP 1393 Thread::SettingsController::CreateInstanceSettings (const char *instance_name) 1394 { 1395 lldb::InstanceSettingsSP new_settings_sp (new ThreadInstanceSettings (GetSettingsController(), 1396 false, 1397 instance_name)); 1398 return new_settings_sp; 1399 } 1400 1401 #pragma mark "ThreadInstanceSettings" 1402 //-------------------------------------------------------------- 1403 // class ThreadInstanceSettings 1404 //-------------------------------------------------------------- 1405 1406 ThreadInstanceSettings::ThreadInstanceSettings (const UserSettingsControllerSP &owner_sp, bool live_instance, const char *name) : 1407 InstanceSettings (owner_sp, name ? name : InstanceSettings::InvalidName().AsCString(), live_instance), 1408 m_avoid_regexp_ap (), 1409 m_trace_enabled (false) 1410 { 1411 // CopyInstanceSettings is a pure virtual function in InstanceSettings; it therefore cannot be called 1412 // until the vtables for ThreadInstanceSettings are properly set up, i.e. AFTER all the initializers. 1413 // For this reason it has to be called here, rather than in the initializer or in the parent constructor. 1414 // This is true for CreateInstanceName() too. 1415 1416 if (GetInstanceName() == InstanceSettings::InvalidName()) 1417 { 1418 ChangeInstanceName (std::string (CreateInstanceName().AsCString())); 1419 owner_sp->RegisterInstanceSettings (this); 1420 } 1421 1422 if (live_instance) 1423 { 1424 CopyInstanceSettings (owner_sp->FindPendingSettings (m_instance_name),false); 1425 } 1426 } 1427 1428 ThreadInstanceSettings::ThreadInstanceSettings (const ThreadInstanceSettings &rhs) : 1429 InstanceSettings (Thread::GetSettingsController(), CreateInstanceName().AsCString()), 1430 m_avoid_regexp_ap (), 1431 m_trace_enabled (rhs.m_trace_enabled) 1432 { 1433 if (m_instance_name != InstanceSettings::GetDefaultName()) 1434 { 1435 UserSettingsControllerSP owner_sp (m_owner_wp.lock()); 1436 if (owner_sp) 1437 { 1438 CopyInstanceSettings (owner_sp->FindPendingSettings (m_instance_name), false); 1439 owner_sp->RemovePendingSettings (m_instance_name); 1440 } 1441 } 1442 if (rhs.m_avoid_regexp_ap.get() != NULL) 1443 m_avoid_regexp_ap.reset(new RegularExpression(rhs.m_avoid_regexp_ap->GetText())); 1444 } 1445 1446 ThreadInstanceSettings::~ThreadInstanceSettings () 1447 { 1448 } 1449 1450 ThreadInstanceSettings& 1451 ThreadInstanceSettings::operator= (const ThreadInstanceSettings &rhs) 1452 { 1453 if (this != &rhs) 1454 { 1455 if (rhs.m_avoid_regexp_ap.get() != NULL) 1456 m_avoid_regexp_ap.reset(new RegularExpression(rhs.m_avoid_regexp_ap->GetText())); 1457 else 1458 m_avoid_regexp_ap.reset(NULL); 1459 } 1460 m_trace_enabled = rhs.m_trace_enabled; 1461 return *this; 1462 } 1463 1464 1465 void 1466 ThreadInstanceSettings::UpdateInstanceSettingsVariable (const ConstString &var_name, 1467 const char *index_value, 1468 const char *value, 1469 const ConstString &instance_name, 1470 const SettingEntry &entry, 1471 VarSetOperationType op, 1472 Error &err, 1473 bool pending) 1474 { 1475 if (var_name == StepAvoidRegexpVarName()) 1476 { 1477 std::string regexp_text; 1478 if (m_avoid_regexp_ap.get() != NULL) 1479 regexp_text.append (m_avoid_regexp_ap->GetText()); 1480 UserSettingsController::UpdateStringVariable (op, regexp_text, value, err); 1481 if (regexp_text.empty()) 1482 m_avoid_regexp_ap.reset(); 1483 else 1484 { 1485 m_avoid_regexp_ap.reset(new RegularExpression(regexp_text.c_str())); 1486 1487 } 1488 } 1489 else if (var_name == GetTraceThreadVarName()) 1490 { 1491 bool success; 1492 bool result = Args::StringToBoolean(value, false, &success); 1493 1494 if (success) 1495 { 1496 m_trace_enabled = result; 1497 if (!pending) 1498 { 1499 Thread *myself = static_cast<Thread *> (this); 1500 myself->EnableTracer(m_trace_enabled, true); 1501 } 1502 } 1503 else 1504 { 1505 err.SetErrorStringWithFormat ("Bad value \"%s\" for trace-thread, should be Boolean.", value); 1506 } 1507 1508 } 1509 } 1510 1511 void 1512 ThreadInstanceSettings::CopyInstanceSettings (const lldb::InstanceSettingsSP &new_settings, 1513 bool pending) 1514 { 1515 if (new_settings.get() == NULL) 1516 return; 1517 1518 ThreadInstanceSettings *new_process_settings = (ThreadInstanceSettings *) new_settings.get(); 1519 if (new_process_settings->GetSymbolsToAvoidRegexp() != NULL) 1520 m_avoid_regexp_ap.reset (new RegularExpression (new_process_settings->GetSymbolsToAvoidRegexp()->GetText())); 1521 else 1522 m_avoid_regexp_ap.reset (); 1523 } 1524 1525 bool 1526 ThreadInstanceSettings::GetInstanceSettingsValue (const SettingEntry &entry, 1527 const ConstString &var_name, 1528 StringList &value, 1529 Error *err) 1530 { 1531 if (var_name == StepAvoidRegexpVarName()) 1532 { 1533 if (m_avoid_regexp_ap.get() != NULL) 1534 { 1535 std::string regexp_text("\""); 1536 regexp_text.append(m_avoid_regexp_ap->GetText()); 1537 regexp_text.append ("\""); 1538 value.AppendString (regexp_text.c_str()); 1539 } 1540 1541 } 1542 else if (var_name == GetTraceThreadVarName()) 1543 { 1544 value.AppendString(m_trace_enabled ? "true" : "false"); 1545 } 1546 else 1547 { 1548 if (err) 1549 err->SetErrorStringWithFormat ("unrecognized variable name '%s'", var_name.AsCString()); 1550 return false; 1551 } 1552 return true; 1553 } 1554 1555 const ConstString 1556 ThreadInstanceSettings::CreateInstanceName () 1557 { 1558 static int instance_count = 1; 1559 StreamString sstr; 1560 1561 sstr.Printf ("thread_%d", instance_count); 1562 ++instance_count; 1563 1564 const ConstString ret_val (sstr.GetData()); 1565 return ret_val; 1566 } 1567 1568 const ConstString & 1569 ThreadInstanceSettings::StepAvoidRegexpVarName () 1570 { 1571 static ConstString step_avoid_var_name ("step-avoid-regexp"); 1572 1573 return step_avoid_var_name; 1574 } 1575 1576 const ConstString & 1577 ThreadInstanceSettings::GetTraceThreadVarName () 1578 { 1579 static ConstString trace_thread_var_name ("trace-thread"); 1580 1581 return trace_thread_var_name; 1582 } 1583 1584 //-------------------------------------------------- 1585 // SettingsController Variable Tables 1586 //-------------------------------------------------- 1587 1588 SettingEntry 1589 Thread::SettingsController::global_settings_table[] = 1590 { 1591 //{ "var-name", var-type , "default", enum-table, init'd, hidden, "help-text"}, 1592 { NULL, eSetVarTypeNone, NULL, NULL, 0, 0, NULL } 1593 }; 1594 1595 1596 SettingEntry 1597 Thread::SettingsController::instance_settings_table[] = 1598 { 1599 //{ "var-name", var-type, "default", enum-table, init'd, hidden, "help-text"}, 1600 { "step-avoid-regexp", eSetVarTypeString, "", NULL, false, false, "A regular expression defining functions step-in won't stop in." }, 1601 { "trace-thread", eSetVarTypeBoolean, "false", NULL, false, false, "If true, this thread will single-step and log execution." }, 1602 { NULL, eSetVarTypeNone, NULL, NULL, 0, 0, NULL } 1603 }; 1604