1 //===-- ExecutionContext.cpp ------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 // C Includes
11 // C++ Includes
12 // Other libraries and framework includes
13 // Project includes
14 #include "lldb/Target/ExecutionContext.h"
15 #include "lldb/Core/State.h"
16 #include "lldb/Target/ExecutionContextScope.h"
17 #include "lldb/Target/StackFrame.h"
18 #include "lldb/Target/Process.h"
19 #include "lldb/Target/Target.h"
20 #include "lldb/Target/Thread.h"
21 
22 using namespace lldb_private;
23 
24 ExecutionContext::ExecutionContext() :
25     m_target_sp (),
26     m_process_sp (),
27     m_thread_sp (),
28     m_frame_sp ()
29 {
30 }
31 
32 ExecutionContext::ExecutionContext (const ExecutionContext &rhs) :
33     m_target_sp(rhs.m_target_sp),
34     m_process_sp(rhs.m_process_sp),
35     m_thread_sp(rhs.m_thread_sp),
36     m_frame_sp(rhs.m_frame_sp)
37 {
38 }
39 
40 ExecutionContext::ExecutionContext (const lldb::TargetSP &target_sp, bool get_process) :
41     m_target_sp (),
42     m_process_sp (),
43     m_thread_sp (),
44     m_frame_sp ()
45 {
46     if (target_sp)
47         SetContext (target_sp, get_process);
48 }
49 
50 ExecutionContext::ExecutionContext (const lldb::ProcessSP &process_sp) :
51     m_target_sp (),
52     m_process_sp (),
53     m_thread_sp (),
54     m_frame_sp ()
55 {
56     if (process_sp)
57         SetContext (process_sp);
58 }
59 
60 ExecutionContext::ExecutionContext (const lldb::ThreadSP &thread_sp) :
61     m_target_sp (),
62     m_process_sp (),
63     m_thread_sp (),
64     m_frame_sp ()
65 {
66     if (thread_sp)
67         SetContext (thread_sp);
68 }
69 
70 ExecutionContext::ExecutionContext (const lldb::StackFrameSP &frame_sp) :
71     m_target_sp (),
72     m_process_sp (),
73     m_thread_sp (),
74     m_frame_sp ()
75 {
76     if (frame_sp)
77         SetContext (frame_sp);
78 }
79 
80 ExecutionContext::ExecutionContext (const lldb::TargetWP &target_wp, bool get_process) :
81     m_target_sp (),
82     m_process_sp (),
83     m_thread_sp (),
84     m_frame_sp ()
85 {
86     lldb::TargetSP target_sp(target_wp.lock());
87     if (target_sp)
88         SetContext (target_sp, get_process);
89 }
90 
91 ExecutionContext::ExecutionContext (const lldb::ProcessWP &process_wp) :
92     m_target_sp (),
93     m_process_sp (),
94     m_thread_sp (),
95     m_frame_sp ()
96 {
97     lldb::ProcessSP process_sp(process_wp.lock());
98     if (process_sp)
99         SetContext (process_sp);
100 }
101 
102 ExecutionContext::ExecutionContext (const lldb::ThreadWP &thread_wp) :
103     m_target_sp (),
104     m_process_sp (),
105     m_thread_sp (),
106     m_frame_sp ()
107 {
108     lldb::ThreadSP thread_sp(thread_wp.lock());
109     if (thread_sp)
110         SetContext (thread_sp);
111 }
112 
113 ExecutionContext::ExecutionContext (const lldb::StackFrameWP &frame_wp) :
114     m_target_sp (),
115     m_process_sp (),
116     m_thread_sp (),
117     m_frame_sp ()
118 {
119     lldb::StackFrameSP frame_sp(frame_wp.lock());
120     if (frame_sp)
121         SetContext (frame_sp);
122 }
123 
124 ExecutionContext::ExecutionContext (Target* t, bool fill_current_process_thread_frame) :
125     m_target_sp (),
126     m_process_sp (),
127     m_thread_sp (),
128     m_frame_sp ()
129 {
130     if (t)
131     {
132         m_target_sp = t->shared_from_this();
133         if (fill_current_process_thread_frame)
134         {
135             m_process_sp = t->GetProcessSP();
136             if (m_process_sp)
137             {
138                 m_thread_sp = m_process_sp->GetThreadList().GetSelectedThread();
139                 if (m_thread_sp)
140                     m_frame_sp = m_thread_sp->GetSelectedFrame();
141             }
142         }
143     }
144 }
145 
146 ExecutionContext::ExecutionContext(Process* process, Thread *thread, StackFrame *frame) :
147     m_target_sp (),
148     m_process_sp (),
149     m_thread_sp (),
150     m_frame_sp ()
151 {
152     if (process)
153     {
154         m_process_sp = process->shared_from_this();
155         m_target_sp = process->GetTarget().shared_from_this();
156     }
157     if (thread)
158         m_thread_sp = thread->shared_from_this();
159     if (frame)
160         m_frame_sp = frame->shared_from_this();
161 }
162 
163 ExecutionContext::ExecutionContext (const ExecutionContextRef &exe_ctx_ref) :
164     m_target_sp (exe_ctx_ref.GetTargetSP()),
165     m_process_sp (exe_ctx_ref.GetProcessSP()),
166     m_thread_sp (exe_ctx_ref.GetThreadSP()),
167     m_frame_sp (exe_ctx_ref.GetFrameSP())
168 {
169 }
170 
171 ExecutionContext::ExecutionContext (const ExecutionContextRef *exe_ctx_ref_ptr, bool thread_and_frame_only_if_stopped) :
172     m_target_sp (),
173     m_process_sp (),
174     m_thread_sp (),
175     m_frame_sp ()
176 {
177     if (exe_ctx_ref_ptr)
178     {
179         m_target_sp  = exe_ctx_ref_ptr->GetTargetSP();
180         m_process_sp = exe_ctx_ref_ptr->GetProcessSP();
181         if (!thread_and_frame_only_if_stopped || (m_process_sp && StateIsStoppedState(m_process_sp->GetState(), true)))
182         {
183             m_thread_sp = exe_ctx_ref_ptr->GetThreadSP();
184             m_frame_sp = exe_ctx_ref_ptr->GetFrameSP();
185         }
186     }
187 }
188 
189 ExecutionContext::ExecutionContext (const ExecutionContextRef *exe_ctx_ref_ptr, Mutex::Locker &locker) :
190     m_target_sp (),
191     m_process_sp (),
192     m_thread_sp (),
193     m_frame_sp ()
194 {
195     if (exe_ctx_ref_ptr)
196     {
197         m_target_sp  = exe_ctx_ref_ptr->GetTargetSP();
198         if (m_target_sp)
199         {
200             locker.Lock(m_target_sp->GetAPIMutex());
201             m_process_sp = exe_ctx_ref_ptr->GetProcessSP();
202             m_thread_sp = exe_ctx_ref_ptr->GetThreadSP();
203             m_frame_sp = exe_ctx_ref_ptr->GetFrameSP();
204         }
205     }
206 }
207 
208 ExecutionContext::ExecutionContext (const ExecutionContextRef &exe_ctx_ref, Mutex::Locker &locker) :
209     m_target_sp (exe_ctx_ref.GetTargetSP()),
210     m_process_sp (),
211     m_thread_sp (),
212     m_frame_sp ()
213 {
214     if (m_target_sp)
215     {
216         locker.Lock(m_target_sp->GetAPIMutex());
217         m_process_sp = exe_ctx_ref.GetProcessSP();
218         m_thread_sp  = exe_ctx_ref.GetThreadSP();
219         m_frame_sp   = exe_ctx_ref.GetFrameSP();
220     }
221 }
222 
223 ExecutionContext::ExecutionContext (ExecutionContextScope *exe_scope_ptr) :
224     m_target_sp (),
225     m_process_sp (),
226     m_thread_sp (),
227     m_frame_sp ()
228 {
229     if (exe_scope_ptr)
230         exe_scope_ptr->CalculateExecutionContext (*this);
231 }
232 
233 ExecutionContext::ExecutionContext (ExecutionContextScope &exe_scope_ref)
234 {
235     exe_scope_ref.CalculateExecutionContext (*this);
236 }
237 
238 void
239 ExecutionContext::Clear()
240 {
241     m_target_sp.reset();
242     m_process_sp.reset();
243     m_thread_sp.reset();
244     m_frame_sp.reset();
245 }
246 
247 ExecutionContext::~ExecutionContext() = default;
248 
249 uint32_t
250 ExecutionContext::GetAddressByteSize() const
251 {
252     if (m_target_sp && m_target_sp->GetArchitecture().IsValid())
253         return m_target_sp->GetArchitecture().GetAddressByteSize();
254     if (m_process_sp)
255         return m_process_sp->GetAddressByteSize();
256     return sizeof(void *);
257 }
258 
259 lldb::ByteOrder
260 ExecutionContext::GetByteOrder() const
261 {
262     if (m_target_sp && m_target_sp->GetArchitecture().IsValid())
263         m_target_sp->GetArchitecture().GetByteOrder();
264     if (m_process_sp)
265         m_process_sp->GetByteOrder();
266     return endian::InlHostByteOrder();
267 }
268 
269 RegisterContext *
270 ExecutionContext::GetRegisterContext () const
271 {
272     if (m_frame_sp)
273         return m_frame_sp->GetRegisterContext().get();
274     else if (m_thread_sp)
275         return m_thread_sp->GetRegisterContext().get();
276     return nullptr;
277 }
278 
279 Target *
280 ExecutionContext::GetTargetPtr () const
281 {
282     if (m_target_sp)
283         return m_target_sp.get();
284     if (m_process_sp)
285         return &m_process_sp->GetTarget();
286     return nullptr;
287 }
288 
289 Process *
290 ExecutionContext::GetProcessPtr () const
291 {
292     if (m_process_sp)
293         return m_process_sp.get();
294     if (m_target_sp)
295         return m_target_sp->GetProcessSP().get();
296     return nullptr;
297 }
298 
299 ExecutionContextScope *
300 ExecutionContext::GetBestExecutionContextScope () const
301 {
302     if (m_frame_sp)
303         return m_frame_sp.get();
304     if (m_thread_sp)
305         return m_thread_sp.get();
306     if (m_process_sp)
307         return m_process_sp.get();
308     return m_target_sp.get();
309 }
310 
311 Target &
312 ExecutionContext::GetTargetRef () const
313 {
314 #if defined (LLDB_CONFIGURATION_DEBUG) || defined (LLDB_CONFIGURATION_RELEASE)
315     assert (m_target_sp);
316 #endif
317     return *m_target_sp;
318 }
319 
320 Process &
321 ExecutionContext::GetProcessRef () const
322 {
323 #if defined (LLDB_CONFIGURATION_DEBUG) || defined (LLDB_CONFIGURATION_RELEASE)
324     assert (m_process_sp);
325 #endif
326     return *m_process_sp;
327 }
328 
329 Thread &
330 ExecutionContext::GetThreadRef () const
331 {
332 #if defined (LLDB_CONFIGURATION_DEBUG) || defined (LLDB_CONFIGURATION_RELEASE)
333     assert (m_thread_sp);
334 #endif
335     return *m_thread_sp;
336 }
337 
338 StackFrame &
339 ExecutionContext::GetFrameRef () const
340 {
341 #if defined (LLDB_CONFIGURATION_DEBUG) || defined (LLDB_CONFIGURATION_RELEASE)
342     assert (m_frame_sp);
343 #endif
344     return *m_frame_sp;
345 }
346 
347 void
348 ExecutionContext::SetTargetSP (const lldb::TargetSP &target_sp)
349 {
350     m_target_sp = target_sp;
351 }
352 
353 void
354 ExecutionContext::SetProcessSP (const lldb::ProcessSP &process_sp)
355 {
356     m_process_sp = process_sp;
357 }
358 
359 void
360 ExecutionContext::SetThreadSP (const lldb::ThreadSP &thread_sp)
361 {
362     m_thread_sp = thread_sp;
363 }
364 
365 void
366 ExecutionContext::SetFrameSP (const lldb::StackFrameSP &frame_sp)
367 {
368     m_frame_sp = frame_sp;
369 }
370 
371 void
372 ExecutionContext::SetTargetPtr (Target* target)
373 {
374     if (target)
375         m_target_sp = target->shared_from_this();
376     else
377         m_target_sp.reset();
378 }
379 
380 void
381 ExecutionContext::SetProcessPtr (Process *process)
382 {
383     if (process)
384         m_process_sp = process->shared_from_this();
385     else
386         m_process_sp.reset();
387 }
388 
389 void
390 ExecutionContext::SetThreadPtr (Thread *thread)
391 {
392     if (thread)
393         m_thread_sp = thread->shared_from_this();
394     else
395         m_thread_sp.reset();
396 }
397 
398 void
399 ExecutionContext::SetFramePtr (StackFrame *frame)
400 {
401     if (frame)
402         m_frame_sp = frame->shared_from_this();
403     else
404         m_frame_sp.reset();
405 }
406 
407 void
408 ExecutionContext::SetContext (const lldb::TargetSP &target_sp, bool get_process)
409 {
410     m_target_sp = target_sp;
411     if (get_process && target_sp)
412         m_process_sp = target_sp->GetProcessSP();
413     else
414         m_process_sp.reset();
415     m_thread_sp.reset();
416     m_frame_sp.reset();
417 }
418 
419 void
420 ExecutionContext::SetContext (const lldb::ProcessSP &process_sp)
421 {
422     m_process_sp = process_sp;
423     if (process_sp)
424         m_target_sp = process_sp->GetTarget().shared_from_this();
425     else
426         m_target_sp.reset();
427     m_thread_sp.reset();
428     m_frame_sp.reset();
429 }
430 
431 void
432 ExecutionContext::SetContext (const lldb::ThreadSP &thread_sp)
433 {
434     m_frame_sp.reset();
435     m_thread_sp = thread_sp;
436     if (thread_sp)
437     {
438         m_process_sp = thread_sp->GetProcess();
439         if (m_process_sp)
440             m_target_sp = m_process_sp->GetTarget().shared_from_this();
441         else
442             m_target_sp.reset();
443     }
444     else
445     {
446         m_target_sp.reset();
447         m_process_sp.reset();
448     }
449 }
450 
451 void
452 ExecutionContext::SetContext (const lldb::StackFrameSP &frame_sp)
453 {
454     m_frame_sp = frame_sp;
455     if (frame_sp)
456     {
457         m_thread_sp = frame_sp->CalculateThread();
458         if (m_thread_sp)
459         {
460             m_process_sp = m_thread_sp->GetProcess();
461             if (m_process_sp)
462                 m_target_sp = m_process_sp->GetTarget().shared_from_this();
463             else
464                 m_target_sp.reset();
465         }
466         else
467         {
468             m_target_sp.reset();
469             m_process_sp.reset();
470         }
471     }
472     else
473     {
474         m_target_sp.reset();
475         m_process_sp.reset();
476         m_thread_sp.reset();
477     }
478 }
479 
480 ExecutionContext &
481 ExecutionContext::operator =(const ExecutionContext &rhs)
482 {
483     if (this != &rhs)
484     {
485         m_target_sp  = rhs.m_target_sp;
486         m_process_sp = rhs.m_process_sp;
487         m_thread_sp  = rhs.m_thread_sp;
488         m_frame_sp   = rhs.m_frame_sp;
489     }
490     return *this;
491 }
492 
493 bool
494 ExecutionContext::operator ==(const ExecutionContext &rhs) const
495 {
496     // Check that the frame shared pointers match, or both are valid and their stack
497     // IDs match since sometimes we get new objects that represent the same
498     // frame within a thread.
499     if ((m_frame_sp == rhs.m_frame_sp) || (m_frame_sp && rhs.m_frame_sp && m_frame_sp->GetStackID() == rhs.m_frame_sp->GetStackID()))
500     {
501         // Check that the thread shared pointers match, or both are valid and
502         // their thread IDs match since sometimes we get new objects that
503         // represent the same thread within a process.
504         if ((m_thread_sp == rhs.m_thread_sp) || (m_thread_sp && rhs.m_thread_sp && m_thread_sp->GetID() == rhs.m_thread_sp->GetID()))
505         {
506             // Processes and targets don't change much
507             return m_process_sp == rhs.m_process_sp && m_target_sp == rhs.m_target_sp;
508         }
509     }
510     return false;
511 }
512 
513 bool
514 ExecutionContext::operator !=(const ExecutionContext &rhs) const
515 {
516     return !(*this == rhs);
517 }
518 
519 bool
520 ExecutionContext::HasTargetScope () const
521 {
522     return ((bool) m_target_sp
523             && m_target_sp->IsValid());
524 }
525 
526 bool
527 ExecutionContext::HasProcessScope () const
528 {
529     return (HasTargetScope()
530             && ((bool) m_process_sp && m_process_sp->IsValid()));
531 }
532 
533 bool
534 ExecutionContext::HasThreadScope () const
535 {
536     return (HasProcessScope()
537            && ((bool) m_thread_sp && m_thread_sp->IsValid()));
538 }
539 
540 bool
541 ExecutionContext::HasFrameScope () const
542 {
543     return HasThreadScope() && m_frame_sp;
544 }
545 
546 ExecutionContextRef::ExecutionContextRef() :
547     m_target_wp (),
548     m_process_wp (),
549     m_thread_wp (),
550     m_tid(LLDB_INVALID_THREAD_ID),
551     m_stack_id ()
552 {
553 }
554 
555 ExecutionContextRef::ExecutionContextRef (const ExecutionContext *exe_ctx) :
556     m_target_wp (),
557     m_process_wp (),
558     m_thread_wp (),
559     m_tid(LLDB_INVALID_THREAD_ID),
560     m_stack_id ()
561 {
562     if (exe_ctx)
563         *this = *exe_ctx;
564 }
565 
566 ExecutionContextRef::ExecutionContextRef (const ExecutionContext &exe_ctx) :
567     m_target_wp (),
568     m_process_wp (),
569     m_thread_wp (),
570     m_tid(LLDB_INVALID_THREAD_ID),
571     m_stack_id ()
572 {
573     *this = exe_ctx;
574 }
575 
576 ExecutionContextRef::ExecutionContextRef (Target *target, bool adopt_selected) :
577     m_target_wp(),
578     m_process_wp(),
579     m_thread_wp(),
580     m_tid(LLDB_INVALID_THREAD_ID),
581     m_stack_id ()
582 {
583     SetTargetPtr (target, adopt_selected);
584 }
585 
586 ExecutionContextRef::ExecutionContextRef (const ExecutionContextRef &rhs) :
587     m_target_wp (rhs.m_target_wp),
588     m_process_wp(rhs.m_process_wp),
589     m_thread_wp (rhs.m_thread_wp),
590     m_tid       (rhs.m_tid),
591     m_stack_id  (rhs.m_stack_id)
592 {
593 }
594 
595 ExecutionContextRef &
596 ExecutionContextRef::operator =(const ExecutionContextRef &rhs)
597 {
598     if (this != &rhs)
599     {
600         m_target_wp  = rhs.m_target_wp;
601         m_process_wp = rhs.m_process_wp;
602         m_thread_wp  = rhs.m_thread_wp;
603         m_tid        = rhs.m_tid;
604         m_stack_id   = rhs.m_stack_id;
605     }
606     return *this;
607 }
608 
609 ExecutionContextRef &
610 ExecutionContextRef::operator =(const ExecutionContext &exe_ctx)
611 {
612     m_target_wp = exe_ctx.GetTargetSP();
613     m_process_wp = exe_ctx.GetProcessSP();
614     lldb::ThreadSP thread_sp (exe_ctx.GetThreadSP());
615     m_thread_wp = thread_sp;
616     if (thread_sp)
617         m_tid = thread_sp->GetID();
618     else
619         m_tid = LLDB_INVALID_THREAD_ID;
620     lldb::StackFrameSP frame_sp (exe_ctx.GetFrameSP());
621     if (frame_sp)
622         m_stack_id = frame_sp->GetStackID();
623     else
624         m_stack_id.Clear();
625     return *this;
626 }
627 
628 void
629 ExecutionContextRef::Clear()
630 {
631     m_target_wp.reset();
632     m_process_wp.reset();
633     ClearThread();
634     ClearFrame();
635 }
636 
637 ExecutionContextRef::~ExecutionContextRef() = default;
638 
639 void
640 ExecutionContextRef::SetTargetSP (const lldb::TargetSP &target_sp)
641 {
642     m_target_wp = target_sp;
643 }
644 
645 void
646 ExecutionContextRef::SetProcessSP (const lldb::ProcessSP &process_sp)
647 {
648     if (process_sp)
649     {
650         m_process_wp = process_sp;
651         SetTargetSP (process_sp->GetTarget().shared_from_this());
652     }
653     else
654     {
655         m_process_wp.reset();
656         m_target_wp.reset();
657     }
658 }
659 
660 void
661 ExecutionContextRef::SetThreadSP (const lldb::ThreadSP &thread_sp)
662 {
663     if (thread_sp)
664     {
665         m_thread_wp = thread_sp;
666         m_tid = thread_sp->GetID();
667         SetProcessSP (thread_sp->GetProcess());
668     }
669     else
670     {
671         ClearThread();
672         m_process_wp.reset();
673         m_target_wp.reset();
674     }
675 }
676 
677 void
678 ExecutionContextRef::SetFrameSP (const lldb::StackFrameSP &frame_sp)
679 {
680     if (frame_sp)
681     {
682         m_stack_id = frame_sp->GetStackID();
683         SetThreadSP (frame_sp->GetThread());
684     }
685     else
686     {
687         ClearFrame();
688         ClearThread();
689         m_process_wp.reset();
690         m_target_wp.reset();
691     }
692 }
693 
694 void
695 ExecutionContextRef::SetTargetPtr (Target* target, bool adopt_selected)
696 {
697     Clear();
698     if (target)
699     {
700         lldb::TargetSP target_sp (target->shared_from_this());
701         if (target_sp)
702         {
703             m_target_wp = target_sp;
704             if (adopt_selected)
705             {
706                 lldb::ProcessSP process_sp (target_sp->GetProcessSP());
707                 if (process_sp)
708                 {
709                     m_process_wp = process_sp;
710                     if (process_sp)
711                     {
712                         // Only fill in the thread and frame if our process is stopped
713                         // Don't just check the state, since we might be in the middle of
714                         // resuming.
715                         Process::StopLocker stop_locker;
716 
717                         if (stop_locker.TryLock(&process_sp->GetRunLock()) && StateIsStoppedState (process_sp->GetState(), true))
718                         {
719                             lldb::ThreadSP thread_sp (process_sp->GetThreadList().GetSelectedThread());
720                             if (!thread_sp)
721                                 thread_sp = process_sp->GetThreadList().GetThreadAtIndex(0);
722 
723                             if (thread_sp)
724                             {
725                                 SetThreadSP (thread_sp);
726                                 lldb::StackFrameSP frame_sp (thread_sp->GetSelectedFrame());
727                                 if (!frame_sp)
728                                     frame_sp = thread_sp->GetStackFrameAtIndex(0);
729                                 if (frame_sp)
730                                     SetFrameSP (frame_sp);
731                             }
732                         }
733                     }
734                 }
735             }
736         }
737     }
738 }
739 
740 void
741 ExecutionContextRef::SetProcessPtr (Process *process)
742 {
743     if (process)
744     {
745         SetProcessSP(process->shared_from_this());
746     }
747     else
748     {
749         m_process_wp.reset();
750         m_target_wp.reset();
751     }
752 }
753 
754 void
755 ExecutionContextRef::SetThreadPtr (Thread *thread)
756 {
757     if (thread)
758     {
759         SetThreadSP (thread->shared_from_this());
760     }
761     else
762     {
763         ClearThread();
764         m_process_wp.reset();
765         m_target_wp.reset();
766     }
767 }
768 
769 void
770 ExecutionContextRef::SetFramePtr (StackFrame *frame)
771 {
772     if (frame)
773         SetFrameSP (frame->shared_from_this());
774     else
775         Clear();
776 }
777 
778 lldb::TargetSP
779 ExecutionContextRef::GetTargetSP () const
780 {
781     lldb::TargetSP target_sp(m_target_wp.lock());
782     if (target_sp && !target_sp->IsValid())
783         target_sp.reset();
784     return target_sp;
785 }
786 
787 lldb::ProcessSP
788 ExecutionContextRef::GetProcessSP () const
789 {
790     lldb::ProcessSP process_sp(m_process_wp.lock());
791     if (process_sp && !process_sp->IsValid())
792         process_sp.reset();
793     return process_sp;
794 }
795 
796 lldb::ThreadSP
797 ExecutionContextRef::GetThreadSP () const
798 {
799     lldb::ThreadSP thread_sp (m_thread_wp.lock());
800 
801     if (m_tid != LLDB_INVALID_THREAD_ID)
802     {
803         // We check if the thread has been destroyed in cases where clients
804         // might still have shared pointer to a thread, but the thread is
805         // not valid anymore (not part of the process)
806         if (!thread_sp || !thread_sp->IsValid())
807         {
808             lldb::ProcessSP process_sp(GetProcessSP());
809             if (process_sp && process_sp->IsValid())
810             {
811                 thread_sp = process_sp->GetThreadList().FindThreadByID(m_tid);
812                 m_thread_wp = thread_sp;
813             }
814         }
815     }
816 
817     // Check that we aren't about to return an invalid thread sp.  We might return a nullptr thread_sp,
818     // but don't return an invalid one.
819 
820     if (thread_sp && !thread_sp->IsValid())
821         thread_sp.reset();
822 
823     return thread_sp;
824 }
825 
826 lldb::StackFrameSP
827 ExecutionContextRef::GetFrameSP () const
828 {
829     if (m_stack_id.IsValid())
830     {
831         lldb::ThreadSP thread_sp (GetThreadSP());
832         if (thread_sp)
833             return thread_sp->GetFrameWithStackID (m_stack_id);
834     }
835     return lldb::StackFrameSP();
836 }
837 
838 ExecutionContext
839 ExecutionContextRef::Lock (bool thread_and_frame_only_if_stopped) const
840 {
841     return ExecutionContext(this, thread_and_frame_only_if_stopped);
842 }
843