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