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
373 // IDs match since sometimes we get new objects that represent the same
374 // frame within a thread.
375 if ((m_frame_sp == rhs.m_frame_sp) ||
376 (m_frame_sp && rhs.m_frame_sp &&
377 m_frame_sp->GetStackID() == rhs.m_frame_sp->GetStackID())) {
378 // Check that the thread shared pointers match, or both are valid and
379 // their thread IDs match since sometimes we get new objects that
380 // represent the same thread within a process.
381 if ((m_thread_sp == rhs.m_thread_sp) ||
382 (m_thread_sp && rhs.m_thread_sp &&
383 m_thread_sp->GetID() == rhs.m_thread_sp->GetID())) {
384 // Processes and targets don't change much
385 return m_process_sp == rhs.m_process_sp && m_target_sp == rhs.m_target_sp;
391 bool ExecutionContext::operator!=(const ExecutionContext &rhs) const {
392 return !(*this == rhs);
395 bool ExecutionContext::HasTargetScope() const {
396 return ((bool)m_target_sp && m_target_sp->IsValid());
399 bool ExecutionContext::HasProcessScope() const {
400 return (HasTargetScope() && ((bool)m_process_sp && m_process_sp->IsValid()));
403 bool ExecutionContext::HasThreadScope() const {
404 return (HasProcessScope() && ((bool)m_thread_sp && m_thread_sp->IsValid()));
407 bool ExecutionContext::HasFrameScope() const {
408 return HasThreadScope() && m_frame_sp;
411 ExecutionContextRef::ExecutionContextRef()
412 : m_target_wp(), m_process_wp(), m_thread_wp(),
413 m_tid(LLDB_INVALID_THREAD_ID), m_stack_id() {}
415 ExecutionContextRef::ExecutionContextRef(const ExecutionContext *exe_ctx)
416 : m_target_wp(), m_process_wp(), m_thread_wp(),
417 m_tid(LLDB_INVALID_THREAD_ID), m_stack_id() {
422 ExecutionContextRef::ExecutionContextRef(const ExecutionContext &exe_ctx)
423 : m_target_wp(), m_process_wp(), m_thread_wp(),
424 m_tid(LLDB_INVALID_THREAD_ID), m_stack_id() {
428 ExecutionContextRef::ExecutionContextRef(Target *target, bool adopt_selected)
429 : m_target_wp(), m_process_wp(), m_thread_wp(),
430 m_tid(LLDB_INVALID_THREAD_ID), m_stack_id() {
431 SetTargetPtr(target, adopt_selected);
434 ExecutionContextRef::ExecutionContextRef(const ExecutionContextRef &rhs)
435 : m_target_wp(rhs.m_target_wp), m_process_wp(rhs.m_process_wp),
436 m_thread_wp(rhs.m_thread_wp), m_tid(rhs.m_tid),
437 m_stack_id(rhs.m_stack_id) {}
439 ExecutionContextRef &ExecutionContextRef::
440 operator=(const ExecutionContextRef &rhs) {
442 m_target_wp = rhs.m_target_wp;
443 m_process_wp = rhs.m_process_wp;
444 m_thread_wp = rhs.m_thread_wp;
446 m_stack_id = rhs.m_stack_id;
451 ExecutionContextRef &ExecutionContextRef::
452 operator=(const ExecutionContext &exe_ctx) {
453 m_target_wp = exe_ctx.GetTargetSP();
454 m_process_wp = exe_ctx.GetProcessSP();
455 lldb::ThreadSP thread_sp(exe_ctx.GetThreadSP());
456 m_thread_wp = thread_sp;
458 m_tid = thread_sp->GetID();
460 m_tid = LLDB_INVALID_THREAD_ID;
461 lldb::StackFrameSP frame_sp(exe_ctx.GetFrameSP());
463 m_stack_id = frame_sp->GetStackID();
469 void ExecutionContextRef::Clear() {
471 m_process_wp.reset();
476 ExecutionContextRef::~ExecutionContextRef() = default;
478 void ExecutionContextRef::SetTargetSP(const lldb::TargetSP &target_sp) {
479 m_target_wp = target_sp;
482 void ExecutionContextRef::SetProcessSP(const lldb::ProcessSP &process_sp) {
484 m_process_wp = process_sp;
485 SetTargetSP(process_sp->GetTarget().shared_from_this());
487 m_process_wp.reset();
492 void ExecutionContextRef::SetThreadSP(const lldb::ThreadSP &thread_sp) {
494 m_thread_wp = thread_sp;
495 m_tid = thread_sp->GetID();
496 SetProcessSP(thread_sp->GetProcess());
499 m_process_wp.reset();
504 void ExecutionContextRef::SetFrameSP(const lldb::StackFrameSP &frame_sp) {
506 m_stack_id = frame_sp->GetStackID();
507 SetThreadSP(frame_sp->GetThread());
511 m_process_wp.reset();
516 void ExecutionContextRef::SetTargetPtr(Target *target, bool adopt_selected) {
519 lldb::TargetSP target_sp(target->shared_from_this());
521 m_target_wp = target_sp;
522 if (adopt_selected) {
523 lldb::ProcessSP process_sp(target_sp->GetProcessSP());
525 m_process_wp = process_sp;
527 // Only fill in the thread and frame if our process is stopped
528 // Don't just check the state, since we might be in the middle of
530 Process::StopLocker stop_locker;
532 if (stop_locker.TryLock(&process_sp->GetRunLock()) &&
533 StateIsStoppedState(process_sp->GetState(), true)) {
534 lldb::ThreadSP thread_sp(
535 process_sp->GetThreadList().GetSelectedThread());
537 thread_sp = process_sp->GetThreadList().GetThreadAtIndex(0);
540 SetThreadSP(thread_sp);
541 lldb::StackFrameSP frame_sp(thread_sp->GetSelectedFrame());
543 frame_sp = thread_sp->GetStackFrameAtIndex(0);
545 SetFrameSP(frame_sp);
555 void ExecutionContextRef::SetProcessPtr(Process *process) {
557 SetProcessSP(process->shared_from_this());
559 m_process_wp.reset();
564 void ExecutionContextRef::SetThreadPtr(Thread *thread) {
566 SetThreadSP(thread->shared_from_this());
569 m_process_wp.reset();
574 void ExecutionContextRef::SetFramePtr(StackFrame *frame) {
576 SetFrameSP(frame->shared_from_this());
581 lldb::TargetSP ExecutionContextRef::GetTargetSP() const {
582 lldb::TargetSP target_sp(m_target_wp.lock());
583 if (target_sp && !target_sp->IsValid())
588 lldb::ProcessSP ExecutionContextRef::GetProcessSP() const {
589 lldb::ProcessSP process_sp(m_process_wp.lock());
590 if (process_sp && !process_sp->IsValid())
595 lldb::ThreadSP ExecutionContextRef::GetThreadSP() const {
596 lldb::ThreadSP thread_sp(m_thread_wp.lock());
598 if (m_tid != LLDB_INVALID_THREAD_ID) {
599 // We check if the thread has been destroyed in cases where clients
600 // might still have shared pointer to a thread, but the thread is
601 // not valid anymore (not part of the process)
602 if (!thread_sp || !thread_sp->IsValid()) {
603 lldb::ProcessSP process_sp(GetProcessSP());
604 if (process_sp && process_sp->IsValid()) {
605 thread_sp = process_sp->GetThreadList().FindThreadByID(m_tid);
606 m_thread_wp = thread_sp;
611 // Check that we aren't about to return an invalid thread sp. We might return
612 // a nullptr thread_sp,
613 // but don't return an invalid one.
615 if (thread_sp && !thread_sp->IsValid())
621 lldb::StackFrameSP ExecutionContextRef::GetFrameSP() const {
622 if (m_stack_id.IsValid()) {
623 lldb::ThreadSP thread_sp(GetThreadSP());
625 return thread_sp->GetFrameWithStackID(m_stack_id);
627 return lldb::StackFrameSP();
631 ExecutionContextRef::Lock(bool thread_and_frame_only_if_stopped) const {
632 return ExecutionContext(this, thread_and_frame_only_if_stopped);