xref: /src/contrib/llvm-project/lldb/source/API/SBFrame.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1cfca06d7SDimitry Andric //===-- SBFrame.cpp -------------------------------------------------------===//
2f034231aSEd Maste //
35f29bb8aSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45f29bb8aSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
55f29bb8aSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6f034231aSEd Maste //
7f034231aSEd Maste //===----------------------------------------------------------------------===//
8f034231aSEd Maste 
9f034231aSEd Maste #include <algorithm>
10f3fbd1c0SDimitry Andric #include <set>
11e81d9d49SDimitry Andric #include <string>
12e81d9d49SDimitry Andric 
13e81d9d49SDimitry Andric #include "lldb/API/SBFrame.h"
14f034231aSEd Maste 
15f034231aSEd Maste #include "lldb/lldb-types.h"
16f034231aSEd Maste 
175f29bb8aSDimitry Andric #include "Utils.h"
18f034231aSEd Maste #include "lldb/Core/Address.h"
197fa27ce4SDimitry Andric #include "lldb/Core/Debugger.h"
20f034231aSEd Maste #include "lldb/Core/ValueObjectRegister.h"
21f034231aSEd Maste #include "lldb/Core/ValueObjectVariable.h"
227fa27ce4SDimitry Andric #include "lldb/Core/ValueObjectConstResult.h"
235f29bb8aSDimitry Andric #include "lldb/Expression/ExpressionVariable.h"
24e81d9d49SDimitry Andric #include "lldb/Expression/UserExpression.h"
25f034231aSEd Maste #include "lldb/Host/Host.h"
26f034231aSEd Maste #include "lldb/Symbol/Block.h"
27f034231aSEd Maste #include "lldb/Symbol/Function.h"
28f034231aSEd Maste #include "lldb/Symbol/Symbol.h"
29f034231aSEd Maste #include "lldb/Symbol/SymbolContext.h"
30f034231aSEd Maste #include "lldb/Symbol/Variable.h"
3114f1b3e8SDimitry Andric #include "lldb/Symbol/VariableList.h"
32f034231aSEd Maste #include "lldb/Target/ExecutionContext.h"
33f034231aSEd Maste #include "lldb/Target/Process.h"
34f034231aSEd Maste #include "lldb/Target/RegisterContext.h"
35f034231aSEd Maste #include "lldb/Target/StackFrame.h"
3694994d37SDimitry Andric #include "lldb/Target/StackFrameRecognizer.h"
37f034231aSEd Maste #include "lldb/Target/StackID.h"
3814f1b3e8SDimitry Andric #include "lldb/Target/Target.h"
39f034231aSEd Maste #include "lldb/Target/Thread.h"
4074a628f7SDimitry Andric #include "lldb/Utility/ConstString.h"
416f8fc217SDimitry Andric #include "lldb/Utility/Instrumentation.h"
42145449b1SDimitry Andric #include "lldb/Utility/LLDBLog.h"
4374a628f7SDimitry Andric #include "lldb/Utility/Stream.h"
44f034231aSEd Maste 
45f034231aSEd Maste #include "lldb/API/SBAddress.h"
4614f1b3e8SDimitry Andric #include "lldb/API/SBDebugger.h"
47f034231aSEd Maste #include "lldb/API/SBExpressionOptions.h"
48b1c73532SDimitry Andric #include "lldb/API/SBFormat.h"
49f034231aSEd Maste #include "lldb/API/SBStream.h"
50f034231aSEd Maste #include "lldb/API/SBSymbolContext.h"
51f034231aSEd Maste #include "lldb/API/SBThread.h"
5214f1b3e8SDimitry Andric #include "lldb/API/SBValue.h"
535e95aa85SEd Maste #include "lldb/API/SBVariablesOptions.h"
54f034231aSEd Maste 
5514f1b3e8SDimitry Andric #include "llvm/Support/PrettyStackTrace.h"
5614f1b3e8SDimitry Andric 
57f034231aSEd Maste using namespace lldb;
58f034231aSEd Maste using namespace lldb_private;
59f034231aSEd Maste 
SBFrame()605f29bb8aSDimitry Andric SBFrame::SBFrame() : m_opaque_sp(new ExecutionContextRef()) {
616f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
625f29bb8aSDimitry Andric }
63f034231aSEd Maste 
SBFrame(const StackFrameSP & lldb_object_sp)6414f1b3e8SDimitry Andric SBFrame::SBFrame(const StackFrameSP &lldb_object_sp)
6514f1b3e8SDimitry Andric     : m_opaque_sp(new ExecutionContextRef(lldb_object_sp)) {
666f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, lldb_object_sp);
67f034231aSEd Maste }
68f034231aSEd Maste 
SBFrame(const SBFrame & rhs)696f8fc217SDimitry Andric SBFrame::SBFrame(const SBFrame &rhs) {
706f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, rhs);
715f29bb8aSDimitry Andric 
725f29bb8aSDimitry Andric   m_opaque_sp = clone(rhs.m_opaque_sp);
735f29bb8aSDimitry Andric }
74f034231aSEd Maste 
75e81d9d49SDimitry Andric SBFrame::~SBFrame() = default;
76e81d9d49SDimitry Andric 
operator =(const SBFrame & rhs)7714f1b3e8SDimitry Andric const SBFrame &SBFrame::operator=(const SBFrame &rhs) {
786f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, rhs);
795f29bb8aSDimitry Andric 
80f034231aSEd Maste   if (this != &rhs)
815f29bb8aSDimitry Andric     m_opaque_sp = clone(rhs.m_opaque_sp);
826f8fc217SDimitry Andric   return *this;
83f034231aSEd Maste }
84f034231aSEd Maste 
GetFrameSP() const8514f1b3e8SDimitry Andric StackFrameSP SBFrame::GetFrameSP() const {
86e81d9d49SDimitry Andric   return (m_opaque_sp ? m_opaque_sp->GetFrameSP() : StackFrameSP());
87f034231aSEd Maste }
88f034231aSEd Maste 
SetFrameSP(const StackFrameSP & lldb_object_sp)8914f1b3e8SDimitry Andric void SBFrame::SetFrameSP(const StackFrameSP &lldb_object_sp) {
90f034231aSEd Maste   return m_opaque_sp->SetFrameSP(lldb_object_sp);
91f034231aSEd Maste }
92f034231aSEd Maste 
IsValid() const9314f1b3e8SDimitry Andric bool SBFrame::IsValid() const {
946f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
955f29bb8aSDimitry Andric   return this->operator bool();
965f29bb8aSDimitry Andric }
operator bool() const975f29bb8aSDimitry Andric SBFrame::operator bool() const {
986f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
995f29bb8aSDimitry Andric 
100f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
101f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
102f3fbd1c0SDimitry Andric 
103f3fbd1c0SDimitry Andric   Target *target = exe_ctx.GetTargetPtr();
104f3fbd1c0SDimitry Andric   Process *process = exe_ctx.GetProcessPtr();
10514f1b3e8SDimitry Andric   if (target && process) {
106f3fbd1c0SDimitry Andric     Process::StopLocker stop_locker;
107f3fbd1c0SDimitry Andric     if (stop_locker.TryLock(&process->GetRunLock()))
108e81d9d49SDimitry Andric       return GetFrameSP().get() != nullptr;
109f034231aSEd Maste   }
110f034231aSEd Maste 
111f3fbd1c0SDimitry Andric   // Without a target & process we can't have a valid stack frame.
112f3fbd1c0SDimitry Andric   return false;
113f3fbd1c0SDimitry Andric }
114f3fbd1c0SDimitry Andric 
GetSymbolContext(uint32_t resolve_scope) const11514f1b3e8SDimitry Andric SBSymbolContext SBFrame::GetSymbolContext(uint32_t resolve_scope) const {
1166f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, resolve_scope);
1175f29bb8aSDimitry Andric 
118f034231aSEd Maste   SBSymbolContext sb_sym_ctx;
119f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
120f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
12194994d37SDimitry Andric   SymbolContextItem scope = static_cast<SymbolContextItem>(resolve_scope);
122f034231aSEd Maste   Target *target = exe_ctx.GetTargetPtr();
123f034231aSEd Maste   Process *process = exe_ctx.GetProcessPtr();
12414f1b3e8SDimitry Andric   if (target && process) {
125f034231aSEd Maste     Process::StopLocker stop_locker;
12614f1b3e8SDimitry Andric     if (stop_locker.TryLock(&process->GetRunLock())) {
12777fc4c14SDimitry Andric       if (StackFrame *frame = exe_ctx.GetFramePtr())
12877fc4c14SDimitry Andric         sb_sym_ctx = frame->GetSymbolContext(scope);
129f034231aSEd Maste     }
130f034231aSEd Maste   }
131f034231aSEd Maste 
1326f8fc217SDimitry Andric   return sb_sym_ctx;
133f034231aSEd Maste }
134f034231aSEd Maste 
GetModule() const13514f1b3e8SDimitry Andric SBModule SBFrame::GetModule() const {
1366f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
1375f29bb8aSDimitry Andric 
138f034231aSEd Maste   SBModule sb_module;
139f034231aSEd Maste   ModuleSP module_sp;
140f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
141f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
142f034231aSEd Maste 
143e81d9d49SDimitry Andric   StackFrame *frame = nullptr;
144f034231aSEd Maste   Target *target = exe_ctx.GetTargetPtr();
145f034231aSEd Maste   Process *process = exe_ctx.GetProcessPtr();
14614f1b3e8SDimitry Andric   if (target && process) {
147f034231aSEd Maste     Process::StopLocker stop_locker;
14814f1b3e8SDimitry Andric     if (stop_locker.TryLock(&process->GetRunLock())) {
149f034231aSEd Maste       frame = exe_ctx.GetFramePtr();
15014f1b3e8SDimitry Andric       if (frame) {
151f034231aSEd Maste         module_sp = frame->GetSymbolContext(eSymbolContextModule).module_sp;
152f034231aSEd Maste         sb_module.SetSP(module_sp);
153f034231aSEd Maste       }
154f034231aSEd Maste     }
155f034231aSEd Maste   }
156f034231aSEd Maste 
1576f8fc217SDimitry Andric   return sb_module;
158f034231aSEd Maste }
159f034231aSEd Maste 
GetCompileUnit() const16014f1b3e8SDimitry Andric SBCompileUnit SBFrame::GetCompileUnit() const {
1616f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
1625f29bb8aSDimitry Andric 
163f034231aSEd Maste   SBCompileUnit sb_comp_unit;
164f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
165f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
166f034231aSEd Maste 
167e81d9d49SDimitry Andric   StackFrame *frame = nullptr;
168f034231aSEd Maste   Target *target = exe_ctx.GetTargetPtr();
169f034231aSEd Maste   Process *process = exe_ctx.GetProcessPtr();
17014f1b3e8SDimitry Andric   if (target && process) {
171f034231aSEd Maste     Process::StopLocker stop_locker;
17214f1b3e8SDimitry Andric     if (stop_locker.TryLock(&process->GetRunLock())) {
173f034231aSEd Maste       frame = exe_ctx.GetFramePtr();
17414f1b3e8SDimitry Andric       if (frame) {
17514f1b3e8SDimitry Andric         sb_comp_unit.reset(
17614f1b3e8SDimitry Andric             frame->GetSymbolContext(eSymbolContextCompUnit).comp_unit);
177f034231aSEd Maste       }
178f034231aSEd Maste     }
1795f29bb8aSDimitry Andric   }
180f034231aSEd Maste 
1816f8fc217SDimitry Andric   return sb_comp_unit;
182f034231aSEd Maste }
183f034231aSEd Maste 
GetFunction() const18414f1b3e8SDimitry Andric SBFunction SBFrame::GetFunction() const {
1856f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
1865f29bb8aSDimitry Andric 
187f034231aSEd Maste   SBFunction sb_function;
188f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
189f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
190f034231aSEd Maste 
191e81d9d49SDimitry Andric   StackFrame *frame = nullptr;
192f034231aSEd Maste   Target *target = exe_ctx.GetTargetPtr();
193f034231aSEd Maste   Process *process = exe_ctx.GetProcessPtr();
19414f1b3e8SDimitry Andric   if (target && process) {
195f034231aSEd Maste     Process::StopLocker stop_locker;
19614f1b3e8SDimitry Andric     if (stop_locker.TryLock(&process->GetRunLock())) {
197f034231aSEd Maste       frame = exe_ctx.GetFramePtr();
19814f1b3e8SDimitry Andric       if (frame) {
19914f1b3e8SDimitry Andric         sb_function.reset(
20014f1b3e8SDimitry Andric             frame->GetSymbolContext(eSymbolContextFunction).function);
201f034231aSEd Maste       }
202f034231aSEd Maste     }
2035f29bb8aSDimitry Andric   }
204f034231aSEd Maste 
2056f8fc217SDimitry Andric   return sb_function;
206f034231aSEd Maste }
207f034231aSEd Maste 
GetSymbol() const20814f1b3e8SDimitry Andric SBSymbol SBFrame::GetSymbol() const {
2096f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
2105f29bb8aSDimitry Andric 
211f034231aSEd Maste   SBSymbol sb_symbol;
212f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
213f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
214f034231aSEd Maste 
215e81d9d49SDimitry Andric   StackFrame *frame = nullptr;
216f034231aSEd Maste   Target *target = exe_ctx.GetTargetPtr();
217f034231aSEd Maste   Process *process = exe_ctx.GetProcessPtr();
21814f1b3e8SDimitry Andric   if (target && process) {
219f034231aSEd Maste     Process::StopLocker stop_locker;
22014f1b3e8SDimitry Andric     if (stop_locker.TryLock(&process->GetRunLock())) {
221f034231aSEd Maste       frame = exe_ctx.GetFramePtr();
22214f1b3e8SDimitry Andric       if (frame) {
223f034231aSEd Maste         sb_symbol.reset(frame->GetSymbolContext(eSymbolContextSymbol).symbol);
224f034231aSEd Maste       }
225f034231aSEd Maste     }
2265f29bb8aSDimitry Andric   }
2275f29bb8aSDimitry Andric 
2286f8fc217SDimitry Andric   return sb_symbol;
229f034231aSEd Maste }
230f034231aSEd Maste 
GetBlock() const23114f1b3e8SDimitry Andric SBBlock SBFrame::GetBlock() const {
2326f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
2335f29bb8aSDimitry Andric 
234f034231aSEd Maste   SBBlock sb_block;
235f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
236f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
237f034231aSEd Maste 
238e81d9d49SDimitry Andric   StackFrame *frame = nullptr;
239f034231aSEd Maste   Target *target = exe_ctx.GetTargetPtr();
240f034231aSEd Maste   Process *process = exe_ctx.GetProcessPtr();
24114f1b3e8SDimitry Andric   if (target && process) {
242f034231aSEd Maste     Process::StopLocker stop_locker;
24314f1b3e8SDimitry Andric     if (stop_locker.TryLock(&process->GetRunLock())) {
244f034231aSEd Maste       frame = exe_ctx.GetFramePtr();
2455f29bb8aSDimitry Andric       if (frame)
246f034231aSEd Maste         sb_block.SetPtr(frame->GetSymbolContext(eSymbolContextBlock).block);
247f034231aSEd Maste     }
248f034231aSEd Maste   }
2496f8fc217SDimitry Andric   return sb_block;
250f034231aSEd Maste }
251f034231aSEd Maste 
GetFrameBlock() const25214f1b3e8SDimitry Andric SBBlock SBFrame::GetFrameBlock() const {
2536f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
2545f29bb8aSDimitry Andric 
255f034231aSEd Maste   SBBlock sb_block;
256f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
257f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
258f034231aSEd Maste 
259e81d9d49SDimitry Andric   StackFrame *frame = nullptr;
260f034231aSEd Maste   Target *target = exe_ctx.GetTargetPtr();
261f034231aSEd Maste   Process *process = exe_ctx.GetProcessPtr();
26214f1b3e8SDimitry Andric   if (target && process) {
263f034231aSEd Maste     Process::StopLocker stop_locker;
26414f1b3e8SDimitry Andric     if (stop_locker.TryLock(&process->GetRunLock())) {
265f034231aSEd Maste       frame = exe_ctx.GetFramePtr();
2665f29bb8aSDimitry Andric       if (frame)
267f034231aSEd Maste         sb_block.SetPtr(frame->GetFrameBlock());
268f034231aSEd Maste     }
269f034231aSEd Maste   }
2706f8fc217SDimitry Andric   return sb_block;
271f034231aSEd Maste }
272f034231aSEd Maste 
GetLineEntry() const27314f1b3e8SDimitry Andric SBLineEntry SBFrame::GetLineEntry() const {
2746f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
2755f29bb8aSDimitry Andric 
276f034231aSEd Maste   SBLineEntry sb_line_entry;
277f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
278f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
279f034231aSEd Maste 
280e81d9d49SDimitry Andric   StackFrame *frame = nullptr;
281f034231aSEd Maste   Target *target = exe_ctx.GetTargetPtr();
282f034231aSEd Maste   Process *process = exe_ctx.GetProcessPtr();
28314f1b3e8SDimitry Andric   if (target && process) {
284f034231aSEd Maste     Process::StopLocker stop_locker;
28514f1b3e8SDimitry Andric     if (stop_locker.TryLock(&process->GetRunLock())) {
286f034231aSEd Maste       frame = exe_ctx.GetFramePtr();
28714f1b3e8SDimitry Andric       if (frame) {
28814f1b3e8SDimitry Andric         sb_line_entry.SetLineEntry(
28914f1b3e8SDimitry Andric             frame->GetSymbolContext(eSymbolContextLineEntry).line_entry);
290f034231aSEd Maste       }
291f034231aSEd Maste     }
2925f29bb8aSDimitry Andric   }
2936f8fc217SDimitry Andric   return sb_line_entry;
294f034231aSEd Maste }
295f034231aSEd Maste 
GetFrameID() const29614f1b3e8SDimitry Andric uint32_t SBFrame::GetFrameID() const {
2976f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
2985f29bb8aSDimitry Andric 
299f034231aSEd Maste   uint32_t frame_idx = UINT32_MAX;
300f034231aSEd Maste 
301f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
302f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
303f3fbd1c0SDimitry Andric 
304f034231aSEd Maste   StackFrame *frame = exe_ctx.GetFramePtr();
305f034231aSEd Maste   if (frame)
306f034231aSEd Maste     frame_idx = frame->GetFrameIndex();
307f034231aSEd Maste 
308f034231aSEd Maste   return frame_idx;
309f034231aSEd Maste }
310f034231aSEd Maste 
GetCFA() const31114f1b3e8SDimitry Andric lldb::addr_t SBFrame::GetCFA() const {
3126f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
3135f29bb8aSDimitry Andric 
314f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
315f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
316f3fbd1c0SDimitry Andric 
3175e95aa85SEd Maste   StackFrame *frame = exe_ctx.GetFramePtr();
3185e95aa85SEd Maste   if (frame)
3195e95aa85SEd Maste     return frame->GetStackID().GetCallFrameAddress();
3205e95aa85SEd Maste   return LLDB_INVALID_ADDRESS;
3215e95aa85SEd Maste }
3225e95aa85SEd Maste 
GetPC() const32314f1b3e8SDimitry Andric addr_t SBFrame::GetPC() const {
3246f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
3255f29bb8aSDimitry Andric 
326f034231aSEd Maste   addr_t addr = LLDB_INVALID_ADDRESS;
327f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
328f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
329f034231aSEd Maste 
330e81d9d49SDimitry Andric   StackFrame *frame = nullptr;
331f034231aSEd Maste   Target *target = exe_ctx.GetTargetPtr();
332f034231aSEd Maste   Process *process = exe_ctx.GetProcessPtr();
33314f1b3e8SDimitry Andric   if (target && process) {
334f034231aSEd Maste     Process::StopLocker stop_locker;
33514f1b3e8SDimitry Andric     if (stop_locker.TryLock(&process->GetRunLock())) {
336f034231aSEd Maste       frame = exe_ctx.GetFramePtr();
33714f1b3e8SDimitry Andric       if (frame) {
33814f1b3e8SDimitry Andric         addr = frame->GetFrameCodeAddress().GetOpcodeLoadAddress(
339f73363f1SDimitry Andric             target, AddressClass::eCode);
340f034231aSEd Maste       }
341f034231aSEd Maste     }
3425f29bb8aSDimitry Andric   }
343f034231aSEd Maste 
344f034231aSEd Maste   return addr;
345f034231aSEd Maste }
346f034231aSEd Maste 
SetPC(addr_t new_pc)34714f1b3e8SDimitry Andric bool SBFrame::SetPC(addr_t new_pc) {
3486f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, new_pc);
3495f29bb8aSDimitry Andric 
350f034231aSEd Maste   bool ret_val = false;
351f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
352f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
353f034231aSEd Maste 
354f034231aSEd Maste   Target *target = exe_ctx.GetTargetPtr();
355f034231aSEd Maste   Process *process = exe_ctx.GetProcessPtr();
35614f1b3e8SDimitry Andric   if (target && process) {
357f034231aSEd Maste     Process::StopLocker stop_locker;
35814f1b3e8SDimitry Andric     if (stop_locker.TryLock(&process->GetRunLock())) {
359cfca06d7SDimitry Andric       if (StackFrame *frame = exe_ctx.GetFramePtr()) {
360cfca06d7SDimitry Andric         if (RegisterContextSP reg_ctx_sp = frame->GetRegisterContext()) {
361cfca06d7SDimitry Andric           ret_val = reg_ctx_sp->SetPC(new_pc);
362cfca06d7SDimitry Andric         }
363f034231aSEd Maste       }
364f034231aSEd Maste     }
3655f29bb8aSDimitry Andric   }
366f034231aSEd Maste 
367f034231aSEd Maste   return ret_val;
368f034231aSEd Maste }
369f034231aSEd Maste 
GetSP() const37014f1b3e8SDimitry Andric addr_t SBFrame::GetSP() const {
3716f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
3725f29bb8aSDimitry Andric 
373f034231aSEd Maste   addr_t addr = LLDB_INVALID_ADDRESS;
374f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
375f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
376f034231aSEd Maste 
377f034231aSEd Maste   Target *target = exe_ctx.GetTargetPtr();
378f034231aSEd Maste   Process *process = exe_ctx.GetProcessPtr();
37914f1b3e8SDimitry Andric   if (target && process) {
380f034231aSEd Maste     Process::StopLocker stop_locker;
38114f1b3e8SDimitry Andric     if (stop_locker.TryLock(&process->GetRunLock())) {
382cfca06d7SDimitry Andric       if (StackFrame *frame = exe_ctx.GetFramePtr()) {
383cfca06d7SDimitry Andric         if (RegisterContextSP reg_ctx_sp = frame->GetRegisterContext()) {
384cfca06d7SDimitry Andric           addr = reg_ctx_sp->GetSP();
385cfca06d7SDimitry Andric         }
386f034231aSEd Maste       }
387f034231aSEd Maste     }
3885f29bb8aSDimitry Andric   }
389f034231aSEd Maste 
390f034231aSEd Maste   return addr;
391f034231aSEd Maste }
392f034231aSEd Maste 
GetFP() const39314f1b3e8SDimitry Andric addr_t SBFrame::GetFP() const {
3946f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
3955f29bb8aSDimitry Andric 
396f034231aSEd Maste   addr_t addr = LLDB_INVALID_ADDRESS;
397f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
398f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
399f034231aSEd Maste 
400f034231aSEd Maste   Target *target = exe_ctx.GetTargetPtr();
401f034231aSEd Maste   Process *process = exe_ctx.GetProcessPtr();
40214f1b3e8SDimitry Andric   if (target && process) {
403f034231aSEd Maste     Process::StopLocker stop_locker;
40414f1b3e8SDimitry Andric     if (stop_locker.TryLock(&process->GetRunLock())) {
405cfca06d7SDimitry Andric       if (StackFrame *frame = exe_ctx.GetFramePtr()) {
406cfca06d7SDimitry Andric         if (RegisterContextSP reg_ctx_sp = frame->GetRegisterContext()) {
407cfca06d7SDimitry Andric           addr = reg_ctx_sp->GetFP();
408cfca06d7SDimitry Andric         }
409cfca06d7SDimitry Andric       }
410f034231aSEd Maste     }
411f034231aSEd Maste   }
412f034231aSEd Maste 
413f034231aSEd Maste   return addr;
414f034231aSEd Maste }
415f034231aSEd Maste 
GetPCAddress() const41614f1b3e8SDimitry Andric SBAddress SBFrame::GetPCAddress() const {
4176f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
4185f29bb8aSDimitry Andric 
419f034231aSEd Maste   SBAddress sb_addr;
420f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
421f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
422f034231aSEd Maste 
423f034231aSEd Maste   StackFrame *frame = exe_ctx.GetFramePtr();
424f034231aSEd Maste   Target *target = exe_ctx.GetTargetPtr();
425f034231aSEd Maste   Process *process = exe_ctx.GetProcessPtr();
42614f1b3e8SDimitry Andric   if (target && process) {
427f034231aSEd Maste     Process::StopLocker stop_locker;
42814f1b3e8SDimitry Andric     if (stop_locker.TryLock(&process->GetRunLock())) {
429f034231aSEd Maste       frame = exe_ctx.GetFramePtr();
4305f29bb8aSDimitry Andric       if (frame)
431b60736ecSDimitry Andric         sb_addr.SetAddress(frame->GetFrameCodeAddress());
432f034231aSEd Maste     }
433f034231aSEd Maste   }
4346f8fc217SDimitry Andric   return sb_addr;
435f034231aSEd Maste }
436f034231aSEd Maste 
Clear()4375f29bb8aSDimitry Andric void SBFrame::Clear() {
4386f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
4395f29bb8aSDimitry Andric 
4405f29bb8aSDimitry Andric   m_opaque_sp->Clear();
4415f29bb8aSDimitry Andric }
442f034231aSEd Maste 
GetValueForVariablePath(const char * var_path)44314f1b3e8SDimitry Andric lldb::SBValue SBFrame::GetValueForVariablePath(const char *var_path) {
4446f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, var_path);
4455f29bb8aSDimitry Andric 
446f034231aSEd Maste   SBValue sb_value;
447f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
448f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
449f3fbd1c0SDimitry Andric 
450f034231aSEd Maste   StackFrame *frame = exe_ctx.GetFramePtr();
451f034231aSEd Maste   Target *target = exe_ctx.GetTargetPtr();
45214f1b3e8SDimitry Andric   if (frame && target) {
45314f1b3e8SDimitry Andric     lldb::DynamicValueType use_dynamic =
45414f1b3e8SDimitry Andric         frame->CalculateTarget()->GetPreferDynamicValue();
455f034231aSEd Maste     sb_value = GetValueForVariablePath(var_path, use_dynamic);
456f034231aSEd Maste   }
4576f8fc217SDimitry Andric   return sb_value;
458f034231aSEd Maste }
459f034231aSEd Maste 
GetValueForVariablePath(const char * var_path,DynamicValueType use_dynamic)46014f1b3e8SDimitry Andric lldb::SBValue SBFrame::GetValueForVariablePath(const char *var_path,
46114f1b3e8SDimitry Andric                                                DynamicValueType use_dynamic) {
4626f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, var_path, use_dynamic);
4635f29bb8aSDimitry Andric 
464f034231aSEd Maste   SBValue sb_value;
46514f1b3e8SDimitry Andric   if (var_path == nullptr || var_path[0] == '\0') {
4666f8fc217SDimitry Andric     return sb_value;
467f034231aSEd Maste   }
468f034231aSEd Maste 
469f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
470f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
471f034231aSEd Maste 
472e81d9d49SDimitry Andric   StackFrame *frame = nullptr;
473f034231aSEd Maste   Target *target = exe_ctx.GetTargetPtr();
474f034231aSEd Maste   Process *process = exe_ctx.GetProcessPtr();
47514f1b3e8SDimitry Andric   if (target && process) {
476f034231aSEd Maste     Process::StopLocker stop_locker;
47714f1b3e8SDimitry Andric     if (stop_locker.TryLock(&process->GetRunLock())) {
478f034231aSEd Maste       frame = exe_ctx.GetFramePtr();
47914f1b3e8SDimitry Andric       if (frame) {
480f034231aSEd Maste         VariableSP var_sp;
481b76161e4SDimitry Andric         Status error;
48214f1b3e8SDimitry Andric         ValueObjectSP value_sp(frame->GetValueForVariableExpressionPath(
48314f1b3e8SDimitry Andric             var_path, eNoDynamicValues,
48414f1b3e8SDimitry Andric             StackFrame::eExpressionPathOptionCheckPtrVsMember |
48514f1b3e8SDimitry Andric                 StackFrame::eExpressionPathOptionsAllowDirectIVarAccess,
48614f1b3e8SDimitry Andric             var_sp, error));
487f034231aSEd Maste         sb_value.SetSP(value_sp, use_dynamic);
488f034231aSEd Maste       }
489f034231aSEd Maste     }
4905f29bb8aSDimitry Andric   }
4916f8fc217SDimitry Andric   return sb_value;
492f034231aSEd Maste }
493f034231aSEd Maste 
FindVariable(const char * name)49414f1b3e8SDimitry Andric SBValue SBFrame::FindVariable(const char *name) {
4956f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, name);
4965f29bb8aSDimitry Andric 
497f034231aSEd Maste   SBValue value;
498f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
499f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
500f3fbd1c0SDimitry Andric 
501f034231aSEd Maste   StackFrame *frame = exe_ctx.GetFramePtr();
502f034231aSEd Maste   Target *target = exe_ctx.GetTargetPtr();
50314f1b3e8SDimitry Andric   if (frame && target) {
50414f1b3e8SDimitry Andric     lldb::DynamicValueType use_dynamic =
50514f1b3e8SDimitry Andric         frame->CalculateTarget()->GetPreferDynamicValue();
506f034231aSEd Maste     value = FindVariable(name, use_dynamic);
507f034231aSEd Maste   }
5086f8fc217SDimitry Andric   return value;
509f034231aSEd Maste }
510f034231aSEd Maste 
FindVariable(const char * name,lldb::DynamicValueType use_dynamic)51114f1b3e8SDimitry Andric SBValue SBFrame::FindVariable(const char *name,
51214f1b3e8SDimitry Andric                               lldb::DynamicValueType use_dynamic) {
5136f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, name, use_dynamic);
5145f29bb8aSDimitry Andric 
515f034231aSEd Maste   VariableSP var_sp;
516f034231aSEd Maste   SBValue sb_value;
517f034231aSEd Maste 
51814f1b3e8SDimitry Andric   if (name == nullptr || name[0] == '\0') {
5196f8fc217SDimitry Andric     return sb_value;
520f034231aSEd Maste   }
521f034231aSEd Maste 
522f034231aSEd Maste   ValueObjectSP value_sp;
523f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
524f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
525f034231aSEd Maste 
526e81d9d49SDimitry Andric   StackFrame *frame = nullptr;
527f034231aSEd Maste   Target *target = exe_ctx.GetTargetPtr();
528f034231aSEd Maste   Process *process = exe_ctx.GetProcessPtr();
52914f1b3e8SDimitry Andric   if (target && process) {
530f034231aSEd Maste     Process::StopLocker stop_locker;
53114f1b3e8SDimitry Andric     if (stop_locker.TryLock(&process->GetRunLock())) {
532f034231aSEd Maste       frame = exe_ctx.GetFramePtr();
53314f1b3e8SDimitry Andric       if (frame) {
53494994d37SDimitry Andric         value_sp = frame->FindVariable(ConstString(name));
535f034231aSEd Maste 
53694994d37SDimitry Andric         if (value_sp)
537f034231aSEd Maste           sb_value.SetSP(value_sp, use_dynamic);
538f034231aSEd Maste       }
539f034231aSEd Maste     }
540f034231aSEd Maste   }
541f034231aSEd Maste 
5426f8fc217SDimitry Andric   return sb_value;
543f034231aSEd Maste }
544f034231aSEd Maste 
FindValue(const char * name,ValueType value_type)54514f1b3e8SDimitry Andric SBValue SBFrame::FindValue(const char *name, ValueType value_type) {
5466f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, name, value_type);
5475f29bb8aSDimitry Andric 
548f034231aSEd Maste   SBValue value;
549f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
550f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
551f3fbd1c0SDimitry Andric 
552f034231aSEd Maste   StackFrame *frame = exe_ctx.GetFramePtr();
553f034231aSEd Maste   Target *target = exe_ctx.GetTargetPtr();
55414f1b3e8SDimitry Andric   if (frame && target) {
55514f1b3e8SDimitry Andric     lldb::DynamicValueType use_dynamic =
55614f1b3e8SDimitry Andric         frame->CalculateTarget()->GetPreferDynamicValue();
557f034231aSEd Maste     value = FindValue(name, value_type, use_dynamic);
558f034231aSEd Maste   }
5596f8fc217SDimitry Andric   return value;
560f034231aSEd Maste }
561f034231aSEd Maste 
FindValue(const char * name,ValueType value_type,lldb::DynamicValueType use_dynamic)56214f1b3e8SDimitry Andric SBValue SBFrame::FindValue(const char *name, ValueType value_type,
56314f1b3e8SDimitry Andric                            lldb::DynamicValueType use_dynamic) {
5646f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, name, value_type, use_dynamic);
5655f29bb8aSDimitry Andric 
566f034231aSEd Maste   SBValue sb_value;
567f034231aSEd Maste 
56814f1b3e8SDimitry Andric   if (name == nullptr || name[0] == '\0') {
5696f8fc217SDimitry Andric     return sb_value;
570f034231aSEd Maste   }
571f034231aSEd Maste 
572f034231aSEd Maste   ValueObjectSP value_sp;
573f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
574f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
575f034231aSEd Maste 
576e81d9d49SDimitry Andric   StackFrame *frame = nullptr;
577f034231aSEd Maste   Target *target = exe_ctx.GetTargetPtr();
578f034231aSEd Maste   Process *process = exe_ctx.GetProcessPtr();
57914f1b3e8SDimitry Andric   if (target && process) {
580f034231aSEd Maste     Process::StopLocker stop_locker;
58114f1b3e8SDimitry Andric     if (stop_locker.TryLock(&process->GetRunLock())) {
582f034231aSEd Maste       frame = exe_ctx.GetFramePtr();
58314f1b3e8SDimitry Andric       if (frame) {
58403b99097SEd Maste         VariableList variable_list;
58503b99097SEd Maste 
58614f1b3e8SDimitry Andric         switch (value_type) {
587f034231aSEd Maste         case eValueTypeVariableGlobal:      // global variable
588f034231aSEd Maste         case eValueTypeVariableStatic:      // static variable
589f034231aSEd Maste         case eValueTypeVariableArgument:    // function argument variables
590f034231aSEd Maste         case eValueTypeVariableLocal:       // function local variables
591f3fbd1c0SDimitry Andric         case eValueTypeVariableThreadLocal: // thread local variables
592f034231aSEd Maste         {
593f034231aSEd Maste           SymbolContext sc(frame->GetSymbolContext(eSymbolContextBlock));
594f034231aSEd Maste 
595f034231aSEd Maste           const bool can_create = true;
596f034231aSEd Maste           const bool get_parent_variables = true;
597f034231aSEd Maste           const bool stop_if_block_is_inlined_function = true;
598f034231aSEd Maste 
5995e95aa85SEd Maste           if (sc.block)
60014f1b3e8SDimitry Andric             sc.block->AppendVariables(
60114f1b3e8SDimitry Andric                 can_create, get_parent_variables,
60214f1b3e8SDimitry Andric                 stop_if_block_is_inlined_function,
60314f1b3e8SDimitry Andric                 [frame](Variable *v) { return v->IsInScope(frame); },
60414f1b3e8SDimitry Andric                 &variable_list);
6057fa27ce4SDimitry Andric           if (value_type == eValueTypeVariableGlobal
6067fa27ce4SDimitry Andric               || value_type == eValueTypeVariableStatic) {
60703b99097SEd Maste             const bool get_file_globals = true;
608e3b55780SDimitry Andric             VariableList *frame_vars = frame->GetVariableList(get_file_globals,
609e3b55780SDimitry Andric                                                               nullptr);
61003b99097SEd Maste             if (frame_vars)
61103b99097SEd Maste               frame_vars->AppendVariablesIfUnique(variable_list);
61203b99097SEd Maste           }
613f034231aSEd Maste           ConstString const_name(name);
61414f1b3e8SDimitry Andric           VariableSP variable_sp(
61514f1b3e8SDimitry Andric               variable_list.FindVariable(const_name, value_type));
61614f1b3e8SDimitry Andric           if (variable_sp) {
61714f1b3e8SDimitry Andric             value_sp = frame->GetValueObjectForFrameVariable(variable_sp,
61814f1b3e8SDimitry Andric                                                              eNoDynamicValues);
619f034231aSEd Maste             sb_value.SetSP(value_sp, use_dynamic);
620f034231aSEd Maste           }
62114f1b3e8SDimitry Andric         } break;
622f034231aSEd Maste 
623f034231aSEd Maste         case eValueTypeRegister: // stack frame register value
624f034231aSEd Maste         {
625f034231aSEd Maste           RegisterContextSP reg_ctx(frame->GetRegisterContext());
62614f1b3e8SDimitry Andric           if (reg_ctx) {
627c0981da4SDimitry Andric             if (const RegisterInfo *reg_info =
628c0981da4SDimitry Andric                     reg_ctx->GetRegisterInfoByName(name)) {
629c0981da4SDimitry Andric               value_sp = ValueObjectRegister::Create(frame, reg_ctx, reg_info);
630f034231aSEd Maste               sb_value.SetSP(value_sp);
631f034231aSEd Maste             }
632f034231aSEd Maste           }
63314f1b3e8SDimitry Andric         } break;
634f034231aSEd Maste 
63514f1b3e8SDimitry Andric         case eValueTypeRegisterSet: // A collection of stack frame register
63614f1b3e8SDimitry Andric                                     // values
637f034231aSEd Maste         {
638f034231aSEd Maste           RegisterContextSP reg_ctx(frame->GetRegisterContext());
63914f1b3e8SDimitry Andric           if (reg_ctx) {
640f034231aSEd Maste             const uint32_t num_sets = reg_ctx->GetRegisterSetCount();
64114f1b3e8SDimitry Andric             for (uint32_t set_idx = 0; set_idx < num_sets; ++set_idx) {
642f034231aSEd Maste               const RegisterSet *reg_set = reg_ctx->GetRegisterSet(set_idx);
643f034231aSEd Maste               if (reg_set &&
644145449b1SDimitry Andric                   (llvm::StringRef(reg_set->name).equals_insensitive(name) ||
645145449b1SDimitry Andric                    llvm::StringRef(reg_set->short_name)
646145449b1SDimitry Andric                        .equals_insensitive(name))) {
64714f1b3e8SDimitry Andric                 value_sp =
64814f1b3e8SDimitry Andric                     ValueObjectRegisterSet::Create(frame, reg_ctx, set_idx);
649f034231aSEd Maste                 sb_value.SetSP(value_sp);
650f034231aSEd Maste                 break;
651f034231aSEd Maste               }
652f034231aSEd Maste             }
653f034231aSEd Maste           }
65414f1b3e8SDimitry Andric         } break;
655f034231aSEd Maste 
656f034231aSEd Maste         case eValueTypeConstResult: // constant result variables
657f034231aSEd Maste         {
658f034231aSEd Maste           ConstString const_name(name);
65914f1b3e8SDimitry Andric           ExpressionVariableSP expr_var_sp(
66014f1b3e8SDimitry Andric               target->GetPersistentVariable(const_name));
66114f1b3e8SDimitry Andric           if (expr_var_sp) {
662f034231aSEd Maste             value_sp = expr_var_sp->GetValueObject();
663f034231aSEd Maste             sb_value.SetSP(value_sp, use_dynamic);
664f034231aSEd Maste           }
66514f1b3e8SDimitry Andric         } break;
666f034231aSEd Maste 
667f034231aSEd Maste         default:
668f034231aSEd Maste           break;
669f034231aSEd Maste         }
670f034231aSEd Maste       }
671f034231aSEd Maste     }
672f034231aSEd Maste   }
673f034231aSEd Maste 
6746f8fc217SDimitry Andric   return sb_value;
675f034231aSEd Maste }
676f034231aSEd Maste 
IsEqual(const SBFrame & that) const67714f1b3e8SDimitry Andric bool SBFrame::IsEqual(const SBFrame &that) const {
6786f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, that);
6795f29bb8aSDimitry Andric 
680f034231aSEd Maste   lldb::StackFrameSP this_sp = GetFrameSP();
681f034231aSEd Maste   lldb::StackFrameSP that_sp = that.GetFrameSP();
682f034231aSEd Maste   return (this_sp && that_sp && this_sp->GetStackID() == that_sp->GetStackID());
683f034231aSEd Maste }
684f034231aSEd Maste 
operator ==(const SBFrame & rhs) const6855f29bb8aSDimitry Andric bool SBFrame::operator==(const SBFrame &rhs) const {
6866f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, rhs);
687f034231aSEd Maste 
6885f29bb8aSDimitry Andric   return IsEqual(rhs);
6895f29bb8aSDimitry Andric }
6905f29bb8aSDimitry Andric 
operator !=(const SBFrame & rhs) const6915f29bb8aSDimitry Andric bool SBFrame::operator!=(const SBFrame &rhs) const {
6926f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, rhs);
6935f29bb8aSDimitry Andric 
6945f29bb8aSDimitry Andric   return !IsEqual(rhs);
6955f29bb8aSDimitry Andric }
696f034231aSEd Maste 
GetThread() const69714f1b3e8SDimitry Andric SBThread SBFrame::GetThread() const {
6986f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
699f034231aSEd Maste 
700f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
701f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
702f3fbd1c0SDimitry Andric 
703f034231aSEd Maste   ThreadSP thread_sp(exe_ctx.GetThreadSP());
704f034231aSEd Maste   SBThread sb_thread(thread_sp);
705f034231aSEd Maste 
7066f8fc217SDimitry Andric   return sb_thread;
707f034231aSEd Maste }
708f034231aSEd Maste 
Disassemble() const70914f1b3e8SDimitry Andric const char *SBFrame::Disassemble() const {
7106f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
7115f29bb8aSDimitry Andric 
712f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
713f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
714f034231aSEd Maste   Target *target = exe_ctx.GetTargetPtr();
715f034231aSEd Maste   Process *process = exe_ctx.GetProcessPtr();
7167fa27ce4SDimitry Andric   if (!target || !process)
7177fa27ce4SDimitry Andric     return nullptr;
7187fa27ce4SDimitry Andric 
719f034231aSEd Maste   Process::StopLocker stop_locker;
72014f1b3e8SDimitry Andric   if (stop_locker.TryLock(&process->GetRunLock())) {
7217fa27ce4SDimitry Andric     if (auto *frame = exe_ctx.GetFramePtr())
7227fa27ce4SDimitry Andric       return ConstString(frame->Disassemble()).GetCString();
7235f29bb8aSDimitry Andric   }
724f034231aSEd Maste 
7257fa27ce4SDimitry Andric   return nullptr;
726f034231aSEd Maste }
727f034231aSEd Maste 
GetVariables(bool arguments,bool locals,bool statics,bool in_scope_only)72814f1b3e8SDimitry Andric SBValueList SBFrame::GetVariables(bool arguments, bool locals, bool statics,
72914f1b3e8SDimitry Andric                                   bool in_scope_only) {
7306f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, arguments, locals, statics, in_scope_only);
7315f29bb8aSDimitry Andric 
732f034231aSEd Maste   SBValueList value_list;
733f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
734f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
735f3fbd1c0SDimitry Andric 
736f034231aSEd Maste   StackFrame *frame = exe_ctx.GetFramePtr();
737f034231aSEd Maste   Target *target = exe_ctx.GetTargetPtr();
73814f1b3e8SDimitry Andric   if (frame && target) {
73914f1b3e8SDimitry Andric     lldb::DynamicValueType use_dynamic =
74014f1b3e8SDimitry Andric         frame->CalculateTarget()->GetPreferDynamicValue();
74114f1b3e8SDimitry Andric     const bool include_runtime_support_values =
742e3b55780SDimitry Andric         target->GetDisplayRuntimeSupportValues();
7435e95aa85SEd Maste 
7445e95aa85SEd Maste     SBVariablesOptions options;
7455e95aa85SEd Maste     options.SetIncludeArguments(arguments);
7465e95aa85SEd Maste     options.SetIncludeLocals(locals);
7475e95aa85SEd Maste     options.SetIncludeStatics(statics);
7485e95aa85SEd Maste     options.SetInScopeOnly(in_scope_only);
7495e95aa85SEd Maste     options.SetIncludeRuntimeSupportValues(include_runtime_support_values);
7505e95aa85SEd Maste     options.SetUseDynamic(use_dynamic);
7515e95aa85SEd Maste 
7525e95aa85SEd Maste     value_list = GetVariables(options);
753f034231aSEd Maste   }
7546f8fc217SDimitry Andric   return value_list;
755f034231aSEd Maste }
756f034231aSEd Maste 
GetVariables(bool arguments,bool locals,bool statics,bool in_scope_only,lldb::DynamicValueType use_dynamic)75714f1b3e8SDimitry Andric lldb::SBValueList SBFrame::GetVariables(bool arguments, bool locals,
75814f1b3e8SDimitry Andric                                         bool statics, bool in_scope_only,
75914f1b3e8SDimitry Andric                                         lldb::DynamicValueType use_dynamic) {
7606f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, arguments, locals, statics, in_scope_only,
7616f8fc217SDimitry Andric                      use_dynamic);
7625f29bb8aSDimitry Andric 
763f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
764f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
765f3fbd1c0SDimitry Andric 
7665e95aa85SEd Maste   Target *target = exe_ctx.GetTargetPtr();
76714f1b3e8SDimitry Andric   const bool include_runtime_support_values =
76814f1b3e8SDimitry Andric       target ? target->GetDisplayRuntimeSupportValues() : false;
7695e95aa85SEd Maste   SBVariablesOptions options;
7705e95aa85SEd Maste   options.SetIncludeArguments(arguments);
7715e95aa85SEd Maste   options.SetIncludeLocals(locals);
7725e95aa85SEd Maste   options.SetIncludeStatics(statics);
7735e95aa85SEd Maste   options.SetInScopeOnly(in_scope_only);
7745e95aa85SEd Maste   options.SetIncludeRuntimeSupportValues(include_runtime_support_values);
7755e95aa85SEd Maste   options.SetUseDynamic(use_dynamic);
7766f8fc217SDimitry Andric   return GetVariables(options);
7775e95aa85SEd Maste }
7785e95aa85SEd Maste 
GetVariables(const lldb::SBVariablesOptions & options)77914f1b3e8SDimitry Andric SBValueList SBFrame::GetVariables(const lldb::SBVariablesOptions &options) {
7806f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, options);
781f034231aSEd Maste 
782f034231aSEd Maste   SBValueList value_list;
783f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
784f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
785f034231aSEd Maste 
786e81d9d49SDimitry Andric   StackFrame *frame = nullptr;
787f034231aSEd Maste   Target *target = exe_ctx.GetTargetPtr();
788f034231aSEd Maste 
7895e95aa85SEd Maste   const bool statics = options.GetIncludeStatics();
7905e95aa85SEd Maste   const bool arguments = options.GetIncludeArguments();
79194994d37SDimitry Andric   const bool recognized_arguments =
79294994d37SDimitry Andric         options.GetIncludeRecognizedArguments(SBTarget(exe_ctx.GetTargetSP()));
7935e95aa85SEd Maste   const bool locals = options.GetIncludeLocals();
7945e95aa85SEd Maste   const bool in_scope_only = options.GetInScopeOnly();
79514f1b3e8SDimitry Andric   const bool include_runtime_support_values =
79614f1b3e8SDimitry Andric       options.GetIncludeRuntimeSupportValues();
7975e95aa85SEd Maste   const lldb::DynamicValueType use_dynamic = options.GetUseDynamic();
7985e95aa85SEd Maste 
799f034231aSEd Maste 
800f3fbd1c0SDimitry Andric   std::set<VariableSP> variable_set;
801f034231aSEd Maste   Process *process = exe_ctx.GetProcessPtr();
80214f1b3e8SDimitry Andric   if (target && process) {
803f034231aSEd Maste     Process::StopLocker stop_locker;
80414f1b3e8SDimitry Andric     if (stop_locker.TryLock(&process->GetRunLock())) {
805f034231aSEd Maste       frame = exe_ctx.GetFramePtr();
80614f1b3e8SDimitry Andric       if (frame) {
8077fa27ce4SDimitry Andric         Debugger &dbg = process->GetTarget().GetDebugger();
808e81d9d49SDimitry Andric         VariableList *variable_list = nullptr;
809e3b55780SDimitry Andric         Status var_error;
810e3b55780SDimitry Andric         variable_list = frame->GetVariableList(true, &var_error);
811e3b55780SDimitry Andric         if (var_error.Fail())
812e3b55780SDimitry Andric           value_list.SetError(var_error);
81314f1b3e8SDimitry Andric         if (variable_list) {
814f034231aSEd Maste           const size_t num_variables = variable_list->GetSize();
81514f1b3e8SDimitry Andric           if (num_variables) {
8167fa27ce4SDimitry Andric             size_t num_produced = 0;
817706b4fc4SDimitry Andric             for (const VariableSP &variable_sp : *variable_list) {
8187fa27ce4SDimitry Andric               if (INTERRUPT_REQUESTED(dbg,
8197fa27ce4SDimitry Andric                     "Interrupted getting frame variables with {0} of {1} "
8207fa27ce4SDimitry Andric                     "produced.", num_produced, num_variables))
8217fa27ce4SDimitry Andric                 return {};
8227fa27ce4SDimitry Andric 
82314f1b3e8SDimitry Andric               if (variable_sp) {
824f034231aSEd Maste                 bool add_variable = false;
82514f1b3e8SDimitry Andric                 switch (variable_sp->GetScope()) {
826f034231aSEd Maste                 case eValueTypeVariableGlobal:
827f034231aSEd Maste                 case eValueTypeVariableStatic:
828f3fbd1c0SDimitry Andric                 case eValueTypeVariableThreadLocal:
829f034231aSEd Maste                   add_variable = statics;
830f034231aSEd Maste                   break;
831f034231aSEd Maste 
832f034231aSEd Maste                 case eValueTypeVariableArgument:
833f034231aSEd Maste                   add_variable = arguments;
834f034231aSEd Maste                   break;
835f034231aSEd Maste 
836f034231aSEd Maste                 case eValueTypeVariableLocal:
837f034231aSEd Maste                   add_variable = locals;
838f034231aSEd Maste                   break;
839f034231aSEd Maste 
840f034231aSEd Maste                 default:
841f034231aSEd Maste                   break;
842f034231aSEd Maste                 }
84314f1b3e8SDimitry Andric                 if (add_variable) {
844f3fbd1c0SDimitry Andric                   // Only add variables once so we don't end up with duplicates
845f3fbd1c0SDimitry Andric                   if (variable_set.find(variable_sp) == variable_set.end())
846f3fbd1c0SDimitry Andric                     variable_set.insert(variable_sp);
847f3fbd1c0SDimitry Andric                   else
848f3fbd1c0SDimitry Andric                     continue;
849f3fbd1c0SDimitry Andric 
850f034231aSEd Maste                   if (in_scope_only && !variable_sp->IsInScope(frame))
851f034231aSEd Maste                     continue;
852f034231aSEd Maste 
85314f1b3e8SDimitry Andric                   ValueObjectSP valobj_sp(frame->GetValueObjectForFrameVariable(
85414f1b3e8SDimitry Andric                       variable_sp, eNoDynamicValues));
8555e95aa85SEd Maste 
85614f1b3e8SDimitry Andric                   if (!include_runtime_support_values && valobj_sp != nullptr &&
857e81d9d49SDimitry Andric                       valobj_sp->IsRuntimeSupportValue())
8585e95aa85SEd Maste                     continue;
8595e95aa85SEd Maste 
860f034231aSEd Maste                   SBValue value_sb;
861f034231aSEd Maste                   value_sb.SetSP(valobj_sp, use_dynamic);
862f034231aSEd Maste                   value_list.Append(value_sb);
863f034231aSEd Maste                 }
864f034231aSEd Maste               }
865f034231aSEd Maste             }
8667fa27ce4SDimitry Andric             num_produced++;
867f034231aSEd Maste           }
868f034231aSEd Maste         }
86994994d37SDimitry Andric         if (recognized_arguments) {
87094994d37SDimitry Andric           auto recognized_frame = frame->GetRecognizedFrame();
87194994d37SDimitry Andric           if (recognized_frame) {
87294994d37SDimitry Andric             ValueObjectListSP recognized_arg_list =
87394994d37SDimitry Andric                 recognized_frame->GetRecognizedArguments();
87494994d37SDimitry Andric             if (recognized_arg_list) {
87594994d37SDimitry Andric               for (auto &rec_value_sp : recognized_arg_list->GetObjects()) {
87694994d37SDimitry Andric                 SBValue value_sb;
87794994d37SDimitry Andric                 value_sb.SetSP(rec_value_sp, use_dynamic);
87894994d37SDimitry Andric                 value_list.Append(value_sb);
87994994d37SDimitry Andric               }
88094994d37SDimitry Andric             }
88194994d37SDimitry Andric           }
88294994d37SDimitry Andric         }
883f034231aSEd Maste       }
884f034231aSEd Maste     }
885f034231aSEd Maste   }
886f034231aSEd Maste 
8876f8fc217SDimitry Andric   return value_list;
888f034231aSEd Maste }
889f034231aSEd Maste 
GetRegisters()89014f1b3e8SDimitry Andric SBValueList SBFrame::GetRegisters() {
8916f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
892f034231aSEd Maste 
893f034231aSEd Maste   SBValueList value_list;
894f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
895f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
896f034231aSEd Maste 
897e81d9d49SDimitry Andric   StackFrame *frame = nullptr;
898f034231aSEd Maste   Target *target = exe_ctx.GetTargetPtr();
899f034231aSEd Maste   Process *process = exe_ctx.GetProcessPtr();
90014f1b3e8SDimitry Andric   if (target && process) {
901f034231aSEd Maste     Process::StopLocker stop_locker;
90214f1b3e8SDimitry Andric     if (stop_locker.TryLock(&process->GetRunLock())) {
903f034231aSEd Maste       frame = exe_ctx.GetFramePtr();
90414f1b3e8SDimitry Andric       if (frame) {
905f034231aSEd Maste         RegisterContextSP reg_ctx(frame->GetRegisterContext());
90614f1b3e8SDimitry Andric         if (reg_ctx) {
907f034231aSEd Maste           const uint32_t num_sets = reg_ctx->GetRegisterSetCount();
90814f1b3e8SDimitry Andric           for (uint32_t set_idx = 0; set_idx < num_sets; ++set_idx) {
90914f1b3e8SDimitry Andric             value_list.Append(
91014f1b3e8SDimitry Andric                 ValueObjectRegisterSet::Create(frame, reg_ctx, set_idx));
911f034231aSEd Maste           }
912f034231aSEd Maste         }
913f034231aSEd Maste       }
914f034231aSEd Maste     }
915f034231aSEd Maste   }
916f034231aSEd Maste 
9176f8fc217SDimitry Andric   return value_list;
918f034231aSEd Maste }
919f034231aSEd Maste 
FindRegister(const char * name)92014f1b3e8SDimitry Andric SBValue SBFrame::FindRegister(const char *name) {
9216f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, name);
922f034231aSEd Maste 
923f034231aSEd Maste   SBValue result;
924f034231aSEd Maste   ValueObjectSP value_sp;
925f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
926f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
927f034231aSEd Maste 
928e81d9d49SDimitry Andric   StackFrame *frame = nullptr;
929f034231aSEd Maste   Target *target = exe_ctx.GetTargetPtr();
930f034231aSEd Maste   Process *process = exe_ctx.GetProcessPtr();
93114f1b3e8SDimitry Andric   if (target && process) {
932f034231aSEd Maste     Process::StopLocker stop_locker;
93314f1b3e8SDimitry Andric     if (stop_locker.TryLock(&process->GetRunLock())) {
934f034231aSEd Maste       frame = exe_ctx.GetFramePtr();
93514f1b3e8SDimitry Andric       if (frame) {
936f034231aSEd Maste         RegisterContextSP reg_ctx(frame->GetRegisterContext());
93714f1b3e8SDimitry Andric         if (reg_ctx) {
938c0981da4SDimitry Andric           if (const RegisterInfo *reg_info =
939c0981da4SDimitry Andric                   reg_ctx->GetRegisterInfoByName(name)) {
940c0981da4SDimitry Andric             value_sp = ValueObjectRegister::Create(frame, reg_ctx, reg_info);
941f034231aSEd Maste             result.SetSP(value_sp);
942f034231aSEd Maste           }
943f034231aSEd Maste         }
944f034231aSEd Maste       }
945f034231aSEd Maste     }
946f034231aSEd Maste   }
947f034231aSEd Maste 
9486f8fc217SDimitry Andric   return result;
949f034231aSEd Maste }
950f034231aSEd Maste 
GetDescriptionWithFormat(const SBFormat & format,SBStream & output)951b1c73532SDimitry Andric SBError SBFrame::GetDescriptionWithFormat(const SBFormat &format,
952b1c73532SDimitry Andric                                           SBStream &output) {
953b1c73532SDimitry Andric   Stream &strm = output.ref();
954b1c73532SDimitry Andric 
955b1c73532SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
956b1c73532SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
957b1c73532SDimitry Andric 
958b1c73532SDimitry Andric   StackFrame *frame = nullptr;
959b1c73532SDimitry Andric   Target *target = exe_ctx.GetTargetPtr();
960b1c73532SDimitry Andric   Process *process = exe_ctx.GetProcessPtr();
961b1c73532SDimitry Andric   SBError error;
962b1c73532SDimitry Andric 
963b1c73532SDimitry Andric   if (!format) {
964b1c73532SDimitry Andric     error.SetErrorString("The provided SBFormat object is invalid");
965b1c73532SDimitry Andric     return error;
966b1c73532SDimitry Andric   }
967b1c73532SDimitry Andric 
968b1c73532SDimitry Andric   if (target && process) {
969b1c73532SDimitry Andric     Process::StopLocker stop_locker;
970b1c73532SDimitry Andric     if (stop_locker.TryLock(&process->GetRunLock())) {
971b1c73532SDimitry Andric       frame = exe_ctx.GetFramePtr();
972b1c73532SDimitry Andric       if (frame &&
973b1c73532SDimitry Andric           frame->DumpUsingFormat(strm, format.GetFormatEntrySP().get())) {
974b1c73532SDimitry Andric         return error;
975b1c73532SDimitry Andric       }
976b1c73532SDimitry Andric     }
977b1c73532SDimitry Andric   }
978b1c73532SDimitry Andric   error.SetErrorStringWithFormat(
979b1c73532SDimitry Andric       "It was not possible to generate a frame "
980b1c73532SDimitry Andric       "description with the given format string '%s'",
981b1c73532SDimitry Andric       format.GetFormatEntrySP()->string.c_str());
982b1c73532SDimitry Andric   return error;
983b1c73532SDimitry Andric }
984b1c73532SDimitry Andric 
GetDescription(SBStream & description)98514f1b3e8SDimitry Andric bool SBFrame::GetDescription(SBStream &description) {
9866f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, description);
9875f29bb8aSDimitry Andric 
988f034231aSEd Maste   Stream &strm = description.ref();
989f034231aSEd Maste 
990f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
991f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
992f034231aSEd Maste 
993f034231aSEd Maste   StackFrame *frame;
994f034231aSEd Maste   Target *target = exe_ctx.GetTargetPtr();
995f034231aSEd Maste   Process *process = exe_ctx.GetProcessPtr();
99614f1b3e8SDimitry Andric   if (target && process) {
997f034231aSEd Maste     Process::StopLocker stop_locker;
99814f1b3e8SDimitry Andric     if (stop_locker.TryLock(&process->GetRunLock())) {
999f034231aSEd Maste       frame = exe_ctx.GetFramePtr();
100014f1b3e8SDimitry Andric       if (frame) {
1001f034231aSEd Maste         frame->DumpUsingSettingsFormat(&strm);
1002f034231aSEd Maste       }
1003f034231aSEd Maste     }
1004f034231aSEd Maste 
100514f1b3e8SDimitry Andric   } else
1006f034231aSEd Maste     strm.PutCString("No value");
1007f034231aSEd Maste 
1008f034231aSEd Maste   return true;
1009f034231aSEd Maste }
1010f034231aSEd Maste 
EvaluateExpression(const char * expr)101114f1b3e8SDimitry Andric SBValue SBFrame::EvaluateExpression(const char *expr) {
10126f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, expr);
10135f29bb8aSDimitry Andric 
1014f034231aSEd Maste   SBValue result;
1015f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
1016f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1017f3fbd1c0SDimitry Andric 
1018f034231aSEd Maste   StackFrame *frame = exe_ctx.GetFramePtr();
1019f034231aSEd Maste   Target *target = exe_ctx.GetTargetPtr();
102014f1b3e8SDimitry Andric   if (frame && target) {
1021f034231aSEd Maste     SBExpressionOptions options;
102214f1b3e8SDimitry Andric     lldb::DynamicValueType fetch_dynamic_value =
102314f1b3e8SDimitry Andric         frame->CalculateTarget()->GetPreferDynamicValue();
1024f034231aSEd Maste     options.SetFetchDynamicValue(fetch_dynamic_value);
1025f034231aSEd Maste     options.SetUnwindOnError(true);
1026f3fbd1c0SDimitry Andric     options.SetIgnoreBreakpoints(true);
1027ac9a064cSDimitry Andric     SourceLanguage language = target->GetLanguage();
1028ac9a064cSDimitry Andric     if (!language)
1029ac9a064cSDimitry Andric       language = frame->GetLanguage();
1030ac9a064cSDimitry Andric     options.SetLanguage((SBSourceLanguageName)language.name, language.version);
10316f8fc217SDimitry Andric     return EvaluateExpression(expr, options);
10327fa27ce4SDimitry Andric   } else {
10337fa27ce4SDimitry Andric     Status error;
10347fa27ce4SDimitry Andric     error.SetErrorString("can't evaluate expressions when the "
10357fa27ce4SDimitry Andric                            "process is running.");
10367fa27ce4SDimitry Andric     ValueObjectSP error_val_sp = ValueObjectConstResult::Create(nullptr, error);
10377fa27ce4SDimitry Andric     result.SetSP(error_val_sp, false);
1038f034231aSEd Maste   }
10396f8fc217SDimitry Andric   return result;
1040f034231aSEd Maste }
1041f034231aSEd Maste 
1042f034231aSEd Maste SBValue
EvaluateExpression(const char * expr,lldb::DynamicValueType fetch_dynamic_value)104314f1b3e8SDimitry Andric SBFrame::EvaluateExpression(const char *expr,
104414f1b3e8SDimitry Andric                             lldb::DynamicValueType fetch_dynamic_value) {
10456f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, expr, fetch_dynamic_value);
10465f29bb8aSDimitry Andric 
1047f034231aSEd Maste   SBExpressionOptions options;
1048f034231aSEd Maste   options.SetFetchDynamicValue(fetch_dynamic_value);
1049f034231aSEd Maste   options.SetUnwindOnError(true);
1050f3fbd1c0SDimitry Andric   options.SetIgnoreBreakpoints(true);
1051f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
1052f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1053f3fbd1c0SDimitry Andric 
1054e81d9d49SDimitry Andric   StackFrame *frame = exe_ctx.GetFramePtr();
1055e81d9d49SDimitry Andric   Target *target = exe_ctx.GetTargetPtr();
1056ac9a064cSDimitry Andric   SourceLanguage language;
1057ac9a064cSDimitry Andric   if (target)
1058ac9a064cSDimitry Andric     language = target->GetLanguage();
1059ac9a064cSDimitry Andric   if (!language && frame)
1060ac9a064cSDimitry Andric     language = frame->GetLanguage();
1061ac9a064cSDimitry Andric   options.SetLanguage((SBSourceLanguageName)language.name, language.version);
10626f8fc217SDimitry Andric   return EvaluateExpression(expr, options);
1063f034231aSEd Maste }
1064f034231aSEd Maste 
EvaluateExpression(const char * expr,lldb::DynamicValueType fetch_dynamic_value,bool unwind_on_error)106514f1b3e8SDimitry Andric SBValue SBFrame::EvaluateExpression(const char *expr,
106614f1b3e8SDimitry Andric                                     lldb::DynamicValueType fetch_dynamic_value,
106714f1b3e8SDimitry Andric                                     bool unwind_on_error) {
10686f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, expr, fetch_dynamic_value, unwind_on_error);
10695f29bb8aSDimitry Andric 
1070f034231aSEd Maste   SBExpressionOptions options;
1071f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
1072f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1073f3fbd1c0SDimitry Andric 
1074f034231aSEd Maste   options.SetFetchDynamicValue(fetch_dynamic_value);
1075f034231aSEd Maste   options.SetUnwindOnError(unwind_on_error);
1076f3fbd1c0SDimitry Andric   options.SetIgnoreBreakpoints(true);
1077e81d9d49SDimitry Andric   StackFrame *frame = exe_ctx.GetFramePtr();
1078e81d9d49SDimitry Andric   Target *target = exe_ctx.GetTargetPtr();
1079ac9a064cSDimitry Andric   SourceLanguage language;
1080ac9a064cSDimitry Andric   if (target)
1081ac9a064cSDimitry Andric     language = target->GetLanguage();
1082ac9a064cSDimitry Andric   if (!language && frame)
1083ac9a064cSDimitry Andric     language = frame->GetLanguage();
1084ac9a064cSDimitry Andric   options.SetLanguage((SBSourceLanguageName)language.name, language.version);
10856f8fc217SDimitry Andric   return EvaluateExpression(expr, options);
1086f034231aSEd Maste }
1087f034231aSEd Maste 
EvaluateExpression(const char * expr,const SBExpressionOptions & options)108814f1b3e8SDimitry Andric lldb::SBValue SBFrame::EvaluateExpression(const char *expr,
108914f1b3e8SDimitry Andric                                           const SBExpressionOptions &options) {
10906f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, expr, options);
1091f034231aSEd Maste 
1092145449b1SDimitry Andric   Log *expr_log = GetLog(LLDBLog::Expressions);
1093f034231aSEd Maste 
1094f034231aSEd Maste   SBValue expr_result;
1095f034231aSEd Maste 
109614f1b3e8SDimitry Andric   if (expr == nullptr || expr[0] == '\0') {
10976f8fc217SDimitry Andric     return expr_result;
1098f034231aSEd Maste   }
1099f034231aSEd Maste 
1100f034231aSEd Maste   ValueObjectSP expr_value_sp;
1101f034231aSEd Maste 
1102f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
1103f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1104f034231aSEd Maste 
1105e81d9d49SDimitry Andric   StackFrame *frame = nullptr;
1106f034231aSEd Maste   Target *target = exe_ctx.GetTargetPtr();
1107f034231aSEd Maste   Process *process = exe_ctx.GetProcessPtr();
1108f034231aSEd Maste 
110914f1b3e8SDimitry Andric   if (target && process) {
1110f034231aSEd Maste     Process::StopLocker stop_locker;
111114f1b3e8SDimitry Andric     if (stop_locker.TryLock(&process->GetRunLock())) {
1112f034231aSEd Maste       frame = exe_ctx.GetFramePtr();
111314f1b3e8SDimitry Andric       if (frame) {
111414f1b3e8SDimitry Andric         std::unique_ptr<llvm::PrettyStackTraceFormat> stack_trace;
111514f1b3e8SDimitry Andric         if (target->GetDisplayExpressionsInCrashlogs()) {
1116f034231aSEd Maste           StreamString frame_description;
1117f034231aSEd Maste           frame->DumpUsingSettingsFormat(&frame_description);
1118ead24645SDimitry Andric           stack_trace = std::make_unique<llvm::PrettyStackTraceFormat>(
111914f1b3e8SDimitry Andric               "SBFrame::EvaluateExpression (expr = \"%s\", fetch_dynamic_value "
112014f1b3e8SDimitry Andric               "= %u) %s",
112114f1b3e8SDimitry Andric               expr, options.GetFetchDynamicValue(),
112214f1b3e8SDimitry Andric               frame_description.GetData());
1123866dcdacSEd Maste         }
1124866dcdacSEd Maste 
11255f29bb8aSDimitry Andric         target->EvaluateExpression(expr, frame, expr_value_sp, options.ref());
1126f034231aSEd Maste         expr_result.SetSP(expr_value_sp, options.GetFetchDynamicValue());
1127f034231aSEd Maste       }
11287fa27ce4SDimitry Andric     } else {
11297fa27ce4SDimitry Andric       Status error;
11307fa27ce4SDimitry Andric       error.SetErrorString("can't evaluate expressions when the "
11317fa27ce4SDimitry Andric                            "process is running.");
11327fa27ce4SDimitry Andric       expr_value_sp = ValueObjectConstResult::Create(nullptr, error);
11337fa27ce4SDimitry Andric       expr_result.SetSP(expr_value_sp, false);
1134f034231aSEd Maste     }
11357fa27ce4SDimitry Andric   } else {
11367fa27ce4SDimitry Andric       Status error;
11377fa27ce4SDimitry Andric       error.SetErrorString("sbframe object is not valid.");
11387fa27ce4SDimitry Andric       expr_value_sp = ValueObjectConstResult::Create(nullptr, error);
11397fa27ce4SDimitry Andric       expr_result.SetSP(expr_value_sp, false);
1140f034231aSEd Maste   }
1141f034231aSEd Maste 
11427fa27ce4SDimitry Andric   if (expr_result.GetError().Success())
1143ead24645SDimitry Andric     LLDB_LOGF(expr_log,
1144ead24645SDimitry Andric               "** [SBFrame::EvaluateExpression] Expression result is "
114514f1b3e8SDimitry Andric               "%s, summary %s **",
11460cac4ca3SEd Maste               expr_result.GetValue(), expr_result.GetSummary());
11477fa27ce4SDimitry Andric   else
11487fa27ce4SDimitry Andric     LLDB_LOGF(expr_log,
11497fa27ce4SDimitry Andric               "** [SBFrame::EvaluateExpression] Expression evaluation failed: "
11507fa27ce4SDimitry Andric               "%s **",
11517fa27ce4SDimitry Andric               expr_result.GetError().GetCString());
1152f034231aSEd Maste 
11536f8fc217SDimitry Andric   return expr_result;
1154f034231aSEd Maste }
1155f034231aSEd Maste 
IsInlined()115614f1b3e8SDimitry Andric bool SBFrame::IsInlined() {
11576f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
11585f29bb8aSDimitry Andric 
11595e95aa85SEd Maste   return static_cast<const SBFrame *>(this)->IsInlined();
11605e95aa85SEd Maste }
11615e95aa85SEd Maste 
IsInlined() const116214f1b3e8SDimitry Andric bool SBFrame::IsInlined() const {
11636f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
11645f29bb8aSDimitry Andric 
1165f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
1166f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1167f3fbd1c0SDimitry Andric 
1168e81d9d49SDimitry Andric   StackFrame *frame = nullptr;
1169f034231aSEd Maste   Target *target = exe_ctx.GetTargetPtr();
1170f034231aSEd Maste   Process *process = exe_ctx.GetProcessPtr();
117114f1b3e8SDimitry Andric   if (target && process) {
1172f034231aSEd Maste     Process::StopLocker stop_locker;
117314f1b3e8SDimitry Andric     if (stop_locker.TryLock(&process->GetRunLock())) {
1174f034231aSEd Maste       frame = exe_ctx.GetFramePtr();
117514f1b3e8SDimitry Andric       if (frame) {
1176f034231aSEd Maste 
1177f034231aSEd Maste         Block *block = frame->GetSymbolContext(eSymbolContextBlock).block;
1178f034231aSEd Maste         if (block)
1179e81d9d49SDimitry Andric           return block->GetContainingInlinedBlock() != nullptr;
1180f034231aSEd Maste       }
1181f034231aSEd Maste     }
1182f034231aSEd Maste   }
1183f034231aSEd Maste   return false;
1184f034231aSEd Maste }
1185f034231aSEd Maste 
IsArtificial()118694994d37SDimitry Andric bool SBFrame::IsArtificial() {
11876f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
11885f29bb8aSDimitry Andric 
118994994d37SDimitry Andric   return static_cast<const SBFrame *>(this)->IsArtificial();
119094994d37SDimitry Andric }
119194994d37SDimitry Andric 
IsArtificial() const119294994d37SDimitry Andric bool SBFrame::IsArtificial() const {
11936f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
11945f29bb8aSDimitry Andric 
119594994d37SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
119694994d37SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
119794994d37SDimitry Andric 
119894994d37SDimitry Andric   StackFrame *frame = exe_ctx.GetFramePtr();
119994994d37SDimitry Andric   if (frame)
120094994d37SDimitry Andric     return frame->IsArtificial();
120194994d37SDimitry Andric 
120294994d37SDimitry Andric   return false;
120394994d37SDimitry Andric }
120494994d37SDimitry Andric 
GetFunctionName()120514f1b3e8SDimitry Andric const char *SBFrame::GetFunctionName() {
12066f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
12075f29bb8aSDimitry Andric 
12085e95aa85SEd Maste   return static_cast<const SBFrame *>(this)->GetFunctionName();
12095e95aa85SEd Maste }
12105e95aa85SEd Maste 
GuessLanguage() const121174a628f7SDimitry Andric lldb::LanguageType SBFrame::GuessLanguage() const {
12126f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
12135f29bb8aSDimitry Andric 
121474a628f7SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
121574a628f7SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
121674a628f7SDimitry Andric 
121774a628f7SDimitry Andric   StackFrame *frame = nullptr;
121874a628f7SDimitry Andric   Target *target = exe_ctx.GetTargetPtr();
121974a628f7SDimitry Andric   Process *process = exe_ctx.GetProcessPtr();
122074a628f7SDimitry Andric   if (target && process) {
122174a628f7SDimitry Andric     Process::StopLocker stop_locker;
122274a628f7SDimitry Andric     if (stop_locker.TryLock(&process->GetRunLock())) {
122374a628f7SDimitry Andric       frame = exe_ctx.GetFramePtr();
122474a628f7SDimitry Andric       if (frame) {
1225ac9a064cSDimitry Andric         return frame->GuessLanguage().AsLanguageType();
122674a628f7SDimitry Andric       }
122774a628f7SDimitry Andric     }
122874a628f7SDimitry Andric   }
122974a628f7SDimitry Andric   return eLanguageTypeUnknown;
123074a628f7SDimitry Andric }
123174a628f7SDimitry Andric 
GetFunctionName() const123214f1b3e8SDimitry Andric const char *SBFrame::GetFunctionName() const {
12336f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
12345f29bb8aSDimitry Andric 
1235e81d9d49SDimitry Andric   const char *name = nullptr;
1236f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
1237f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1238f3fbd1c0SDimitry Andric 
1239e81d9d49SDimitry Andric   StackFrame *frame = nullptr;
1240f034231aSEd Maste   Target *target = exe_ctx.GetTargetPtr();
1241f034231aSEd Maste   Process *process = exe_ctx.GetProcessPtr();
124214f1b3e8SDimitry Andric   if (target && process) {
1243f034231aSEd Maste     Process::StopLocker stop_locker;
124414f1b3e8SDimitry Andric     if (stop_locker.TryLock(&process->GetRunLock())) {
1245f034231aSEd Maste       frame = exe_ctx.GetFramePtr();
124614f1b3e8SDimitry Andric       if (frame) {
124714f1b3e8SDimitry Andric         SymbolContext sc(frame->GetSymbolContext(eSymbolContextFunction |
124814f1b3e8SDimitry Andric                                                  eSymbolContextBlock |
124914f1b3e8SDimitry Andric                                                  eSymbolContextSymbol));
125014f1b3e8SDimitry Andric         if (sc.block) {
1251f034231aSEd Maste           Block *inlined_block = sc.block->GetContainingInlinedBlock();
125214f1b3e8SDimitry Andric           if (inlined_block) {
125314f1b3e8SDimitry Andric             const InlineFunctionInfo *inlined_info =
125414f1b3e8SDimitry Andric                 inlined_block->GetInlinedFunctionInfo();
1255cfca06d7SDimitry Andric             name = inlined_info->GetName().AsCString();
1256f034231aSEd Maste           }
1257f034231aSEd Maste         }
1258f034231aSEd Maste 
125914f1b3e8SDimitry Andric         if (name == nullptr) {
1260f034231aSEd Maste           if (sc.function)
1261f034231aSEd Maste             name = sc.function->GetName().GetCString();
1262f034231aSEd Maste         }
1263f034231aSEd Maste 
126414f1b3e8SDimitry Andric         if (name == nullptr) {
1265f034231aSEd Maste           if (sc.symbol)
1266f034231aSEd Maste             name = sc.symbol->GetName().GetCString();
1267f034231aSEd Maste         }
1268f034231aSEd Maste       }
1269f034231aSEd Maste     }
1270f034231aSEd Maste   }
1271f034231aSEd Maste   return name;
1272f034231aSEd Maste }
1273027f1c96SDimitry Andric 
GetDisplayFunctionName()127414f1b3e8SDimitry Andric const char *SBFrame::GetDisplayFunctionName() {
12756f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
12765f29bb8aSDimitry Andric 
1277e81d9d49SDimitry Andric   const char *name = nullptr;
1278f3fbd1c0SDimitry Andric 
1279f3fbd1c0SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
1280f3fbd1c0SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1281f3fbd1c0SDimitry Andric 
1282e81d9d49SDimitry Andric   StackFrame *frame = nullptr;
1283027f1c96SDimitry Andric   Target *target = exe_ctx.GetTargetPtr();
1284027f1c96SDimitry Andric   Process *process = exe_ctx.GetProcessPtr();
128514f1b3e8SDimitry Andric   if (target && process) {
1286027f1c96SDimitry Andric     Process::StopLocker stop_locker;
128714f1b3e8SDimitry Andric     if (stop_locker.TryLock(&process->GetRunLock())) {
1288027f1c96SDimitry Andric       frame = exe_ctx.GetFramePtr();
128914f1b3e8SDimitry Andric       if (frame) {
129014f1b3e8SDimitry Andric         SymbolContext sc(frame->GetSymbolContext(eSymbolContextFunction |
129114f1b3e8SDimitry Andric                                                  eSymbolContextBlock |
129214f1b3e8SDimitry Andric                                                  eSymbolContextSymbol));
129314f1b3e8SDimitry Andric         if (sc.block) {
1294027f1c96SDimitry Andric           Block *inlined_block = sc.block->GetContainingInlinedBlock();
129514f1b3e8SDimitry Andric           if (inlined_block) {
129614f1b3e8SDimitry Andric             const InlineFunctionInfo *inlined_info =
129714f1b3e8SDimitry Andric                 inlined_block->GetInlinedFunctionInfo();
1298cfca06d7SDimitry Andric             name = inlined_info->GetDisplayName().AsCString();
1299027f1c96SDimitry Andric           }
1300027f1c96SDimitry Andric         }
1301027f1c96SDimitry Andric 
130214f1b3e8SDimitry Andric         if (name == nullptr) {
1303027f1c96SDimitry Andric           if (sc.function)
1304027f1c96SDimitry Andric             name = sc.function->GetDisplayName().GetCString();
1305027f1c96SDimitry Andric         }
1306027f1c96SDimitry Andric 
130714f1b3e8SDimitry Andric         if (name == nullptr) {
1308027f1c96SDimitry Andric           if (sc.symbol)
1309027f1c96SDimitry Andric             name = sc.symbol->GetDisplayName().GetCString();
1310027f1c96SDimitry Andric         }
1311027f1c96SDimitry Andric       }
1312027f1c96SDimitry Andric     }
1313027f1c96SDimitry Andric   }
1314027f1c96SDimitry Andric   return name;
1315027f1c96SDimitry Andric }
1316