/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/include/lldb/Target/ThreadList.h
Line | Count | Source (jump to first uncovered line) |
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: |
49 | | ExpressionExecutionThreadPusher(ThreadList &thread_list, lldb::tid_t tid) |
50 | 0 | : m_thread_list(&thread_list), m_tid(tid) { |
51 | 0 | m_thread_list->PushExpressionExecutionThread(m_tid); |
52 | 0 | } |
53 | | |
54 | | ExpressionExecutionThreadPusher(lldb::ThreadSP thread_sp); |
55 | | |
56 | 12.0k | ~ExpressionExecutionThreadPusher() { |
57 | 12.0k | if (m_thread_list && m_tid != 11.7k LLDB_INVALID_THREAD_ID11.7k ) |
58 | 11.7k | m_thread_list->PopExpressionExecutionThread(m_tid); |
59 | 12.0k | } |
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 |