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