1 //===-- ThreadList.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 // C Includes 11 #include <stdlib.h> 12 13 // C++ Includes 14 #include <algorithm> 15 16 // Other libraries and framework includes 17 // Project includes 18 #include "lldb/Core/Log.h" 19 #include "lldb/Core/State.h" 20 #include "lldb/Target/RegisterContext.h" 21 #include "lldb/Target/ThreadList.h" 22 #include "lldb/Target/Thread.h" 23 #include "lldb/Target/ThreadPlan.h" 24 #include "lldb/Target/Process.h" 25 #include "lldb/Utility/ConvertEnum.h" 26 #include "lldb/Utility/LLDBAssert.h" 27 28 using namespace lldb; 29 using namespace lldb_private; 30 31 ThreadList::ThreadList (Process *process) : 32 ThreadCollection(), 33 m_process (process), 34 m_stop_id (0), 35 m_selected_tid (LLDB_INVALID_THREAD_ID) 36 { 37 } 38 39 ThreadList::ThreadList (const ThreadList &rhs) : 40 ThreadCollection(), 41 m_process (rhs.m_process), 42 m_stop_id (rhs.m_stop_id), 43 m_selected_tid () 44 { 45 // Use the assignment operator since it uses the mutex 46 *this = rhs; 47 } 48 49 const ThreadList& 50 ThreadList::operator = (const ThreadList& rhs) 51 { 52 if (this != &rhs) 53 { 54 // Lock both mutexes to make sure neither side changes anyone on us 55 // while the assignment occurs 56 Mutex::Locker locker(GetMutex()); 57 m_process = rhs.m_process; 58 m_stop_id = rhs.m_stop_id; 59 m_threads = rhs.m_threads; 60 m_selected_tid = rhs.m_selected_tid; 61 } 62 return *this; 63 } 64 65 66 ThreadList::~ThreadList() 67 { 68 // Clear the thread list. Clear will take the mutex lock 69 // which will ensure that if anyone is using the list 70 // they won't get it removed while using it. 71 Clear(); 72 } 73 74 75 uint32_t 76 ThreadList::GetStopID () const 77 { 78 return m_stop_id; 79 } 80 81 void 82 ThreadList::SetStopID (uint32_t stop_id) 83 { 84 m_stop_id = stop_id; 85 } 86 87 uint32_t 88 ThreadList::GetSize (bool can_update) 89 { 90 Mutex::Locker locker(GetMutex()); 91 if (can_update) 92 m_process->UpdateThreadListIfNeeded(); 93 return m_threads.size(); 94 } 95 96 ThreadSP 97 ThreadList::GetThreadAtIndex (uint32_t idx, bool can_update) 98 { 99 Mutex::Locker locker(GetMutex()); 100 if (can_update) 101 m_process->UpdateThreadListIfNeeded(); 102 103 ThreadSP thread_sp; 104 if (idx < m_threads.size()) 105 thread_sp = m_threads[idx]; 106 return thread_sp; 107 } 108 109 ThreadSP 110 ThreadList::FindThreadByID (lldb::tid_t tid, bool can_update) 111 { 112 Mutex::Locker locker(GetMutex()); 113 114 if (can_update) 115 m_process->UpdateThreadListIfNeeded(); 116 117 ThreadSP thread_sp; 118 uint32_t idx = 0; 119 const uint32_t num_threads = m_threads.size(); 120 for (idx = 0; idx < num_threads; ++idx) 121 { 122 if (m_threads[idx]->GetID() == tid) 123 { 124 thread_sp = m_threads[idx]; 125 break; 126 } 127 } 128 return thread_sp; 129 } 130 131 ThreadSP 132 ThreadList::FindThreadByProtocolID (lldb::tid_t tid, bool can_update) 133 { 134 Mutex::Locker locker(GetMutex()); 135 136 if (can_update) 137 m_process->UpdateThreadListIfNeeded(); 138 139 ThreadSP thread_sp; 140 uint32_t idx = 0; 141 const uint32_t num_threads = m_threads.size(); 142 for (idx = 0; idx < num_threads; ++idx) 143 { 144 if (m_threads[idx]->GetProtocolID() == tid) 145 { 146 thread_sp = m_threads[idx]; 147 break; 148 } 149 } 150 return thread_sp; 151 } 152 153 154 ThreadSP 155 ThreadList::RemoveThreadByID (lldb::tid_t tid, bool can_update) 156 { 157 Mutex::Locker locker(GetMutex()); 158 159 if (can_update) 160 m_process->UpdateThreadListIfNeeded(); 161 162 ThreadSP thread_sp; 163 uint32_t idx = 0; 164 const uint32_t num_threads = m_threads.size(); 165 for (idx = 0; idx < num_threads; ++idx) 166 { 167 if (m_threads[idx]->GetID() == tid) 168 { 169 thread_sp = m_threads[idx]; 170 m_threads.erase(m_threads.begin()+idx); 171 break; 172 } 173 } 174 return thread_sp; 175 } 176 177 ThreadSP 178 ThreadList::RemoveThreadByProtocolID (lldb::tid_t tid, bool can_update) 179 { 180 Mutex::Locker locker(GetMutex()); 181 182 if (can_update) 183 m_process->UpdateThreadListIfNeeded(); 184 185 ThreadSP thread_sp; 186 uint32_t idx = 0; 187 const uint32_t num_threads = m_threads.size(); 188 for (idx = 0; idx < num_threads; ++idx) 189 { 190 if (m_threads[idx]->GetProtocolID() == tid) 191 { 192 thread_sp = m_threads[idx]; 193 m_threads.erase(m_threads.begin()+idx); 194 break; 195 } 196 } 197 return thread_sp; 198 } 199 200 ThreadSP 201 ThreadList::GetThreadSPForThreadPtr (Thread *thread_ptr) 202 { 203 ThreadSP thread_sp; 204 if (thread_ptr) 205 { 206 Mutex::Locker locker(GetMutex()); 207 208 uint32_t idx = 0; 209 const uint32_t num_threads = m_threads.size(); 210 for (idx = 0; idx < num_threads; ++idx) 211 { 212 if (m_threads[idx].get() == thread_ptr) 213 { 214 thread_sp = m_threads[idx]; 215 break; 216 } 217 } 218 } 219 return thread_sp; 220 } 221 222 223 224 ThreadSP 225 ThreadList::FindThreadByIndexID (uint32_t index_id, bool can_update) 226 { 227 Mutex::Locker locker(GetMutex()); 228 229 if (can_update) 230 m_process->UpdateThreadListIfNeeded(); 231 232 ThreadSP thread_sp; 233 const uint32_t num_threads = m_threads.size(); 234 for (uint32_t idx = 0; idx < num_threads; ++idx) 235 { 236 if (m_threads[idx]->GetIndexID() == index_id) 237 { 238 thread_sp = m_threads[idx]; 239 break; 240 } 241 } 242 return thread_sp; 243 } 244 245 bool 246 ThreadList::ShouldStop (Event *event_ptr) 247 { 248 // Running events should never stop, obviously... 249 250 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 251 252 // The ShouldStop method of the threads can do a whole lot of work, 253 // figuring out whether the thread plan conditions are met. So we don't want 254 // to keep the ThreadList locked the whole time we are doing this. 255 // FIXME: It is possible that running code could cause new threads 256 // to be created. If that happens, we will miss asking them whether 257 // they should stop. This is not a big deal since we haven't had 258 // a chance to hang any interesting operations on those threads yet. 259 260 collection threads_copy; 261 { 262 // Scope for locker 263 Mutex::Locker locker(GetMutex()); 264 265 m_process->UpdateThreadListIfNeeded(); 266 for (lldb::ThreadSP thread_sp : m_threads) 267 { 268 // This is an optimization... If we didn't let a thread run in between the previous stop and this 269 // one, we shouldn't have to consult it for ShouldStop. So just leave it off the list we are going to 270 // inspect. 271 // On Linux, if a thread-specific conditional breakpoint was hit, it won't necessarily be the thread 272 // that hit the breakpoint itself that evaluates the conditional expression, so the thread that hit 273 // the breakpoint could still be asked to stop, even though it hasn't been allowed to run since the 274 // previous stop. 275 if (thread_sp->GetTemporaryResumeState () != eStateSuspended || thread_sp->IsStillAtLastBreakpointHit()) 276 threads_copy.push_back(thread_sp); 277 } 278 279 // It is possible the threads we were allowing to run all exited and then maybe the user interrupted 280 // or something, then fall back on looking at all threads: 281 282 if (threads_copy.size() == 0) 283 threads_copy = m_threads; 284 } 285 286 collection::iterator pos, end = threads_copy.end(); 287 288 if (log) 289 { 290 log->PutCString(""); 291 log->Printf ("ThreadList::%s: %" PRIu64 " threads, %" PRIu64 " unsuspended threads", 292 __FUNCTION__, 293 (uint64_t)m_threads.size(), 294 (uint64_t)threads_copy.size()); 295 } 296 297 bool did_anybody_stop_for_a_reason = false; 298 299 // If the event is an Interrupt event, then we're going to stop no matter what. Otherwise, presume we won't stop. 300 bool should_stop = false; 301 if (Process::ProcessEventData::GetInterruptedFromEvent(event_ptr)) 302 { 303 if (log) 304 log->Printf("ThreadList::%s handling interrupt event, should stop set to true", __FUNCTION__); 305 306 should_stop = true; 307 } 308 309 // Now we run through all the threads and get their stop info's. We want to make sure to do this first before 310 // we start running the ShouldStop, because one thread's ShouldStop could destroy information (like deleting a 311 // thread specific breakpoint another thread had stopped at) which could lead us to compute the StopInfo incorrectly. 312 // We don't need to use it here, we just want to make sure it gets computed. 313 314 for (pos = threads_copy.begin(); pos != end; ++pos) 315 { 316 ThreadSP thread_sp(*pos); 317 thread_sp->GetStopInfo(); 318 } 319 320 for (pos = threads_copy.begin(); pos != end; ++pos) 321 { 322 ThreadSP thread_sp(*pos); 323 324 // We should never get a stop for which no thread had a stop reason, but sometimes we do see this - 325 // for instance when we first connect to a remote stub. In that case we should stop, since we can't figure out 326 // the right thing to do and stopping gives the user control over what to do in this instance. 327 // 328 // Note, this causes a problem when you have a thread specific breakpoint, and a bunch of threads hit the breakpoint, 329 // but not the thread which we are waiting for. All the threads that are not "supposed" to hit the breakpoint 330 // are marked as having no stop reason, which is right, they should not show a stop reason. But that triggers this 331 // code and causes us to stop seemingly for no reason. 332 // 333 // Since the only way we ever saw this error was on first attach, I'm only going to trigger set did_anybody_stop_for_a_reason 334 // to true unless this is the first stop. 335 // 336 // If this becomes a problem, we'll have to have another StopReason like "StopInfoHidden" which will look invalid 337 // everywhere but at this check. 338 339 if (thread_sp->GetProcess()->GetStopID() > 1) 340 did_anybody_stop_for_a_reason = true; 341 else 342 did_anybody_stop_for_a_reason |= thread_sp->ThreadStoppedForAReason(); 343 344 const bool thread_should_stop = thread_sp->ShouldStop(event_ptr); 345 if (thread_should_stop) 346 should_stop |= true; 347 } 348 349 if (!should_stop && !did_anybody_stop_for_a_reason) 350 { 351 should_stop = true; 352 if (log) 353 log->Printf ("ThreadList::%s we stopped but no threads had a stop reason, overriding should_stop and stopping.", __FUNCTION__); 354 } 355 356 if (log) 357 log->Printf ("ThreadList::%s overall should_stop = %i", __FUNCTION__, should_stop); 358 359 if (should_stop) 360 { 361 for (pos = threads_copy.begin(); pos != end; ++pos) 362 { 363 ThreadSP thread_sp(*pos); 364 thread_sp->WillStop (); 365 } 366 } 367 368 return should_stop; 369 } 370 371 Vote 372 ThreadList::ShouldReportStop (Event *event_ptr) 373 { 374 Mutex::Locker locker(GetMutex()); 375 376 Vote result = eVoteNoOpinion; 377 m_process->UpdateThreadListIfNeeded(); 378 collection::iterator pos, end = m_threads.end(); 379 380 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 381 382 if (log) 383 log->Printf ("ThreadList::%s %" PRIu64 " threads", __FUNCTION__, (uint64_t)m_threads.size()); 384 385 // Run through the threads and ask whether we should report this event. 386 // For stopping, a YES vote wins over everything. A NO vote wins over NO opinion. 387 for (pos = m_threads.begin(); pos != end; ++pos) 388 { 389 ThreadSP thread_sp(*pos); 390 const Vote vote = thread_sp->ShouldReportStop (event_ptr); 391 switch (vote) 392 { 393 case eVoteNoOpinion: 394 continue; 395 396 case eVoteYes: 397 result = eVoteYes; 398 break; 399 400 case eVoteNo: 401 if (result == eVoteNoOpinion) 402 { 403 result = eVoteNo; 404 } 405 else 406 { 407 if (log) 408 log->Printf ("ThreadList::%s thread 0x%4.4" PRIx64 ": voted %s, but lost out because result was %s", 409 __FUNCTION__, 410 thread_sp->GetID (), 411 GetVoteAsCString (vote), 412 GetVoteAsCString (result)); 413 } 414 break; 415 } 416 } 417 if (log) 418 log->Printf ("ThreadList::%s returning %s", __FUNCTION__, GetVoteAsCString (result)); 419 return result; 420 } 421 422 void 423 ThreadList::SetShouldReportStop (Vote vote) 424 { 425 Mutex::Locker locker(GetMutex()); 426 m_process->UpdateThreadListIfNeeded(); 427 collection::iterator pos, end = m_threads.end(); 428 for (pos = m_threads.begin(); pos != end; ++pos) 429 { 430 ThreadSP thread_sp(*pos); 431 thread_sp->SetShouldReportStop (vote); 432 } 433 } 434 435 Vote 436 ThreadList::ShouldReportRun (Event *event_ptr) 437 { 438 439 Mutex::Locker locker(GetMutex()); 440 441 Vote result = eVoteNoOpinion; 442 m_process->UpdateThreadListIfNeeded(); 443 collection::iterator pos, end = m_threads.end(); 444 445 // Run through the threads and ask whether we should report this event. 446 // The rule is NO vote wins over everything, a YES vote wins over no opinion. 447 448 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 449 450 for (pos = m_threads.begin(); pos != end; ++pos) 451 { 452 if ((*pos)->GetResumeState () != eStateSuspended) 453 { 454 switch ((*pos)->ShouldReportRun (event_ptr)) 455 { 456 case eVoteNoOpinion: 457 continue; 458 case eVoteYes: 459 if (result == eVoteNoOpinion) 460 result = eVoteYes; 461 break; 462 case eVoteNo: 463 if (log) 464 log->Printf ("ThreadList::ShouldReportRun() thread %d (0x%4.4" PRIx64 ") says don't report.", 465 (*pos)->GetIndexID(), 466 (*pos)->GetID()); 467 result = eVoteNo; 468 break; 469 } 470 } 471 } 472 return result; 473 } 474 475 void 476 ThreadList::Clear() 477 { 478 Mutex::Locker locker(GetMutex()); 479 m_stop_id = 0; 480 m_threads.clear(); 481 m_selected_tid = LLDB_INVALID_THREAD_ID; 482 } 483 484 void 485 ThreadList::Destroy() 486 { 487 Mutex::Locker locker(GetMutex()); 488 const uint32_t num_threads = m_threads.size(); 489 for (uint32_t idx = 0; idx < num_threads; ++idx) 490 { 491 m_threads[idx]->DestroyThread(); 492 } 493 } 494 495 void 496 ThreadList::RefreshStateAfterStop () 497 { 498 Mutex::Locker locker(GetMutex()); 499 500 m_process->UpdateThreadListIfNeeded(); 501 502 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 503 if (log && log->GetVerbose()) 504 log->Printf ("Turning off notification of new threads while single stepping a thread."); 505 506 collection::iterator pos, end = m_threads.end(); 507 for (pos = m_threads.begin(); pos != end; ++pos) 508 (*pos)->RefreshStateAfterStop (); 509 } 510 511 void 512 ThreadList::DiscardThreadPlans () 513 { 514 // You don't need to update the thread list here, because only threads 515 // that you currently know about have any thread plans. 516 Mutex::Locker locker(GetMutex()); 517 518 collection::iterator pos, end = m_threads.end(); 519 for (pos = m_threads.begin(); pos != end; ++pos) 520 (*pos)->DiscardThreadPlans (true); 521 522 } 523 524 bool 525 ThreadList::WillResume () 526 { 527 // Run through the threads and perform their momentary actions. 528 // But we only do this for threads that are running, user suspended 529 // threads stay where they are. 530 531 Mutex::Locker locker(GetMutex()); 532 m_process->UpdateThreadListIfNeeded(); 533 534 collection::iterator pos, end = m_threads.end(); 535 536 // See if any thread wants to run stopping others. If it does, then we won't 537 // setup the other threads for resume, since they aren't going to get a chance 538 // to run. This is necessary because the SetupForResume might add "StopOthers" 539 // plans which would then get to be part of the who-gets-to-run negotiation, but 540 // they're coming in after the fact, and the threads that are already set up should 541 // take priority. 542 543 bool wants_solo_run = false; 544 545 for (pos = m_threads.begin(); pos != end; ++pos) 546 { 547 lldbassert((*pos)->GetCurrentPlan() && "thread should not have null thread plan"); 548 if ((*pos)->GetResumeState() != eStateSuspended && 549 (*pos)->GetCurrentPlan()->StopOthers()) 550 { 551 if ((*pos)->IsOperatingSystemPluginThread() && !(*pos)->GetBackingThread()) 552 continue; 553 wants_solo_run = true; 554 break; 555 } 556 } 557 558 if (wants_solo_run) 559 { 560 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 561 if (log && log->GetVerbose()) 562 log->Printf ("Turning on notification of new threads while single stepping a thread."); 563 m_process->StartNoticingNewThreads(); 564 } 565 else 566 { 567 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 568 if (log && log->GetVerbose()) 569 log->Printf ("Turning off notification of new threads while single stepping a thread."); 570 m_process->StopNoticingNewThreads(); 571 } 572 573 // Give all the threads that are likely to run a last chance to set up their state before we 574 // negotiate who is actually going to get a chance to run... 575 // Don't set to resume suspended threads, and if any thread wanted to stop others, only 576 // call setup on the threads that request StopOthers... 577 578 for (pos = m_threads.begin(); pos != end; ++pos) 579 { 580 if ((*pos)->GetResumeState() != eStateSuspended 581 && (!wants_solo_run || (*pos)->GetCurrentPlan()->StopOthers())) 582 { 583 if ((*pos)->IsOperatingSystemPluginThread() && !(*pos)->GetBackingThread()) 584 continue; 585 (*pos)->SetupForResume (); 586 } 587 } 588 589 // Now go through the threads and see if any thread wants to run just itself. 590 // if so then pick one and run it. 591 592 ThreadList run_me_only_list (m_process); 593 594 run_me_only_list.SetStopID(m_process->GetStopID()); 595 596 bool run_only_current_thread = false; 597 598 for (pos = m_threads.begin(); pos != end; ++pos) 599 { 600 ThreadSP thread_sp(*pos); 601 if (thread_sp->GetResumeState() != eStateSuspended && 602 thread_sp->GetCurrentPlan()->StopOthers()) 603 { 604 if ((*pos)->IsOperatingSystemPluginThread() && !(*pos)->GetBackingThread()) 605 continue; 606 607 // You can't say "stop others" and also want yourself to be suspended. 608 assert (thread_sp->GetCurrentPlan()->RunState() != eStateSuspended); 609 610 if (thread_sp == GetSelectedThread()) 611 { 612 // If the currently selected thread wants to run on its own, always let it. 613 run_only_current_thread = true; 614 run_me_only_list.Clear(); 615 run_me_only_list.AddThread (thread_sp); 616 break; 617 } 618 619 run_me_only_list.AddThread (thread_sp); 620 } 621 622 } 623 624 bool need_to_resume = true; 625 626 if (run_me_only_list.GetSize (false) == 0) 627 { 628 // Everybody runs as they wish: 629 for (pos = m_threads.begin(); pos != end; ++pos) 630 { 631 ThreadSP thread_sp(*pos); 632 StateType run_state; 633 if (thread_sp->GetResumeState() != eStateSuspended) 634 run_state = thread_sp->GetCurrentPlan()->RunState(); 635 else 636 run_state = eStateSuspended; 637 if (!thread_sp->ShouldResume(run_state)) 638 need_to_resume = false; 639 } 640 } 641 else 642 { 643 ThreadSP thread_to_run; 644 645 if (run_only_current_thread) 646 { 647 thread_to_run = GetSelectedThread(); 648 } 649 else if (run_me_only_list.GetSize (false) == 1) 650 { 651 thread_to_run = run_me_only_list.GetThreadAtIndex (0); 652 } 653 else 654 { 655 int random_thread = (int) 656 ((run_me_only_list.GetSize (false) * (double) rand ()) / (RAND_MAX + 1.0)); 657 thread_to_run = run_me_only_list.GetThreadAtIndex (random_thread); 658 } 659 660 for (pos = m_threads.begin(); pos != end; ++pos) 661 { 662 ThreadSP thread_sp(*pos); 663 if (thread_sp == thread_to_run) 664 { 665 if (!thread_sp->ShouldResume(thread_sp->GetCurrentPlan()->RunState())) 666 need_to_resume = false; 667 } 668 else 669 thread_sp->ShouldResume (eStateSuspended); 670 } 671 } 672 673 return need_to_resume; 674 } 675 676 void 677 ThreadList::DidResume () 678 { 679 Mutex::Locker locker(GetMutex()); 680 collection::iterator pos, end = m_threads.end(); 681 for (pos = m_threads.begin(); pos != end; ++pos) 682 { 683 // Don't clear out threads that aren't going to get a chance to run, rather 684 // leave their state for the next time around. 685 ThreadSP thread_sp(*pos); 686 if (thread_sp->GetResumeState() != eStateSuspended) 687 thread_sp->DidResume (); 688 } 689 } 690 691 void 692 ThreadList::DidStop () 693 { 694 Mutex::Locker locker(GetMutex()); 695 collection::iterator pos, end = m_threads.end(); 696 for (pos = m_threads.begin(); pos != end; ++pos) 697 { 698 // Notify threads that the process just stopped. 699 // Note, this currently assumes that all threads in the list 700 // stop when the process stops. In the future we will want to support 701 // a debugging model where some threads continue to run while others 702 // are stopped. We either need to handle that somehow here or 703 // create a special thread list containing only threads which will 704 // stop in the code that calls this method (currently 705 // Process::SetPrivateState). 706 ThreadSP thread_sp(*pos); 707 if (StateIsRunningState(thread_sp->GetState())) 708 thread_sp->DidStop (); 709 } 710 } 711 712 ThreadSP 713 ThreadList::GetSelectedThread () 714 { 715 Mutex::Locker locker(GetMutex()); 716 ThreadSP thread_sp = FindThreadByID(m_selected_tid); 717 if (!thread_sp.get()) 718 { 719 if (m_threads.size() == 0) 720 return thread_sp; 721 m_selected_tid = m_threads[0]->GetID(); 722 thread_sp = m_threads[0]; 723 } 724 return thread_sp; 725 } 726 727 bool 728 ThreadList::SetSelectedThreadByID (lldb::tid_t tid, bool notify) 729 { 730 Mutex::Locker locker(GetMutex()); 731 ThreadSP selected_thread_sp(FindThreadByID(tid)); 732 if (selected_thread_sp) 733 { 734 m_selected_tid = tid; 735 selected_thread_sp->SetDefaultFileAndLineToSelectedFrame(); 736 } 737 else 738 m_selected_tid = LLDB_INVALID_THREAD_ID; 739 740 if (notify) 741 NotifySelectedThreadChanged(m_selected_tid); 742 743 return m_selected_tid != LLDB_INVALID_THREAD_ID; 744 } 745 746 bool 747 ThreadList::SetSelectedThreadByIndexID (uint32_t index_id, bool notify) 748 { 749 Mutex::Locker locker(GetMutex()); 750 ThreadSP selected_thread_sp (FindThreadByIndexID(index_id)); 751 if (selected_thread_sp.get()) 752 { 753 m_selected_tid = selected_thread_sp->GetID(); 754 selected_thread_sp->SetDefaultFileAndLineToSelectedFrame(); 755 } 756 else 757 m_selected_tid = LLDB_INVALID_THREAD_ID; 758 759 if (notify) 760 NotifySelectedThreadChanged(m_selected_tid); 761 762 return m_selected_tid != LLDB_INVALID_THREAD_ID; 763 } 764 765 void 766 ThreadList::NotifySelectedThreadChanged (lldb::tid_t tid) 767 { 768 ThreadSP selected_thread_sp (FindThreadByID(tid)); 769 if (selected_thread_sp->EventTypeHasListeners(Thread::eBroadcastBitThreadSelected)) 770 selected_thread_sp->BroadcastEvent(Thread::eBroadcastBitThreadSelected, 771 new Thread::ThreadEventData(selected_thread_sp)); 772 } 773 774 void 775 ThreadList::Update (ThreadList &rhs) 776 { 777 if (this != &rhs) 778 { 779 // Lock both mutexes to make sure neither side changes anyone on us 780 // while the assignment occurs 781 Mutex::Locker locker(GetMutex()); 782 m_process = rhs.m_process; 783 m_stop_id = rhs.m_stop_id; 784 m_threads.swap(rhs.m_threads); 785 m_selected_tid = rhs.m_selected_tid; 786 787 788 // Now we look for threads that we are done with and 789 // make sure to clear them up as much as possible so 790 // anyone with a shared pointer will still have a reference, 791 // but the thread won't be of much use. Using std::weak_ptr 792 // for all backward references (such as a thread to a process) 793 // will eventually solve this issue for us, but for now, we 794 // need to work around the issue 795 collection::iterator rhs_pos, rhs_end = rhs.m_threads.end(); 796 for (rhs_pos = rhs.m_threads.begin(); rhs_pos != rhs_end; ++rhs_pos) 797 { 798 const lldb::tid_t tid = (*rhs_pos)->GetID(); 799 bool thread_is_alive = false; 800 const uint32_t num_threads = m_threads.size(); 801 for (uint32_t idx = 0; idx < num_threads; ++idx) 802 { 803 ThreadSP backing_thread = m_threads[idx]->GetBackingThread(); 804 if (m_threads[idx]->GetID() == tid || (backing_thread && backing_thread->GetID() == tid)) 805 { 806 thread_is_alive = true; 807 break; 808 } 809 } 810 if (!thread_is_alive) 811 (*rhs_pos)->DestroyThread(); 812 } 813 } 814 } 815 816 void 817 ThreadList::Flush () 818 { 819 Mutex::Locker locker(GetMutex()); 820 collection::iterator pos, end = m_threads.end(); 821 for (pos = m_threads.begin(); pos != end; ++pos) 822 (*pos)->Flush (); 823 } 824 825 Mutex & 826 ThreadList::GetMutex () 827 { 828 return m_process->m_thread_mutex; 829 } 830 831