blob: 0aa4a54ee24ae157484c6154631e80e02fb784b2 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- ExecutionContext.cpp ------------------------------------*- C++ -*-===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006//
7//===----------------------------------------------------------------------===//
Chris Lattner30fdc8d2010-06-08 16:52:24 +00008
9#include "lldb/Target/ExecutionContext.h"
10#include "lldb/Target/ExecutionContextScope.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000011#include "lldb/Target/Process.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000012#include "lldb/Target/StackFrame.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000013#include "lldb/Target/Target.h"
14#include "lldb/Target/Thread.h"
Pavel Labathd821c992018-08-07 11:07:21 +000015#include "lldb/Utility/State.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000016
17using namespace lldb_private;
18
Kate Stoneb9c1b512016-09-06 20:57:50 +000019ExecutionContext::ExecutionContext()
20 : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {}
21
22ExecutionContext::ExecutionContext(const ExecutionContext &rhs)
23 : m_target_sp(rhs.m_target_sp), m_process_sp(rhs.m_process_sp),
24 m_thread_sp(rhs.m_thread_sp), m_frame_sp(rhs.m_frame_sp) {}
25
26ExecutionContext::ExecutionContext(const lldb::TargetSP &target_sp,
27 bool get_process)
28 : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
29 if (target_sp)
30 SetContext(target_sp, get_process);
Chris Lattner30fdc8d2010-06-08 16:52:24 +000031}
32
Kate Stoneb9c1b512016-09-06 20:57:50 +000033ExecutionContext::ExecutionContext(const lldb::ProcessSP &process_sp)
34 : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
35 if (process_sp)
36 SetContext(process_sp);
Greg Claytonc14ee322011-09-22 04:58:26 +000037}
38
Kate Stoneb9c1b512016-09-06 20:57:50 +000039ExecutionContext::ExecutionContext(const lldb::ThreadSP &thread_sp)
40 : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
41 if (thread_sp)
42 SetContext(thread_sp);
Greg Claytoncc4d0142012-02-17 07:49:44 +000043}
44
Kate Stoneb9c1b512016-09-06 20:57:50 +000045ExecutionContext::ExecutionContext(const lldb::StackFrameSP &frame_sp)
46 : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
47 if (frame_sp)
48 SetContext(frame_sp);
Greg Claytoncc4d0142012-02-17 07:49:44 +000049}
50
Kate Stoneb9c1b512016-09-06 20:57:50 +000051ExecutionContext::ExecutionContext(const lldb::TargetWP &target_wp,
52 bool get_process)
53 : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
54 lldb::TargetSP target_sp(target_wp.lock());
55 if (target_sp)
56 SetContext(target_sp, get_process);
Greg Claytoncc4d0142012-02-17 07:49:44 +000057}
58
Kate Stoneb9c1b512016-09-06 20:57:50 +000059ExecutionContext::ExecutionContext(const lldb::ProcessWP &process_wp)
60 : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
61 lldb::ProcessSP process_sp(process_wp.lock());
62 if (process_sp)
63 SetContext(process_sp);
Greg Claytonc14ee322011-09-22 04:58:26 +000064}
65
Kate Stoneb9c1b512016-09-06 20:57:50 +000066ExecutionContext::ExecutionContext(const lldb::ThreadWP &thread_wp)
67 : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
68 lldb::ThreadSP thread_sp(thread_wp.lock());
69 if (thread_sp)
70 SetContext(thread_sp);
Greg Clayton1ac04c32012-02-21 00:09:25 +000071}
72
Kate Stoneb9c1b512016-09-06 20:57:50 +000073ExecutionContext::ExecutionContext(const lldb::StackFrameWP &frame_wp)
74 : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
75 lldb::StackFrameSP frame_sp(frame_wp.lock());
76 if (frame_sp)
77 SetContext(frame_sp);
Greg Clayton1ac04c32012-02-21 00:09:25 +000078}
79
Kate Stoneb9c1b512016-09-06 20:57:50 +000080ExecutionContext::ExecutionContext(Target *t,
81 bool fill_current_process_thread_frame)
82 : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
83 if (t) {
84 m_target_sp = t->shared_from_this();
85 if (fill_current_process_thread_frame) {
86 m_process_sp = t->GetProcessSP();
87 if (m_process_sp) {
88 m_thread_sp = m_process_sp->GetThreadList().GetSelectedThread();
89 if (m_thread_sp)
90 m_frame_sp = m_thread_sp->GetSelectedFrame();
91 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000092 }
Kate Stoneb9c1b512016-09-06 20:57:50 +000093 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000094}
95
Kate Stoneb9c1b512016-09-06 20:57:50 +000096ExecutionContext::ExecutionContext(Process *process, Thread *thread,
97 StackFrame *frame)
98 : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
99 if (process) {
100 m_process_sp = process->shared_from_this();
101 m_target_sp = process->GetTarget().shared_from_this();
102 }
103 if (thread)
104 m_thread_sp = thread->shared_from_this();
105 if (frame)
106 m_frame_sp = frame->shared_from_this();
107}
108
109ExecutionContext::ExecutionContext(const ExecutionContextRef &exe_ctx_ref)
110 : m_target_sp(exe_ctx_ref.GetTargetSP()),
111 m_process_sp(exe_ctx_ref.GetProcessSP()),
112 m_thread_sp(exe_ctx_ref.GetThreadSP()),
113 m_frame_sp(exe_ctx_ref.GetFrameSP()) {}
114
115ExecutionContext::ExecutionContext(const ExecutionContextRef *exe_ctx_ref_ptr,
116 bool thread_and_frame_only_if_stopped)
117 : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
118 if (exe_ctx_ref_ptr) {
119 m_target_sp = exe_ctx_ref_ptr->GetTargetSP();
120 m_process_sp = exe_ctx_ref_ptr->GetProcessSP();
121 if (!thread_and_frame_only_if_stopped ||
122 (m_process_sp && StateIsStoppedState(m_process_sp->GetState(), true))) {
123 m_thread_sp = exe_ctx_ref_ptr->GetThreadSP();
124 m_frame_sp = exe_ctx_ref_ptr->GetFrameSP();
Greg Clayton526ae042015-02-12 00:34:25 +0000125 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000126 }
Greg Claytoncc4d0142012-02-17 07:49:44 +0000127}
128
Saleem Abdulrasoolbb19a132016-05-19 05:13:57 +0000129ExecutionContext::ExecutionContext(const ExecutionContextRef *exe_ctx_ref_ptr,
130 std::unique_lock<std::recursive_mutex> &lock)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000131 : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
132 if (exe_ctx_ref_ptr) {
133 m_target_sp = exe_ctx_ref_ptr->GetTargetSP();
134 if (m_target_sp) {
135 lock = std::unique_lock<std::recursive_mutex>(m_target_sp->GetAPIMutex());
Saleem Abdulrasoolbb19a132016-05-19 05:13:57 +0000136
Kate Stoneb9c1b512016-09-06 20:57:50 +0000137 m_process_sp = exe_ctx_ref_ptr->GetProcessSP();
138 m_thread_sp = exe_ctx_ref_ptr->GetThreadSP();
139 m_frame_sp = exe_ctx_ref_ptr->GetFrameSP();
Jim Ingham4fc6cb92012-08-22 21:34:33 +0000140 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000141 }
Jim Ingham4fc6cb92012-08-22 21:34:33 +0000142}
143
Kate Stoneb9c1b512016-09-06 20:57:50 +0000144ExecutionContext::ExecutionContext(const ExecutionContextRef &exe_ctx_ref,
145 std::unique_lock<std::recursive_mutex> &lock)
146 : m_target_sp(exe_ctx_ref.GetTargetSP()), m_process_sp(), m_thread_sp(),
147 m_frame_sp() {
148 if (m_target_sp) {
149 lock = std::unique_lock<std::recursive_mutex>(m_target_sp->GetAPIMutex());
Saleem Abdulrasoolbb19a132016-05-19 05:13:57 +0000150
Kate Stoneb9c1b512016-09-06 20:57:50 +0000151 m_process_sp = exe_ctx_ref.GetProcessSP();
152 m_thread_sp = exe_ctx_ref.GetThreadSP();
153 m_frame_sp = exe_ctx_ref.GetFrameSP();
154 }
Jim Ingham4fc6cb92012-08-22 21:34:33 +0000155}
156
Kate Stoneb9c1b512016-09-06 20:57:50 +0000157ExecutionContext::ExecutionContext(ExecutionContextScope *exe_scope_ptr)
158 : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
159 if (exe_scope_ptr)
160 exe_scope_ptr->CalculateExecutionContext(*this);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000161}
162
Kate Stoneb9c1b512016-09-06 20:57:50 +0000163ExecutionContext::ExecutionContext(ExecutionContextScope &exe_scope_ref) {
164 exe_scope_ref.CalculateExecutionContext(*this);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000165}
166
Kate Stoneb9c1b512016-09-06 20:57:50 +0000167void ExecutionContext::Clear() {
168 m_target_sp.reset();
169 m_process_sp.reset();
170 m_thread_sp.reset();
171 m_frame_sp.reset();
Greg Claytonc14ee322011-09-22 04:58:26 +0000172}
173
Eugene Zelenko9394d7722016-02-18 00:10:17 +0000174ExecutionContext::~ExecutionContext() = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000175
Kate Stoneb9c1b512016-09-06 20:57:50 +0000176uint32_t ExecutionContext::GetAddressByteSize() const {
177 if (m_target_sp && m_target_sp->GetArchitecture().IsValid())
178 return m_target_sp->GetArchitecture().GetAddressByteSize();
179 if (m_process_sp)
180 return m_process_sp->GetAddressByteSize();
181 return sizeof(void *);
Greg Claytoncc4d0142012-02-17 07:49:44 +0000182}
183
Kate Stoneb9c1b512016-09-06 20:57:50 +0000184lldb::ByteOrder ExecutionContext::GetByteOrder() const {
185 if (m_target_sp && m_target_sp->GetArchitecture().IsValid())
186 m_target_sp->GetArchitecture().GetByteOrder();
187 if (m_process_sp)
188 m_process_sp->GetByteOrder();
189 return endian::InlHostByteOrder();
Enrico Granata347c2aa2013-10-08 21:49:02 +0000190}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000191
Kate Stoneb9c1b512016-09-06 20:57:50 +0000192RegisterContext *ExecutionContext::GetRegisterContext() const {
193 if (m_frame_sp)
194 return m_frame_sp->GetRegisterContext().get();
195 else if (m_thread_sp)
196 return m_thread_sp->GetRegisterContext().get();
197 return nullptr;
Greg Claytonc14ee322011-09-22 04:58:26 +0000198}
199
Kate Stoneb9c1b512016-09-06 20:57:50 +0000200Target *ExecutionContext::GetTargetPtr() const {
201 if (m_target_sp)
Greg Claytonc14ee322011-09-22 04:58:26 +0000202 return m_target_sp.get();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000203 if (m_process_sp)
204 return &m_process_sp->GetTarget();
205 return nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000206}
Greg Clayton644247c2011-07-07 01:59:51 +0000207
Kate Stoneb9c1b512016-09-06 20:57:50 +0000208Process *ExecutionContext::GetProcessPtr() const {
209 if (m_process_sp)
210 return m_process_sp.get();
211 if (m_target_sp)
212 return m_target_sp->GetProcessSP().get();
213 return nullptr;
214}
215
216ExecutionContextScope *ExecutionContext::GetBestExecutionContextScope() const {
217 if (m_frame_sp)
218 return m_frame_sp.get();
219 if (m_thread_sp)
220 return m_thread_sp.get();
221 if (m_process_sp)
222 return m_process_sp.get();
223 return m_target_sp.get();
224}
225
226Target &ExecutionContext::GetTargetRef() const {
227#if defined(LLDB_CONFIGURATION_DEBUG) || defined(LLDB_CONFIGURATION_RELEASE)
228 assert(m_target_sp);
Greg Clayton1ac04c32012-02-21 00:09:25 +0000229#endif
Kate Stoneb9c1b512016-09-06 20:57:50 +0000230 return *m_target_sp;
Greg Clayton644247c2011-07-07 01:59:51 +0000231}
Greg Claytonc14ee322011-09-22 04:58:26 +0000232
Kate Stoneb9c1b512016-09-06 20:57:50 +0000233Process &ExecutionContext::GetProcessRef() const {
234#if defined(LLDB_CONFIGURATION_DEBUG) || defined(LLDB_CONFIGURATION_RELEASE)
235 assert(m_process_sp);
Greg Clayton1ac04c32012-02-21 00:09:25 +0000236#endif
Kate Stoneb9c1b512016-09-06 20:57:50 +0000237 return *m_process_sp;
Greg Claytonc14ee322011-09-22 04:58:26 +0000238}
239
Kate Stoneb9c1b512016-09-06 20:57:50 +0000240Thread &ExecutionContext::GetThreadRef() const {
241#if defined(LLDB_CONFIGURATION_DEBUG) || defined(LLDB_CONFIGURATION_RELEASE)
242 assert(m_thread_sp);
Greg Clayton1ac04c32012-02-21 00:09:25 +0000243#endif
Kate Stoneb9c1b512016-09-06 20:57:50 +0000244 return *m_thread_sp;
Greg Claytonc14ee322011-09-22 04:58:26 +0000245}
246
Kate Stoneb9c1b512016-09-06 20:57:50 +0000247StackFrame &ExecutionContext::GetFrameRef() const {
248#if defined(LLDB_CONFIGURATION_DEBUG) || defined(LLDB_CONFIGURATION_RELEASE)
249 assert(m_frame_sp);
Greg Clayton1ac04c32012-02-21 00:09:25 +0000250#endif
Kate Stoneb9c1b512016-09-06 20:57:50 +0000251 return *m_frame_sp;
Greg Claytonc14ee322011-09-22 04:58:26 +0000252}
253
Kate Stoneb9c1b512016-09-06 20:57:50 +0000254void ExecutionContext::SetTargetSP(const lldb::TargetSP &target_sp) {
255 m_target_sp = target_sp;
Greg Claytonc14ee322011-09-22 04:58:26 +0000256}
257
Kate Stoneb9c1b512016-09-06 20:57:50 +0000258void ExecutionContext::SetProcessSP(const lldb::ProcessSP &process_sp) {
259 m_process_sp = process_sp;
Greg Claytonc14ee322011-09-22 04:58:26 +0000260}
261
Kate Stoneb9c1b512016-09-06 20:57:50 +0000262void ExecutionContext::SetThreadSP(const lldb::ThreadSP &thread_sp) {
263 m_thread_sp = thread_sp;
Greg Claytonc14ee322011-09-22 04:58:26 +0000264}
265
Kate Stoneb9c1b512016-09-06 20:57:50 +0000266void ExecutionContext::SetFrameSP(const lldb::StackFrameSP &frame_sp) {
267 m_frame_sp = frame_sp;
Greg Claytonc14ee322011-09-22 04:58:26 +0000268}
269
Kate Stoneb9c1b512016-09-06 20:57:50 +0000270void ExecutionContext::SetTargetPtr(Target *target) {
271 if (target)
272 m_target_sp = target->shared_from_this();
273 else
274 m_target_sp.reset();
Greg Claytonc14ee322011-09-22 04:58:26 +0000275}
276
Kate Stoneb9c1b512016-09-06 20:57:50 +0000277void ExecutionContext::SetProcessPtr(Process *process) {
278 if (process)
279 m_process_sp = process->shared_from_this();
280 else
281 m_process_sp.reset();
Greg Claytonc14ee322011-09-22 04:58:26 +0000282}
283
Kate Stoneb9c1b512016-09-06 20:57:50 +0000284void ExecutionContext::SetThreadPtr(Thread *thread) {
285 if (thread)
286 m_thread_sp = thread->shared_from_this();
287 else
Greg Claytoncc4d0142012-02-17 07:49:44 +0000288 m_thread_sp.reset();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000289}
290
291void ExecutionContext::SetFramePtr(StackFrame *frame) {
292 if (frame)
293 m_frame_sp = frame->shared_from_this();
294 else
Greg Claytoncc4d0142012-02-17 07:49:44 +0000295 m_frame_sp.reset();
296}
297
Kate Stoneb9c1b512016-09-06 20:57:50 +0000298void ExecutionContext::SetContext(const lldb::TargetSP &target_sp,
299 bool get_process) {
300 m_target_sp = target_sp;
301 if (get_process && target_sp)
302 m_process_sp = target_sp->GetProcessSP();
303 else
304 m_process_sp.reset();
305 m_thread_sp.reset();
306 m_frame_sp.reset();
307}
308
309void ExecutionContext::SetContext(const lldb::ProcessSP &process_sp) {
310 m_process_sp = process_sp;
311 if (process_sp)
312 m_target_sp = process_sp->GetTarget().shared_from_this();
313 else
314 m_target_sp.reset();
315 m_thread_sp.reset();
316 m_frame_sp.reset();
317}
318
319void ExecutionContext::SetContext(const lldb::ThreadSP &thread_sp) {
320 m_frame_sp.reset();
321 m_thread_sp = thread_sp;
322 if (thread_sp) {
323 m_process_sp = thread_sp->GetProcess();
324 if (m_process_sp)
325 m_target_sp = m_process_sp->GetTarget().shared_from_this();
Greg Claytoncc4d0142012-02-17 07:49:44 +0000326 else
Kate Stoneb9c1b512016-09-06 20:57:50 +0000327 m_target_sp.reset();
328 } else {
329 m_target_sp.reset();
330 m_process_sp.reset();
331 }
332}
333
334void ExecutionContext::SetContext(const lldb::StackFrameSP &frame_sp) {
335 m_frame_sp = frame_sp;
336 if (frame_sp) {
337 m_thread_sp = frame_sp->CalculateThread();
338 if (m_thread_sp) {
339 m_process_sp = m_thread_sp->GetProcess();
340 if (m_process_sp)
341 m_target_sp = m_process_sp->GetTarget().shared_from_this();
342 else
Greg Claytoncc4d0142012-02-17 07:49:44 +0000343 m_target_sp.reset();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000344 } else {
345 m_target_sp.reset();
346 m_process_sp.reset();
347 }
348 } else {
349 m_target_sp.reset();
350 m_process_sp.reset();
Greg Claytoncc4d0142012-02-17 07:49:44 +0000351 m_thread_sp.reset();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000352 }
Greg Claytoncc4d0142012-02-17 07:49:44 +0000353}
354
Kate Stoneb9c1b512016-09-06 20:57:50 +0000355ExecutionContext &ExecutionContext::operator=(const ExecutionContext &rhs) {
356 if (this != &rhs) {
357 m_target_sp = rhs.m_target_sp;
358 m_process_sp = rhs.m_process_sp;
359 m_thread_sp = rhs.m_thread_sp;
360 m_frame_sp = rhs.m_frame_sp;
361 }
362 return *this;
363}
364
365bool ExecutionContext::operator==(const ExecutionContext &rhs) const {
366 // Check that the frame shared pointers match, or both are valid and their
Adrian Prantl05097242018-04-30 16:49:04 +0000367 // stack IDs match since sometimes we get new objects that represent the same
Kate Stoneb9c1b512016-09-06 20:57:50 +0000368 // frame within a thread.
369 if ((m_frame_sp == rhs.m_frame_sp) ||
370 (m_frame_sp && rhs.m_frame_sp &&
371 m_frame_sp->GetStackID() == rhs.m_frame_sp->GetStackID())) {
Adrian Prantl05097242018-04-30 16:49:04 +0000372 // Check that the thread shared pointers match, or both are valid and their
373 // thread IDs match since sometimes we get new objects that represent the
374 // same thread within a process.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000375 if ((m_thread_sp == rhs.m_thread_sp) ||
376 (m_thread_sp && rhs.m_thread_sp &&
377 m_thread_sp->GetID() == rhs.m_thread_sp->GetID())) {
378 // Processes and targets don't change much
379 return m_process_sp == rhs.m_process_sp && m_target_sp == rhs.m_target_sp;
Greg Claytoncc4d0142012-02-17 07:49:44 +0000380 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000381 }
382 return false;
Greg Claytoncc4d0142012-02-17 07:49:44 +0000383}
384
Kate Stoneb9c1b512016-09-06 20:57:50 +0000385bool ExecutionContext::operator!=(const ExecutionContext &rhs) const {
386 return !(*this == rhs);
Greg Claytoncc4d0142012-02-17 07:49:44 +0000387}
388
Kate Stoneb9c1b512016-09-06 20:57:50 +0000389bool ExecutionContext::HasTargetScope() const {
390 return ((bool)m_target_sp && m_target_sp->IsValid());
Greg Claytoncc4d0142012-02-17 07:49:44 +0000391}
392
Kate Stoneb9c1b512016-09-06 20:57:50 +0000393bool ExecutionContext::HasProcessScope() const {
394 return (HasTargetScope() && ((bool)m_process_sp && m_process_sp->IsValid()));
Greg Claytoncc4d0142012-02-17 07:49:44 +0000395}
396
Kate Stoneb9c1b512016-09-06 20:57:50 +0000397bool ExecutionContext::HasThreadScope() const {
398 return (HasProcessScope() && ((bool)m_thread_sp && m_thread_sp->IsValid()));
Greg Claytoncc4d0142012-02-17 07:49:44 +0000399}
400
Kate Stoneb9c1b512016-09-06 20:57:50 +0000401bool ExecutionContext::HasFrameScope() const {
402 return HasThreadScope() && m_frame_sp;
Jim Ingham4fc6cb92012-08-22 21:34:33 +0000403}
404
Kate Stoneb9c1b512016-09-06 20:57:50 +0000405ExecutionContextRef::ExecutionContextRef()
406 : m_target_wp(), m_process_wp(), m_thread_wp(),
407 m_tid(LLDB_INVALID_THREAD_ID), m_stack_id() {}
408
409ExecutionContextRef::ExecutionContextRef(const ExecutionContext *exe_ctx)
410 : m_target_wp(), m_process_wp(), m_thread_wp(),
411 m_tid(LLDB_INVALID_THREAD_ID), m_stack_id() {
412 if (exe_ctx)
413 *this = *exe_ctx;
Jim Ingham4fc6cb92012-08-22 21:34:33 +0000414}
415
Kate Stoneb9c1b512016-09-06 20:57:50 +0000416ExecutionContextRef::ExecutionContextRef(const ExecutionContext &exe_ctx)
417 : m_target_wp(), m_process_wp(), m_thread_wp(),
418 m_tid(LLDB_INVALID_THREAD_ID), m_stack_id() {
419 *this = exe_ctx;
Jim Ingham4fc6cb92012-08-22 21:34:33 +0000420}
421
Kate Stoneb9c1b512016-09-06 20:57:50 +0000422ExecutionContextRef::ExecutionContextRef(Target *target, bool adopt_selected)
423 : m_target_wp(), m_process_wp(), m_thread_wp(),
424 m_tid(LLDB_INVALID_THREAD_ID), m_stack_id() {
425 SetTargetPtr(target, adopt_selected);
Jim Ingham4fc6cb92012-08-22 21:34:33 +0000426}
Greg Claytoncc4d0142012-02-17 07:49:44 +0000427
Kate Stoneb9c1b512016-09-06 20:57:50 +0000428ExecutionContextRef::ExecutionContextRef(const ExecutionContextRef &rhs)
429 : m_target_wp(rhs.m_target_wp), m_process_wp(rhs.m_process_wp),
430 m_thread_wp(rhs.m_thread_wp), m_tid(rhs.m_tid),
431 m_stack_id(rhs.m_stack_id) {}
432
433ExecutionContextRef &ExecutionContextRef::
434operator=(const ExecutionContextRef &rhs) {
435 if (this != &rhs) {
436 m_target_wp = rhs.m_target_wp;
437 m_process_wp = rhs.m_process_wp;
438 m_thread_wp = rhs.m_thread_wp;
439 m_tid = rhs.m_tid;
440 m_stack_id = rhs.m_stack_id;
441 }
442 return *this;
Greg Claytoncc4d0142012-02-17 07:49:44 +0000443}
444
Kate Stoneb9c1b512016-09-06 20:57:50 +0000445ExecutionContextRef &ExecutionContextRef::
446operator=(const ExecutionContext &exe_ctx) {
447 m_target_wp = exe_ctx.GetTargetSP();
448 m_process_wp = exe_ctx.GetProcessSP();
449 lldb::ThreadSP thread_sp(exe_ctx.GetThreadSP());
450 m_thread_wp = thread_sp;
451 if (thread_sp)
452 m_tid = thread_sp->GetID();
453 else
454 m_tid = LLDB_INVALID_THREAD_ID;
455 lldb::StackFrameSP frame_sp(exe_ctx.GetFrameSP());
456 if (frame_sp)
457 m_stack_id = frame_sp->GetStackID();
458 else
459 m_stack_id.Clear();
460 return *this;
Greg Claytoncc4d0142012-02-17 07:49:44 +0000461}
462
Kate Stoneb9c1b512016-09-06 20:57:50 +0000463void ExecutionContextRef::Clear() {
464 m_target_wp.reset();
465 m_process_wp.reset();
466 ClearThread();
467 ClearFrame();
Greg Claytoncc4d0142012-02-17 07:49:44 +0000468}
469
Eugene Zelenko9394d7722016-02-18 00:10:17 +0000470ExecutionContextRef::~ExecutionContextRef() = default;
Greg Claytoncc4d0142012-02-17 07:49:44 +0000471
Kate Stoneb9c1b512016-09-06 20:57:50 +0000472void ExecutionContextRef::SetTargetSP(const lldb::TargetSP &target_sp) {
473 m_target_wp = target_sp;
Greg Claytoncc4d0142012-02-17 07:49:44 +0000474}
475
Kate Stoneb9c1b512016-09-06 20:57:50 +0000476void ExecutionContextRef::SetProcessSP(const lldb::ProcessSP &process_sp) {
477 if (process_sp) {
478 m_process_wp = process_sp;
479 SetTargetSP(process_sp->GetTarget().shared_from_this());
480 } else {
481 m_process_wp.reset();
482 m_target_wp.reset();
483 }
Greg Claytoncc4d0142012-02-17 07:49:44 +0000484}
485
Kate Stoneb9c1b512016-09-06 20:57:50 +0000486void ExecutionContextRef::SetThreadSP(const lldb::ThreadSP &thread_sp) {
487 if (thread_sp) {
488 m_thread_wp = thread_sp;
489 m_tid = thread_sp->GetID();
490 SetProcessSP(thread_sp->GetProcess());
491 } else {
492 ClearThread();
493 m_process_wp.reset();
494 m_target_wp.reset();
495 }
Greg Claytoncc4d0142012-02-17 07:49:44 +0000496}
497
Kate Stoneb9c1b512016-09-06 20:57:50 +0000498void ExecutionContextRef::SetFrameSP(const lldb::StackFrameSP &frame_sp) {
499 if (frame_sp) {
500 m_stack_id = frame_sp->GetStackID();
501 SetThreadSP(frame_sp->GetThread());
502 } else {
503 ClearFrame();
504 ClearThread();
505 m_process_wp.reset();
506 m_target_wp.reset();
507 }
Greg Claytoncc4d0142012-02-17 07:49:44 +0000508}
509
Kate Stoneb9c1b512016-09-06 20:57:50 +0000510void ExecutionContextRef::SetTargetPtr(Target *target, bool adopt_selected) {
511 Clear();
512 if (target) {
513 lldb::TargetSP target_sp(target->shared_from_this());
514 if (target_sp) {
515 m_target_wp = target_sp;
516 if (adopt_selected) {
517 lldb::ProcessSP process_sp(target_sp->GetProcessSP());
518 if (process_sp) {
519 m_process_wp = process_sp;
520 if (process_sp) {
521 // Only fill in the thread and frame if our process is stopped
522 // Don't just check the state, since we might be in the middle of
523 // resuming.
524 Process::StopLocker stop_locker;
525
526 if (stop_locker.TryLock(&process_sp->GetRunLock()) &&
527 StateIsStoppedState(process_sp->GetState(), true)) {
528 lldb::ThreadSP thread_sp(
529 process_sp->GetThreadList().GetSelectedThread());
530 if (!thread_sp)
531 thread_sp = process_sp->GetThreadList().GetThreadAtIndex(0);
532
533 if (thread_sp) {
534 SetThreadSP(thread_sp);
535 lldb::StackFrameSP frame_sp(thread_sp->GetSelectedFrame());
536 if (!frame_sp)
537 frame_sp = thread_sp->GetStackFrameAtIndex(0);
538 if (frame_sp)
539 SetFrameSP(frame_sp);
540 }
541 }
542 }
543 }
544 }
545 }
546 }
547}
548
549void ExecutionContextRef::SetProcessPtr(Process *process) {
550 if (process) {
551 SetProcessSP(process->shared_from_this());
552 } else {
553 m_process_wp.reset();
554 m_target_wp.reset();
555 }
556}
557
558void ExecutionContextRef::SetThreadPtr(Thread *thread) {
559 if (thread) {
560 SetThreadSP(thread->shared_from_this());
561 } else {
562 ClearThread();
563 m_process_wp.reset();
564 m_target_wp.reset();
565 }
566}
567
568void ExecutionContextRef::SetFramePtr(StackFrame *frame) {
569 if (frame)
570 SetFrameSP(frame->shared_from_this());
571 else
Greg Claytoncc4d0142012-02-17 07:49:44 +0000572 Clear();
Greg Claytoncc4d0142012-02-17 07:49:44 +0000573}
574
Kate Stoneb9c1b512016-09-06 20:57:50 +0000575lldb::TargetSP ExecutionContextRef::GetTargetSP() const {
576 lldb::TargetSP target_sp(m_target_wp.lock());
577 if (target_sp && !target_sp->IsValid())
578 target_sp.reset();
579 return target_sp;
Greg Claytoncc4d0142012-02-17 07:49:44 +0000580}
581
Kate Stoneb9c1b512016-09-06 20:57:50 +0000582lldb::ProcessSP ExecutionContextRef::GetProcessSP() const {
583 lldb::ProcessSP process_sp(m_process_wp.lock());
584 if (process_sp && !process_sp->IsValid())
585 process_sp.reset();
586 return process_sp;
587}
588
589lldb::ThreadSP ExecutionContextRef::GetThreadSP() const {
590 lldb::ThreadSP thread_sp(m_thread_wp.lock());
591
592 if (m_tid != LLDB_INVALID_THREAD_ID) {
Adrian Prantl05097242018-04-30 16:49:04 +0000593 // We check if the thread has been destroyed in cases where clients might
594 // still have shared pointer to a thread, but the thread is not valid
595 // anymore (not part of the process)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000596 if (!thread_sp || !thread_sp->IsValid()) {
597 lldb::ProcessSP process_sp(GetProcessSP());
598 if (process_sp && process_sp->IsValid()) {
599 thread_sp = process_sp->GetThreadList().FindThreadByID(m_tid);
600 m_thread_wp = thread_sp;
601 }
Greg Clayton7fdf9ef2012-04-05 16:12:35 +0000602 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000603 }
604
Adrian Prantl05097242018-04-30 16:49:04 +0000605 // Check that we aren't about to return an invalid thread sp. We might
606 // return a nullptr thread_sp, but don't return an invalid one.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000607
608 if (thread_sp && !thread_sp->IsValid())
609 thread_sp.reset();
610
611 return thread_sp;
Greg Claytoncc4d0142012-02-17 07:49:44 +0000612}
613
Kate Stoneb9c1b512016-09-06 20:57:50 +0000614lldb::StackFrameSP ExecutionContextRef::GetFrameSP() const {
615 if (m_stack_id.IsValid()) {
616 lldb::ThreadSP thread_sp(GetThreadSP());
617 if (thread_sp)
618 return thread_sp->GetFrameWithStackID(m_stack_id);
619 }
620 return lldb::StackFrameSP();
Greg Claytoncc4d0142012-02-17 07:49:44 +0000621}
622
623ExecutionContext
Kate Stoneb9c1b512016-09-06 20:57:50 +0000624ExecutionContextRef::Lock(bool thread_and_frame_only_if_stopped) const {
625 return ExecutionContext(this, thread_and_frame_only_if_stopped);
Greg Claytoncc4d0142012-02-17 07:49:44 +0000626}