LLDB mainline
ThreadList.h
Go to the documentation of this file.
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"
18#include "lldb/Utility/UserID.h"
19#include "lldb/lldb-private.h"
20
21#include "llvm/ADT/DenseMap.h"
22#include "llvm/ADT/DenseSet.h"
23
24namespace lldb_private {
25
26// This is a thread list with lots of functionality for use only by the process
27// for which this is the thread list. A generic container class with iterator
28// functionality is ThreadCollection.
30 friend class Process;
31
32public:
33 ThreadList(Process &process);
34
35 ThreadList(const ThreadList &rhs);
36
37 ~ThreadList() override;
38
39 /// Precondition: both thread lists must be belong to the same process.
40 const ThreadList &operator=(const ThreadList &rhs);
41
42 uint32_t GetSize(bool can_update = true);
43
44 // Return the selected thread if there is one. Otherwise, return the thread
45 // selected at index 0.
47
48 // Manage the thread to use for running expressions. This is usually the
49 // Selected thread, but sometimes (e.g. when evaluating breakpoint conditions
50 // & stop hooks) it isn't.
52 public:
54 : m_thread_list(&thread_list), m_tid(tid) {
55 m_thread_list->PushExpressionExecutionThread(m_tid);
56 }
57
59
62 m_thread_list->PopExpressionExecutionThread(m_tid);
63 }
64
65 private:
68 };
69
71
72protected:
74
76
77public:
78 bool SetSelectedThreadByID(lldb::tid_t tid, bool notify = false);
79
80 bool SetSelectedThreadByIndexID(uint32_t index_id, bool notify = false);
81
82 void Clear();
83
84 void Flush();
85
86 void Destroy();
87
88 // Note that "idx" is not the same as the "thread_index". It is a zero based
89 // index to accessing the current threads, whereas "thread_index" is a unique
90 // index assigned
91 lldb::ThreadSP GetThreadAtIndex(uint32_t idx, bool can_update = true);
92
93 lldb::ThreadSP FindThreadByID(lldb::tid_t tid, bool can_update = true);
94
96 bool can_update = true);
97
98 lldb::ThreadSP RemoveThreadByID(lldb::tid_t tid, bool can_update = true);
99
101 bool can_update = true);
102
103 lldb::ThreadSP FindThreadByIndexID(uint32_t index_id, bool can_update = true);
104
106
107 bool ShouldStop(Event *event_ptr);
108
109 Vote ShouldReportStop(Event *event_ptr);
110
111 Vote ShouldReportRun(Event *event_ptr);
112
114
115 /// The thread list asks tells all the threads it is about to resume.
116 /// If a thread can "resume" without having to resume the target, it
117 /// will return false for WillResume, and then the process will not be
118 /// restarted.
119 /// Sets *direction to the run direction of the thread(s) that will
120 /// be resumed. If threads that we want to run disagree about the
121 /// direction, we execute forwards and pop any of the thread plans
122 /// that requested reverse execution.
123 ///
124 /// \return
125 /// \b true instructs the process to resume normally,
126 /// \b false means start & stopped events will be generated, but
127 /// the process will not actually run. The thread must then return
128 /// the correct StopInfo when asked.
129 ///
130 bool WillResume(lldb::RunDirection &direction);
131
132 void DidResume();
133
134 void DidStop();
135
136 void DiscardThreadPlans();
137
138 uint32_t GetStopID() const;
139
140 void SetStopID(uint32_t stop_id);
141
142 std::recursive_mutex &GetMutex() const override;
143
144 /// Precondition: both thread lists must be belong to the same process.
145 void Update(ThreadList &rhs);
146
147 /// Called by ThreadPlanStepOverBreakpoint when a thread finishes stepping
148 /// over a breakpoint. This tracks which threads are still stepping over
149 /// each breakpoint address, and only re-enables the breakpoint when ALL
150 /// threads have finished stepping over it.
152 lldb::tid_t tid);
153
154 /// Register a thread that is about to step over a breakpoint.
155 /// The breakpoint will be re-enabled only after all registered threads
156 /// have called ThreadFinishedSteppingOverBreakpoint.
158 lldb::tid_t tid);
159
160protected:
161 void SetShouldReportStop(Vote vote);
162
164
165 // Classes that inherit from Process can see and modify these
166 Process &m_process; ///< The process that manages this thread list.
167 uint32_t
168 m_stop_id; ///< The process stop ID that this thread list is valid for.
170 m_selected_tid; ///< For targets that need the notion of a current thread.
171 std::vector<lldb::tid_t> m_expression_tid_stack;
172
173 /// Tracks which threads are currently stepping over each breakpoint address.
174 /// Key: breakpoint address, Value: set of thread IDs stepping over it.
175 /// When a thread finishes stepping, it's removed from the set. When the set
176 /// becomes empty, the breakpoint is re-enabled.
177 llvm::DenseMap<lldb::addr_t, llvm::DenseSet<lldb::tid_t>>
179
180private:
181 ThreadList() = delete;
182};
183
184} // namespace lldb_private
185
186#endif // LLDB_TARGET_THREADLIST_H
ExpressionExecutionThreadPusher(ThreadList &thread_list, lldb::tid_t tid)
Definition ThreadList.h:53
lldb::ThreadSP RemoveThreadByID(lldb::tid_t tid, bool can_update=true)
lldb::ThreadSP GetSelectedThread()
bool ShouldStop(Event *event_ptr)
Vote ShouldReportStop(Event *event_ptr)
uint32_t GetStopID() const
void ThreadFinishedSteppingOverBreakpoint(lldb::addr_t breakpoint_addr, lldb::tid_t tid)
Called by ThreadPlanStepOverBreakpoint when a thread finishes stepping over a breakpoint.
bool SetSelectedThreadByIndexID(uint32_t index_id, bool notify=false)
lldb::ThreadSP FindThreadByProtocolID(lldb::tid_t tid, bool can_update=true)
void PopExpressionExecutionThread(lldb::tid_t tid)
bool WillResume(lldb::RunDirection &direction)
The thread list asks tells all the threads it is about to resume.
bool SetSelectedThreadByID(lldb::tid_t tid, bool notify=false)
lldb::ThreadSP FindThreadByIndexID(uint32_t index_id, bool can_update=true)
Vote ShouldReportRun(Event *event_ptr)
void SetStopID(uint32_t stop_id)
lldb::ThreadSP GetThreadSPForThreadPtr(Thread *thread_ptr)
lldb::ThreadSP GetThreadAtIndex(uint32_t idx, bool can_update=true)
uint32_t m_stop_id
The process stop ID that this thread list is valid for.
Definition ThreadList.h:168
std::recursive_mutex & GetMutex() const override
lldb::ThreadSP FindThreadByID(lldb::tid_t tid, bool can_update=true)
lldb::ThreadSP GetExpressionExecutionThread()
const ThreadList & operator=(const ThreadList &rhs)
Precondition: both thread lists must be belong to the same process.
void RegisterThreadSteppingOverBreakpoint(lldb::addr_t breakpoint_addr, lldb::tid_t tid)
Register a thread that is about to step over a breakpoint.
void Update(ThreadList &rhs)
Precondition: both thread lists must be belong to the same process.
void PushExpressionExecutionThread(lldb::tid_t tid)
void SetShouldReportStop(Vote vote)
lldb::tid_t m_selected_tid
For targets that need the notion of a current thread.
Definition ThreadList.h:170
void NotifySelectedThreadChanged(lldb::tid_t tid)
ThreadList(Process &process)
lldb::ThreadSP RemoveThreadByProtocolID(lldb::tid_t tid, bool can_update=true)
llvm::DenseMap< lldb::addr_t, llvm::DenseSet< lldb::tid_t > > m_threads_stepping_over_bp
Tracks which threads are currently stepping over each breakpoint address.
Definition ThreadList.h:178
Process & m_process
The process that manages this thread list.
Definition ThreadList.h:166
std::vector< lldb::tid_t > m_expression_tid_stack
Definition ThreadList.h:171
#define LLDB_INVALID_THREAD_ID
A class that represents a running process on the host machine.
RunDirection
Execution directions.
std::shared_ptr< lldb_private::Thread > ThreadSP
uint64_t addr_t
Definition lldb-types.h:80
uint64_t tid_t
Definition lldb-types.h:84