1cfca06d7SDimitry Andric //===-- ExecutionContext.cpp ----------------------------------------------===//
2f034231aSEd Maste //
35f29bb8aSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45f29bb8aSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
55f29bb8aSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6f034231aSEd Maste //
7f034231aSEd Maste //===----------------------------------------------------------------------===//
8f034231aSEd Maste
9f034231aSEd Maste #include "lldb/Target/ExecutionContext.h"
10f034231aSEd Maste #include "lldb/Target/ExecutionContextScope.h"
11f034231aSEd Maste #include "lldb/Target/Process.h"
1214f1b3e8SDimitry Andric #include "lldb/Target/StackFrame.h"
13f034231aSEd Maste #include "lldb/Target/Target.h"
14f034231aSEd Maste #include "lldb/Target/Thread.h"
1594994d37SDimitry Andric #include "lldb/Utility/State.h"
16f034231aSEd Maste
17f034231aSEd Maste using namespace lldb_private;
18f034231aSEd Maste
ExecutionContext()1914f1b3e8SDimitry Andric ExecutionContext::ExecutionContext()
2014f1b3e8SDimitry Andric : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {}
21f034231aSEd Maste
22145449b1SDimitry Andric ExecutionContext::ExecutionContext(const ExecutionContext &rhs) = default;
23f034231aSEd Maste
ExecutionContext(const lldb::TargetSP & target_sp,bool get_process)2414f1b3e8SDimitry Andric ExecutionContext::ExecutionContext(const lldb::TargetSP &target_sp,
2514f1b3e8SDimitry Andric bool get_process)
2614f1b3e8SDimitry Andric : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
27f034231aSEd Maste if (target_sp)
28f034231aSEd Maste SetContext(target_sp, get_process);
29f034231aSEd Maste }
30f034231aSEd Maste
ExecutionContext(const lldb::ProcessSP & process_sp)3114f1b3e8SDimitry Andric ExecutionContext::ExecutionContext(const lldb::ProcessSP &process_sp)
3214f1b3e8SDimitry Andric : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
33f034231aSEd Maste if (process_sp)
34f034231aSEd Maste SetContext(process_sp);
35f034231aSEd Maste }
36f034231aSEd Maste
ExecutionContext(const lldb::ThreadSP & thread_sp)3714f1b3e8SDimitry Andric ExecutionContext::ExecutionContext(const lldb::ThreadSP &thread_sp)
3814f1b3e8SDimitry Andric : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
39f034231aSEd Maste if (thread_sp)
40f034231aSEd Maste SetContext(thread_sp);
41f034231aSEd Maste }
42f034231aSEd Maste
ExecutionContext(const lldb::StackFrameSP & frame_sp)4314f1b3e8SDimitry Andric ExecutionContext::ExecutionContext(const lldb::StackFrameSP &frame_sp)
4414f1b3e8SDimitry Andric : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
45f034231aSEd Maste if (frame_sp)
46f034231aSEd Maste SetContext(frame_sp);
47f034231aSEd Maste }
48f034231aSEd Maste
ExecutionContext(const lldb::TargetWP & target_wp,bool get_process)4914f1b3e8SDimitry Andric ExecutionContext::ExecutionContext(const lldb::TargetWP &target_wp,
5014f1b3e8SDimitry Andric bool get_process)
5114f1b3e8SDimitry Andric : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
52f034231aSEd Maste lldb::TargetSP target_sp(target_wp.lock());
53f034231aSEd Maste if (target_sp)
54f034231aSEd Maste SetContext(target_sp, get_process);
55f034231aSEd Maste }
56f034231aSEd Maste
ExecutionContext(const lldb::ProcessWP & process_wp)5714f1b3e8SDimitry Andric ExecutionContext::ExecutionContext(const lldb::ProcessWP &process_wp)
5814f1b3e8SDimitry Andric : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
59f034231aSEd Maste lldb::ProcessSP process_sp(process_wp.lock());
60f034231aSEd Maste if (process_sp)
61f034231aSEd Maste SetContext(process_sp);
62f034231aSEd Maste }
63f034231aSEd Maste
ExecutionContext(const lldb::ThreadWP & thread_wp)6414f1b3e8SDimitry Andric ExecutionContext::ExecutionContext(const lldb::ThreadWP &thread_wp)
6514f1b3e8SDimitry Andric : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
66f034231aSEd Maste lldb::ThreadSP thread_sp(thread_wp.lock());
67f034231aSEd Maste if (thread_sp)
68f034231aSEd Maste SetContext(thread_sp);
69f034231aSEd Maste }
70f034231aSEd Maste
ExecutionContext(const lldb::StackFrameWP & frame_wp)7114f1b3e8SDimitry Andric ExecutionContext::ExecutionContext(const lldb::StackFrameWP &frame_wp)
7214f1b3e8SDimitry Andric : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
73f034231aSEd Maste lldb::StackFrameSP frame_sp(frame_wp.lock());
74f034231aSEd Maste if (frame_sp)
75f034231aSEd Maste SetContext(frame_sp);
76f034231aSEd Maste }
77f034231aSEd Maste
ExecutionContext(Target * t,bool fill_current_process_thread_frame)7814f1b3e8SDimitry Andric ExecutionContext::ExecutionContext(Target *t,
7914f1b3e8SDimitry Andric bool fill_current_process_thread_frame)
8014f1b3e8SDimitry Andric : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
8114f1b3e8SDimitry Andric if (t) {
825e95aa85SEd Maste m_target_sp = t->shared_from_this();
8314f1b3e8SDimitry Andric if (fill_current_process_thread_frame) {
84f034231aSEd Maste m_process_sp = t->GetProcessSP();
8514f1b3e8SDimitry Andric if (m_process_sp) {
86f034231aSEd Maste m_thread_sp = m_process_sp->GetThreadList().GetSelectedThread();
87f034231aSEd Maste if (m_thread_sp)
887fa27ce4SDimitry Andric m_frame_sp =
897fa27ce4SDimitry Andric m_thread_sp->GetSelectedFrame(DoNoSelectMostRelevantFrame);
90f034231aSEd Maste }
91f034231aSEd Maste }
92f034231aSEd Maste }
935e95aa85SEd Maste }
94f034231aSEd Maste
ExecutionContext(Process * process,Thread * thread,StackFrame * frame)9514f1b3e8SDimitry Andric ExecutionContext::ExecutionContext(Process *process, Thread *thread,
9614f1b3e8SDimitry Andric StackFrame *frame)
9714f1b3e8SDimitry Andric : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
9814f1b3e8SDimitry Andric if (process) {
995e95aa85SEd Maste m_process_sp = process->shared_from_this();
100f034231aSEd Maste m_target_sp = process->GetTarget().shared_from_this();
101f034231aSEd Maste }
1025e95aa85SEd Maste if (thread)
1035e95aa85SEd Maste m_thread_sp = thread->shared_from_this();
1045e95aa85SEd Maste if (frame)
1055e95aa85SEd Maste m_frame_sp = frame->shared_from_this();
1065e95aa85SEd Maste }
107f034231aSEd Maste
ExecutionContext(const ExecutionContextRef & exe_ctx_ref)10814f1b3e8SDimitry Andric ExecutionContext::ExecutionContext(const ExecutionContextRef &exe_ctx_ref)
10914f1b3e8SDimitry Andric : m_target_sp(exe_ctx_ref.GetTargetSP()),
110f034231aSEd Maste m_process_sp(exe_ctx_ref.GetProcessSP()),
111f034231aSEd Maste m_thread_sp(exe_ctx_ref.GetThreadSP()),
11214f1b3e8SDimitry Andric m_frame_sp(exe_ctx_ref.GetFrameSP()) {}
113f034231aSEd Maste
ExecutionContext(const ExecutionContextRef * exe_ctx_ref_ptr,bool thread_and_frame_only_if_stopped)11414f1b3e8SDimitry Andric ExecutionContext::ExecutionContext(const ExecutionContextRef *exe_ctx_ref_ptr,
11514f1b3e8SDimitry Andric bool thread_and_frame_only_if_stopped)
11614f1b3e8SDimitry Andric : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
11714f1b3e8SDimitry Andric if (exe_ctx_ref_ptr) {
118f034231aSEd Maste m_target_sp = exe_ctx_ref_ptr->GetTargetSP();
119f034231aSEd Maste m_process_sp = exe_ctx_ref_ptr->GetProcessSP();
12014f1b3e8SDimitry Andric if (!thread_and_frame_only_if_stopped ||
12114f1b3e8SDimitry Andric (m_process_sp && StateIsStoppedState(m_process_sp->GetState(), true))) {
122f034231aSEd Maste m_thread_sp = exe_ctx_ref_ptr->GetThreadSP();
123f034231aSEd Maste m_frame_sp = exe_ctx_ref_ptr->GetFrameSP();
124f034231aSEd Maste }
125f034231aSEd Maste }
126866dcdacSEd Maste }
127f034231aSEd Maste
ExecutionContext(const ExecutionContextRef * exe_ctx_ref_ptr,std::unique_lock<std::recursive_mutex> & lock)128f3fbd1c0SDimitry Andric ExecutionContext::ExecutionContext(const ExecutionContextRef *exe_ctx_ref_ptr,
129f3fbd1c0SDimitry Andric std::unique_lock<std::recursive_mutex> &lock)
13014f1b3e8SDimitry Andric : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
13114f1b3e8SDimitry Andric if (exe_ctx_ref_ptr) {
132f034231aSEd Maste m_target_sp = exe_ctx_ref_ptr->GetTargetSP();
13314f1b3e8SDimitry Andric if (m_target_sp) {
134f3fbd1c0SDimitry Andric lock = std::unique_lock<std::recursive_mutex>(m_target_sp->GetAPIMutex());
135f3fbd1c0SDimitry Andric
136f034231aSEd Maste m_process_sp = exe_ctx_ref_ptr->GetProcessSP();
137f034231aSEd Maste m_thread_sp = exe_ctx_ref_ptr->GetThreadSP();
138f034231aSEd Maste m_frame_sp = exe_ctx_ref_ptr->GetFrameSP();
139f034231aSEd Maste }
140f034231aSEd Maste }
141f034231aSEd Maste }
142f034231aSEd Maste
ExecutionContext(const ExecutionContextRef & exe_ctx_ref,std::unique_lock<std::recursive_mutex> & lock)14314f1b3e8SDimitry Andric ExecutionContext::ExecutionContext(const ExecutionContextRef &exe_ctx_ref,
14414f1b3e8SDimitry Andric std::unique_lock<std::recursive_mutex> &lock)
14514f1b3e8SDimitry Andric : m_target_sp(exe_ctx_ref.GetTargetSP()), m_process_sp(), m_thread_sp(),
14614f1b3e8SDimitry Andric m_frame_sp() {
14714f1b3e8SDimitry Andric if (m_target_sp) {
148f3fbd1c0SDimitry Andric lock = std::unique_lock<std::recursive_mutex>(m_target_sp->GetAPIMutex());
149f3fbd1c0SDimitry Andric
150f034231aSEd Maste m_process_sp = exe_ctx_ref.GetProcessSP();
151f034231aSEd Maste m_thread_sp = exe_ctx_ref.GetThreadSP();
152f034231aSEd Maste m_frame_sp = exe_ctx_ref.GetFrameSP();
153f034231aSEd Maste }
154f034231aSEd Maste }
155f034231aSEd Maste
ExecutionContext(ExecutionContextScope * exe_scope_ptr)15614f1b3e8SDimitry Andric ExecutionContext::ExecutionContext(ExecutionContextScope *exe_scope_ptr)
15714f1b3e8SDimitry Andric : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
158f034231aSEd Maste if (exe_scope_ptr)
159f034231aSEd Maste exe_scope_ptr->CalculateExecutionContext(*this);
160f034231aSEd Maste }
161f034231aSEd Maste
ExecutionContext(ExecutionContextScope & exe_scope_ref)16214f1b3e8SDimitry Andric ExecutionContext::ExecutionContext(ExecutionContextScope &exe_scope_ref) {
163f034231aSEd Maste exe_scope_ref.CalculateExecutionContext(*this);
164f034231aSEd Maste }
165f034231aSEd Maste
Clear()16614f1b3e8SDimitry Andric void ExecutionContext::Clear() {
167f034231aSEd Maste m_target_sp.reset();
168f034231aSEd Maste m_process_sp.reset();
169f034231aSEd Maste m_thread_sp.reset();
170f034231aSEd Maste m_frame_sp.reset();
171f034231aSEd Maste }
172f034231aSEd Maste
173f3fbd1c0SDimitry Andric ExecutionContext::~ExecutionContext() = default;
174f034231aSEd Maste
GetAddressByteSize() const17514f1b3e8SDimitry Andric uint32_t ExecutionContext::GetAddressByteSize() const {
176f034231aSEd Maste if (m_target_sp && m_target_sp->GetArchitecture().IsValid())
1775e95aa85SEd Maste return m_target_sp->GetArchitecture().GetAddressByteSize();
178f034231aSEd Maste if (m_process_sp)
1795e95aa85SEd Maste return m_process_sp->GetAddressByteSize();
180f034231aSEd Maste return sizeof(void *);
181f034231aSEd Maste }
182f034231aSEd Maste
GetByteOrder() const18314f1b3e8SDimitry Andric lldb::ByteOrder ExecutionContext::GetByteOrder() const {
184f21a844fSEd Maste if (m_target_sp && m_target_sp->GetArchitecture().IsValid())
185ead24645SDimitry Andric return m_target_sp->GetArchitecture().GetByteOrder();
186f21a844fSEd Maste if (m_process_sp)
187ead24645SDimitry Andric return m_process_sp->GetByteOrder();
188e81d9d49SDimitry Andric return endian::InlHostByteOrder();
189f21a844fSEd Maste }
190f034231aSEd Maste
GetRegisterContext() const19114f1b3e8SDimitry Andric RegisterContext *ExecutionContext::GetRegisterContext() const {
192f034231aSEd Maste if (m_frame_sp)
193f034231aSEd Maste return m_frame_sp->GetRegisterContext().get();
194f034231aSEd Maste else if (m_thread_sp)
195f034231aSEd Maste return m_thread_sp->GetRegisterContext().get();
196f3fbd1c0SDimitry Andric return nullptr;
197f034231aSEd Maste }
198f034231aSEd Maste
GetTargetPtr() const19914f1b3e8SDimitry Andric Target *ExecutionContext::GetTargetPtr() const {
200f034231aSEd Maste if (m_target_sp)
201f034231aSEd Maste return m_target_sp.get();
202f034231aSEd Maste if (m_process_sp)
203f034231aSEd Maste return &m_process_sp->GetTarget();
204f3fbd1c0SDimitry Andric return nullptr;
205f034231aSEd Maste }
206f034231aSEd Maste
GetProcessPtr() const20714f1b3e8SDimitry Andric Process *ExecutionContext::GetProcessPtr() const {
208f034231aSEd Maste if (m_process_sp)
209f034231aSEd Maste return m_process_sp.get();
210f034231aSEd Maste if (m_target_sp)
211f034231aSEd Maste return m_target_sp->GetProcessSP().get();
212f3fbd1c0SDimitry Andric return nullptr;
213f034231aSEd Maste }
214f034231aSEd Maste
GetBestExecutionContextScope() const21514f1b3e8SDimitry Andric ExecutionContextScope *ExecutionContext::GetBestExecutionContextScope() const {
216f034231aSEd Maste if (m_frame_sp)
217f034231aSEd Maste return m_frame_sp.get();
218f034231aSEd Maste if (m_thread_sp)
219f034231aSEd Maste return m_thread_sp.get();
220f034231aSEd Maste if (m_process_sp)
221f034231aSEd Maste return m_process_sp.get();
222f034231aSEd Maste return m_target_sp.get();
223f034231aSEd Maste }
224f034231aSEd Maste
GetTargetRef() const22514f1b3e8SDimitry Andric Target &ExecutionContext::GetTargetRef() const {
226f3fbd1c0SDimitry Andric assert(m_target_sp);
227f034231aSEd Maste return *m_target_sp;
228f034231aSEd Maste }
229f034231aSEd Maste
GetProcessRef() const23014f1b3e8SDimitry Andric Process &ExecutionContext::GetProcessRef() const {
231f3fbd1c0SDimitry Andric assert(m_process_sp);
232f034231aSEd Maste return *m_process_sp;
233f034231aSEd Maste }
234f034231aSEd Maste
GetThreadRef() const23514f1b3e8SDimitry Andric Thread &ExecutionContext::GetThreadRef() const {
236f3fbd1c0SDimitry Andric assert(m_thread_sp);
237f034231aSEd Maste return *m_thread_sp;
238f034231aSEd Maste }
239f034231aSEd Maste
GetFrameRef() const24014f1b3e8SDimitry Andric StackFrame &ExecutionContext::GetFrameRef() const {
241f3fbd1c0SDimitry Andric assert(m_frame_sp);
242f034231aSEd Maste return *m_frame_sp;
243f034231aSEd Maste }
244f034231aSEd Maste
SetTargetSP(const lldb::TargetSP & target_sp)24514f1b3e8SDimitry Andric void ExecutionContext::SetTargetSP(const lldb::TargetSP &target_sp) {
246f034231aSEd Maste m_target_sp = target_sp;
247f034231aSEd Maste }
248f034231aSEd Maste
SetProcessSP(const lldb::ProcessSP & process_sp)24914f1b3e8SDimitry Andric void ExecutionContext::SetProcessSP(const lldb::ProcessSP &process_sp) {
250f034231aSEd Maste m_process_sp = process_sp;
251f034231aSEd Maste }
252f034231aSEd Maste
SetThreadSP(const lldb::ThreadSP & thread_sp)25314f1b3e8SDimitry Andric void ExecutionContext::SetThreadSP(const lldb::ThreadSP &thread_sp) {
254f034231aSEd Maste m_thread_sp = thread_sp;
255f034231aSEd Maste }
256f034231aSEd Maste
SetFrameSP(const lldb::StackFrameSP & frame_sp)25714f1b3e8SDimitry Andric void ExecutionContext::SetFrameSP(const lldb::StackFrameSP &frame_sp) {
258f034231aSEd Maste m_frame_sp = frame_sp;
259f034231aSEd Maste }
260f034231aSEd Maste
SetTargetPtr(Target * target)26114f1b3e8SDimitry Andric void ExecutionContext::SetTargetPtr(Target *target) {
262f034231aSEd Maste if (target)
263f034231aSEd Maste m_target_sp = target->shared_from_this();
264f034231aSEd Maste else
265f034231aSEd Maste m_target_sp.reset();
266f034231aSEd Maste }
267f034231aSEd Maste
SetProcessPtr(Process * process)26814f1b3e8SDimitry Andric void ExecutionContext::SetProcessPtr(Process *process) {
269f034231aSEd Maste if (process)
270f034231aSEd Maste m_process_sp = process->shared_from_this();
271f034231aSEd Maste else
272f034231aSEd Maste m_process_sp.reset();
273f034231aSEd Maste }
274f034231aSEd Maste
SetThreadPtr(Thread * thread)27514f1b3e8SDimitry Andric void ExecutionContext::SetThreadPtr(Thread *thread) {
276f034231aSEd Maste if (thread)
277f034231aSEd Maste m_thread_sp = thread->shared_from_this();
278f034231aSEd Maste else
279f034231aSEd Maste m_thread_sp.reset();
280f034231aSEd Maste }
281f034231aSEd Maste
SetFramePtr(StackFrame * frame)28214f1b3e8SDimitry Andric void ExecutionContext::SetFramePtr(StackFrame *frame) {
283f034231aSEd Maste if (frame)
284f034231aSEd Maste m_frame_sp = frame->shared_from_this();
285f034231aSEd Maste else
286f034231aSEd Maste m_frame_sp.reset();
287f034231aSEd Maste }
288f034231aSEd Maste
SetContext(const lldb::TargetSP & target_sp,bool get_process)28914f1b3e8SDimitry Andric void ExecutionContext::SetContext(const lldb::TargetSP &target_sp,
29014f1b3e8SDimitry Andric bool get_process) {
291f034231aSEd Maste m_target_sp = target_sp;
292f034231aSEd Maste if (get_process && target_sp)
293f034231aSEd Maste m_process_sp = target_sp->GetProcessSP();
294f034231aSEd Maste else
295f034231aSEd Maste m_process_sp.reset();
296f034231aSEd Maste m_thread_sp.reset();
297f034231aSEd Maste m_frame_sp.reset();
298f034231aSEd Maste }
299f034231aSEd Maste
SetContext(const lldb::ProcessSP & process_sp)30014f1b3e8SDimitry Andric void ExecutionContext::SetContext(const lldb::ProcessSP &process_sp) {
301f034231aSEd Maste m_process_sp = process_sp;
302f034231aSEd Maste if (process_sp)
303f034231aSEd Maste m_target_sp = process_sp->GetTarget().shared_from_this();
304f034231aSEd Maste else
305f034231aSEd Maste m_target_sp.reset();
306f034231aSEd Maste m_thread_sp.reset();
307f034231aSEd Maste m_frame_sp.reset();
308f034231aSEd Maste }
309f034231aSEd Maste
SetContext(const lldb::ThreadSP & thread_sp)31014f1b3e8SDimitry Andric void ExecutionContext::SetContext(const lldb::ThreadSP &thread_sp) {
311f034231aSEd Maste m_frame_sp.reset();
312f034231aSEd Maste m_thread_sp = thread_sp;
31314f1b3e8SDimitry Andric if (thread_sp) {
314f034231aSEd Maste m_process_sp = thread_sp->GetProcess();
315f034231aSEd Maste if (m_process_sp)
316f034231aSEd Maste m_target_sp = m_process_sp->GetTarget().shared_from_this();
317f034231aSEd Maste else
318f034231aSEd Maste m_target_sp.reset();
31914f1b3e8SDimitry Andric } else {
320f034231aSEd Maste m_target_sp.reset();
321f034231aSEd Maste m_process_sp.reset();
322f034231aSEd Maste }
323f034231aSEd Maste }
324f034231aSEd Maste
SetContext(const lldb::StackFrameSP & frame_sp)32514f1b3e8SDimitry Andric void ExecutionContext::SetContext(const lldb::StackFrameSP &frame_sp) {
326f034231aSEd Maste m_frame_sp = frame_sp;
32714f1b3e8SDimitry Andric if (frame_sp) {
328f034231aSEd Maste m_thread_sp = frame_sp->CalculateThread();
32914f1b3e8SDimitry Andric if (m_thread_sp) {
330f034231aSEd Maste m_process_sp = m_thread_sp->GetProcess();
331f034231aSEd Maste if (m_process_sp)
332f034231aSEd Maste m_target_sp = m_process_sp->GetTarget().shared_from_this();
333f034231aSEd Maste else
334f034231aSEd Maste m_target_sp.reset();
33514f1b3e8SDimitry Andric } else {
336f034231aSEd Maste m_target_sp.reset();
337f034231aSEd Maste m_process_sp.reset();
338f034231aSEd Maste }
33914f1b3e8SDimitry Andric } else {
340f034231aSEd Maste m_target_sp.reset();
341f034231aSEd Maste m_process_sp.reset();
342f034231aSEd Maste m_thread_sp.reset();
343f034231aSEd Maste }
344f034231aSEd Maste }
345f034231aSEd Maste
operator =(const ExecutionContext & rhs)34614f1b3e8SDimitry Andric ExecutionContext &ExecutionContext::operator=(const ExecutionContext &rhs) {
34714f1b3e8SDimitry Andric if (this != &rhs) {
348f034231aSEd Maste m_target_sp = rhs.m_target_sp;
349f034231aSEd Maste m_process_sp = rhs.m_process_sp;
350f034231aSEd Maste m_thread_sp = rhs.m_thread_sp;
351f034231aSEd Maste m_frame_sp = rhs.m_frame_sp;
352f034231aSEd Maste }
353f034231aSEd Maste return *this;
354f034231aSEd Maste }
355f034231aSEd Maste
operator ==(const ExecutionContext & rhs) const35614f1b3e8SDimitry Andric bool ExecutionContext::operator==(const ExecutionContext &rhs) const {
35714f1b3e8SDimitry Andric // Check that the frame shared pointers match, or both are valid and their
358f73363f1SDimitry Andric // stack IDs match since sometimes we get new objects that represent the same
359f034231aSEd Maste // frame within a thread.
36014f1b3e8SDimitry Andric if ((m_frame_sp == rhs.m_frame_sp) ||
36114f1b3e8SDimitry Andric (m_frame_sp && rhs.m_frame_sp &&
36214f1b3e8SDimitry Andric m_frame_sp->GetStackID() == rhs.m_frame_sp->GetStackID())) {
363f73363f1SDimitry Andric // Check that the thread shared pointers match, or both are valid and their
364f73363f1SDimitry Andric // thread IDs match since sometimes we get new objects that represent the
365f73363f1SDimitry Andric // same thread within a process.
36614f1b3e8SDimitry Andric if ((m_thread_sp == rhs.m_thread_sp) ||
36714f1b3e8SDimitry Andric (m_thread_sp && rhs.m_thread_sp &&
36814f1b3e8SDimitry Andric m_thread_sp->GetID() == rhs.m_thread_sp->GetID())) {
369f034231aSEd Maste // Processes and targets don't change much
370f034231aSEd Maste return m_process_sp == rhs.m_process_sp && m_target_sp == rhs.m_target_sp;
371f034231aSEd Maste }
372f034231aSEd Maste }
373f034231aSEd Maste return false;
374f034231aSEd Maste }
375f034231aSEd Maste
operator !=(const ExecutionContext & rhs) const37614f1b3e8SDimitry Andric bool ExecutionContext::operator!=(const ExecutionContext &rhs) const {
377f034231aSEd Maste return !(*this == rhs);
378f034231aSEd Maste }
379f034231aSEd Maste
HasTargetScope() const38014f1b3e8SDimitry Andric bool ExecutionContext::HasTargetScope() const {
38114f1b3e8SDimitry Andric return ((bool)m_target_sp && m_target_sp->IsValid());
382f034231aSEd Maste }
383f034231aSEd Maste
HasProcessScope() const38414f1b3e8SDimitry Andric bool ExecutionContext::HasProcessScope() const {
38514f1b3e8SDimitry Andric return (HasTargetScope() && ((bool)m_process_sp && m_process_sp->IsValid()));
386f034231aSEd Maste }
387f034231aSEd Maste
HasThreadScope() const38814f1b3e8SDimitry Andric bool ExecutionContext::HasThreadScope() const {
38914f1b3e8SDimitry Andric return (HasProcessScope() && ((bool)m_thread_sp && m_thread_sp->IsValid()));
390f034231aSEd Maste }
391f034231aSEd Maste
HasFrameScope() const39214f1b3e8SDimitry Andric bool ExecutionContext::HasFrameScope() const {
393f034231aSEd Maste return HasThreadScope() && m_frame_sp;
394f034231aSEd Maste }
395f034231aSEd Maste
ExecutionContextRef()39614f1b3e8SDimitry Andric ExecutionContextRef::ExecutionContextRef()
397344a3780SDimitry Andric : m_target_wp(), m_process_wp(), m_thread_wp(), m_stack_id() {}
398f034231aSEd Maste
ExecutionContextRef(const ExecutionContext * exe_ctx)39914f1b3e8SDimitry Andric ExecutionContextRef::ExecutionContextRef(const ExecutionContext *exe_ctx)
400145449b1SDimitry Andric : m_target_wp(), m_process_wp(), m_thread_wp(), m_stack_id() {
401f034231aSEd Maste if (exe_ctx)
402f034231aSEd Maste *this = *exe_ctx;
403f034231aSEd Maste }
404f034231aSEd Maste
ExecutionContextRef(const ExecutionContext & exe_ctx)40514f1b3e8SDimitry Andric ExecutionContextRef::ExecutionContextRef(const ExecutionContext &exe_ctx)
406145449b1SDimitry Andric : m_target_wp(), m_process_wp(), m_thread_wp(), m_stack_id() {
407f034231aSEd Maste *this = exe_ctx;
408f034231aSEd Maste }
409f034231aSEd Maste
ExecutionContextRef(Target * target,bool adopt_selected)41014f1b3e8SDimitry Andric ExecutionContextRef::ExecutionContextRef(Target *target, bool adopt_selected)
411145449b1SDimitry Andric : m_target_wp(), m_process_wp(), m_thread_wp(), m_stack_id() {
412f034231aSEd Maste SetTargetPtr(target, adopt_selected);
413f034231aSEd Maste }
414f034231aSEd Maste
41514f1b3e8SDimitry Andric ExecutionContextRef::ExecutionContextRef(const ExecutionContextRef &rhs)
416145449b1SDimitry Andric
417145449b1SDimitry Andric = default;
418f034231aSEd Maste
41914f1b3e8SDimitry Andric ExecutionContextRef &ExecutionContextRef::
operator =(const ExecutionContextRef & rhs)42014f1b3e8SDimitry Andric operator=(const ExecutionContextRef &rhs) {
42114f1b3e8SDimitry Andric if (this != &rhs) {
422f034231aSEd Maste m_target_wp = rhs.m_target_wp;
423f034231aSEd Maste m_process_wp = rhs.m_process_wp;
424f034231aSEd Maste m_thread_wp = rhs.m_thread_wp;
425f034231aSEd Maste m_tid = rhs.m_tid;
426f034231aSEd Maste m_stack_id = rhs.m_stack_id;
427f034231aSEd Maste }
428f034231aSEd Maste return *this;
429f034231aSEd Maste }
430f034231aSEd Maste
43114f1b3e8SDimitry Andric ExecutionContextRef &ExecutionContextRef::
operator =(const ExecutionContext & exe_ctx)43214f1b3e8SDimitry Andric operator=(const ExecutionContext &exe_ctx) {
433f034231aSEd Maste m_target_wp = exe_ctx.GetTargetSP();
434f034231aSEd Maste m_process_wp = exe_ctx.GetProcessSP();
435f034231aSEd Maste lldb::ThreadSP thread_sp(exe_ctx.GetThreadSP());
436f034231aSEd Maste m_thread_wp = thread_sp;
437f034231aSEd Maste if (thread_sp)
438f034231aSEd Maste m_tid = thread_sp->GetID();
439f034231aSEd Maste else
440f034231aSEd Maste m_tid = LLDB_INVALID_THREAD_ID;
441f034231aSEd Maste lldb::StackFrameSP frame_sp(exe_ctx.GetFrameSP());
442f034231aSEd Maste if (frame_sp)
443f034231aSEd Maste m_stack_id = frame_sp->GetStackID();
444f034231aSEd Maste else
445f034231aSEd Maste m_stack_id.Clear();
446f034231aSEd Maste return *this;
447f034231aSEd Maste }
448f034231aSEd Maste
Clear()44914f1b3e8SDimitry Andric void ExecutionContextRef::Clear() {
450f034231aSEd Maste m_target_wp.reset();
451f034231aSEd Maste m_process_wp.reset();
452f034231aSEd Maste ClearThread();
453f034231aSEd Maste ClearFrame();
454f034231aSEd Maste }
455f034231aSEd Maste
456f3fbd1c0SDimitry Andric ExecutionContextRef::~ExecutionContextRef() = default;
457f034231aSEd Maste
SetTargetSP(const lldb::TargetSP & target_sp)45814f1b3e8SDimitry Andric void ExecutionContextRef::SetTargetSP(const lldb::TargetSP &target_sp) {
459f034231aSEd Maste m_target_wp = target_sp;
460f034231aSEd Maste }
461f034231aSEd Maste
SetProcessSP(const lldb::ProcessSP & process_sp)46214f1b3e8SDimitry Andric void ExecutionContextRef::SetProcessSP(const lldb::ProcessSP &process_sp) {
46314f1b3e8SDimitry Andric if (process_sp) {
464f034231aSEd Maste m_process_wp = process_sp;
465f034231aSEd Maste SetTargetSP(process_sp->GetTarget().shared_from_this());
46614f1b3e8SDimitry Andric } else {
467f034231aSEd Maste m_process_wp.reset();
468f034231aSEd Maste m_target_wp.reset();
469f034231aSEd Maste }
470f034231aSEd Maste }
471f034231aSEd Maste
SetThreadSP(const lldb::ThreadSP & thread_sp)47214f1b3e8SDimitry Andric void ExecutionContextRef::SetThreadSP(const lldb::ThreadSP &thread_sp) {
47314f1b3e8SDimitry Andric if (thread_sp) {
474f034231aSEd Maste m_thread_wp = thread_sp;
475f034231aSEd Maste m_tid = thread_sp->GetID();
476f034231aSEd Maste SetProcessSP(thread_sp->GetProcess());
47714f1b3e8SDimitry Andric } else {
478f034231aSEd Maste ClearThread();
479f034231aSEd Maste m_process_wp.reset();
480f034231aSEd Maste m_target_wp.reset();
481f034231aSEd Maste }
482f034231aSEd Maste }
483f034231aSEd Maste
SetFrameSP(const lldb::StackFrameSP & frame_sp)48414f1b3e8SDimitry Andric void ExecutionContextRef::SetFrameSP(const lldb::StackFrameSP &frame_sp) {
48514f1b3e8SDimitry Andric if (frame_sp) {
486f034231aSEd Maste m_stack_id = frame_sp->GetStackID();
487f034231aSEd Maste SetThreadSP(frame_sp->GetThread());
48814f1b3e8SDimitry Andric } else {
489f034231aSEd Maste ClearFrame();
490f034231aSEd Maste ClearThread();
491f034231aSEd Maste m_process_wp.reset();
492f034231aSEd Maste m_target_wp.reset();
493f034231aSEd Maste }
494f034231aSEd Maste }
495f034231aSEd Maste
SetTargetPtr(Target * target,bool adopt_selected)49614f1b3e8SDimitry Andric void ExecutionContextRef::SetTargetPtr(Target *target, bool adopt_selected) {
497f034231aSEd Maste Clear();
49814f1b3e8SDimitry Andric if (target) {
499f034231aSEd Maste lldb::TargetSP target_sp(target->shared_from_this());
50014f1b3e8SDimitry Andric if (target_sp) {
501f034231aSEd Maste m_target_wp = target_sp;
50214f1b3e8SDimitry Andric if (adopt_selected) {
503f034231aSEd Maste lldb::ProcessSP process_sp(target_sp->GetProcessSP());
50414f1b3e8SDimitry Andric if (process_sp) {
505f034231aSEd Maste m_process_wp = process_sp;
50614f1b3e8SDimitry Andric if (process_sp) {
507f034231aSEd Maste // Only fill in the thread and frame if our process is stopped
50812bd4897SEd Maste // Don't just check the state, since we might be in the middle of
50912bd4897SEd Maste // resuming.
51012bd4897SEd Maste Process::StopLocker stop_locker;
51112bd4897SEd Maste
51214f1b3e8SDimitry Andric if (stop_locker.TryLock(&process_sp->GetRunLock()) &&
51314f1b3e8SDimitry Andric StateIsStoppedState(process_sp->GetState(), true)) {
51414f1b3e8SDimitry Andric lldb::ThreadSP thread_sp(
51514f1b3e8SDimitry Andric process_sp->GetThreadList().GetSelectedThread());
516f034231aSEd Maste if (!thread_sp)
517f034231aSEd Maste thread_sp = process_sp->GetThreadList().GetThreadAtIndex(0);
518f034231aSEd Maste
51914f1b3e8SDimitry Andric if (thread_sp) {
520f034231aSEd Maste SetThreadSP(thread_sp);
5217fa27ce4SDimitry Andric lldb::StackFrameSP frame_sp(
5227fa27ce4SDimitry Andric thread_sp->GetSelectedFrame(DoNoSelectMostRelevantFrame));
523f034231aSEd Maste if (!frame_sp)
524f034231aSEd Maste frame_sp = thread_sp->GetStackFrameAtIndex(0);
525f034231aSEd Maste if (frame_sp)
526f034231aSEd Maste SetFrameSP(frame_sp);
527f034231aSEd Maste }
528f034231aSEd Maste }
529f034231aSEd Maste }
530f034231aSEd Maste }
531f034231aSEd Maste }
532f034231aSEd Maste }
533f034231aSEd Maste }
534f034231aSEd Maste }
535f034231aSEd Maste
SetProcessPtr(Process * process)53614f1b3e8SDimitry Andric void ExecutionContextRef::SetProcessPtr(Process *process) {
53714f1b3e8SDimitry Andric if (process) {
538f034231aSEd Maste SetProcessSP(process->shared_from_this());
53914f1b3e8SDimitry Andric } else {
540f034231aSEd Maste m_process_wp.reset();
541f034231aSEd Maste m_target_wp.reset();
542f034231aSEd Maste }
543f034231aSEd Maste }
544f034231aSEd Maste
SetThreadPtr(Thread * thread)54514f1b3e8SDimitry Andric void ExecutionContextRef::SetThreadPtr(Thread *thread) {
54614f1b3e8SDimitry Andric if (thread) {
547f034231aSEd Maste SetThreadSP(thread->shared_from_this());
54814f1b3e8SDimitry Andric } else {
549f034231aSEd Maste ClearThread();
550f034231aSEd Maste m_process_wp.reset();
551f034231aSEd Maste m_target_wp.reset();
552f034231aSEd Maste }
553f034231aSEd Maste }
554f034231aSEd Maste
SetFramePtr(StackFrame * frame)55514f1b3e8SDimitry Andric void ExecutionContextRef::SetFramePtr(StackFrame *frame) {
556f034231aSEd Maste if (frame)
557f034231aSEd Maste SetFrameSP(frame->shared_from_this());
558f034231aSEd Maste else
559f034231aSEd Maste Clear();
560f034231aSEd Maste }
561f034231aSEd Maste
GetTargetSP() const56214f1b3e8SDimitry Andric lldb::TargetSP ExecutionContextRef::GetTargetSP() const {
563f034231aSEd Maste lldb::TargetSP target_sp(m_target_wp.lock());
564f034231aSEd Maste if (target_sp && !target_sp->IsValid())
565f034231aSEd Maste target_sp.reset();
566f034231aSEd Maste return target_sp;
567f034231aSEd Maste }
568f034231aSEd Maste
GetProcessSP() const56914f1b3e8SDimitry Andric lldb::ProcessSP ExecutionContextRef::GetProcessSP() const {
570f034231aSEd Maste lldb::ProcessSP process_sp(m_process_wp.lock());
571f034231aSEd Maste if (process_sp && !process_sp->IsValid())
572f034231aSEd Maste process_sp.reset();
573f034231aSEd Maste return process_sp;
574f034231aSEd Maste }
575f034231aSEd Maste
GetThreadSP() const57614f1b3e8SDimitry Andric lldb::ThreadSP ExecutionContextRef::GetThreadSP() const {
577f034231aSEd Maste lldb::ThreadSP thread_sp(m_thread_wp.lock());
578f034231aSEd Maste
57914f1b3e8SDimitry Andric if (m_tid != LLDB_INVALID_THREAD_ID) {
580f73363f1SDimitry Andric // We check if the thread has been destroyed in cases where clients might
581f73363f1SDimitry Andric // still have shared pointer to a thread, but the thread is not valid
582f73363f1SDimitry Andric // anymore (not part of the process)
58314f1b3e8SDimitry Andric if (!thread_sp || !thread_sp->IsValid()) {
584f034231aSEd Maste lldb::ProcessSP process_sp(GetProcessSP());
58514f1b3e8SDimitry Andric if (process_sp && process_sp->IsValid()) {
586f034231aSEd Maste thread_sp = process_sp->GetThreadList().FindThreadByID(m_tid);
587f034231aSEd Maste m_thread_wp = thread_sp;
588f034231aSEd Maste }
589f034231aSEd Maste }
590f034231aSEd Maste }
591f034231aSEd Maste
592f73363f1SDimitry Andric // Check that we aren't about to return an invalid thread sp. We might
593f73363f1SDimitry Andric // return a nullptr thread_sp, but don't return an invalid one.
594f034231aSEd Maste
595f034231aSEd Maste if (thread_sp && !thread_sp->IsValid())
596f034231aSEd Maste thread_sp.reset();
597f034231aSEd Maste
598f034231aSEd Maste return thread_sp;
599f034231aSEd Maste }
600f034231aSEd Maste
GetFrameSP() const60114f1b3e8SDimitry Andric lldb::StackFrameSP ExecutionContextRef::GetFrameSP() const {
60214f1b3e8SDimitry Andric if (m_stack_id.IsValid()) {
603f034231aSEd Maste lldb::ThreadSP thread_sp(GetThreadSP());
604f034231aSEd Maste if (thread_sp)
605f034231aSEd Maste return thread_sp->GetFrameWithStackID(m_stack_id);
606f034231aSEd Maste }
607f034231aSEd Maste return lldb::StackFrameSP();
608f034231aSEd Maste }
609f034231aSEd Maste
610f034231aSEd Maste ExecutionContext
Lock(bool thread_and_frame_only_if_stopped) const61114f1b3e8SDimitry Andric ExecutionContextRef::Lock(bool thread_and_frame_only_if_stopped) const {
612866dcdacSEd Maste return ExecutionContext(this, thread_and_frame_only_if_stopped);
613f034231aSEd Maste }
614