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 const ThreadList &operator=(const ThreadList &rhs); 37 38 uint32_t GetSize(bool can_update = true); 39 40 // Return the selected thread if there is one. Otherwise, return the thread 41 // selected at index 0. 42 lldb::ThreadSP GetSelectedThread(); 43 44 // Manage the thread to use for running expressions. This is usually the 45 // Selected thread, but sometimes (e.g. when evaluating breakpoint conditions 46 // & stop hooks) it isn't. 47 class ExpressionExecutionThreadPusher { 48 public: ExpressionExecutionThreadPusher(ThreadList & thread_list,lldb::tid_t tid)49 ExpressionExecutionThreadPusher(ThreadList &thread_list, lldb::tid_t tid) 50 : m_thread_list(&thread_list), m_tid(tid) { 51 m_thread_list->PushExpressionExecutionThread(m_tid); 52 } 53 54 ExpressionExecutionThreadPusher(lldb::ThreadSP thread_sp); 55 ~ExpressionExecutionThreadPusher()56 ~ExpressionExecutionThreadPusher() { 57 if (m_thread_list && m_tid != LLDB_INVALID_THREAD_ID) 58 m_thread_list->PopExpressionExecutionThread(m_tid); 59 } 60 61 private: 62 ThreadList *m_thread_list; 63 lldb::tid_t m_tid; 64 }; 65 66 lldb::ThreadSP GetExpressionExecutionThread(); 67 68 protected: 69 void PushExpressionExecutionThread(lldb::tid_t tid); 70 71 void PopExpressionExecutionThread(lldb::tid_t tid); 72 73 public: 74 bool SetSelectedThreadByID(lldb::tid_t tid, bool notify = false); 75 76 bool SetSelectedThreadByIndexID(uint32_t index_id, bool notify = false); 77 78 void Clear(); 79 80 void Flush(); 81 82 void Destroy(); 83 84 // Note that "idx" is not the same as the "thread_index". It is a zero based 85 // index to accessing the current threads, whereas "thread_index" is a unique 86 // index assigned 87 lldb::ThreadSP GetThreadAtIndex(uint32_t idx, bool can_update = true); 88 89 lldb::ThreadSP FindThreadByID(lldb::tid_t tid, bool can_update = true); 90 91 lldb::ThreadSP FindThreadByProtocolID(lldb::tid_t tid, 92 bool can_update = true); 93 94 lldb::ThreadSP RemoveThreadByID(lldb::tid_t tid, bool can_update = true); 95 96 lldb::ThreadSP RemoveThreadByProtocolID(lldb::tid_t tid, 97 bool can_update = true); 98 99 lldb::ThreadSP FindThreadByIndexID(uint32_t index_id, bool can_update = true); 100 101 lldb::ThreadSP GetThreadSPForThreadPtr(Thread *thread_ptr); 102 103 lldb::ThreadSP GetBackingThread(const lldb::ThreadSP &real_thread); 104 105 bool ShouldStop(Event *event_ptr); 106 107 Vote ShouldReportStop(Event *event_ptr); 108 109 Vote ShouldReportRun(Event *event_ptr); 110 111 void RefreshStateAfterStop(); 112 113 /// The thread list asks tells all the threads it is about to resume. 114 /// If a thread can "resume" without having to resume the target, it 115 /// will return false for WillResume, and then the process will not be 116 /// restarted. 117 /// 118 /// \return 119 /// \b true instructs the process to resume normally, 120 /// \b false means start & stopped events will be generated, but 121 /// the process will not actually run. The thread must then return 122 /// the correct StopInfo when asked. 123 /// 124 bool WillResume(); 125 126 void DidResume(); 127 128 void DidStop(); 129 130 void DiscardThreadPlans(); 131 132 uint32_t GetStopID() const; 133 134 void SetStopID(uint32_t stop_id); 135 136 std::recursive_mutex &GetMutex() const override; 137 138 void Update(ThreadList &rhs); 139 140 protected: 141 void SetShouldReportStop(Vote vote); 142 143 void NotifySelectedThreadChanged(lldb::tid_t tid); 144 145 // Classes that inherit from Process can see and modify these 146 Process *m_process; ///< The process that manages this thread list. 147 uint32_t 148 m_stop_id; ///< The process stop ID that this thread list is valid for. 149 lldb::tid_t 150 m_selected_tid; ///< For targets that need the notion of a current thread. 151 std::vector<lldb::tid_t> m_expression_tid_stack; 152 153 private: 154 ThreadList() = delete; 155 }; 156 157 } // namespace lldb_private 158 159 #endif // LLDB_TARGET_THREADLIST_H 160