1 //===-- ThreadList.h --------------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLDB_TARGET_THREADLIST_H 10 #define LLDB_TARGET_THREADLIST_H 11 12 #include <mutex> 13 #include <vector> 14 15 #include "lldb/Target/Thread.h" 16 #include "lldb/Target/ThreadCollection.h" 17 #include "lldb/Utility/Iterable.h" 18 #include "lldb/Utility/UserID.h" 19 #include "lldb/lldb-private.h" 20 21 namespace lldb_private { 22 23 // This is a thread list with lots of functionality for use only by the process 24 // for which this is the thread list. A generic container class with iterator 25 // functionality is ThreadCollection. 26 class ThreadList : public ThreadCollection { 27 friend class Process; 28 29 public: 30 ThreadList(Process &process); 31 32 ThreadList(const ThreadList &rhs); 33 34 ~ThreadList() override; 35 36 /// Precondition: both thread lists must be belong to the same process. 37 const ThreadList &operator=(const ThreadList &rhs); 38 39 uint32_t GetSize(bool can_update = true); 40 41 // Return the selected thread if there is one. Otherwise, return the thread 42 // selected at index 0. 43 lldb::ThreadSP GetSelectedThread(); 44 45 // Manage the thread to use for running expressions. This is usually the 46 // Selected thread, but sometimes (e.g. when evaluating breakpoint conditions 47 // & stop hooks) it isn't. 48 class ExpressionExecutionThreadPusher { 49 public: ExpressionExecutionThreadPusher(ThreadList & thread_list,lldb::tid_t tid)50 ExpressionExecutionThreadPusher(ThreadList &thread_list, lldb::tid_t tid) 51 : m_thread_list(&thread_list), m_tid(tid) { 52 m_thread_list->PushExpressionExecutionThread(m_tid); 53 } 54 55 ExpressionExecutionThreadPusher(lldb::ThreadSP thread_sp); 56 ~ExpressionExecutionThreadPusher()57 ~ExpressionExecutionThreadPusher() { 58 if (m_thread_list && m_tid != LLDB_INVALID_THREAD_ID) 59 m_thread_list->PopExpressionExecutionThread(m_tid); 60 } 61 62 private: 63 ThreadList *m_thread_list; 64 lldb::tid_t m_tid; 65 }; 66 67 lldb::ThreadSP GetExpressionExecutionThread(); 68 69 protected: 70 void PushExpressionExecutionThread(lldb::tid_t tid); 71 72 void PopExpressionExecutionThread(lldb::tid_t tid); 73 74 public: 75 bool SetSelectedThreadByID(lldb::tid_t tid, bool notify = false); 76 77 bool SetSelectedThreadByIndexID(uint32_t index_id, bool notify = false); 78 79 void Clear(); 80 81 void Flush(); 82 83 void Destroy(); 84 85 // Note that "idx" is not the same as the "thread_index". It is a zero based 86 // index to accessing the current threads, whereas "thread_index" is a unique 87 // index assigned 88 lldb::ThreadSP GetThreadAtIndex(uint32_t idx, bool can_update = true); 89 90 lldb::ThreadSP FindThreadByID(lldb::tid_t tid, bool can_update = true); 91 92 lldb::ThreadSP FindThreadByProtocolID(lldb::tid_t tid, 93 bool can_update = true); 94 95 lldb::ThreadSP RemoveThreadByID(lldb::tid_t tid, bool can_update = true); 96 97 lldb::ThreadSP RemoveThreadByProtocolID(lldb::tid_t tid, 98 bool can_update = true); 99 100 lldb::ThreadSP FindThreadByIndexID(uint32_t index_id, bool can_update = true); 101 102 lldb::ThreadSP GetThreadSPForThreadPtr(Thread *thread_ptr); 103 104 lldb::ThreadSP GetBackingThread(const lldb::ThreadSP &real_thread); 105 106 bool ShouldStop(Event *event_ptr); 107 108 Vote ShouldReportStop(Event *event_ptr); 109 110 Vote ShouldReportRun(Event *event_ptr); 111 112 void RefreshStateAfterStop(); 113 114 /// The thread list asks tells all the threads it is about to resume. 115 /// If a thread can "resume" without having to resume the target, it 116 /// will return false for WillResume, and then the process will not be 117 /// restarted. 118 /// 119 /// \return 120 /// \b true instructs the process to resume normally, 121 /// \b false means start & stopped events will be generated, but 122 /// the process will not actually run. The thread must then return 123 /// the correct StopInfo when asked. 124 /// 125 bool WillResume(); 126 127 void DidResume(); 128 129 void DidStop(); 130 131 void DiscardThreadPlans(); 132 133 uint32_t GetStopID() const; 134 135 void SetStopID(uint32_t stop_id); 136 137 std::recursive_mutex &GetMutex() const override; 138 139 /// Precondition: both thread lists must be belong to the same process. 140 void Update(ThreadList &rhs); 141 142 protected: 143 void SetShouldReportStop(Vote vote); 144 145 void NotifySelectedThreadChanged(lldb::tid_t tid); 146 147 // Classes that inherit from Process can see and modify these 148 Process &m_process; ///< The process that manages this thread list. 149 uint32_t 150 m_stop_id; ///< The process stop ID that this thread list is valid for. 151 lldb::tid_t 152 m_selected_tid; ///< For targets that need the notion of a current thread. 153 std::vector<lldb::tid_t> m_expression_tid_stack; 154 155 private: 156 ThreadList() = delete; 157 }; 158 159 } // namespace lldb_private 160 161 #endif // LLDB_TARGET_THREADLIST_H 162