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