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 
ExecutionContext()21 ExecutionContext::ExecutionContext() :
22     m_target_sp (),
23     m_process_sp (),
24     m_thread_sp (),
25     m_frame_sp ()
26 {
27 }
28 
ExecutionContext(const ExecutionContext & rhs)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 
ExecutionContext(const lldb::TargetSP & target_sp,bool get_process)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 
ExecutionContext(const lldb::ProcessSP & process_sp)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 
ExecutionContext(const lldb::ThreadSP & thread_sp)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 
ExecutionContext(const lldb::StackFrameSP & frame_sp)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 
ExecutionContext(const lldb::TargetWP & target_wp,bool get_process)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 
ExecutionContext(const lldb::ProcessWP & process_wp)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 
ExecutionContext(const lldb::ThreadWP & thread_wp)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 
ExecutionContext(const lldb::StackFrameWP & frame_wp)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 
ExecutionContext(Target * t,bool fill_current_process_thread_frame)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 
ExecutionContext(Process * process,Thread * thread,StackFrame * frame)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 
ExecutionContext(const ExecutionContextRef & exe_ctx_ref)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 
ExecutionContext(const ExecutionContextRef * exe_ctx_ref_ptr)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 
ExecutionContext(const ExecutionContextRef * exe_ctx_ref_ptr,Mutex::Locker & locker)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 
ExecutionContext(const ExecutionContextRef & exe_ctx_ref,Mutex::Locker & locker)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 
ExecutionContext(ExecutionContextScope * exe_scope_ptr)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 
ExecutionContext(ExecutionContextScope & exe_scope_ref)216 ExecutionContext::ExecutionContext (ExecutionContextScope &exe_scope_ref)
217 {
218     exe_scope_ref.CalculateExecutionContext (*this);
219 }
220 
221 void
Clear()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 
~ExecutionContext()230 ExecutionContext::~ExecutionContext()
231 {
232 }
233 
234 uint32_t
GetAddressByteSize() const235 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 
245 
246 RegisterContext *
GetRegisterContext() const247 ExecutionContext::GetRegisterContext () const
248 {
249     if (m_frame_sp)
250         return m_frame_sp->GetRegisterContext().get();
251     else if (m_thread_sp)
252         return m_thread_sp->GetRegisterContext().get();
253     return NULL;
254 }
255 
256 Target *
GetTargetPtr() const257 ExecutionContext::GetTargetPtr () const
258 {
259     if (m_target_sp)
260         return m_target_sp.get();
261     if (m_process_sp)
262         return &m_process_sp->GetTarget();
263     return NULL;
264 }
265 
266 Process *
GetProcessPtr() const267 ExecutionContext::GetProcessPtr () const
268 {
269     if (m_process_sp)
270         return m_process_sp.get();
271     if (m_target_sp)
272         return m_target_sp->GetProcessSP().get();
273     return NULL;
274 }
275 
276 ExecutionContextScope *
GetBestExecutionContextScope() const277 ExecutionContext::GetBestExecutionContextScope () const
278 {
279     if (m_frame_sp)
280         return m_frame_sp.get();
281     if (m_thread_sp)
282         return m_thread_sp.get();
283     if (m_process_sp)
284         return m_process_sp.get();
285     return m_target_sp.get();
286 }
287 
288 Target &
GetTargetRef() const289 ExecutionContext::GetTargetRef () const
290 {
291 #if defined (LLDB_CONFIGURATION_DEBUG) || defined (LLDB_CONFIGURATION_RELEASE)
292     assert (m_target_sp.get());
293 #endif
294     return *m_target_sp;
295 }
296 
297 Process &
GetProcessRef() const298 ExecutionContext::GetProcessRef () const
299 {
300 #if defined (LLDB_CONFIGURATION_DEBUG) || defined (LLDB_CONFIGURATION_RELEASE)
301     assert (m_process_sp.get());
302 #endif
303     return *m_process_sp;
304 }
305 
306 Thread &
GetThreadRef() const307 ExecutionContext::GetThreadRef () const
308 {
309 #if defined (LLDB_CONFIGURATION_DEBUG) || defined (LLDB_CONFIGURATION_RELEASE)
310     assert (m_thread_sp.get());
311 #endif
312     return *m_thread_sp;
313 }
314 
315 StackFrame &
GetFrameRef() const316 ExecutionContext::GetFrameRef () const
317 {
318 #if defined (LLDB_CONFIGURATION_DEBUG) || defined (LLDB_CONFIGURATION_RELEASE)
319     assert (m_frame_sp.get());
320 #endif
321     return *m_frame_sp;
322 }
323 
324 void
SetTargetSP(const lldb::TargetSP & target_sp)325 ExecutionContext::SetTargetSP (const lldb::TargetSP &target_sp)
326 {
327     m_target_sp = target_sp;
328 }
329 
330 void
SetProcessSP(const lldb::ProcessSP & process_sp)331 ExecutionContext::SetProcessSP (const lldb::ProcessSP &process_sp)
332 {
333     m_process_sp = process_sp;
334 }
335 
336 void
SetThreadSP(const lldb::ThreadSP & thread_sp)337 ExecutionContext::SetThreadSP (const lldb::ThreadSP &thread_sp)
338 {
339     m_thread_sp = thread_sp;
340 }
341 
342 void
SetFrameSP(const lldb::StackFrameSP & frame_sp)343 ExecutionContext::SetFrameSP (const lldb::StackFrameSP &frame_sp)
344 {
345     m_frame_sp = frame_sp;
346 }
347 
348 void
SetTargetPtr(Target * target)349 ExecutionContext::SetTargetPtr (Target* target)
350 {
351     if (target)
352         m_target_sp = target->shared_from_this();
353     else
354         m_target_sp.reset();
355 }
356 
357 void
SetProcessPtr(Process * process)358 ExecutionContext::SetProcessPtr (Process *process)
359 {
360     if (process)
361         m_process_sp = process->shared_from_this();
362     else
363         m_process_sp.reset();
364 }
365 
366 void
SetThreadPtr(Thread * thread)367 ExecutionContext::SetThreadPtr (Thread *thread)
368 {
369     if (thread)
370         m_thread_sp = thread->shared_from_this();
371     else
372         m_thread_sp.reset();
373 }
374 
375 void
SetFramePtr(StackFrame * frame)376 ExecutionContext::SetFramePtr (StackFrame *frame)
377 {
378     if (frame)
379         m_frame_sp = frame->shared_from_this();
380     else
381         m_frame_sp.reset();
382 }
383 
384 void
SetContext(const lldb::TargetSP & target_sp,bool get_process)385 ExecutionContext::SetContext (const lldb::TargetSP &target_sp, bool get_process)
386 {
387     m_target_sp = target_sp;
388     if (get_process && target_sp)
389         m_process_sp = target_sp->GetProcessSP();
390     else
391         m_process_sp.reset();
392     m_thread_sp.reset();
393     m_frame_sp.reset();
394 }
395 
396 void
SetContext(const lldb::ProcessSP & process_sp)397 ExecutionContext::SetContext (const lldb::ProcessSP &process_sp)
398 {
399     m_process_sp = process_sp;
400     if (process_sp)
401         m_target_sp = process_sp->GetTarget().shared_from_this();
402     else
403         m_target_sp.reset();
404     m_thread_sp.reset();
405     m_frame_sp.reset();
406 }
407 
408 void
SetContext(const lldb::ThreadSP & thread_sp)409 ExecutionContext::SetContext (const lldb::ThreadSP &thread_sp)
410 {
411     m_frame_sp.reset();
412     m_thread_sp = thread_sp;
413     if (thread_sp)
414     {
415         m_process_sp = thread_sp->GetProcess();
416         if (m_process_sp)
417             m_target_sp = m_process_sp->GetTarget().shared_from_this();
418         else
419             m_target_sp.reset();
420     }
421     else
422     {
423         m_target_sp.reset();
424         m_process_sp.reset();
425     }
426 }
427 
428 void
SetContext(const lldb::StackFrameSP & frame_sp)429 ExecutionContext::SetContext (const lldb::StackFrameSP &frame_sp)
430 {
431     m_frame_sp = frame_sp;
432     if (frame_sp)
433     {
434         m_thread_sp = frame_sp->CalculateThread();
435         if (m_thread_sp)
436         {
437             m_process_sp = m_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     else
450     {
451         m_target_sp.reset();
452         m_process_sp.reset();
453         m_thread_sp.reset();
454     }
455 }
456 
457 ExecutionContext &
operator =(const ExecutionContext & rhs)458 ExecutionContext::operator =(const ExecutionContext &rhs)
459 {
460     if (this != &rhs)
461     {
462         m_target_sp  = rhs.m_target_sp;
463         m_process_sp = rhs.m_process_sp;
464         m_thread_sp  = rhs.m_thread_sp;
465         m_frame_sp   = rhs.m_frame_sp;
466     }
467     return *this;
468 }
469 
470 bool
operator ==(const ExecutionContext & rhs) const471 ExecutionContext::operator ==(const ExecutionContext &rhs) const
472 {
473     // Check that the frame shared pointers match, or both are valid and their stack
474     // IDs match since sometimes we get new objects that represent the same
475     // frame within a thread.
476     if ((m_frame_sp == rhs.m_frame_sp) || (m_frame_sp && rhs.m_frame_sp && m_frame_sp->GetStackID() == rhs.m_frame_sp->GetStackID()))
477     {
478         // Check that the thread shared pointers match, or both are valid and
479         // their thread IDs match since sometimes we get new objects that
480         // represent the same thread within a process.
481         if ((m_thread_sp == rhs.m_thread_sp) || (m_thread_sp && rhs.m_thread_sp && m_thread_sp->GetID() == rhs.m_thread_sp->GetID()))
482         {
483             // Processes and targets don't change much
484             return m_process_sp == rhs.m_process_sp && m_target_sp == rhs.m_target_sp;
485         }
486     }
487     return false;
488 }
489 
490 bool
operator !=(const ExecutionContext & rhs) const491 ExecutionContext::operator !=(const ExecutionContext &rhs) const
492 {
493     return !(*this == rhs);
494 }
495 
496 bool
HasTargetScope() const497 ExecutionContext::HasTargetScope () const
498 {
499     return ((bool) m_target_sp
500             && m_target_sp->IsValid());
501 }
502 
503 bool
HasProcessScope() const504 ExecutionContext::HasProcessScope () const
505 {
506     return (HasTargetScope()
507             && ((bool) m_process_sp && m_process_sp->IsValid()));
508 }
509 
510 bool
HasThreadScope() const511 ExecutionContext::HasThreadScope () const
512 {
513     return (HasProcessScope()
514            && ((bool) m_thread_sp && m_thread_sp->IsValid()));
515 }
516 
517 bool
HasFrameScope() const518 ExecutionContext::HasFrameScope () const
519 {
520     return HasThreadScope() && m_frame_sp;
521 }
522 
ExecutionContextRef()523 ExecutionContextRef::ExecutionContextRef() :
524     m_target_wp (),
525     m_process_wp (),
526     m_thread_wp (),
527     m_tid(LLDB_INVALID_THREAD_ID),
528     m_stack_id ()
529 {
530 }
531 
ExecutionContextRef(const ExecutionContext * exe_ctx)532 ExecutionContextRef::ExecutionContextRef (const ExecutionContext *exe_ctx) :
533     m_target_wp (),
534     m_process_wp (),
535     m_thread_wp (),
536     m_tid(LLDB_INVALID_THREAD_ID),
537     m_stack_id ()
538 {
539     if (exe_ctx)
540         *this = *exe_ctx;
541 }
542 
ExecutionContextRef(const ExecutionContext & exe_ctx)543 ExecutionContextRef::ExecutionContextRef (const ExecutionContext &exe_ctx) :
544     m_target_wp (),
545     m_process_wp (),
546     m_thread_wp (),
547     m_tid(LLDB_INVALID_THREAD_ID),
548     m_stack_id ()
549 {
550     *this = exe_ctx;
551 }
552 
553 
ExecutionContextRef(Target * target,bool adopt_selected)554 ExecutionContextRef::ExecutionContextRef (Target *target, bool adopt_selected) :
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     SetTargetPtr (target, adopt_selected);
562 }
563 
564 
565 
566 
ExecutionContextRef(const ExecutionContextRef & rhs)567 ExecutionContextRef::ExecutionContextRef (const ExecutionContextRef &rhs) :
568     m_target_wp (rhs.m_target_wp),
569     m_process_wp(rhs.m_process_wp),
570     m_thread_wp (rhs.m_thread_wp),
571     m_tid       (rhs.m_tid),
572     m_stack_id  (rhs.m_stack_id)
573 {
574 }
575 
576 ExecutionContextRef &
operator =(const ExecutionContextRef & rhs)577 ExecutionContextRef::operator =(const ExecutionContextRef &rhs)
578 {
579     if (this != &rhs)
580     {
581         m_target_wp  = rhs.m_target_wp;
582         m_process_wp = rhs.m_process_wp;
583         m_thread_wp  = rhs.m_thread_wp;
584         m_tid        = rhs.m_tid;
585         m_stack_id   = rhs.m_stack_id;
586     }
587     return *this;
588 }
589 
590 ExecutionContextRef &
operator =(const ExecutionContext & exe_ctx)591 ExecutionContextRef::operator =(const ExecutionContext &exe_ctx)
592 {
593     m_target_wp = exe_ctx.GetTargetSP();
594     m_process_wp = exe_ctx.GetProcessSP();
595     lldb::ThreadSP thread_sp (exe_ctx.GetThreadSP());
596     m_thread_wp = thread_sp;
597     if (thread_sp)
598         m_tid = thread_sp->GetID();
599     else
600         m_tid = LLDB_INVALID_THREAD_ID;
601     lldb::StackFrameSP frame_sp (exe_ctx.GetFrameSP());
602     if (frame_sp)
603         m_stack_id = frame_sp->GetStackID();
604     else
605         m_stack_id.Clear();
606     return *this;
607 }
608 
609 void
Clear()610 ExecutionContextRef::Clear()
611 {
612     m_target_wp.reset();
613     m_process_wp.reset();
614     ClearThread();
615     ClearFrame();
616 }
617 
~ExecutionContextRef()618 ExecutionContextRef::~ExecutionContextRef()
619 {
620 }
621 
622 void
SetTargetSP(const lldb::TargetSP & target_sp)623 ExecutionContextRef::SetTargetSP (const lldb::TargetSP &target_sp)
624 {
625     m_target_wp = target_sp;
626 }
627 
628 void
SetProcessSP(const lldb::ProcessSP & process_sp)629 ExecutionContextRef::SetProcessSP (const lldb::ProcessSP &process_sp)
630 {
631     if (process_sp)
632     {
633         m_process_wp = process_sp;
634         SetTargetSP (process_sp->GetTarget().shared_from_this());
635     }
636     else
637     {
638         m_process_wp.reset();
639         m_target_wp.reset();
640     }
641 }
642 
643 void
SetThreadSP(const lldb::ThreadSP & thread_sp)644 ExecutionContextRef::SetThreadSP (const lldb::ThreadSP &thread_sp)
645 {
646     if (thread_sp)
647     {
648         m_thread_wp = thread_sp;
649         m_tid = thread_sp->GetID();
650         SetProcessSP (thread_sp->GetProcess());
651     }
652     else
653     {
654         ClearThread();
655         m_process_wp.reset();
656         m_target_wp.reset();
657     }
658 }
659 
660 void
SetFrameSP(const lldb::StackFrameSP & frame_sp)661 ExecutionContextRef::SetFrameSP (const lldb::StackFrameSP &frame_sp)
662 {
663     if (frame_sp)
664     {
665         m_stack_id = frame_sp->GetStackID();
666         SetThreadSP (frame_sp->GetThread());
667     }
668     else
669     {
670         ClearFrame();
671         ClearThread();
672         m_process_wp.reset();
673         m_target_wp.reset();
674     }
675 
676 }
677 
678 void
SetTargetPtr(Target * target,bool adopt_selected)679 ExecutionContextRef::SetTargetPtr (Target* target, bool adopt_selected)
680 {
681     Clear();
682     if (target)
683     {
684         lldb::TargetSP target_sp (target->shared_from_this());
685         if (target_sp)
686         {
687             m_target_wp = target_sp;
688             if (adopt_selected)
689             {
690                 lldb::ProcessSP process_sp (target_sp->GetProcessSP());
691                 if (process_sp)
692                 {
693                     m_process_wp = process_sp;
694                     if (process_sp)
695                     {
696                         // Only fill in the thread and frame if our process is stopped
697                         if (StateIsStoppedState (process_sp->GetState(), true))
698                         {
699                             lldb::ThreadSP thread_sp (process_sp->GetThreadList().GetSelectedThread());
700                             if (!thread_sp)
701                                 thread_sp = process_sp->GetThreadList().GetThreadAtIndex(0);
702 
703                             if (thread_sp)
704                             {
705                                 SetThreadSP (thread_sp);
706                                 lldb::StackFrameSP frame_sp (thread_sp->GetSelectedFrame());
707                                 if (!frame_sp)
708                                     frame_sp = thread_sp->GetStackFrameAtIndex(0);
709                                 if (frame_sp)
710                                     SetFrameSP (frame_sp);
711                             }
712                         }
713                     }
714                 }
715             }
716         }
717     }
718 }
719 
720 void
SetProcessPtr(Process * process)721 ExecutionContextRef::SetProcessPtr (Process *process)
722 {
723     if (process)
724     {
725         SetProcessSP(process->shared_from_this());
726     }
727     else
728     {
729         m_process_wp.reset();
730         m_target_wp.reset();
731     }
732 }
733 
734 void
SetThreadPtr(Thread * thread)735 ExecutionContextRef::SetThreadPtr (Thread *thread)
736 {
737     if (thread)
738     {
739         SetThreadSP (thread->shared_from_this());
740     }
741     else
742     {
743         ClearThread();
744         m_process_wp.reset();
745         m_target_wp.reset();
746     }
747 }
748 
749 void
SetFramePtr(StackFrame * frame)750 ExecutionContextRef::SetFramePtr (StackFrame *frame)
751 {
752     if (frame)
753         SetFrameSP (frame->shared_from_this());
754     else
755         Clear();
756 }
757 
758 lldb::TargetSP
GetTargetSP() const759 ExecutionContextRef::GetTargetSP () const
760 {
761     lldb::TargetSP target_sp(m_target_wp.lock());
762     if (target_sp && !target_sp->IsValid())
763         target_sp.reset();
764     return target_sp;
765 }
766 
767 lldb::ProcessSP
GetProcessSP() const768 ExecutionContextRef::GetProcessSP () const
769 {
770     lldb::ProcessSP process_sp(m_process_wp.lock());
771     if (process_sp && !process_sp->IsValid())
772         process_sp.reset();
773     return process_sp;
774 }
775 
776 lldb::ThreadSP
GetThreadSP() const777 ExecutionContextRef::GetThreadSP () const
778 {
779     lldb::ThreadSP thread_sp (m_thread_wp.lock());
780 
781     if (m_tid != LLDB_INVALID_THREAD_ID)
782     {
783         // We check if the thread has been destroyed in cases where clients
784         // might still have shared pointer to a thread, but the thread is
785         // not valid anymore (not part of the process)
786         if (!thread_sp || !thread_sp->IsValid())
787         {
788             lldb::ProcessSP process_sp(GetProcessSP());
789             if (process_sp && process_sp->IsValid())
790             {
791                 thread_sp = process_sp->GetThreadList().FindThreadByID(m_tid);
792                 m_thread_wp = thread_sp;
793             }
794         }
795     }
796 
797     // Check that we aren't about to return an invalid thread sp.  We might return a NULL thread_sp,
798     // but don't return an invalid one.
799 
800     if (thread_sp && !thread_sp->IsValid())
801         thread_sp.reset();
802 
803     return thread_sp;
804 }
805 
806 lldb::StackFrameSP
GetFrameSP() const807 ExecutionContextRef::GetFrameSP () const
808 {
809     if (m_stack_id.IsValid())
810     {
811         lldb::ThreadSP thread_sp (GetThreadSP());
812         if (thread_sp)
813             return thread_sp->GetFrameWithStackID (m_stack_id);
814     }
815     return lldb::StackFrameSP();
816 }
817 
818 ExecutionContext
Lock() const819 ExecutionContextRef::Lock () const
820 {
821     return ExecutionContext(this);
822 }
823 
824 
825