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