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