1254721Semaste//===-- ExecutionContext.cpp ------------------------------------*- C++ -*-===//
2254721Semaste//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6254721Semaste//
7254721Semaste//===----------------------------------------------------------------------===//
8254721Semaste
9254721Semaste#include "lldb/Target/ExecutionContext.h"
10254721Semaste#include "lldb/Target/ExecutionContextScope.h"
11314564Sdim#include "lldb/Target/Process.h"
12254721Semaste#include "lldb/Target/StackFrame.h"
13254721Semaste#include "lldb/Target/Target.h"
14254721Semaste#include "lldb/Target/Thread.h"
15344779Sdim#include "lldb/Utility/State.h"
16254721Semaste
17254721Semasteusing namespace lldb_private;
18254721Semaste
19314564SdimExecutionContext::ExecutionContext()
20314564Sdim    : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {}
21254721Semaste
22314564SdimExecutionContext::ExecutionContext(const ExecutionContext &rhs)
23314564Sdim    : m_target_sp(rhs.m_target_sp), m_process_sp(rhs.m_process_sp),
24314564Sdim      m_thread_sp(rhs.m_thread_sp), m_frame_sp(rhs.m_frame_sp) {}
25254721Semaste
26314564SdimExecutionContext::ExecutionContext(const lldb::TargetSP &target_sp,
27314564Sdim                                   bool get_process)
28314564Sdim    : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
29314564Sdim  if (target_sp)
30314564Sdim    SetContext(target_sp, get_process);
31254721Semaste}
32254721Semaste
33314564SdimExecutionContext::ExecutionContext(const lldb::ProcessSP &process_sp)
34314564Sdim    : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
35314564Sdim  if (process_sp)
36314564Sdim    SetContext(process_sp);
37254721Semaste}
38254721Semaste
39314564SdimExecutionContext::ExecutionContext(const lldb::ThreadSP &thread_sp)
40314564Sdim    : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
41314564Sdim  if (thread_sp)
42314564Sdim    SetContext(thread_sp);
43254721Semaste}
44254721Semaste
45314564SdimExecutionContext::ExecutionContext(const lldb::StackFrameSP &frame_sp)
46314564Sdim    : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
47314564Sdim  if (frame_sp)
48314564Sdim    SetContext(frame_sp);
49254721Semaste}
50254721Semaste
51314564SdimExecutionContext::ExecutionContext(const lldb::TargetWP &target_wp,
52314564Sdim                                   bool get_process)
53314564Sdim    : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
54314564Sdim  lldb::TargetSP target_sp(target_wp.lock());
55314564Sdim  if (target_sp)
56314564Sdim    SetContext(target_sp, get_process);
57254721Semaste}
58254721Semaste
59314564SdimExecutionContext::ExecutionContext(const lldb::ProcessWP &process_wp)
60314564Sdim    : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
61314564Sdim  lldb::ProcessSP process_sp(process_wp.lock());
62314564Sdim  if (process_sp)
63314564Sdim    SetContext(process_sp);
64254721Semaste}
65254721Semaste
66314564SdimExecutionContext::ExecutionContext(const lldb::ThreadWP &thread_wp)
67314564Sdim    : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
68314564Sdim  lldb::ThreadSP thread_sp(thread_wp.lock());
69314564Sdim  if (thread_sp)
70314564Sdim    SetContext(thread_sp);
71254721Semaste}
72254721Semaste
73314564SdimExecutionContext::ExecutionContext(const lldb::StackFrameWP &frame_wp)
74314564Sdim    : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
75314564Sdim  lldb::StackFrameSP frame_sp(frame_wp.lock());
76314564Sdim  if (frame_sp)
77314564Sdim    SetContext(frame_sp);
78254721Semaste}
79254721Semaste
80314564SdimExecutionContext::ExecutionContext(Target *t,
81314564Sdim                                   bool fill_current_process_thread_frame)
82314564Sdim    : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
83314564Sdim  if (t) {
84314564Sdim    m_target_sp = t->shared_from_this();
85314564Sdim    if (fill_current_process_thread_frame) {
86314564Sdim      m_process_sp = t->GetProcessSP();
87314564Sdim      if (m_process_sp) {
88314564Sdim        m_thread_sp = m_process_sp->GetThreadList().GetSelectedThread();
89314564Sdim        if (m_thread_sp)
90314564Sdim          m_frame_sp = m_thread_sp->GetSelectedFrame();
91314564Sdim      }
92254721Semaste    }
93314564Sdim  }
94254721Semaste}
95254721Semaste
96314564SdimExecutionContext::ExecutionContext(Process *process, Thread *thread,
97314564Sdim                                   StackFrame *frame)
98314564Sdim    : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
99314564Sdim  if (process) {
100314564Sdim    m_process_sp = process->shared_from_this();
101314564Sdim    m_target_sp = process->GetTarget().shared_from_this();
102314564Sdim  }
103314564Sdim  if (thread)
104314564Sdim    m_thread_sp = thread->shared_from_this();
105314564Sdim  if (frame)
106314564Sdim    m_frame_sp = frame->shared_from_this();
107254721Semaste}
108254721Semaste
109314564SdimExecutionContext::ExecutionContext(const ExecutionContextRef &exe_ctx_ref)
110314564Sdim    : m_target_sp(exe_ctx_ref.GetTargetSP()),
111314564Sdim      m_process_sp(exe_ctx_ref.GetProcessSP()),
112314564Sdim      m_thread_sp(exe_ctx_ref.GetThreadSP()),
113314564Sdim      m_frame_sp(exe_ctx_ref.GetFrameSP()) {}
114254721Semaste
115314564SdimExecutionContext::ExecutionContext(const ExecutionContextRef *exe_ctx_ref_ptr,
116314564Sdim                                   bool thread_and_frame_only_if_stopped)
117314564Sdim    : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
118314564Sdim  if (exe_ctx_ref_ptr) {
119314564Sdim    m_target_sp = exe_ctx_ref_ptr->GetTargetSP();
120314564Sdim    m_process_sp = exe_ctx_ref_ptr->GetProcessSP();
121314564Sdim    if (!thread_and_frame_only_if_stopped ||
122314564Sdim        (m_process_sp && StateIsStoppedState(m_process_sp->GetState(), true))) {
123314564Sdim      m_thread_sp = exe_ctx_ref_ptr->GetThreadSP();
124314564Sdim      m_frame_sp = exe_ctx_ref_ptr->GetFrameSP();
125254721Semaste    }
126314564Sdim  }
127254721Semaste}
128254721Semaste
129309124SdimExecutionContext::ExecutionContext(const ExecutionContextRef *exe_ctx_ref_ptr,
130309124Sdim                                   std::unique_lock<std::recursive_mutex> &lock)
131314564Sdim    : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
132314564Sdim  if (exe_ctx_ref_ptr) {
133314564Sdim    m_target_sp = exe_ctx_ref_ptr->GetTargetSP();
134314564Sdim    if (m_target_sp) {
135314564Sdim      lock = std::unique_lock<std::recursive_mutex>(m_target_sp->GetAPIMutex());
136309124Sdim
137314564Sdim      m_process_sp = exe_ctx_ref_ptr->GetProcessSP();
138314564Sdim      m_thread_sp = exe_ctx_ref_ptr->GetThreadSP();
139314564Sdim      m_frame_sp = exe_ctx_ref_ptr->GetFrameSP();
140254721Semaste    }
141314564Sdim  }
142254721Semaste}
143254721Semaste
144314564SdimExecutionContext::ExecutionContext(const ExecutionContextRef &exe_ctx_ref,
145314564Sdim                                   std::unique_lock<std::recursive_mutex> &lock)
146314564Sdim    : m_target_sp(exe_ctx_ref.GetTargetSP()), m_process_sp(), m_thread_sp(),
147314564Sdim      m_frame_sp() {
148314564Sdim  if (m_target_sp) {
149314564Sdim    lock = std::unique_lock<std::recursive_mutex>(m_target_sp->GetAPIMutex());
150309124Sdim
151314564Sdim    m_process_sp = exe_ctx_ref.GetProcessSP();
152314564Sdim    m_thread_sp = exe_ctx_ref.GetThreadSP();
153314564Sdim    m_frame_sp = exe_ctx_ref.GetFrameSP();
154314564Sdim  }
155254721Semaste}
156254721Semaste
157314564SdimExecutionContext::ExecutionContext(ExecutionContextScope *exe_scope_ptr)
158314564Sdim    : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
159314564Sdim  if (exe_scope_ptr)
160314564Sdim    exe_scope_ptr->CalculateExecutionContext(*this);
161254721Semaste}
162254721Semaste
163314564SdimExecutionContext::ExecutionContext(ExecutionContextScope &exe_scope_ref) {
164314564Sdim  exe_scope_ref.CalculateExecutionContext(*this);
165254721Semaste}
166254721Semaste
167314564Sdimvoid ExecutionContext::Clear() {
168314564Sdim  m_target_sp.reset();
169314564Sdim  m_process_sp.reset();
170314564Sdim  m_thread_sp.reset();
171314564Sdim  m_frame_sp.reset();
172254721Semaste}
173254721Semaste
174309124SdimExecutionContext::~ExecutionContext() = default;
175254721Semaste
176314564Sdimuint32_t ExecutionContext::GetAddressByteSize() const {
177314564Sdim  if (m_target_sp && m_target_sp->GetArchitecture().IsValid())
178314564Sdim    return m_target_sp->GetArchitecture().GetAddressByteSize();
179314564Sdim  if (m_process_sp)
180314564Sdim    return m_process_sp->GetAddressByteSize();
181314564Sdim  return sizeof(void *);
182254721Semaste}
183254721Semaste
184314564Sdimlldb::ByteOrder ExecutionContext::GetByteOrder() const {
185314564Sdim  if (m_target_sp && m_target_sp->GetArchitecture().IsValid())
186360784Sdim    return m_target_sp->GetArchitecture().GetByteOrder();
187314564Sdim  if (m_process_sp)
188360784Sdim    return m_process_sp->GetByteOrder();
189314564Sdim  return endian::InlHostByteOrder();
190258054Semaste}
191254721Semaste
192314564SdimRegisterContext *ExecutionContext::GetRegisterContext() const {
193314564Sdim  if (m_frame_sp)
194314564Sdim    return m_frame_sp->GetRegisterContext().get();
195314564Sdim  else if (m_thread_sp)
196314564Sdim    return m_thread_sp->GetRegisterContext().get();
197314564Sdim  return nullptr;
198254721Semaste}
199254721Semaste
200314564SdimTarget *ExecutionContext::GetTargetPtr() const {
201314564Sdim  if (m_target_sp)
202314564Sdim    return m_target_sp.get();
203314564Sdim  if (m_process_sp)
204314564Sdim    return &m_process_sp->GetTarget();
205314564Sdim  return nullptr;
206254721Semaste}
207254721Semaste
208314564SdimProcess *ExecutionContext::GetProcessPtr() const {
209314564Sdim  if (m_process_sp)
210314564Sdim    return m_process_sp.get();
211314564Sdim  if (m_target_sp)
212314564Sdim    return m_target_sp->GetProcessSP().get();
213314564Sdim  return nullptr;
214254721Semaste}
215254721Semaste
216314564SdimExecutionContextScope *ExecutionContext::GetBestExecutionContextScope() const {
217314564Sdim  if (m_frame_sp)
218314564Sdim    return m_frame_sp.get();
219314564Sdim  if (m_thread_sp)
220314564Sdim    return m_thread_sp.get();
221314564Sdim  if (m_process_sp)
222314564Sdim    return m_process_sp.get();
223314564Sdim  return m_target_sp.get();
224254721Semaste}
225254721Semaste
226314564SdimTarget &ExecutionContext::GetTargetRef() const {
227314564Sdim  assert(m_target_sp);
228314564Sdim  return *m_target_sp;
229254721Semaste}
230254721Semaste
231314564SdimProcess &ExecutionContext::GetProcessRef() const {
232314564Sdim  assert(m_process_sp);
233314564Sdim  return *m_process_sp;
234254721Semaste}
235254721Semaste
236314564SdimThread &ExecutionContext::GetThreadRef() const {
237314564Sdim  assert(m_thread_sp);
238314564Sdim  return *m_thread_sp;
239254721Semaste}
240254721Semaste
241314564SdimStackFrame &ExecutionContext::GetFrameRef() const {
242314564Sdim  assert(m_frame_sp);
243314564Sdim  return *m_frame_sp;
244254721Semaste}
245254721Semaste
246314564Sdimvoid ExecutionContext::SetTargetSP(const lldb::TargetSP &target_sp) {
247314564Sdim  m_target_sp = target_sp;
248254721Semaste}
249254721Semaste
250314564Sdimvoid ExecutionContext::SetProcessSP(const lldb::ProcessSP &process_sp) {
251314564Sdim  m_process_sp = process_sp;
252254721Semaste}
253254721Semaste
254314564Sdimvoid ExecutionContext::SetThreadSP(const lldb::ThreadSP &thread_sp) {
255314564Sdim  m_thread_sp = thread_sp;
256254721Semaste}
257254721Semaste
258314564Sdimvoid ExecutionContext::SetFrameSP(const lldb::StackFrameSP &frame_sp) {
259314564Sdim  m_frame_sp = frame_sp;
260254721Semaste}
261254721Semaste
262314564Sdimvoid ExecutionContext::SetTargetPtr(Target *target) {
263314564Sdim  if (target)
264314564Sdim    m_target_sp = target->shared_from_this();
265314564Sdim  else
266314564Sdim    m_target_sp.reset();
267254721Semaste}
268254721Semaste
269314564Sdimvoid ExecutionContext::SetProcessPtr(Process *process) {
270314564Sdim  if (process)
271314564Sdim    m_process_sp = process->shared_from_this();
272314564Sdim  else
273314564Sdim    m_process_sp.reset();
274254721Semaste}
275254721Semaste
276314564Sdimvoid ExecutionContext::SetThreadPtr(Thread *thread) {
277314564Sdim  if (thread)
278314564Sdim    m_thread_sp = thread->shared_from_this();
279314564Sdim  else
280314564Sdim    m_thread_sp.reset();
281254721Semaste}
282254721Semaste
283314564Sdimvoid ExecutionContext::SetFramePtr(StackFrame *frame) {
284314564Sdim  if (frame)
285314564Sdim    m_frame_sp = frame->shared_from_this();
286314564Sdim  else
287314564Sdim    m_frame_sp.reset();
288254721Semaste}
289254721Semaste
290314564Sdimvoid ExecutionContext::SetContext(const lldb::TargetSP &target_sp,
291314564Sdim                                  bool get_process) {
292314564Sdim  m_target_sp = target_sp;
293314564Sdim  if (get_process && target_sp)
294314564Sdim    m_process_sp = target_sp->GetProcessSP();
295314564Sdim  else
296314564Sdim    m_process_sp.reset();
297314564Sdim  m_thread_sp.reset();
298314564Sdim  m_frame_sp.reset();
299254721Semaste}
300254721Semaste
301314564Sdimvoid ExecutionContext::SetContext(const lldb::ProcessSP &process_sp) {
302314564Sdim  m_process_sp = process_sp;
303314564Sdim  if (process_sp)
304314564Sdim    m_target_sp = process_sp->GetTarget().shared_from_this();
305314564Sdim  else
306314564Sdim    m_target_sp.reset();
307314564Sdim  m_thread_sp.reset();
308314564Sdim  m_frame_sp.reset();
309254721Semaste}
310254721Semaste
311314564Sdimvoid ExecutionContext::SetContext(const lldb::ThreadSP &thread_sp) {
312314564Sdim  m_frame_sp.reset();
313314564Sdim  m_thread_sp = thread_sp;
314314564Sdim  if (thread_sp) {
315314564Sdim    m_process_sp = thread_sp->GetProcess();
316314564Sdim    if (m_process_sp)
317314564Sdim      m_target_sp = m_process_sp->GetTarget().shared_from_this();
318254721Semaste    else
319314564Sdim      m_target_sp.reset();
320314564Sdim  } else {
321314564Sdim    m_target_sp.reset();
322314564Sdim    m_process_sp.reset();
323314564Sdim  }
324254721Semaste}
325254721Semaste
326314564Sdimvoid ExecutionContext::SetContext(const lldb::StackFrameSP &frame_sp) {
327314564Sdim  m_frame_sp = frame_sp;
328314564Sdim  if (frame_sp) {
329314564Sdim    m_thread_sp = frame_sp->CalculateThread();
330314564Sdim    if (m_thread_sp) {
331314564Sdim      m_process_sp = m_thread_sp->GetProcess();
332314564Sdim      if (m_process_sp)
333314564Sdim        m_target_sp = m_process_sp->GetTarget().shared_from_this();
334314564Sdim      else
335254721Semaste        m_target_sp.reset();
336314564Sdim    } else {
337314564Sdim      m_target_sp.reset();
338314564Sdim      m_process_sp.reset();
339254721Semaste    }
340314564Sdim  } else {
341314564Sdim    m_target_sp.reset();
342314564Sdim    m_process_sp.reset();
343314564Sdim    m_thread_sp.reset();
344314564Sdim  }
345254721Semaste}
346254721Semaste
347314564SdimExecutionContext &ExecutionContext::operator=(const ExecutionContext &rhs) {
348314564Sdim  if (this != &rhs) {
349314564Sdim    m_target_sp = rhs.m_target_sp;
350314564Sdim    m_process_sp = rhs.m_process_sp;
351314564Sdim    m_thread_sp = rhs.m_thread_sp;
352314564Sdim    m_frame_sp = rhs.m_frame_sp;
353314564Sdim  }
354314564Sdim  return *this;
355254721Semaste}
356254721Semaste
357314564Sdimbool ExecutionContext::operator==(const ExecutionContext &rhs) const {
358314564Sdim  // Check that the frame shared pointers match, or both are valid and their
359341825Sdim  // stack IDs match since sometimes we get new objects that represent the same
360314564Sdim  // frame within a thread.
361314564Sdim  if ((m_frame_sp == rhs.m_frame_sp) ||
362314564Sdim      (m_frame_sp && rhs.m_frame_sp &&
363314564Sdim       m_frame_sp->GetStackID() == rhs.m_frame_sp->GetStackID())) {
364341825Sdim    // Check that the thread shared pointers match, or both are valid and their
365341825Sdim    // thread IDs match since sometimes we get new objects that represent the
366341825Sdim    // same thread within a process.
367314564Sdim    if ((m_thread_sp == rhs.m_thread_sp) ||
368314564Sdim        (m_thread_sp && rhs.m_thread_sp &&
369314564Sdim         m_thread_sp->GetID() == rhs.m_thread_sp->GetID())) {
370314564Sdim      // Processes and targets don't change much
371314564Sdim      return m_process_sp == rhs.m_process_sp && m_target_sp == rhs.m_target_sp;
372254721Semaste    }
373314564Sdim  }
374314564Sdim  return false;
375254721Semaste}
376254721Semaste
377314564Sdimbool ExecutionContext::operator!=(const ExecutionContext &rhs) const {
378314564Sdim  return !(*this == rhs);
379254721Semaste}
380254721Semaste
381314564Sdimbool ExecutionContext::HasTargetScope() const {
382314564Sdim  return ((bool)m_target_sp && m_target_sp->IsValid());
383254721Semaste}
384254721Semaste
385314564Sdimbool ExecutionContext::HasProcessScope() const {
386314564Sdim  return (HasTargetScope() && ((bool)m_process_sp && m_process_sp->IsValid()));
387254721Semaste}
388254721Semaste
389314564Sdimbool ExecutionContext::HasThreadScope() const {
390314564Sdim  return (HasProcessScope() && ((bool)m_thread_sp && m_thread_sp->IsValid()));
391254721Semaste}
392254721Semaste
393314564Sdimbool ExecutionContext::HasFrameScope() const {
394314564Sdim  return HasThreadScope() && m_frame_sp;
395254721Semaste}
396254721Semaste
397314564SdimExecutionContextRef::ExecutionContextRef()
398314564Sdim    : m_target_wp(), m_process_wp(), m_thread_wp(),
399314564Sdim      m_tid(LLDB_INVALID_THREAD_ID), m_stack_id() {}
400254721Semaste
401314564SdimExecutionContextRef::ExecutionContextRef(const ExecutionContext *exe_ctx)
402314564Sdim    : m_target_wp(), m_process_wp(), m_thread_wp(),
403314564Sdim      m_tid(LLDB_INVALID_THREAD_ID), m_stack_id() {
404314564Sdim  if (exe_ctx)
405314564Sdim    *this = *exe_ctx;
406254721Semaste}
407254721Semaste
408314564SdimExecutionContextRef::ExecutionContextRef(const ExecutionContext &exe_ctx)
409314564Sdim    : m_target_wp(), m_process_wp(), m_thread_wp(),
410314564Sdim      m_tid(LLDB_INVALID_THREAD_ID), m_stack_id() {
411314564Sdim  *this = exe_ctx;
412254721Semaste}
413254721Semaste
414314564SdimExecutionContextRef::ExecutionContextRef(Target *target, bool adopt_selected)
415314564Sdim    : m_target_wp(), m_process_wp(), m_thread_wp(),
416314564Sdim      m_tid(LLDB_INVALID_THREAD_ID), m_stack_id() {
417314564Sdim  SetTargetPtr(target, adopt_selected);
418254721Semaste}
419254721Semaste
420314564SdimExecutionContextRef::ExecutionContextRef(const ExecutionContextRef &rhs)
421314564Sdim    : m_target_wp(rhs.m_target_wp), m_process_wp(rhs.m_process_wp),
422314564Sdim      m_thread_wp(rhs.m_thread_wp), m_tid(rhs.m_tid),
423314564Sdim      m_stack_id(rhs.m_stack_id) {}
424254721Semaste
425314564SdimExecutionContextRef &ExecutionContextRef::
426314564Sdimoperator=(const ExecutionContextRef &rhs) {
427314564Sdim  if (this != &rhs) {
428314564Sdim    m_target_wp = rhs.m_target_wp;
429314564Sdim    m_process_wp = rhs.m_process_wp;
430314564Sdim    m_thread_wp = rhs.m_thread_wp;
431314564Sdim    m_tid = rhs.m_tid;
432314564Sdim    m_stack_id = rhs.m_stack_id;
433314564Sdim  }
434314564Sdim  return *this;
435254721Semaste}
436254721Semaste
437314564SdimExecutionContextRef &ExecutionContextRef::
438314564Sdimoperator=(const ExecutionContext &exe_ctx) {
439314564Sdim  m_target_wp = exe_ctx.GetTargetSP();
440314564Sdim  m_process_wp = exe_ctx.GetProcessSP();
441314564Sdim  lldb::ThreadSP thread_sp(exe_ctx.GetThreadSP());
442314564Sdim  m_thread_wp = thread_sp;
443314564Sdim  if (thread_sp)
444314564Sdim    m_tid = thread_sp->GetID();
445314564Sdim  else
446314564Sdim    m_tid = LLDB_INVALID_THREAD_ID;
447314564Sdim  lldb::StackFrameSP frame_sp(exe_ctx.GetFrameSP());
448314564Sdim  if (frame_sp)
449314564Sdim    m_stack_id = frame_sp->GetStackID();
450314564Sdim  else
451314564Sdim    m_stack_id.Clear();
452314564Sdim  return *this;
453254721Semaste}
454254721Semaste
455314564Sdimvoid ExecutionContextRef::Clear() {
456314564Sdim  m_target_wp.reset();
457314564Sdim  m_process_wp.reset();
458314564Sdim  ClearThread();
459314564Sdim  ClearFrame();
460254721Semaste}
461254721Semaste
462309124SdimExecutionContextRef::~ExecutionContextRef() = default;
463254721Semaste
464314564Sdimvoid ExecutionContextRef::SetTargetSP(const lldb::TargetSP &target_sp) {
465314564Sdim  m_target_wp = target_sp;
466254721Semaste}
467254721Semaste
468314564Sdimvoid ExecutionContextRef::SetProcessSP(const lldb::ProcessSP &process_sp) {
469314564Sdim  if (process_sp) {
470314564Sdim    m_process_wp = process_sp;
471314564Sdim    SetTargetSP(process_sp->GetTarget().shared_from_this());
472314564Sdim  } else {
473314564Sdim    m_process_wp.reset();
474314564Sdim    m_target_wp.reset();
475314564Sdim  }
476254721Semaste}
477254721Semaste
478314564Sdimvoid ExecutionContextRef::SetThreadSP(const lldb::ThreadSP &thread_sp) {
479314564Sdim  if (thread_sp) {
480314564Sdim    m_thread_wp = thread_sp;
481314564Sdim    m_tid = thread_sp->GetID();
482314564Sdim    SetProcessSP(thread_sp->GetProcess());
483314564Sdim  } else {
484314564Sdim    ClearThread();
485314564Sdim    m_process_wp.reset();
486314564Sdim    m_target_wp.reset();
487314564Sdim  }
488254721Semaste}
489254721Semaste
490314564Sdimvoid ExecutionContextRef::SetFrameSP(const lldb::StackFrameSP &frame_sp) {
491314564Sdim  if (frame_sp) {
492314564Sdim    m_stack_id = frame_sp->GetStackID();
493314564Sdim    SetThreadSP(frame_sp->GetThread());
494314564Sdim  } else {
495314564Sdim    ClearFrame();
496314564Sdim    ClearThread();
497314564Sdim    m_process_wp.reset();
498314564Sdim    m_target_wp.reset();
499314564Sdim  }
500254721Semaste}
501254721Semaste
502314564Sdimvoid ExecutionContextRef::SetTargetPtr(Target *target, bool adopt_selected) {
503314564Sdim  Clear();
504314564Sdim  if (target) {
505314564Sdim    lldb::TargetSP target_sp(target->shared_from_this());
506314564Sdim    if (target_sp) {
507314564Sdim      m_target_wp = target_sp;
508314564Sdim      if (adopt_selected) {
509314564Sdim        lldb::ProcessSP process_sp(target_sp->GetProcessSP());
510314564Sdim        if (process_sp) {
511314564Sdim          m_process_wp = process_sp;
512314564Sdim          if (process_sp) {
513314564Sdim            // Only fill in the thread and frame if our process is stopped
514314564Sdim            // Don't just check the state, since we might be in the middle of
515314564Sdim            // resuming.
516314564Sdim            Process::StopLocker stop_locker;
517288943Sdim
518314564Sdim            if (stop_locker.TryLock(&process_sp->GetRunLock()) &&
519314564Sdim                StateIsStoppedState(process_sp->GetState(), true)) {
520314564Sdim              lldb::ThreadSP thread_sp(
521314564Sdim                  process_sp->GetThreadList().GetSelectedThread());
522314564Sdim              if (!thread_sp)
523314564Sdim                thread_sp = process_sp->GetThreadList().GetThreadAtIndex(0);
524314564Sdim
525314564Sdim              if (thread_sp) {
526314564Sdim                SetThreadSP(thread_sp);
527314564Sdim                lldb::StackFrameSP frame_sp(thread_sp->GetSelectedFrame());
528314564Sdim                if (!frame_sp)
529314564Sdim                  frame_sp = thread_sp->GetStackFrameAtIndex(0);
530314564Sdim                if (frame_sp)
531314564Sdim                  SetFrameSP(frame_sp);
532314564Sdim              }
533254721Semaste            }
534314564Sdim          }
535254721Semaste        }
536314564Sdim      }
537254721Semaste    }
538314564Sdim  }
539254721Semaste}
540254721Semaste
541314564Sdimvoid ExecutionContextRef::SetProcessPtr(Process *process) {
542314564Sdim  if (process) {
543314564Sdim    SetProcessSP(process->shared_from_this());
544314564Sdim  } else {
545314564Sdim    m_process_wp.reset();
546314564Sdim    m_target_wp.reset();
547314564Sdim  }
548254721Semaste}
549254721Semaste
550314564Sdimvoid ExecutionContextRef::SetThreadPtr(Thread *thread) {
551314564Sdim  if (thread) {
552314564Sdim    SetThreadSP(thread->shared_from_this());
553314564Sdim  } else {
554314564Sdim    ClearThread();
555314564Sdim    m_process_wp.reset();
556314564Sdim    m_target_wp.reset();
557314564Sdim  }
558254721Semaste}
559254721Semaste
560314564Sdimvoid ExecutionContextRef::SetFramePtr(StackFrame *frame) {
561314564Sdim  if (frame)
562314564Sdim    SetFrameSP(frame->shared_from_this());
563314564Sdim  else
564314564Sdim    Clear();
565254721Semaste}
566254721Semaste
567314564Sdimlldb::TargetSP ExecutionContextRef::GetTargetSP() const {
568314564Sdim  lldb::TargetSP target_sp(m_target_wp.lock());
569314564Sdim  if (target_sp && !target_sp->IsValid())
570314564Sdim    target_sp.reset();
571314564Sdim  return target_sp;
572254721Semaste}
573254721Semaste
574314564Sdimlldb::ProcessSP ExecutionContextRef::GetProcessSP() const {
575314564Sdim  lldb::ProcessSP process_sp(m_process_wp.lock());
576314564Sdim  if (process_sp && !process_sp->IsValid())
577314564Sdim    process_sp.reset();
578314564Sdim  return process_sp;
579254721Semaste}
580254721Semaste
581314564Sdimlldb::ThreadSP ExecutionContextRef::GetThreadSP() const {
582314564Sdim  lldb::ThreadSP thread_sp(m_thread_wp.lock());
583314564Sdim
584314564Sdim  if (m_tid != LLDB_INVALID_THREAD_ID) {
585341825Sdim    // We check if the thread has been destroyed in cases where clients might
586341825Sdim    // still have shared pointer to a thread, but the thread is not valid
587341825Sdim    // anymore (not part of the process)
588314564Sdim    if (!thread_sp || !thread_sp->IsValid()) {
589314564Sdim      lldb::ProcessSP process_sp(GetProcessSP());
590314564Sdim      if (process_sp && process_sp->IsValid()) {
591314564Sdim        thread_sp = process_sp->GetThreadList().FindThreadByID(m_tid);
592314564Sdim        m_thread_wp = thread_sp;
593314564Sdim      }
594254721Semaste    }
595314564Sdim  }
596314564Sdim
597341825Sdim  // Check that we aren't about to return an invalid thread sp.  We might
598341825Sdim  // return a nullptr thread_sp, but don't return an invalid one.
599314564Sdim
600314564Sdim  if (thread_sp && !thread_sp->IsValid())
601314564Sdim    thread_sp.reset();
602314564Sdim
603314564Sdim  return thread_sp;
604254721Semaste}
605254721Semaste
606314564Sdimlldb::StackFrameSP ExecutionContextRef::GetFrameSP() const {
607314564Sdim  if (m_stack_id.IsValid()) {
608314564Sdim    lldb::ThreadSP thread_sp(GetThreadSP());
609314564Sdim    if (thread_sp)
610314564Sdim      return thread_sp->GetFrameWithStackID(m_stack_id);
611314564Sdim  }
612314564Sdim  return lldb::StackFrameSP();
613254721Semaste}
614254721Semaste
615254721SemasteExecutionContext
616314564SdimExecutionContextRef::Lock(bool thread_and_frame_only_if_stopped) const {
617314564Sdim  return ExecutionContext(this, thread_and_frame_only_if_stopped);
618254721Semaste}
619