180814287SRaphael Isemann //===-- ExecutionContext.cpp ----------------------------------------------===//
230fdc8d8SChris Lattner //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
630fdc8d8SChris Lattner //
730fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
830fdc8d8SChris Lattner
930fdc8d8SChris Lattner #include "lldb/Target/ExecutionContext.h"
1030fdc8d8SChris Lattner #include "lldb/Target/ExecutionContextScope.h"
1130fdc8d8SChris Lattner #include "lldb/Target/Process.h"
12b9c1b51eSKate Stone #include "lldb/Target/StackFrame.h"
1330fdc8d8SChris Lattner #include "lldb/Target/Target.h"
1430fdc8d8SChris Lattner #include "lldb/Target/Thread.h"
15d821c997SPavel Labath #include "lldb/Utility/State.h"
1630fdc8d8SChris Lattner
1730fdc8d8SChris Lattner using namespace lldb_private;
1830fdc8d8SChris Lattner
ExecutionContext()19b9c1b51eSKate Stone ExecutionContext::ExecutionContext()
20b9c1b51eSKate Stone : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {}
2130fdc8d8SChris Lattner
22*24f9a2f5SShafik Yaghmour ExecutionContext::ExecutionContext(const ExecutionContext &rhs) = default;
23c14ee32dSGreg Clayton
ExecutionContext(const lldb::TargetSP & target_sp,bool get_process)24b9c1b51eSKate Stone ExecutionContext::ExecutionContext(const lldb::TargetSP &target_sp,
25b9c1b51eSKate Stone bool get_process)
26b9c1b51eSKate Stone : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
27cc4d0146SGreg Clayton if (target_sp)
28cc4d0146SGreg Clayton SetContext(target_sp, get_process);
29c14ee32dSGreg Clayton }
30cc4d0146SGreg Clayton
ExecutionContext(const lldb::ProcessSP & process_sp)31b9c1b51eSKate Stone ExecutionContext::ExecutionContext(const lldb::ProcessSP &process_sp)
32b9c1b51eSKate Stone : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
33cc4d0146SGreg Clayton if (process_sp)
34cc4d0146SGreg Clayton SetContext(process_sp);
35cc4d0146SGreg Clayton }
36cc4d0146SGreg Clayton
ExecutionContext(const lldb::ThreadSP & thread_sp)37b9c1b51eSKate Stone ExecutionContext::ExecutionContext(const lldb::ThreadSP &thread_sp)
38b9c1b51eSKate Stone : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
39cc4d0146SGreg Clayton if (thread_sp)
40cc4d0146SGreg Clayton SetContext(thread_sp);
41cc4d0146SGreg Clayton }
42cc4d0146SGreg Clayton
ExecutionContext(const lldb::StackFrameSP & frame_sp)43b9c1b51eSKate Stone ExecutionContext::ExecutionContext(const lldb::StackFrameSP &frame_sp)
44b9c1b51eSKate Stone : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
45cc4d0146SGreg Clayton if (frame_sp)
46cc4d0146SGreg Clayton SetContext(frame_sp);
47c14ee32dSGreg Clayton }
48c14ee32dSGreg Clayton
ExecutionContext(const lldb::TargetWP & target_wp,bool get_process)49b9c1b51eSKate Stone ExecutionContext::ExecutionContext(const lldb::TargetWP &target_wp,
50b9c1b51eSKate Stone bool get_process)
51b9c1b51eSKate Stone : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
521ac04c30SGreg Clayton lldb::TargetSP target_sp(target_wp.lock());
531ac04c30SGreg Clayton if (target_sp)
541ac04c30SGreg Clayton SetContext(target_sp, get_process);
551ac04c30SGreg Clayton }
561ac04c30SGreg Clayton
ExecutionContext(const lldb::ProcessWP & process_wp)57b9c1b51eSKate Stone ExecutionContext::ExecutionContext(const lldb::ProcessWP &process_wp)
58b9c1b51eSKate Stone : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
591ac04c30SGreg Clayton lldb::ProcessSP process_sp(process_wp.lock());
601ac04c30SGreg Clayton if (process_sp)
611ac04c30SGreg Clayton SetContext(process_sp);
621ac04c30SGreg Clayton }
631ac04c30SGreg Clayton
ExecutionContext(const lldb::ThreadWP & thread_wp)64b9c1b51eSKate Stone ExecutionContext::ExecutionContext(const lldb::ThreadWP &thread_wp)
65b9c1b51eSKate Stone : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
661ac04c30SGreg Clayton lldb::ThreadSP thread_sp(thread_wp.lock());
671ac04c30SGreg Clayton if (thread_sp)
681ac04c30SGreg Clayton SetContext(thread_sp);
691ac04c30SGreg Clayton }
701ac04c30SGreg Clayton
ExecutionContext(const lldb::StackFrameWP & frame_wp)71b9c1b51eSKate Stone ExecutionContext::ExecutionContext(const lldb::StackFrameWP &frame_wp)
72b9c1b51eSKate Stone : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
73b57e4a1bSJason Molenda lldb::StackFrameSP frame_sp(frame_wp.lock());
741ac04c30SGreg Clayton if (frame_sp)
751ac04c30SGreg Clayton SetContext(frame_sp);
761ac04c30SGreg Clayton }
771ac04c30SGreg Clayton
ExecutionContext(Target * t,bool fill_current_process_thread_frame)78b9c1b51eSKate Stone ExecutionContext::ExecutionContext(Target *t,
79b9c1b51eSKate Stone bool fill_current_process_thread_frame)
80b9c1b51eSKate Stone : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
81b9c1b51eSKate Stone if (t) {
82526ae040SGreg Clayton m_target_sp = t->shared_from_this();
83b9c1b51eSKate Stone if (fill_current_process_thread_frame) {
84c14ee32dSGreg Clayton m_process_sp = t->GetProcessSP();
85b9c1b51eSKate Stone if (m_process_sp) {
86c14ee32dSGreg Clayton m_thread_sp = m_process_sp->GetThreadList().GetSelectedThread();
87c14ee32dSGreg Clayton if (m_thread_sp)
88e1cd1be6SGreg Clayton m_frame_sp = m_thread_sp->GetSelectedFrame();
8930fdc8d8SChris Lattner }
9030fdc8d8SChris Lattner }
9130fdc8d8SChris Lattner }
92526ae040SGreg Clayton }
9330fdc8d8SChris Lattner
ExecutionContext(Process * process,Thread * thread,StackFrame * frame)94b9c1b51eSKate Stone ExecutionContext::ExecutionContext(Process *process, Thread *thread,
95b9c1b51eSKate Stone StackFrame *frame)
96b9c1b51eSKate Stone : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
97b9c1b51eSKate Stone if (process) {
98526ae040SGreg Clayton m_process_sp = process->shared_from_this();
99e1cd1be6SGreg Clayton m_target_sp = process->GetTarget().shared_from_this();
10030fdc8d8SChris Lattner }
101526ae040SGreg Clayton if (thread)
102526ae040SGreg Clayton m_thread_sp = thread->shared_from_this();
103526ae040SGreg Clayton if (frame)
104526ae040SGreg Clayton m_frame_sp = frame->shared_from_this();
105526ae040SGreg Clayton }
10630fdc8d8SChris Lattner
ExecutionContext(const ExecutionContextRef & exe_ctx_ref)107b9c1b51eSKate Stone ExecutionContext::ExecutionContext(const ExecutionContextRef &exe_ctx_ref)
108b9c1b51eSKate Stone : m_target_sp(exe_ctx_ref.GetTargetSP()),
109cc4d0146SGreg Clayton m_process_sp(exe_ctx_ref.GetProcessSP()),
110cc4d0146SGreg Clayton m_thread_sp(exe_ctx_ref.GetThreadSP()),
111b9c1b51eSKate Stone m_frame_sp(exe_ctx_ref.GetFrameSP()) {}
112cc4d0146SGreg Clayton
ExecutionContext(const ExecutionContextRef * exe_ctx_ref_ptr,bool thread_and_frame_only_if_stopped)113b9c1b51eSKate Stone ExecutionContext::ExecutionContext(const ExecutionContextRef *exe_ctx_ref_ptr,
114b9c1b51eSKate Stone bool thread_and_frame_only_if_stopped)
115b9c1b51eSKate Stone : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
116b9c1b51eSKate Stone if (exe_ctx_ref_ptr) {
117cc4d0146SGreg Clayton m_target_sp = exe_ctx_ref_ptr->GetTargetSP();
118cc4d0146SGreg Clayton m_process_sp = exe_ctx_ref_ptr->GetProcessSP();
119b9c1b51eSKate Stone if (!thread_and_frame_only_if_stopped ||
120b9c1b51eSKate Stone (m_process_sp && StateIsStoppedState(m_process_sp->GetState(), true))) {
121cc4d0146SGreg Clayton m_thread_sp = exe_ctx_ref_ptr->GetThreadSP();
122cc4d0146SGreg Clayton m_frame_sp = exe_ctx_ref_ptr->GetFrameSP();
123cc4d0146SGreg Clayton }
124cc4d0146SGreg Clayton }
12544d93782SGreg Clayton }
126cc4d0146SGreg Clayton
ExecutionContext(const ExecutionContextRef * exe_ctx_ref_ptr,std::unique_lock<std::recursive_mutex> & lock)127bb19a13cSSaleem Abdulrasool ExecutionContext::ExecutionContext(const ExecutionContextRef *exe_ctx_ref_ptr,
128bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> &lock)
129b9c1b51eSKate Stone : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
130b9c1b51eSKate Stone if (exe_ctx_ref_ptr) {
1314fc6cb9cSJim Ingham m_target_sp = exe_ctx_ref_ptr->GetTargetSP();
132b9c1b51eSKate Stone if (m_target_sp) {
133bb19a13cSSaleem Abdulrasool lock = std::unique_lock<std::recursive_mutex>(m_target_sp->GetAPIMutex());
134bb19a13cSSaleem Abdulrasool
1354fc6cb9cSJim Ingham m_process_sp = exe_ctx_ref_ptr->GetProcessSP();
1364fc6cb9cSJim Ingham m_thread_sp = exe_ctx_ref_ptr->GetThreadSP();
1374fc6cb9cSJim Ingham m_frame_sp = exe_ctx_ref_ptr->GetFrameSP();
1384fc6cb9cSJim Ingham }
1394fc6cb9cSJim Ingham }
1404fc6cb9cSJim Ingham }
1414fc6cb9cSJim Ingham
ExecutionContext(const ExecutionContextRef & exe_ctx_ref,std::unique_lock<std::recursive_mutex> & lock)142b9c1b51eSKate Stone ExecutionContext::ExecutionContext(const ExecutionContextRef &exe_ctx_ref,
143b9c1b51eSKate Stone std::unique_lock<std::recursive_mutex> &lock)
144b9c1b51eSKate Stone : m_target_sp(exe_ctx_ref.GetTargetSP()), m_process_sp(), m_thread_sp(),
145b9c1b51eSKate Stone m_frame_sp() {
146b9c1b51eSKate Stone if (m_target_sp) {
147bb19a13cSSaleem Abdulrasool lock = std::unique_lock<std::recursive_mutex>(m_target_sp->GetAPIMutex());
148bb19a13cSSaleem Abdulrasool
1494fc6cb9cSJim Ingham m_process_sp = exe_ctx_ref.GetProcessSP();
1504fc6cb9cSJim Ingham m_thread_sp = exe_ctx_ref.GetThreadSP();
1514fc6cb9cSJim Ingham m_frame_sp = exe_ctx_ref.GetFrameSP();
1524fc6cb9cSJim Ingham }
1534fc6cb9cSJim Ingham }
1544fc6cb9cSJim Ingham
ExecutionContext(ExecutionContextScope * exe_scope_ptr)155b9c1b51eSKate Stone ExecutionContext::ExecutionContext(ExecutionContextScope *exe_scope_ptr)
156b9c1b51eSKate Stone : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
15730fdc8d8SChris Lattner if (exe_scope_ptr)
1580603aa9dSGreg Clayton exe_scope_ptr->CalculateExecutionContext(*this);
15930fdc8d8SChris Lattner }
16030fdc8d8SChris Lattner
ExecutionContext(ExecutionContextScope & exe_scope_ref)161b9c1b51eSKate Stone ExecutionContext::ExecutionContext(ExecutionContextScope &exe_scope_ref) {
1620603aa9dSGreg Clayton exe_scope_ref.CalculateExecutionContext(*this);
16330fdc8d8SChris Lattner }
16430fdc8d8SChris Lattner
Clear()165b9c1b51eSKate Stone void ExecutionContext::Clear() {
166c14ee32dSGreg Clayton m_target_sp.reset();
167c14ee32dSGreg Clayton m_process_sp.reset();
168c14ee32dSGreg Clayton m_thread_sp.reset();
169c14ee32dSGreg Clayton m_frame_sp.reset();
170c14ee32dSGreg Clayton }
171c14ee32dSGreg Clayton
1729394d772SEugene Zelenko ExecutionContext::~ExecutionContext() = default;
17330fdc8d8SChris Lattner
GetAddressByteSize() const174b9c1b51eSKate Stone uint32_t ExecutionContext::GetAddressByteSize() const {
175cc4d0146SGreg Clayton if (m_target_sp && m_target_sp->GetArchitecture().IsValid())
176ed69e30dSHafiz Abid Qadeer return m_target_sp->GetArchitecture().GetAddressByteSize();
177cc4d0146SGreg Clayton if (m_process_sp)
178ed69e30dSHafiz Abid Qadeer return m_process_sp->GetAddressByteSize();
179cc4d0146SGreg Clayton return sizeof(void *);
180cc4d0146SGreg Clayton }
181cc4d0146SGreg Clayton
GetByteOrder() const182b9c1b51eSKate Stone lldb::ByteOrder ExecutionContext::GetByteOrder() const {
183347c2aa3SEnrico Granata if (m_target_sp && m_target_sp->GetArchitecture().IsValid())
184af0c828aSJonas Devlieghere return m_target_sp->GetArchitecture().GetByteOrder();
185347c2aa3SEnrico Granata if (m_process_sp)
186af0c828aSJonas Devlieghere return m_process_sp->GetByteOrder();
1879ccb970fSBruce Mitchener return endian::InlHostByteOrder();
188347c2aa3SEnrico Granata }
18930fdc8d8SChris Lattner
GetRegisterContext() const190b9c1b51eSKate Stone RegisterContext *ExecutionContext::GetRegisterContext() const {
191c14ee32dSGreg Clayton if (m_frame_sp)
192c14ee32dSGreg Clayton return m_frame_sp->GetRegisterContext().get();
193c14ee32dSGreg Clayton else if (m_thread_sp)
194c14ee32dSGreg Clayton return m_thread_sp->GetRegisterContext().get();
1959394d772SEugene Zelenko return nullptr;
196c14ee32dSGreg Clayton }
197c14ee32dSGreg Clayton
GetTargetPtr() const198b9c1b51eSKate Stone Target *ExecutionContext::GetTargetPtr() const {
199c14ee32dSGreg Clayton if (m_target_sp)
200c14ee32dSGreg Clayton return m_target_sp.get();
201c14ee32dSGreg Clayton if (m_process_sp)
202c14ee32dSGreg Clayton return &m_process_sp->GetTarget();
2039394d772SEugene Zelenko return nullptr;
204c14ee32dSGreg Clayton }
205c14ee32dSGreg Clayton
GetProcessPtr() const206b9c1b51eSKate Stone Process *ExecutionContext::GetProcessPtr() const {
207c14ee32dSGreg Clayton if (m_process_sp)
208c14ee32dSGreg Clayton return m_process_sp.get();
209c14ee32dSGreg Clayton if (m_target_sp)
210c14ee32dSGreg Clayton return m_target_sp->GetProcessSP().get();
2119394d772SEugene Zelenko return nullptr;
21230fdc8d8SChris Lattner }
21330fdc8d8SChris Lattner
GetBestExecutionContextScope() const214b9c1b51eSKate Stone ExecutionContextScope *ExecutionContext::GetBestExecutionContextScope() const {
215c14ee32dSGreg Clayton if (m_frame_sp)
216c14ee32dSGreg Clayton return m_frame_sp.get();
217c14ee32dSGreg Clayton if (m_thread_sp)
218c14ee32dSGreg Clayton return m_thread_sp.get();
219c14ee32dSGreg Clayton if (m_process_sp)
220c14ee32dSGreg Clayton return m_process_sp.get();
221c14ee32dSGreg Clayton return m_target_sp.get();
22230fdc8d8SChris Lattner }
223644247c1SGreg Clayton
GetTargetRef() const224b9c1b51eSKate Stone Target &ExecutionContext::GetTargetRef() const {
2259394d772SEugene Zelenko assert(m_target_sp);
226c14ee32dSGreg Clayton return *m_target_sp;
227644247c1SGreg Clayton }
228c14ee32dSGreg Clayton
GetProcessRef() const229b9c1b51eSKate Stone Process &ExecutionContext::GetProcessRef() const {
2309394d772SEugene Zelenko assert(m_process_sp);
231c14ee32dSGreg Clayton return *m_process_sp;
232c14ee32dSGreg Clayton }
233c14ee32dSGreg Clayton
GetThreadRef() const234b9c1b51eSKate Stone Thread &ExecutionContext::GetThreadRef() const {
2359394d772SEugene Zelenko assert(m_thread_sp);
236c14ee32dSGreg Clayton return *m_thread_sp;
237c14ee32dSGreg Clayton }
238c14ee32dSGreg Clayton
GetFrameRef() const239b9c1b51eSKate Stone StackFrame &ExecutionContext::GetFrameRef() const {
2409394d772SEugene Zelenko assert(m_frame_sp);
241c14ee32dSGreg Clayton return *m_frame_sp;
242c14ee32dSGreg Clayton }
243c14ee32dSGreg Clayton
SetTargetSP(const lldb::TargetSP & target_sp)244b9c1b51eSKate Stone void ExecutionContext::SetTargetSP(const lldb::TargetSP &target_sp) {
245c14ee32dSGreg Clayton m_target_sp = target_sp;
246c14ee32dSGreg Clayton }
247c14ee32dSGreg Clayton
SetProcessSP(const lldb::ProcessSP & process_sp)248b9c1b51eSKate Stone void ExecutionContext::SetProcessSP(const lldb::ProcessSP &process_sp) {
249c14ee32dSGreg Clayton m_process_sp = process_sp;
250c14ee32dSGreg Clayton }
251c14ee32dSGreg Clayton
SetThreadSP(const lldb::ThreadSP & thread_sp)252b9c1b51eSKate Stone void ExecutionContext::SetThreadSP(const lldb::ThreadSP &thread_sp) {
253c14ee32dSGreg Clayton m_thread_sp = thread_sp;
254c14ee32dSGreg Clayton }
255c14ee32dSGreg Clayton
SetFrameSP(const lldb::StackFrameSP & frame_sp)256b9c1b51eSKate Stone void ExecutionContext::SetFrameSP(const lldb::StackFrameSP &frame_sp) {
257c14ee32dSGreg Clayton m_frame_sp = frame_sp;
258c14ee32dSGreg Clayton }
259c14ee32dSGreg Clayton
SetTargetPtr(Target * target)260b9c1b51eSKate Stone void ExecutionContext::SetTargetPtr(Target *target) {
261e1cd1be6SGreg Clayton if (target)
262e1cd1be6SGreg Clayton m_target_sp = target->shared_from_this();
263e1cd1be6SGreg Clayton else
264e1cd1be6SGreg Clayton m_target_sp.reset();
265c14ee32dSGreg Clayton }
266c14ee32dSGreg Clayton
SetProcessPtr(Process * process)267b9c1b51eSKate Stone void ExecutionContext::SetProcessPtr(Process *process) {
268e1cd1be6SGreg Clayton if (process)
269e1cd1be6SGreg Clayton m_process_sp = process->shared_from_this();
270e1cd1be6SGreg Clayton else
271e1cd1be6SGreg Clayton m_process_sp.reset();
272c14ee32dSGreg Clayton }
273c14ee32dSGreg Clayton
SetThreadPtr(Thread * thread)274b9c1b51eSKate Stone void ExecutionContext::SetThreadPtr(Thread *thread) {
275e1cd1be6SGreg Clayton if (thread)
276e1cd1be6SGreg Clayton m_thread_sp = thread->shared_from_this();
277e1cd1be6SGreg Clayton else
278e1cd1be6SGreg Clayton m_thread_sp.reset();
279c14ee32dSGreg Clayton }
280c14ee32dSGreg Clayton
SetFramePtr(StackFrame * frame)281b9c1b51eSKate Stone void ExecutionContext::SetFramePtr(StackFrame *frame) {
282e1cd1be6SGreg Clayton if (frame)
283e1cd1be6SGreg Clayton m_frame_sp = frame->shared_from_this();
284e1cd1be6SGreg Clayton else
285e1cd1be6SGreg Clayton m_frame_sp.reset();
286c14ee32dSGreg Clayton }
287c14ee32dSGreg Clayton
SetContext(const lldb::TargetSP & target_sp,bool get_process)288b9c1b51eSKate Stone void ExecutionContext::SetContext(const lldb::TargetSP &target_sp,
289b9c1b51eSKate Stone bool get_process) {
290cc4d0146SGreg Clayton m_target_sp = target_sp;
291cc4d0146SGreg Clayton if (get_process && target_sp)
292cc4d0146SGreg Clayton m_process_sp = target_sp->GetProcessSP();
293cc4d0146SGreg Clayton else
294cc4d0146SGreg Clayton m_process_sp.reset();
295cc4d0146SGreg Clayton m_thread_sp.reset();
296cc4d0146SGreg Clayton m_frame_sp.reset();
297cc4d0146SGreg Clayton }
298cc4d0146SGreg Clayton
SetContext(const lldb::ProcessSP & process_sp)299b9c1b51eSKate Stone void ExecutionContext::SetContext(const lldb::ProcessSP &process_sp) {
300cc4d0146SGreg Clayton m_process_sp = process_sp;
301cc4d0146SGreg Clayton if (process_sp)
302cc4d0146SGreg Clayton m_target_sp = process_sp->GetTarget().shared_from_this();
303cc4d0146SGreg Clayton else
304cc4d0146SGreg Clayton m_target_sp.reset();
305cc4d0146SGreg Clayton m_thread_sp.reset();
306cc4d0146SGreg Clayton m_frame_sp.reset();
307cc4d0146SGreg Clayton }
308cc4d0146SGreg Clayton
SetContext(const lldb::ThreadSP & thread_sp)309b9c1b51eSKate Stone void ExecutionContext::SetContext(const lldb::ThreadSP &thread_sp) {
310cc4d0146SGreg Clayton m_frame_sp.reset();
311cc4d0146SGreg Clayton m_thread_sp = thread_sp;
312b9c1b51eSKate Stone if (thread_sp) {
3131ac04c30SGreg Clayton m_process_sp = thread_sp->GetProcess();
314cc4d0146SGreg Clayton if (m_process_sp)
315cc4d0146SGreg Clayton m_target_sp = m_process_sp->GetTarget().shared_from_this();
316cc4d0146SGreg Clayton else
317cc4d0146SGreg Clayton m_target_sp.reset();
318b9c1b51eSKate Stone } else {
319cc4d0146SGreg Clayton m_target_sp.reset();
320cc4d0146SGreg Clayton m_process_sp.reset();
321cc4d0146SGreg Clayton }
322cc4d0146SGreg Clayton }
323cc4d0146SGreg Clayton
SetContext(const lldb::StackFrameSP & frame_sp)324b9c1b51eSKate Stone void ExecutionContext::SetContext(const lldb::StackFrameSP &frame_sp) {
325cc4d0146SGreg Clayton m_frame_sp = frame_sp;
326b9c1b51eSKate Stone if (frame_sp) {
327d9e416c0SGreg Clayton m_thread_sp = frame_sp->CalculateThread();
328b9c1b51eSKate Stone if (m_thread_sp) {
3291ac04c30SGreg Clayton m_process_sp = m_thread_sp->GetProcess();
330cc4d0146SGreg Clayton if (m_process_sp)
331cc4d0146SGreg Clayton m_target_sp = m_process_sp->GetTarget().shared_from_this();
332cc4d0146SGreg Clayton else
333cc4d0146SGreg Clayton m_target_sp.reset();
334b9c1b51eSKate Stone } else {
335cc4d0146SGreg Clayton m_target_sp.reset();
336cc4d0146SGreg Clayton m_process_sp.reset();
337cc4d0146SGreg Clayton }
338b9c1b51eSKate Stone } else {
339cc4d0146SGreg Clayton m_target_sp.reset();
340cc4d0146SGreg Clayton m_process_sp.reset();
341cc4d0146SGreg Clayton m_thread_sp.reset();
342cc4d0146SGreg Clayton }
343cc4d0146SGreg Clayton }
344cc4d0146SGreg Clayton
operator =(const ExecutionContext & rhs)345b9c1b51eSKate Stone ExecutionContext &ExecutionContext::operator=(const ExecutionContext &rhs) {
346b9c1b51eSKate Stone if (this != &rhs) {
347cc4d0146SGreg Clayton m_target_sp = rhs.m_target_sp;
348cc4d0146SGreg Clayton m_process_sp = rhs.m_process_sp;
349cc4d0146SGreg Clayton m_thread_sp = rhs.m_thread_sp;
350cc4d0146SGreg Clayton m_frame_sp = rhs.m_frame_sp;
351cc4d0146SGreg Clayton }
352cc4d0146SGreg Clayton return *this;
353cc4d0146SGreg Clayton }
354cc4d0146SGreg Clayton
operator ==(const ExecutionContext & rhs) const355b9c1b51eSKate Stone bool ExecutionContext::operator==(const ExecutionContext &rhs) const {
356b9c1b51eSKate Stone // Check that the frame shared pointers match, or both are valid and their
35705097246SAdrian Prantl // stack IDs match since sometimes we get new objects that represent the same
358cc4d0146SGreg Clayton // frame within a thread.
359b9c1b51eSKate Stone if ((m_frame_sp == rhs.m_frame_sp) ||
360b9c1b51eSKate Stone (m_frame_sp && rhs.m_frame_sp &&
361b9c1b51eSKate Stone m_frame_sp->GetStackID() == rhs.m_frame_sp->GetStackID())) {
36205097246SAdrian Prantl // Check that the thread shared pointers match, or both are valid and their
36305097246SAdrian Prantl // thread IDs match since sometimes we get new objects that represent the
36405097246SAdrian Prantl // same thread within a process.
365b9c1b51eSKate Stone if ((m_thread_sp == rhs.m_thread_sp) ||
366b9c1b51eSKate Stone (m_thread_sp && rhs.m_thread_sp &&
367b9c1b51eSKate Stone m_thread_sp->GetID() == rhs.m_thread_sp->GetID())) {
368cc4d0146SGreg Clayton // Processes and targets don't change much
369cc4d0146SGreg Clayton return m_process_sp == rhs.m_process_sp && m_target_sp == rhs.m_target_sp;
370cc4d0146SGreg Clayton }
371cc4d0146SGreg Clayton }
372cc4d0146SGreg Clayton return false;
373cc4d0146SGreg Clayton }
374cc4d0146SGreg Clayton
operator !=(const ExecutionContext & rhs) const375b9c1b51eSKate Stone bool ExecutionContext::operator!=(const ExecutionContext &rhs) const {
376cc4d0146SGreg Clayton return !(*this == rhs);
377cc4d0146SGreg Clayton }
378cc4d0146SGreg Clayton
HasTargetScope() const379b9c1b51eSKate Stone bool ExecutionContext::HasTargetScope() const {
380b9c1b51eSKate Stone return ((bool)m_target_sp && m_target_sp->IsValid());
3814fc6cb9cSJim Ingham }
3824fc6cb9cSJim Ingham
HasProcessScope() const383b9c1b51eSKate Stone bool ExecutionContext::HasProcessScope() const {
384b9c1b51eSKate Stone return (HasTargetScope() && ((bool)m_process_sp && m_process_sp->IsValid()));
3854fc6cb9cSJim Ingham }
3864fc6cb9cSJim Ingham
HasThreadScope() const387b9c1b51eSKate Stone bool ExecutionContext::HasThreadScope() const {
388b9c1b51eSKate Stone return (HasProcessScope() && ((bool)m_thread_sp && m_thread_sp->IsValid()));
3894fc6cb9cSJim Ingham }
3904fc6cb9cSJim Ingham
HasFrameScope() const391b9c1b51eSKate Stone bool ExecutionContext::HasFrameScope() const {
3924fc6cb9cSJim Ingham return HasThreadScope() && m_frame_sp;
3934fc6cb9cSJim Ingham }
394cc4d0146SGreg Clayton
ExecutionContextRef()395b9c1b51eSKate Stone ExecutionContextRef::ExecutionContextRef()
3969494c510SJonas Devlieghere : m_target_wp(), m_process_wp(), m_thread_wp(), m_stack_id() {}
397cc4d0146SGreg Clayton
ExecutionContextRef(const ExecutionContext * exe_ctx)398b9c1b51eSKate Stone ExecutionContextRef::ExecutionContextRef(const ExecutionContext *exe_ctx)
39928c878aeSShafik Yaghmour : m_target_wp(), m_process_wp(), m_thread_wp(), m_stack_id() {
400cc4d0146SGreg Clayton if (exe_ctx)
401cc4d0146SGreg Clayton *this = *exe_ctx;
402cc4d0146SGreg Clayton }
403cc4d0146SGreg Clayton
ExecutionContextRef(const ExecutionContext & exe_ctx)404b9c1b51eSKate Stone ExecutionContextRef::ExecutionContextRef(const ExecutionContext &exe_ctx)
40528c878aeSShafik Yaghmour : m_target_wp(), m_process_wp(), m_thread_wp(), m_stack_id() {
406cc4d0146SGreg Clayton *this = exe_ctx;
407cc4d0146SGreg Clayton }
408cc4d0146SGreg Clayton
ExecutionContextRef(Target * target,bool adopt_selected)409b9c1b51eSKate Stone ExecutionContextRef::ExecutionContextRef(Target *target, bool adopt_selected)
41028c878aeSShafik Yaghmour : m_target_wp(), m_process_wp(), m_thread_wp(), m_stack_id() {
411cc4d0146SGreg Clayton SetTargetPtr(target, adopt_selected);
412cc4d0146SGreg Clayton }
413cc4d0146SGreg Clayton
414b9c1b51eSKate Stone ExecutionContextRef::ExecutionContextRef(const ExecutionContextRef &rhs)
415*24f9a2f5SShafik Yaghmour
416*24f9a2f5SShafik Yaghmour = default;
417cc4d0146SGreg Clayton
418b9c1b51eSKate Stone ExecutionContextRef &ExecutionContextRef::
operator =(const ExecutionContextRef & rhs)419b9c1b51eSKate Stone operator=(const ExecutionContextRef &rhs) {
420b9c1b51eSKate Stone if (this != &rhs) {
421cc4d0146SGreg Clayton m_target_wp = rhs.m_target_wp;
422cc4d0146SGreg Clayton m_process_wp = rhs.m_process_wp;
423cc4d0146SGreg Clayton m_thread_wp = rhs.m_thread_wp;
424cc4d0146SGreg Clayton m_tid = rhs.m_tid;
425cc4d0146SGreg Clayton m_stack_id = rhs.m_stack_id;
426cc4d0146SGreg Clayton }
427cc4d0146SGreg Clayton return *this;
428cc4d0146SGreg Clayton }
429cc4d0146SGreg Clayton
430b9c1b51eSKate Stone ExecutionContextRef &ExecutionContextRef::
operator =(const ExecutionContext & exe_ctx)431b9c1b51eSKate Stone operator=(const ExecutionContext &exe_ctx) {
432cc4d0146SGreg Clayton m_target_wp = exe_ctx.GetTargetSP();
433cc4d0146SGreg Clayton m_process_wp = exe_ctx.GetProcessSP();
4347fdf9ef1SGreg Clayton lldb::ThreadSP thread_sp(exe_ctx.GetThreadSP());
4357fdf9ef1SGreg Clayton m_thread_wp = thread_sp;
4367fdf9ef1SGreg Clayton if (thread_sp)
4377fdf9ef1SGreg Clayton m_tid = thread_sp->GetID();
4387fdf9ef1SGreg Clayton else
4397fdf9ef1SGreg Clayton m_tid = LLDB_INVALID_THREAD_ID;
440b57e4a1bSJason Molenda lldb::StackFrameSP frame_sp(exe_ctx.GetFrameSP());
4417fdf9ef1SGreg Clayton if (frame_sp)
4427fdf9ef1SGreg Clayton m_stack_id = frame_sp->GetStackID();
4437fdf9ef1SGreg Clayton else
4447fdf9ef1SGreg Clayton m_stack_id.Clear();
445cc4d0146SGreg Clayton return *this;
446cc4d0146SGreg Clayton }
447cc4d0146SGreg Clayton
Clear()448b9c1b51eSKate Stone void ExecutionContextRef::Clear() {
449cc4d0146SGreg Clayton m_target_wp.reset();
450cc4d0146SGreg Clayton m_process_wp.reset();
4517fdf9ef1SGreg Clayton ClearThread();
4527fdf9ef1SGreg Clayton ClearFrame();
453cc4d0146SGreg Clayton }
454cc4d0146SGreg Clayton
4559394d772SEugene Zelenko ExecutionContextRef::~ExecutionContextRef() = default;
456cc4d0146SGreg Clayton
SetTargetSP(const lldb::TargetSP & target_sp)457b9c1b51eSKate Stone void ExecutionContextRef::SetTargetSP(const lldb::TargetSP &target_sp) {
458cc4d0146SGreg Clayton m_target_wp = target_sp;
459cc4d0146SGreg Clayton }
460cc4d0146SGreg Clayton
SetProcessSP(const lldb::ProcessSP & process_sp)461b9c1b51eSKate Stone void ExecutionContextRef::SetProcessSP(const lldb::ProcessSP &process_sp) {
462b9c1b51eSKate Stone if (process_sp) {
463cc4d0146SGreg Clayton m_process_wp = process_sp;
4647fdf9ef1SGreg Clayton SetTargetSP(process_sp->GetTarget().shared_from_this());
465b9c1b51eSKate Stone } else {
4667fdf9ef1SGreg Clayton m_process_wp.reset();
4677fdf9ef1SGreg Clayton m_target_wp.reset();
4687fdf9ef1SGreg Clayton }
469cc4d0146SGreg Clayton }
470cc4d0146SGreg Clayton
SetThreadSP(const lldb::ThreadSP & thread_sp)471b9c1b51eSKate Stone void ExecutionContextRef::SetThreadSP(const lldb::ThreadSP &thread_sp) {
472b9c1b51eSKate Stone if (thread_sp) {
4737fdf9ef1SGreg Clayton m_thread_wp = thread_sp;
474cc4d0146SGreg Clayton m_tid = thread_sp->GetID();
4757fdf9ef1SGreg Clayton SetProcessSP(thread_sp->GetProcess());
476b9c1b51eSKate Stone } else {
4777fdf9ef1SGreg Clayton ClearThread();
4787fdf9ef1SGreg Clayton m_process_wp.reset();
4797fdf9ef1SGreg Clayton m_target_wp.reset();
4807fdf9ef1SGreg Clayton }
481cc4d0146SGreg Clayton }
482cc4d0146SGreg Clayton
SetFrameSP(const lldb::StackFrameSP & frame_sp)483b9c1b51eSKate Stone void ExecutionContextRef::SetFrameSP(const lldb::StackFrameSP &frame_sp) {
484b9c1b51eSKate Stone if (frame_sp) {
485cc4d0146SGreg Clayton m_stack_id = frame_sp->GetStackID();
4867fdf9ef1SGreg Clayton SetThreadSP(frame_sp->GetThread());
487b9c1b51eSKate Stone } else {
4887fdf9ef1SGreg Clayton ClearFrame();
4897fdf9ef1SGreg Clayton ClearThread();
4907fdf9ef1SGreg Clayton m_process_wp.reset();
4917fdf9ef1SGreg Clayton m_target_wp.reset();
4927fdf9ef1SGreg Clayton }
493cc4d0146SGreg Clayton }
494cc4d0146SGreg Clayton
SetTargetPtr(Target * target,bool adopt_selected)495b9c1b51eSKate Stone void ExecutionContextRef::SetTargetPtr(Target *target, bool adopt_selected) {
496cc4d0146SGreg Clayton Clear();
497b9c1b51eSKate Stone if (target) {
498cc4d0146SGreg Clayton lldb::TargetSP target_sp(target->shared_from_this());
499b9c1b51eSKate Stone if (target_sp) {
500cc4d0146SGreg Clayton m_target_wp = target_sp;
501b9c1b51eSKate Stone if (adopt_selected) {
502cc4d0146SGreg Clayton lldb::ProcessSP process_sp(target_sp->GetProcessSP());
503b9c1b51eSKate Stone if (process_sp) {
504cc4d0146SGreg Clayton m_process_wp = process_sp;
505b9c1b51eSKate Stone if (process_sp) {
5069b5450f6SGreg Clayton // Only fill in the thread and frame if our process is stopped
507d5ac1ab6SJim Ingham // Don't just check the state, since we might be in the middle of
508d5ac1ab6SJim Ingham // resuming.
509d5ac1ab6SJim Ingham Process::StopLocker stop_locker;
510d5ac1ab6SJim Ingham
511b9c1b51eSKate Stone if (stop_locker.TryLock(&process_sp->GetRunLock()) &&
512b9c1b51eSKate Stone StateIsStoppedState(process_sp->GetState(), true)) {
513b9c1b51eSKate Stone lldb::ThreadSP thread_sp(
514b9c1b51eSKate Stone process_sp->GetThreadList().GetSelectedThread());
515cc4d0146SGreg Clayton if (!thread_sp)
516cc4d0146SGreg Clayton thread_sp = process_sp->GetThreadList().GetThreadAtIndex(0);
517cc4d0146SGreg Clayton
518b9c1b51eSKate Stone if (thread_sp) {
519cc4d0146SGreg Clayton SetThreadSP(thread_sp);
520b57e4a1bSJason Molenda lldb::StackFrameSP frame_sp(thread_sp->GetSelectedFrame());
521cc4d0146SGreg Clayton if (!frame_sp)
522cc4d0146SGreg Clayton frame_sp = thread_sp->GetStackFrameAtIndex(0);
523cc4d0146SGreg Clayton if (frame_sp)
524cc4d0146SGreg Clayton SetFrameSP(frame_sp);
525cc4d0146SGreg Clayton }
526cc4d0146SGreg Clayton }
527cc4d0146SGreg Clayton }
528cc4d0146SGreg Clayton }
529cc4d0146SGreg Clayton }
530cc4d0146SGreg Clayton }
531cc4d0146SGreg Clayton }
5329b5450f6SGreg Clayton }
533cc4d0146SGreg Clayton
SetProcessPtr(Process * process)534b9c1b51eSKate Stone void ExecutionContextRef::SetProcessPtr(Process *process) {
535b9c1b51eSKate Stone if (process) {
5367fdf9ef1SGreg Clayton SetProcessSP(process->shared_from_this());
537b9c1b51eSKate Stone } else {
538cc4d0146SGreg Clayton m_process_wp.reset();
5397fdf9ef1SGreg Clayton m_target_wp.reset();
5407fdf9ef1SGreg Clayton }
541cc4d0146SGreg Clayton }
542cc4d0146SGreg Clayton
SetThreadPtr(Thread * thread)543b9c1b51eSKate Stone void ExecutionContextRef::SetThreadPtr(Thread *thread) {
544b9c1b51eSKate Stone if (thread) {
5457fdf9ef1SGreg Clayton SetThreadSP(thread->shared_from_this());
546b9c1b51eSKate Stone } else {
5477fdf9ef1SGreg Clayton ClearThread();
5487fdf9ef1SGreg Clayton m_process_wp.reset();
5497fdf9ef1SGreg Clayton m_target_wp.reset();
5507fdf9ef1SGreg Clayton }
551cc4d0146SGreg Clayton }
552cc4d0146SGreg Clayton
SetFramePtr(StackFrame * frame)553b9c1b51eSKate Stone void ExecutionContextRef::SetFramePtr(StackFrame *frame) {
554cc4d0146SGreg Clayton if (frame)
5557fdf9ef1SGreg Clayton SetFrameSP(frame->shared_from_this());
556cc4d0146SGreg Clayton else
5577fdf9ef1SGreg Clayton Clear();
558cc4d0146SGreg Clayton }
559cc4d0146SGreg Clayton
GetTargetSP() const560b9c1b51eSKate Stone lldb::TargetSP ExecutionContextRef::GetTargetSP() const {
5614fc6cb9cSJim Ingham lldb::TargetSP target_sp(m_target_wp.lock());
5624fc6cb9cSJim Ingham if (target_sp && !target_sp->IsValid())
5634fc6cb9cSJim Ingham target_sp.reset();
5644fc6cb9cSJim Ingham return target_sp;
5654fc6cb9cSJim Ingham }
5664fc6cb9cSJim Ingham
GetProcessSP() const567b9c1b51eSKate Stone lldb::ProcessSP ExecutionContextRef::GetProcessSP() const {
5684fc6cb9cSJim Ingham lldb::ProcessSP process_sp(m_process_wp.lock());
5694fc6cb9cSJim Ingham if (process_sp && !process_sp->IsValid())
5704fc6cb9cSJim Ingham process_sp.reset();
5714fc6cb9cSJim Ingham return process_sp;
5724fc6cb9cSJim Ingham }
573cc4d0146SGreg Clayton
GetThreadSP() const574b9c1b51eSKate Stone lldb::ThreadSP ExecutionContextRef::GetThreadSP() const {
575cc4d0146SGreg Clayton lldb::ThreadSP thread_sp(m_thread_wp.lock());
5764fc6cb9cSJim Ingham
577b9c1b51eSKate Stone if (m_tid != LLDB_INVALID_THREAD_ID) {
57805097246SAdrian Prantl // We check if the thread has been destroyed in cases where clients might
57905097246SAdrian Prantl // still have shared pointer to a thread, but the thread is not valid
58005097246SAdrian Prantl // anymore (not part of the process)
581b9c1b51eSKate Stone if (!thread_sp || !thread_sp->IsValid()) {
582cc4d0146SGreg Clayton lldb::ProcessSP process_sp(GetProcessSP());
583b9c1b51eSKate Stone if (process_sp && process_sp->IsValid()) {
584cc4d0146SGreg Clayton thread_sp = process_sp->GetThreadList().FindThreadByID(m_tid);
585cc4d0146SGreg Clayton m_thread_wp = thread_sp;
586cc4d0146SGreg Clayton }
587cc4d0146SGreg Clayton }
5880b88d815SGreg Clayton }
5894fc6cb9cSJim Ingham
59005097246SAdrian Prantl // Check that we aren't about to return an invalid thread sp. We might
59105097246SAdrian Prantl // return a nullptr thread_sp, but don't return an invalid one.
5924fc6cb9cSJim Ingham
5934fc6cb9cSJim Ingham if (thread_sp && !thread_sp->IsValid())
5944fc6cb9cSJim Ingham thread_sp.reset();
5954fc6cb9cSJim Ingham
596cc4d0146SGreg Clayton return thread_sp;
597cc4d0146SGreg Clayton }
598cc4d0146SGreg Clayton
GetFrameSP() const599b9c1b51eSKate Stone lldb::StackFrameSP ExecutionContextRef::GetFrameSP() const {
600b9c1b51eSKate Stone if (m_stack_id.IsValid()) {
601cc4d0146SGreg Clayton lldb::ThreadSP thread_sp(GetThreadSP());
6026482d230SGreg Clayton if (thread_sp)
6036482d230SGreg Clayton return thread_sp->GetFrameWithStackID(m_stack_id);
6047bcb93d5SGreg Clayton }
605b57e4a1bSJason Molenda return lldb::StackFrameSP();
606ebafd2f1SEnrico Granata }
607cc4d0146SGreg Clayton
608cc4d0146SGreg Clayton ExecutionContext
Lock(bool thread_and_frame_only_if_stopped) const609b9c1b51eSKate Stone ExecutionContextRef::Lock(bool thread_and_frame_only_if_stopped) const {
61044d93782SGreg Clayton return ExecutionContext(this, thread_and_frame_only_if_stopped);
611cc4d0146SGreg Clayton }
612