1 //===-- ExecutionContext.cpp ------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
12 // Other libraries and framework includes
14 #include "lldb/Target/ExecutionContext.h"
15 #include "lldb/Core/State.h"
16 #include "lldb/Target/ExecutionContextScope.h"
17 #include "lldb/Target/Process.h"
18 #include "lldb/Target/StackFrame.h"
19 #include "lldb/Target/Target.h"
20 #include "lldb/Target/Thread.h"
22 using namespace lldb_private;
24 ExecutionContext::ExecutionContext()
25 : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {}
27 ExecutionContext::ExecutionContext(const ExecutionContext &rhs)
28 : m_target_sp(rhs.m_target_sp), m_process_sp(rhs.m_process_sp),
29 m_thread_sp(rhs.m_thread_sp), m_frame_sp(rhs.m_frame_sp) {}
31 ExecutionContext::ExecutionContext(const lldb::TargetSP &target_sp,
33 : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
35 SetContext(target_sp, get_process);
38 ExecutionContext::ExecutionContext(const lldb::ProcessSP &process_sp)
39 : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
41 SetContext(process_sp);
44 ExecutionContext::ExecutionContext(const lldb::ThreadSP &thread_sp)
45 : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
47 SetContext(thread_sp);
50 ExecutionContext::ExecutionContext(const lldb::StackFrameSP &frame_sp)
51 : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
56 ExecutionContext::ExecutionContext(const lldb::TargetWP &target_wp,
58 : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
59 lldb::TargetSP target_sp(target_wp.lock());
61 SetContext(target_sp, get_process);
64 ExecutionContext::ExecutionContext(const lldb::ProcessWP &process_wp)
65 : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
66 lldb::ProcessSP process_sp(process_wp.lock());
68 SetContext(process_sp);
71 ExecutionContext::ExecutionContext(const lldb::ThreadWP &thread_wp)
72 : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
73 lldb::ThreadSP thread_sp(thread_wp.lock());
75 SetContext(thread_sp);
78 ExecutionContext::ExecutionContext(const lldb::StackFrameWP &frame_wp)
79 : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
80 lldb::StackFrameSP frame_sp(frame_wp.lock());
85 ExecutionContext::ExecutionContext(Target *t,
86 bool fill_current_process_thread_frame)
87 : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
89 m_target_sp = t->shared_from_this();
90 if (fill_current_process_thread_frame) {
91 m_process_sp = t->GetProcessSP();
93 m_thread_sp = m_process_sp->GetThreadList().GetSelectedThread();
95 m_frame_sp = m_thread_sp->GetSelectedFrame();
101 ExecutionContext::ExecutionContext(Process *process, Thread *thread,
103 : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
105 m_process_sp = process->shared_from_this();
106 m_target_sp = process->GetTarget().shared_from_this();
109 m_thread_sp = thread->shared_from_this();
111 m_frame_sp = frame->shared_from_this();
114 ExecutionContext::ExecutionContext(const ExecutionContextRef &exe_ctx_ref)
115 : m_target_sp(exe_ctx_ref.GetTargetSP()),
116 m_process_sp(exe_ctx_ref.GetProcessSP()),
117 m_thread_sp(exe_ctx_ref.GetThreadSP()),
118 m_frame_sp(exe_ctx_ref.GetFrameSP()) {}
120 ExecutionContext::ExecutionContext(const ExecutionContextRef *exe_ctx_ref_ptr,
121 bool thread_and_frame_only_if_stopped)
122 : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
123 if (exe_ctx_ref_ptr) {
124 m_target_sp = exe_ctx_ref_ptr->GetTargetSP();
125 m_process_sp = exe_ctx_ref_ptr->GetProcessSP();
126 if (!thread_and_frame_only_if_stopped ||
127 (m_process_sp && StateIsStoppedState(m_process_sp->GetState(), true))) {
128 m_thread_sp = exe_ctx_ref_ptr->GetThreadSP();
129 m_frame_sp = exe_ctx_ref_ptr->GetFrameSP();
134 ExecutionContext::ExecutionContext(const ExecutionContextRef *exe_ctx_ref_ptr,
135 std::unique_lock<std::recursive_mutex> &lock)
136 : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
137 if (exe_ctx_ref_ptr) {
138 m_target_sp = exe_ctx_ref_ptr->GetTargetSP();
140 lock = std::unique_lock<std::recursive_mutex>(m_target_sp->GetAPIMutex());
142 m_process_sp = exe_ctx_ref_ptr->GetProcessSP();
143 m_thread_sp = exe_ctx_ref_ptr->GetThreadSP();
144 m_frame_sp = exe_ctx_ref_ptr->GetFrameSP();
149 ExecutionContext::ExecutionContext(const ExecutionContextRef &exe_ctx_ref,
150 std::unique_lock<std::recursive_mutex> &lock)
151 : m_target_sp(exe_ctx_ref.GetTargetSP()), m_process_sp(), m_thread_sp(),
154 lock = std::unique_lock<std::recursive_mutex>(m_target_sp->GetAPIMutex());
156 m_process_sp = exe_ctx_ref.GetProcessSP();
157 m_thread_sp = exe_ctx_ref.GetThreadSP();
158 m_frame_sp = exe_ctx_ref.GetFrameSP();
162 ExecutionContext::ExecutionContext(ExecutionContextScope *exe_scope_ptr)
163 : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
165 exe_scope_ptr->CalculateExecutionContext(*this);
168 ExecutionContext::ExecutionContext(ExecutionContextScope &exe_scope_ref) {
169 exe_scope_ref.CalculateExecutionContext(*this);
172 void ExecutionContext::Clear() {
174 m_process_sp.reset();
179 ExecutionContext::~ExecutionContext() = default;
181 uint32_t ExecutionContext::GetAddressByteSize() const {
182 if (m_target_sp && m_target_sp->GetArchitecture().IsValid())
183 return m_target_sp->GetArchitecture().GetAddressByteSize();
185 return m_process_sp->GetAddressByteSize();
186 return sizeof(void *);
189 lldb::ByteOrder ExecutionContext::GetByteOrder() const {
190 if (m_target_sp && m_target_sp->GetArchitecture().IsValid())
191 m_target_sp->GetArchitecture().GetByteOrder();
193 m_process_sp->GetByteOrder();
194 return endian::InlHostByteOrder();
197 RegisterContext *ExecutionContext::GetRegisterContext() const {
199 return m_frame_sp->GetRegisterContext().get();
200 else if (m_thread_sp)
201 return m_thread_sp->GetRegisterContext().get();
205 Target *ExecutionContext::GetTargetPtr() const {
207 return m_target_sp.get();
209 return &m_process_sp->GetTarget();
213 Process *ExecutionContext::GetProcessPtr() const {
215 return m_process_sp.get();
217 return m_target_sp->GetProcessSP().get();
221 ExecutionContextScope *ExecutionContext::GetBestExecutionContextScope() const {
223 return m_frame_sp.get();
225 return m_thread_sp.get();
227 return m_process_sp.get();
228 return m_target_sp.get();
231 Target &ExecutionContext::GetTargetRef() const {
232 #if defined(LLDB_CONFIGURATION_DEBUG) || defined(LLDB_CONFIGURATION_RELEASE)
238 Process &ExecutionContext::GetProcessRef() const {
239 #if defined(LLDB_CONFIGURATION_DEBUG) || defined(LLDB_CONFIGURATION_RELEASE)
240 assert(m_process_sp);
242 return *m_process_sp;
245 Thread &ExecutionContext::GetThreadRef() const {
246 #if defined(LLDB_CONFIGURATION_DEBUG) || defined(LLDB_CONFIGURATION_RELEASE)
252 StackFrame &ExecutionContext::GetFrameRef() const {
253 #if defined(LLDB_CONFIGURATION_DEBUG) || defined(LLDB_CONFIGURATION_RELEASE)
259 void ExecutionContext::SetTargetSP(const lldb::TargetSP &target_sp) {
260 m_target_sp = target_sp;
263 void ExecutionContext::SetProcessSP(const lldb::ProcessSP &process_sp) {
264 m_process_sp = process_sp;
267 void ExecutionContext::SetThreadSP(const lldb::ThreadSP &thread_sp) {
268 m_thread_sp = thread_sp;
271 void ExecutionContext::SetFrameSP(const lldb::StackFrameSP &frame_sp) {
272 m_frame_sp = frame_sp;
275 void ExecutionContext::SetTargetPtr(Target *target) {
277 m_target_sp = target->shared_from_this();
282 void ExecutionContext::SetProcessPtr(Process *process) {
284 m_process_sp = process->shared_from_this();
286 m_process_sp.reset();
289 void ExecutionContext::SetThreadPtr(Thread *thread) {
291 m_thread_sp = thread->shared_from_this();
296 void ExecutionContext::SetFramePtr(StackFrame *frame) {
298 m_frame_sp = frame->shared_from_this();
303 void ExecutionContext::SetContext(const lldb::TargetSP &target_sp,
305 m_target_sp = target_sp;
306 if (get_process && target_sp)
307 m_process_sp = target_sp->GetProcessSP();
309 m_process_sp.reset();
314 void ExecutionContext::SetContext(const lldb::ProcessSP &process_sp) {
315 m_process_sp = process_sp;
317 m_target_sp = process_sp->GetTarget().shared_from_this();
324 void ExecutionContext::SetContext(const lldb::ThreadSP &thread_sp) {
326 m_thread_sp = thread_sp;
328 m_process_sp = thread_sp->GetProcess();
330 m_target_sp = m_process_sp->GetTarget().shared_from_this();
335 m_process_sp.reset();
339 void ExecutionContext::SetContext(const lldb::StackFrameSP &frame_sp) {
340 m_frame_sp = frame_sp;
342 m_thread_sp = frame_sp->CalculateThread();
344 m_process_sp = m_thread_sp->GetProcess();
346 m_target_sp = m_process_sp->GetTarget().shared_from_this();
351 m_process_sp.reset();
355 m_process_sp.reset();
360 ExecutionContext &ExecutionContext::operator=(const ExecutionContext &rhs) {
362 m_target_sp = rhs.m_target_sp;
363 m_process_sp = rhs.m_process_sp;
364 m_thread_sp = rhs.m_thread_sp;
365 m_frame_sp = rhs.m_frame_sp;
370 bool ExecutionContext::operator==(const ExecutionContext &rhs) const {
371 // Check that the frame shared pointers match, or both are valid and their
372 // stack IDs match since sometimes we get new objects that represent the same
373 // frame within a thread.
374 if ((m_frame_sp == rhs.m_frame_sp) ||
375 (m_frame_sp && rhs.m_frame_sp &&
376 m_frame_sp->GetStackID() == rhs.m_frame_sp->GetStackID())) {
377 // Check that the thread shared pointers match, or both are valid and their
378 // thread IDs match since sometimes we get new objects that represent the
379 // same thread within a process.
380 if ((m_thread_sp == rhs.m_thread_sp) ||
381 (m_thread_sp && rhs.m_thread_sp &&
382 m_thread_sp->GetID() == rhs.m_thread_sp->GetID())) {
383 // Processes and targets don't change much
384 return m_process_sp == rhs.m_process_sp && m_target_sp == rhs.m_target_sp;
390 bool ExecutionContext::operator!=(const ExecutionContext &rhs) const {
391 return !(*this == rhs);
394 bool ExecutionContext::HasTargetScope() const {
395 return ((bool)m_target_sp && m_target_sp->IsValid());
398 bool ExecutionContext::HasProcessScope() const {
399 return (HasTargetScope() && ((bool)m_process_sp && m_process_sp->IsValid()));
402 bool ExecutionContext::HasThreadScope() const {
403 return (HasProcessScope() && ((bool)m_thread_sp && m_thread_sp->IsValid()));
406 bool ExecutionContext::HasFrameScope() const {
407 return HasThreadScope() && m_frame_sp;
410 ExecutionContextRef::ExecutionContextRef()
411 : m_target_wp(), m_process_wp(), m_thread_wp(),
412 m_tid(LLDB_INVALID_THREAD_ID), m_stack_id() {}
414 ExecutionContextRef::ExecutionContextRef(const ExecutionContext *exe_ctx)
415 : m_target_wp(), m_process_wp(), m_thread_wp(),
416 m_tid(LLDB_INVALID_THREAD_ID), m_stack_id() {
421 ExecutionContextRef::ExecutionContextRef(const ExecutionContext &exe_ctx)
422 : m_target_wp(), m_process_wp(), m_thread_wp(),
423 m_tid(LLDB_INVALID_THREAD_ID), m_stack_id() {
427 ExecutionContextRef::ExecutionContextRef(Target *target, bool adopt_selected)
428 : m_target_wp(), m_process_wp(), m_thread_wp(),
429 m_tid(LLDB_INVALID_THREAD_ID), m_stack_id() {
430 SetTargetPtr(target, adopt_selected);
433 ExecutionContextRef::ExecutionContextRef(const ExecutionContextRef &rhs)
434 : m_target_wp(rhs.m_target_wp), m_process_wp(rhs.m_process_wp),
435 m_thread_wp(rhs.m_thread_wp), m_tid(rhs.m_tid),
436 m_stack_id(rhs.m_stack_id) {}
438 ExecutionContextRef &ExecutionContextRef::
439 operator=(const ExecutionContextRef &rhs) {
441 m_target_wp = rhs.m_target_wp;
442 m_process_wp = rhs.m_process_wp;
443 m_thread_wp = rhs.m_thread_wp;
445 m_stack_id = rhs.m_stack_id;
450 ExecutionContextRef &ExecutionContextRef::
451 operator=(const ExecutionContext &exe_ctx) {
452 m_target_wp = exe_ctx.GetTargetSP();
453 m_process_wp = exe_ctx.GetProcessSP();
454 lldb::ThreadSP thread_sp(exe_ctx.GetThreadSP());
455 m_thread_wp = thread_sp;
457 m_tid = thread_sp->GetID();
459 m_tid = LLDB_INVALID_THREAD_ID;
460 lldb::StackFrameSP frame_sp(exe_ctx.GetFrameSP());
462 m_stack_id = frame_sp->GetStackID();
468 void ExecutionContextRef::Clear() {
470 m_process_wp.reset();
475 ExecutionContextRef::~ExecutionContextRef() = default;
477 void ExecutionContextRef::SetTargetSP(const lldb::TargetSP &target_sp) {
478 m_target_wp = target_sp;
481 void ExecutionContextRef::SetProcessSP(const lldb::ProcessSP &process_sp) {
483 m_process_wp = process_sp;
484 SetTargetSP(process_sp->GetTarget().shared_from_this());
486 m_process_wp.reset();
491 void ExecutionContextRef::SetThreadSP(const lldb::ThreadSP &thread_sp) {
493 m_thread_wp = thread_sp;
494 m_tid = thread_sp->GetID();
495 SetProcessSP(thread_sp->GetProcess());
498 m_process_wp.reset();
503 void ExecutionContextRef::SetFrameSP(const lldb::StackFrameSP &frame_sp) {
505 m_stack_id = frame_sp->GetStackID();
506 SetThreadSP(frame_sp->GetThread());
510 m_process_wp.reset();
515 void ExecutionContextRef::SetTargetPtr(Target *target, bool adopt_selected) {
518 lldb::TargetSP target_sp(target->shared_from_this());
520 m_target_wp = target_sp;
521 if (adopt_selected) {
522 lldb::ProcessSP process_sp(target_sp->GetProcessSP());
524 m_process_wp = process_sp;
526 // Only fill in the thread and frame if our process is stopped
527 // Don't just check the state, since we might be in the middle of
529 Process::StopLocker stop_locker;
531 if (stop_locker.TryLock(&process_sp->GetRunLock()) &&
532 StateIsStoppedState(process_sp->GetState(), true)) {
533 lldb::ThreadSP thread_sp(
534 process_sp->GetThreadList().GetSelectedThread());
536 thread_sp = process_sp->GetThreadList().GetThreadAtIndex(0);
539 SetThreadSP(thread_sp);
540 lldb::StackFrameSP frame_sp(thread_sp->GetSelectedFrame());
542 frame_sp = thread_sp->GetStackFrameAtIndex(0);
544 SetFrameSP(frame_sp);
554 void ExecutionContextRef::SetProcessPtr(Process *process) {
556 SetProcessSP(process->shared_from_this());
558 m_process_wp.reset();
563 void ExecutionContextRef::SetThreadPtr(Thread *thread) {
565 SetThreadSP(thread->shared_from_this());
568 m_process_wp.reset();
573 void ExecutionContextRef::SetFramePtr(StackFrame *frame) {
575 SetFrameSP(frame->shared_from_this());
580 lldb::TargetSP ExecutionContextRef::GetTargetSP() const {
581 lldb::TargetSP target_sp(m_target_wp.lock());
582 if (target_sp && !target_sp->IsValid())
587 lldb::ProcessSP ExecutionContextRef::GetProcessSP() const {
588 lldb::ProcessSP process_sp(m_process_wp.lock());
589 if (process_sp && !process_sp->IsValid())
594 lldb::ThreadSP ExecutionContextRef::GetThreadSP() const {
595 lldb::ThreadSP thread_sp(m_thread_wp.lock());
597 if (m_tid != LLDB_INVALID_THREAD_ID) {
598 // We check if the thread has been destroyed in cases where clients might
599 // still have shared pointer to a thread, but the thread is not valid
600 // anymore (not part of the process)
601 if (!thread_sp || !thread_sp->IsValid()) {
602 lldb::ProcessSP process_sp(GetProcessSP());
603 if (process_sp && process_sp->IsValid()) {
604 thread_sp = process_sp->GetThreadList().FindThreadByID(m_tid);
605 m_thread_wp = thread_sp;
610 // Check that we aren't about to return an invalid thread sp. We might
611 // return a nullptr thread_sp, but don't return an invalid one.
613 if (thread_sp && !thread_sp->IsValid())
619 lldb::StackFrameSP ExecutionContextRef::GetFrameSP() const {
620 if (m_stack_id.IsValid()) {
621 lldb::ThreadSP thread_sp(GetThreadSP());
623 return thread_sp->GetFrameWithStackID(m_stack_id);
625 return lldb::StackFrameSP();
629 ExecutionContextRef::Lock(bool thread_and_frame_only_if_stopped) const {
630 return ExecutionContext(this, thread_and_frame_only_if_stopped);