1 //===-- ExecutionContext.cpp ----------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "lldb/Target/ExecutionContext.h"
10 #include "lldb/Target/ExecutionContextScope.h"
11 #include "lldb/Target/Process.h"
12 #include "lldb/Target/StackFrame.h"
13 #include "lldb/Target/Target.h"
14 #include "lldb/Target/Thread.h"
15 #include "lldb/Utility/State.h"
17 using namespace lldb_private
;
19 ExecutionContext::ExecutionContext()
20 : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {}
22 ExecutionContext::ExecutionContext(const ExecutionContext
&rhs
) = default;
24 ExecutionContext::ExecutionContext(const lldb::TargetSP
&target_sp
,
26 : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
28 SetContext(target_sp
, get_process
);
31 ExecutionContext::ExecutionContext(const lldb::ProcessSP
&process_sp
)
32 : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
34 SetContext(process_sp
);
37 ExecutionContext::ExecutionContext(const lldb::ThreadSP
&thread_sp
)
38 : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
40 SetContext(thread_sp
);
43 ExecutionContext::ExecutionContext(const lldb::StackFrameSP
&frame_sp
)
44 : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
49 ExecutionContext::ExecutionContext(const lldb::TargetWP
&target_wp
,
51 : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
52 lldb::TargetSP
target_sp(target_wp
.lock());
54 SetContext(target_sp
, get_process
);
57 ExecutionContext::ExecutionContext(const lldb::ProcessWP
&process_wp
)
58 : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
59 lldb::ProcessSP
process_sp(process_wp
.lock());
61 SetContext(process_sp
);
64 ExecutionContext::ExecutionContext(const lldb::ThreadWP
&thread_wp
)
65 : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
66 lldb::ThreadSP
thread_sp(thread_wp
.lock());
68 SetContext(thread_sp
);
71 ExecutionContext::ExecutionContext(const lldb::StackFrameWP
&frame_wp
)
72 : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
73 lldb::StackFrameSP
frame_sp(frame_wp
.lock());
78 ExecutionContext::ExecutionContext(Target
*t
,
79 bool fill_current_process_thread_frame
)
80 : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
82 m_target_sp
= t
->shared_from_this();
83 if (fill_current_process_thread_frame
) {
84 m_process_sp
= t
->GetProcessSP();
86 m_thread_sp
= m_process_sp
->GetThreadList().GetSelectedThread();
89 m_thread_sp
->GetSelectedFrame(DoNoSelectMostRelevantFrame
);
95 ExecutionContext::ExecutionContext(Process
*process
, Thread
*thread
,
97 : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
99 m_process_sp
= process
->shared_from_this();
100 m_target_sp
= process
->GetTarget().shared_from_this();
103 m_thread_sp
= thread
->shared_from_this();
105 m_frame_sp
= frame
->shared_from_this();
108 ExecutionContext::ExecutionContext(const ExecutionContextRef
&exe_ctx_ref
)
109 : m_target_sp(exe_ctx_ref
.GetTargetSP()),
110 m_process_sp(exe_ctx_ref
.GetProcessSP()),
111 m_thread_sp(exe_ctx_ref
.GetThreadSP()),
112 m_frame_sp(exe_ctx_ref
.GetFrameSP()) {}
114 ExecutionContext::ExecutionContext(const ExecutionContextRef
*exe_ctx_ref_ptr
,
115 bool thread_and_frame_only_if_stopped
)
116 : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
117 if (exe_ctx_ref_ptr
) {
118 m_target_sp
= exe_ctx_ref_ptr
->GetTargetSP();
119 m_process_sp
= exe_ctx_ref_ptr
->GetProcessSP();
120 if (!thread_and_frame_only_if_stopped
||
121 (m_process_sp
&& StateIsStoppedState(m_process_sp
->GetState(), true))) {
122 m_thread_sp
= exe_ctx_ref_ptr
->GetThreadSP();
123 m_frame_sp
= exe_ctx_ref_ptr
->GetFrameSP();
128 ExecutionContext::ExecutionContext(const ExecutionContextRef
*exe_ctx_ref_ptr
,
129 std::unique_lock
<std::recursive_mutex
> &lock
)
130 : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
131 if (exe_ctx_ref_ptr
) {
132 m_target_sp
= exe_ctx_ref_ptr
->GetTargetSP();
134 lock
= std::unique_lock
<std::recursive_mutex
>(m_target_sp
->GetAPIMutex());
136 m_process_sp
= exe_ctx_ref_ptr
->GetProcessSP();
137 m_thread_sp
= exe_ctx_ref_ptr
->GetThreadSP();
138 m_frame_sp
= exe_ctx_ref_ptr
->GetFrameSP();
143 ExecutionContext::ExecutionContext(const ExecutionContextRef
&exe_ctx_ref
,
144 std::unique_lock
<std::recursive_mutex
> &lock
)
145 : m_target_sp(exe_ctx_ref
.GetTargetSP()), m_process_sp(), m_thread_sp(),
148 lock
= std::unique_lock
<std::recursive_mutex
>(m_target_sp
->GetAPIMutex());
150 m_process_sp
= exe_ctx_ref
.GetProcessSP();
151 m_thread_sp
= exe_ctx_ref
.GetThreadSP();
152 m_frame_sp
= exe_ctx_ref
.GetFrameSP();
156 ExecutionContext::ExecutionContext(ExecutionContextScope
*exe_scope_ptr
)
157 : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
159 exe_scope_ptr
->CalculateExecutionContext(*this);
162 ExecutionContext::ExecutionContext(ExecutionContextScope
&exe_scope_ref
) {
163 exe_scope_ref
.CalculateExecutionContext(*this);
166 void ExecutionContext::Clear() {
168 m_process_sp
.reset();
173 ExecutionContext::~ExecutionContext() = default;
175 uint32_t ExecutionContext::GetAddressByteSize() const {
176 if (m_target_sp
&& m_target_sp
->GetArchitecture().IsValid())
177 return m_target_sp
->GetArchitecture().GetAddressByteSize();
179 return m_process_sp
->GetAddressByteSize();
180 return sizeof(void *);
183 lldb::ByteOrder
ExecutionContext::GetByteOrder() const {
184 if (m_target_sp
&& m_target_sp
->GetArchitecture().IsValid())
185 return m_target_sp
->GetArchitecture().GetByteOrder();
187 return m_process_sp
->GetByteOrder();
188 return endian::InlHostByteOrder();
191 RegisterContext
*ExecutionContext::GetRegisterContext() const {
193 return m_frame_sp
->GetRegisterContext().get();
194 else if (m_thread_sp
)
195 return m_thread_sp
->GetRegisterContext().get();
199 Target
*ExecutionContext::GetTargetPtr() const {
201 return m_target_sp
.get();
203 return &m_process_sp
->GetTarget();
207 Process
*ExecutionContext::GetProcessPtr() const {
209 return m_process_sp
.get();
211 return m_target_sp
->GetProcessSP().get();
215 ExecutionContextScope
*ExecutionContext::GetBestExecutionContextScope() const {
217 return m_frame_sp
.get();
219 return m_thread_sp
.get();
221 return m_process_sp
.get();
222 return m_target_sp
.get();
225 Target
&ExecutionContext::GetTargetRef() const {
230 Process
&ExecutionContext::GetProcessRef() const {
231 assert(m_process_sp
);
232 return *m_process_sp
;
235 Thread
&ExecutionContext::GetThreadRef() const {
240 StackFrame
&ExecutionContext::GetFrameRef() const {
245 void ExecutionContext::SetTargetSP(const lldb::TargetSP
&target_sp
) {
246 m_target_sp
= target_sp
;
249 void ExecutionContext::SetProcessSP(const lldb::ProcessSP
&process_sp
) {
250 m_process_sp
= process_sp
;
253 void ExecutionContext::SetThreadSP(const lldb::ThreadSP
&thread_sp
) {
254 m_thread_sp
= thread_sp
;
257 void ExecutionContext::SetFrameSP(const lldb::StackFrameSP
&frame_sp
) {
258 m_frame_sp
= frame_sp
;
261 void ExecutionContext::SetTargetPtr(Target
*target
) {
263 m_target_sp
= target
->shared_from_this();
268 void ExecutionContext::SetProcessPtr(Process
*process
) {
270 m_process_sp
= process
->shared_from_this();
272 m_process_sp
.reset();
275 void ExecutionContext::SetThreadPtr(Thread
*thread
) {
277 m_thread_sp
= thread
->shared_from_this();
282 void ExecutionContext::SetFramePtr(StackFrame
*frame
) {
284 m_frame_sp
= frame
->shared_from_this();
289 void ExecutionContext::SetContext(const lldb::TargetSP
&target_sp
,
291 m_target_sp
= target_sp
;
292 if (get_process
&& target_sp
)
293 m_process_sp
= target_sp
->GetProcessSP();
295 m_process_sp
.reset();
300 void ExecutionContext::SetContext(const lldb::ProcessSP
&process_sp
) {
301 m_process_sp
= process_sp
;
303 m_target_sp
= process_sp
->GetTarget().shared_from_this();
310 void ExecutionContext::SetContext(const lldb::ThreadSP
&thread_sp
) {
312 m_thread_sp
= thread_sp
;
314 m_process_sp
= thread_sp
->GetProcess();
316 m_target_sp
= m_process_sp
->GetTarget().shared_from_this();
321 m_process_sp
.reset();
325 void ExecutionContext::SetContext(const lldb::StackFrameSP
&frame_sp
) {
326 m_frame_sp
= frame_sp
;
328 m_thread_sp
= frame_sp
->CalculateThread();
330 m_process_sp
= m_thread_sp
->GetProcess();
332 m_target_sp
= m_process_sp
->GetTarget().shared_from_this();
337 m_process_sp
.reset();
341 m_process_sp
.reset();
346 ExecutionContext
&ExecutionContext::operator=(const ExecutionContext
&rhs
) {
348 m_target_sp
= rhs
.m_target_sp
;
349 m_process_sp
= rhs
.m_process_sp
;
350 m_thread_sp
= rhs
.m_thread_sp
;
351 m_frame_sp
= rhs
.m_frame_sp
;
356 bool ExecutionContext::operator==(const ExecutionContext
&rhs
) const {
357 // Check that the frame shared pointers match, or both are valid and their
358 // stack IDs match since sometimes we get new objects that represent the same
359 // frame within a thread.
360 if ((m_frame_sp
== rhs
.m_frame_sp
) ||
361 (m_frame_sp
&& rhs
.m_frame_sp
&&
362 m_frame_sp
->GetStackID() == rhs
.m_frame_sp
->GetStackID())) {
363 // Check that the thread shared pointers match, or both are valid and their
364 // thread IDs match since sometimes we get new objects that represent the
365 // same thread within a process.
366 if ((m_thread_sp
== rhs
.m_thread_sp
) ||
367 (m_thread_sp
&& rhs
.m_thread_sp
&&
368 m_thread_sp
->GetID() == rhs
.m_thread_sp
->GetID())) {
369 // Processes and targets don't change much
370 return m_process_sp
== rhs
.m_process_sp
&& m_target_sp
== rhs
.m_target_sp
;
376 bool ExecutionContext::operator!=(const ExecutionContext
&rhs
) const {
377 return !(*this == rhs
);
380 bool ExecutionContext::HasTargetScope() const {
381 return ((bool)m_target_sp
&& m_target_sp
->IsValid());
384 bool ExecutionContext::HasProcessScope() const {
385 return (HasTargetScope() && ((bool)m_process_sp
&& m_process_sp
->IsValid()));
388 bool ExecutionContext::HasThreadScope() const {
389 return (HasProcessScope() && ((bool)m_thread_sp
&& m_thread_sp
->IsValid()));
392 bool ExecutionContext::HasFrameScope() const {
393 return HasThreadScope() && m_frame_sp
;
396 ExecutionContextRef::ExecutionContextRef()
397 : m_target_wp(), m_process_wp(), m_thread_wp(), m_stack_id() {}
399 ExecutionContextRef::ExecutionContextRef(const ExecutionContext
*exe_ctx
)
400 : m_target_wp(), m_process_wp(), m_thread_wp(), m_stack_id() {
405 ExecutionContextRef::ExecutionContextRef(const ExecutionContext
&exe_ctx
)
406 : m_target_wp(), m_process_wp(), m_thread_wp(), m_stack_id() {
410 ExecutionContextRef::ExecutionContextRef(Target
*target
, bool adopt_selected
)
411 : m_target_wp(), m_process_wp(), m_thread_wp(), m_stack_id() {
412 SetTargetPtr(target
, adopt_selected
);
415 ExecutionContextRef::ExecutionContextRef(const ExecutionContextRef
&rhs
)
419 ExecutionContextRef
&ExecutionContextRef::
420 operator=(const ExecutionContextRef
&rhs
) {
422 m_target_wp
= rhs
.m_target_wp
;
423 m_process_wp
= rhs
.m_process_wp
;
424 m_thread_wp
= rhs
.m_thread_wp
;
426 m_stack_id
= rhs
.m_stack_id
;
431 ExecutionContextRef
&ExecutionContextRef::
432 operator=(const ExecutionContext
&exe_ctx
) {
433 m_target_wp
= exe_ctx
.GetTargetSP();
434 m_process_wp
= exe_ctx
.GetProcessSP();
435 lldb::ThreadSP
thread_sp(exe_ctx
.GetThreadSP());
436 m_thread_wp
= thread_sp
;
438 m_tid
= thread_sp
->GetID();
440 m_tid
= LLDB_INVALID_THREAD_ID
;
441 lldb::StackFrameSP
frame_sp(exe_ctx
.GetFrameSP());
443 m_stack_id
= frame_sp
->GetStackID();
449 void ExecutionContextRef::Clear() {
451 m_process_wp
.reset();
456 ExecutionContextRef::~ExecutionContextRef() = default;
458 void ExecutionContextRef::SetTargetSP(const lldb::TargetSP
&target_sp
) {
459 m_target_wp
= target_sp
;
462 void ExecutionContextRef::SetProcessSP(const lldb::ProcessSP
&process_sp
) {
464 m_process_wp
= process_sp
;
465 SetTargetSP(process_sp
->GetTarget().shared_from_this());
467 m_process_wp
.reset();
472 void ExecutionContextRef::SetThreadSP(const lldb::ThreadSP
&thread_sp
) {
474 m_thread_wp
= thread_sp
;
475 m_tid
= thread_sp
->GetID();
476 SetProcessSP(thread_sp
->GetProcess());
479 m_process_wp
.reset();
484 void ExecutionContextRef::SetFrameSP(const lldb::StackFrameSP
&frame_sp
) {
486 m_stack_id
= frame_sp
->GetStackID();
487 SetThreadSP(frame_sp
->GetThread());
491 m_process_wp
.reset();
496 void ExecutionContextRef::SetTargetPtr(Target
*target
, bool adopt_selected
) {
499 lldb::TargetSP
target_sp(target
->shared_from_this());
501 m_target_wp
= target_sp
;
502 if (adopt_selected
) {
503 lldb::ProcessSP
process_sp(target_sp
->GetProcessSP());
505 m_process_wp
= process_sp
;
507 // Only fill in the thread and frame if our process is stopped
508 // Don't just check the state, since we might be in the middle of
510 Process::StopLocker stop_locker
;
512 if (stop_locker
.TryLock(&process_sp
->GetRunLock()) &&
513 StateIsStoppedState(process_sp
->GetState(), true)) {
514 lldb::ThreadSP
thread_sp(
515 process_sp
->GetThreadList().GetSelectedThread());
517 thread_sp
= process_sp
->GetThreadList().GetThreadAtIndex(0);
520 SetThreadSP(thread_sp
);
521 lldb::StackFrameSP
frame_sp(
522 thread_sp
->GetSelectedFrame(DoNoSelectMostRelevantFrame
));
524 frame_sp
= thread_sp
->GetStackFrameAtIndex(0);
526 SetFrameSP(frame_sp
);
536 void ExecutionContextRef::SetProcessPtr(Process
*process
) {
538 SetProcessSP(process
->shared_from_this());
540 m_process_wp
.reset();
545 void ExecutionContextRef::SetThreadPtr(Thread
*thread
) {
547 SetThreadSP(thread
->shared_from_this());
550 m_process_wp
.reset();
555 void ExecutionContextRef::SetFramePtr(StackFrame
*frame
) {
557 SetFrameSP(frame
->shared_from_this());
562 lldb::TargetSP
ExecutionContextRef::GetTargetSP() const {
563 lldb::TargetSP
target_sp(m_target_wp
.lock());
564 if (target_sp
&& !target_sp
->IsValid())
569 lldb::ProcessSP
ExecutionContextRef::GetProcessSP() const {
570 lldb::ProcessSP
process_sp(m_process_wp
.lock());
571 if (process_sp
&& !process_sp
->IsValid())
576 lldb::ThreadSP
ExecutionContextRef::GetThreadSP() const {
577 lldb::ThreadSP
thread_sp(m_thread_wp
.lock());
579 if (m_tid
!= LLDB_INVALID_THREAD_ID
) {
580 // We check if the thread has been destroyed in cases where clients might
581 // still have shared pointer to a thread, but the thread is not valid
582 // anymore (not part of the process)
583 if (!thread_sp
|| !thread_sp
->IsValid()) {
584 lldb::ProcessSP
process_sp(GetProcessSP());
585 if (process_sp
&& process_sp
->IsValid()) {
586 thread_sp
= process_sp
->GetThreadList().FindThreadByID(m_tid
);
587 m_thread_wp
= thread_sp
;
592 // Check that we aren't about to return an invalid thread sp. We might
593 // return a nullptr thread_sp, but don't return an invalid one.
595 if (thread_sp
&& !thread_sp
->IsValid())
601 lldb::StackFrameSP
ExecutionContextRef::GetFrameSP() const {
602 if (m_stack_id
.IsValid()) {
603 lldb::ThreadSP
thread_sp(GetThreadSP());
605 return thread_sp
->GetFrameWithStackID(m_stack_id
);
607 return lldb::StackFrameSP();
611 ExecutionContextRef::Lock(bool thread_and_frame_only_if_stopped
) const {
612 return ExecutionContext(this, thread_and_frame_only_if_stopped
);