ExecutionContext.cpp revision 263363
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
19using namespace lldb_private;
20
21ExecutionContext::ExecutionContext() :
22    m_target_sp (),
23    m_process_sp (),
24    m_thread_sp (),
25    m_frame_sp ()
26{
27}
28
29ExecutionContext::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
37ExecutionContext::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
47ExecutionContext::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
57ExecutionContext::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
67ExecutionContext::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
77ExecutionContext::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
88ExecutionContext::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
99ExecutionContext::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
110ExecutionContext::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
121ExecutionContext::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
139ExecutionContext::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
149ExecutionContext::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
157ExecutionContext::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
172ExecutionContext::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
191ExecutionContext::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
206ExecutionContext::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
216ExecutionContext::ExecutionContext (ExecutionContextScope &exe_scope_ref)
217{
218    exe_scope_ref.CalculateExecutionContext (*this);
219}
220
221void
222ExecutionContext::Clear()
223{
224    m_target_sp.reset();
225    m_process_sp.reset();
226    m_thread_sp.reset();
227    m_frame_sp.reset();
228}
229
230ExecutionContext::~ExecutionContext()
231{
232}
233
234uint32_t
235ExecutionContext::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
244lldb::ByteOrder
245ExecutionContext::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
254RegisterContext *
255ExecutionContext::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
264Target *
265ExecutionContext::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
274Process *
275ExecutionContext::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
284ExecutionContextScope *
285ExecutionContext::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
296Target &
297ExecutionContext::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
305Process &
306ExecutionContext::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
314Thread &
315ExecutionContext::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
323StackFrame &
324ExecutionContext::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
332void
333ExecutionContext::SetTargetSP (const lldb::TargetSP &target_sp)
334{
335    m_target_sp = target_sp;
336}
337
338void
339ExecutionContext::SetProcessSP (const lldb::ProcessSP &process_sp)
340{
341    m_process_sp = process_sp;
342}
343
344void
345ExecutionContext::SetThreadSP (const lldb::ThreadSP &thread_sp)
346{
347    m_thread_sp = thread_sp;
348}
349
350void
351ExecutionContext::SetFrameSP (const lldb::StackFrameSP &frame_sp)
352{
353    m_frame_sp = frame_sp;
354}
355
356void
357ExecutionContext::SetTargetPtr (Target* target)
358{
359    if (target)
360        m_target_sp = target->shared_from_this();
361    else
362        m_target_sp.reset();
363}
364
365void
366ExecutionContext::SetProcessPtr (Process *process)
367{
368    if (process)
369        m_process_sp = process->shared_from_this();
370    else
371        m_process_sp.reset();
372}
373
374void
375ExecutionContext::SetThreadPtr (Thread *thread)
376{
377    if (thread)
378        m_thread_sp = thread->shared_from_this();
379    else
380        m_thread_sp.reset();
381}
382
383void
384ExecutionContext::SetFramePtr (StackFrame *frame)
385{
386    if (frame)
387        m_frame_sp = frame->shared_from_this();
388    else
389        m_frame_sp.reset();
390}
391
392void
393ExecutionContext::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
404void
405ExecutionContext::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
416void
417ExecutionContext::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
436void
437ExecutionContext::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
465ExecutionContext &
466ExecutionContext::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
478bool
479ExecutionContext::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
498bool
499ExecutionContext::operator !=(const ExecutionContext &rhs) const
500{
501    return !(*this == rhs);
502}
503
504bool
505ExecutionContext::HasTargetScope () const
506{
507    return ((bool) m_target_sp
508            && m_target_sp->IsValid());
509}
510
511bool
512ExecutionContext::HasProcessScope () const
513{
514    return (HasTargetScope()
515            && ((bool) m_process_sp && m_process_sp->IsValid()));
516}
517
518bool
519ExecutionContext::HasThreadScope () const
520{
521    return (HasProcessScope()
522           && ((bool) m_thread_sp && m_thread_sp->IsValid()));
523}
524
525bool
526ExecutionContext::HasFrameScope () const
527{
528    return HasThreadScope() && m_frame_sp;
529}
530
531ExecutionContextRef::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
540ExecutionContextRef::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
551ExecutionContextRef::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
562ExecutionContextRef::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
575ExecutionContextRef::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
584ExecutionContextRef &
585ExecutionContextRef::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
598ExecutionContextRef &
599ExecutionContextRef::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
617void
618ExecutionContextRef::Clear()
619{
620    m_target_wp.reset();
621    m_process_wp.reset();
622    ClearThread();
623    ClearFrame();
624}
625
626ExecutionContextRef::~ExecutionContextRef()
627{
628}
629
630void
631ExecutionContextRef::SetTargetSP (const lldb::TargetSP &target_sp)
632{
633    m_target_wp = target_sp;
634}
635
636void
637ExecutionContextRef::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
651void
652ExecutionContextRef::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
668void
669ExecutionContextRef::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
686void
687ExecutionContextRef::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
728void
729ExecutionContextRef::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
742void
743ExecutionContextRef::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
757void
758ExecutionContextRef::SetFramePtr (StackFrame *frame)
759{
760    if (frame)
761        SetFrameSP (frame->shared_from_this());
762    else
763        Clear();
764}
765
766lldb::TargetSP
767ExecutionContextRef::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
775lldb::ProcessSP
776ExecutionContextRef::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
784lldb::ThreadSP
785ExecutionContextRef::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
814lldb::StackFrameSP
815ExecutionContextRef::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
826ExecutionContext
827ExecutionContextRef::Lock () const
828{
829    return ExecutionContext(this);
830}
831
832
833