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 (ExecutionContextScope *exe_scope_ptr) :
173     m_target_sp (),
174     m_process_sp (),
175     m_thread_sp (),
176     m_frame_sp ()
177 {
178     if (exe_scope_ptr)
179         exe_scope_ptr->CalculateExecutionContext (*this);
180 }
181 
182 ExecutionContext::ExecutionContext (ExecutionContextScope &exe_scope_ref)
183 {
184     exe_scope_ref.CalculateExecutionContext (*this);
185 }
186 
187 void
188 ExecutionContext::Clear()
189 {
190     m_target_sp.reset();
191     m_process_sp.reset();
192     m_thread_sp.reset();
193     m_frame_sp.reset();
194 }
195 
196 ExecutionContext::~ExecutionContext()
197 {
198 }
199 
200 uint32_t
201 ExecutionContext::GetAddressByteSize() const
202 {
203     if (m_target_sp && m_target_sp->GetArchitecture().IsValid())
204         m_target_sp->GetArchitecture().GetAddressByteSize();
205     if (m_process_sp)
206         m_process_sp->GetAddressByteSize();
207     return sizeof(void *);
208 }
209 
210 
211 
212 RegisterContext *
213 ExecutionContext::GetRegisterContext () const
214 {
215     if (m_frame_sp)
216         return m_frame_sp->GetRegisterContext().get();
217     else if (m_thread_sp)
218         return m_thread_sp->GetRegisterContext().get();
219     return NULL;
220 }
221 
222 Target *
223 ExecutionContext::GetTargetPtr () const
224 {
225     if (m_target_sp)
226         return m_target_sp.get();
227     if (m_process_sp)
228         return &m_process_sp->GetTarget();
229     return NULL;
230 }
231 
232 Process *
233 ExecutionContext::GetProcessPtr () const
234 {
235     if (m_process_sp)
236         return m_process_sp.get();
237     if (m_target_sp)
238         return m_target_sp->GetProcessSP().get();
239     return NULL;
240 }
241 
242 ExecutionContextScope *
243 ExecutionContext::GetBestExecutionContextScope () const
244 {
245     if (m_frame_sp)
246         return m_frame_sp.get();
247     if (m_thread_sp)
248         return m_thread_sp.get();
249     if (m_process_sp)
250         return m_process_sp.get();
251     return m_target_sp.get();
252 }
253 
254 Target &
255 ExecutionContext::GetTargetRef () const
256 {
257 #if defined (LLDB_CONFIGURATION_DEBUG) || defined (LLDB_CONFIGURATION_RELEASE)
258     assert (m_target_sp.get());
259 #endif
260     return *m_target_sp;
261 }
262 
263 Process &
264 ExecutionContext::GetProcessRef () const
265 {
266 #if defined (LLDB_CONFIGURATION_DEBUG) || defined (LLDB_CONFIGURATION_RELEASE)
267     assert (m_process_sp.get());
268 #endif
269     return *m_process_sp;
270 }
271 
272 Thread &
273 ExecutionContext::GetThreadRef () const
274 {
275 #if defined (LLDB_CONFIGURATION_DEBUG) || defined (LLDB_CONFIGURATION_RELEASE)
276     assert (m_thread_sp.get());
277 #endif
278     return *m_thread_sp;
279 }
280 
281 StackFrame &
282 ExecutionContext::GetFrameRef () const
283 {
284 #if defined (LLDB_CONFIGURATION_DEBUG) || defined (LLDB_CONFIGURATION_RELEASE)
285     assert (m_frame_sp.get());
286 #endif
287     return *m_frame_sp;
288 }
289 
290 void
291 ExecutionContext::SetTargetSP (const lldb::TargetSP &target_sp)
292 {
293     m_target_sp = target_sp;
294 }
295 
296 void
297 ExecutionContext::SetProcessSP (const lldb::ProcessSP &process_sp)
298 {
299     m_process_sp = process_sp;
300 }
301 
302 void
303 ExecutionContext::SetThreadSP (const lldb::ThreadSP &thread_sp)
304 {
305     m_thread_sp = thread_sp;
306 }
307 
308 void
309 ExecutionContext::SetFrameSP (const lldb::StackFrameSP &frame_sp)
310 {
311     m_frame_sp = frame_sp;
312 }
313 
314 void
315 ExecutionContext::SetTargetPtr (Target* target)
316 {
317     if (target)
318         m_target_sp = target->shared_from_this();
319     else
320         m_target_sp.reset();
321 }
322 
323 void
324 ExecutionContext::SetProcessPtr (Process *process)
325 {
326     if (process)
327         m_process_sp = process->shared_from_this();
328     else
329         m_process_sp.reset();
330 }
331 
332 void
333 ExecutionContext::SetThreadPtr (Thread *thread)
334 {
335     if (thread)
336         m_thread_sp = thread->shared_from_this();
337     else
338         m_thread_sp.reset();
339 }
340 
341 void
342 ExecutionContext::SetFramePtr (StackFrame *frame)
343 {
344     if (frame)
345         m_frame_sp = frame->shared_from_this();
346     else
347         m_frame_sp.reset();
348 }
349 
350 void
351 ExecutionContext::SetContext (const lldb::TargetSP &target_sp, bool get_process)
352 {
353     m_target_sp = target_sp;
354     if (get_process && target_sp)
355         m_process_sp = target_sp->GetProcessSP();
356     else
357         m_process_sp.reset();
358     m_thread_sp.reset();
359     m_frame_sp.reset();
360 }
361 
362 void
363 ExecutionContext::SetContext (const lldb::ProcessSP &process_sp)
364 {
365     m_process_sp = process_sp;
366     if (process_sp)
367         m_target_sp = process_sp->GetTarget().shared_from_this();
368     else
369         m_target_sp.reset();
370     m_thread_sp.reset();
371     m_frame_sp.reset();
372 }
373 
374 void
375 ExecutionContext::SetContext (const lldb::ThreadSP &thread_sp)
376 {
377     m_frame_sp.reset();
378     m_thread_sp = thread_sp;
379     if (thread_sp)
380     {
381         m_process_sp = thread_sp->GetProcess();
382         if (m_process_sp)
383             m_target_sp = m_process_sp->GetTarget().shared_from_this();
384         else
385             m_target_sp.reset();
386     }
387     else
388     {
389         m_target_sp.reset();
390         m_process_sp.reset();
391     }
392 }
393 
394 void
395 ExecutionContext::SetContext (const lldb::StackFrameSP &frame_sp)
396 {
397     m_frame_sp = frame_sp;
398     if (frame_sp)
399     {
400         m_thread_sp = frame_sp->CalculateThread();
401         if (m_thread_sp)
402         {
403             m_process_sp = m_thread_sp->GetProcess();
404             if (m_process_sp)
405                 m_target_sp = m_process_sp->GetTarget().shared_from_this();
406             else
407                 m_target_sp.reset();
408         }
409         else
410         {
411             m_target_sp.reset();
412             m_process_sp.reset();
413         }
414     }
415     else
416     {
417         m_target_sp.reset();
418         m_process_sp.reset();
419         m_thread_sp.reset();
420     }
421 }
422 
423 ExecutionContext &
424 ExecutionContext::operator =(const ExecutionContext &rhs)
425 {
426     if (this != &rhs)
427     {
428         m_target_sp  = rhs.m_target_sp;
429         m_process_sp = rhs.m_process_sp;
430         m_thread_sp  = rhs.m_thread_sp;
431         m_frame_sp   = rhs.m_frame_sp;
432     }
433     return *this;
434 }
435 
436 bool
437 ExecutionContext::operator ==(const ExecutionContext &rhs) const
438 {
439     // Check that the frame shared pointers match, or both are valid and their stack
440     // IDs match since sometimes we get new objects that represent the same
441     // frame within a thread.
442     if ((m_frame_sp == rhs.m_frame_sp) || (m_frame_sp && rhs.m_frame_sp && m_frame_sp->GetStackID() == rhs.m_frame_sp->GetStackID()))
443     {
444         // Check that the thread shared pointers match, or both are valid and
445         // their thread IDs match since sometimes we get new objects that
446         // represent the same thread within a process.
447         if ((m_thread_sp == rhs.m_thread_sp) || (m_thread_sp && rhs.m_thread_sp && m_thread_sp->GetID() == rhs.m_thread_sp->GetID()))
448         {
449             // Processes and targets don't change much
450             return m_process_sp == rhs.m_process_sp && m_target_sp == rhs.m_target_sp;
451         }
452     }
453     return false;
454 }
455 
456 bool
457 ExecutionContext::operator !=(const ExecutionContext &rhs) const
458 {
459     return !(*this == rhs);
460 }
461 
462 
463 ExecutionContextRef::ExecutionContextRef() :
464     m_target_wp (),
465     m_process_wp (),
466     m_thread_wp (),
467     m_frame_wp (),
468     m_tid(LLDB_INVALID_THREAD_ID),
469     m_stack_id ()
470 {
471 }
472 
473 ExecutionContextRef::ExecutionContextRef (const ExecutionContext *exe_ctx) :
474     m_target_wp (),
475     m_process_wp (),
476     m_thread_wp (),
477     m_frame_wp (),
478     m_tid(LLDB_INVALID_THREAD_ID),
479     m_stack_id ()
480 {
481     if (exe_ctx)
482         *this = *exe_ctx;
483 }
484 
485 ExecutionContextRef::ExecutionContextRef (const ExecutionContext &exe_ctx) :
486     m_target_wp (),
487     m_process_wp (),
488     m_thread_wp (),
489     m_frame_wp (),
490     m_tid(LLDB_INVALID_THREAD_ID),
491     m_stack_id ()
492 {
493     *this = exe_ctx;
494 }
495 
496 
497 ExecutionContextRef::ExecutionContextRef (Target *target, bool adopt_selected) :
498     m_target_wp(),
499     m_process_wp(),
500     m_thread_wp(),
501     m_frame_wp(),
502     m_tid(LLDB_INVALID_THREAD_ID),
503     m_stack_id ()
504 {
505     SetTargetPtr (target, adopt_selected);
506 }
507 
508 
509 
510 
511 ExecutionContextRef::ExecutionContextRef (const ExecutionContextRef &rhs) :
512     m_target_wp (rhs.m_target_wp),
513     m_process_wp(rhs.m_process_wp),
514     m_thread_wp (rhs.m_thread_wp),
515     m_frame_wp  (rhs.m_frame_wp),
516     m_tid       (rhs.m_tid),
517     m_stack_id  (rhs.m_stack_id)
518 {
519 }
520 
521 ExecutionContextRef &
522 ExecutionContextRef::operator =(const ExecutionContextRef &rhs)
523 {
524     if (this != &rhs)
525     {
526         m_target_wp  = rhs.m_target_wp;
527         m_process_wp = rhs.m_process_wp;
528         m_thread_wp  = rhs.m_thread_wp;
529         m_frame_wp   = rhs.m_frame_wp;
530         m_tid        = rhs.m_tid;
531         m_stack_id   = rhs.m_stack_id;
532     }
533     return *this;
534 }
535 
536 ExecutionContextRef &
537 ExecutionContextRef::operator =(const ExecutionContext &exe_ctx)
538 {
539     m_target_wp = exe_ctx.GetTargetSP();
540     m_process_wp = exe_ctx.GetProcessSP();
541     lldb::ThreadSP thread_sp (exe_ctx.GetThreadSP());
542     m_thread_wp = thread_sp;
543     if (thread_sp)
544         m_tid = thread_sp->GetID();
545     else
546         m_tid = LLDB_INVALID_THREAD_ID;
547     lldb::StackFrameSP frame_sp (exe_ctx.GetFrameSP());
548     m_frame_wp = frame_sp;
549     if (frame_sp)
550         m_stack_id = frame_sp->GetStackID();
551     else
552         m_stack_id.Clear();
553     return *this;
554 }
555 
556 void
557 ExecutionContextRef::Clear()
558 {
559     m_target_wp.reset();
560     m_process_wp.reset();
561     ClearThread();
562     ClearFrame();
563 }
564 
565 ExecutionContextRef::~ExecutionContextRef()
566 {
567 }
568 
569 void
570 ExecutionContextRef::SetTargetSP (const lldb::TargetSP &target_sp)
571 {
572     m_target_wp = target_sp;
573 }
574 
575 void
576 ExecutionContextRef::SetProcessSP (const lldb::ProcessSP &process_sp)
577 {
578     if (process_sp)
579     {
580         m_process_wp = process_sp;
581         SetTargetSP (process_sp->GetTarget().shared_from_this());
582     }
583     else
584     {
585         m_process_wp.reset();
586         m_target_wp.reset();
587     }
588 }
589 
590 void
591 ExecutionContextRef::SetThreadSP (const lldb::ThreadSP &thread_sp)
592 {
593     if (thread_sp)
594     {
595         m_thread_wp = thread_sp;
596         m_tid = thread_sp->GetID();
597         SetProcessSP (thread_sp->GetProcess());
598     }
599     else
600     {
601         ClearThread();
602         m_process_wp.reset();
603         m_target_wp.reset();
604     }
605 }
606 
607 void
608 ExecutionContextRef::SetFrameSP (const lldb::StackFrameSP &frame_sp)
609 {
610     if (frame_sp)
611     {
612         m_frame_wp = frame_sp;
613         m_stack_id = frame_sp->GetStackID();
614         SetThreadSP (frame_sp->GetThread());
615     }
616     else
617     {
618         ClearFrame();
619         ClearThread();
620         m_process_wp.reset();
621         m_target_wp.reset();
622     }
623 
624 }
625 
626 void
627 ExecutionContextRef::SetTargetPtr (Target* target, bool adopt_selected)
628 {
629     Clear();
630     if (target)
631     {
632         lldb::TargetSP target_sp (target->shared_from_this());
633         if (target_sp)
634         {
635             m_target_wp = target_sp;
636             if (adopt_selected)
637             {
638                 lldb::ProcessSP process_sp (target_sp->GetProcessSP());
639                 if (process_sp)
640                 {
641                     m_process_wp = process_sp;
642                     if (process_sp)
643                     {
644                         // Only fill in the thread and frame if our process is stopped
645                         if (StateIsStoppedState (process_sp->GetState(), true))
646                         {
647                             lldb::ThreadSP thread_sp (process_sp->GetThreadList().GetSelectedThread());
648                             if (!thread_sp)
649                                 thread_sp = process_sp->GetThreadList().GetThreadAtIndex(0);
650 
651                             if (thread_sp)
652                             {
653                                 SetThreadSP (thread_sp);
654                                 lldb::StackFrameSP frame_sp (thread_sp->GetSelectedFrame());
655                                 if (!frame_sp)
656                                     frame_sp = thread_sp->GetStackFrameAtIndex(0);
657                                 if (frame_sp)
658                                     SetFrameSP (frame_sp);
659                             }
660                         }
661                     }
662                 }
663             }
664         }
665     }
666 }
667 
668 void
669 ExecutionContextRef::SetProcessPtr (Process *process)
670 {
671     if (process)
672     {
673         SetProcessSP(process->shared_from_this());
674     }
675     else
676     {
677         m_process_wp.reset();
678         m_target_wp.reset();
679     }
680 }
681 
682 void
683 ExecutionContextRef::SetThreadPtr (Thread *thread)
684 {
685     if (thread)
686     {
687         SetThreadSP (thread->shared_from_this());
688     }
689     else
690     {
691         ClearThread();
692         m_process_wp.reset();
693         m_target_wp.reset();
694     }
695 }
696 
697 void
698 ExecutionContextRef::SetFramePtr (StackFrame *frame)
699 {
700     if (frame)
701         SetFrameSP (frame->shared_from_this());
702     else
703         Clear();
704 }
705 
706 
707 lldb::ThreadSP
708 ExecutionContextRef::GetThreadSP () const
709 {
710     lldb::ThreadSP thread_sp (m_thread_wp.lock());
711     if (m_tid != LLDB_INVALID_THREAD_ID)
712     {
713         // We check if the thread has been destroyed in cases where clients
714         // might still have shared pointer to a thread, but the thread is
715         // not valid anymore (not part of the process)
716         if (!thread_sp || !thread_sp->IsValid())
717         {
718             lldb::ProcessSP process_sp(GetProcessSP());
719             if (process_sp)
720             {
721                 thread_sp = process_sp->GetThreadList().FindThreadByID(m_tid);
722                 m_thread_wp = thread_sp;
723             }
724         }
725     }
726     return thread_sp;
727 }
728 
729 lldb::StackFrameSP
730 ExecutionContextRef::GetFrameSP () const
731 {
732     lldb::StackFrameSP frame_sp (m_frame_wp.lock());
733     if (!frame_sp && m_stack_id.IsValid())
734     {
735         lldb::ThreadSP thread_sp (GetThreadSP());
736         if (thread_sp)
737         {
738             frame_sp = thread_sp->GetFrameWithStackID (m_stack_id);
739             m_frame_wp = frame_sp;
740         }
741     }
742     return frame_sp;
743 }
744 
745 ExecutionContext
746 ExecutionContextRef::Lock () const
747 {
748     return ExecutionContext(this);
749 }
750 
751 
752