xref: /freebsd/contrib/llvm-project/lldb/source/API/SBFrame.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
15ffd83dbSDimitry Andric //===-- SBFrame.cpp -------------------------------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #include <algorithm>
100b57cec5SDimitry Andric #include <set>
110b57cec5SDimitry Andric #include <string>
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "lldb/API/SBFrame.h"
140b57cec5SDimitry Andric 
150b57cec5SDimitry Andric #include "lldb/lldb-types.h"
160b57cec5SDimitry Andric 
170b57cec5SDimitry Andric #include "Utils.h"
180b57cec5SDimitry Andric #include "lldb/Core/Address.h"
1906c3fb27SDimitry Andric #include "lldb/Core/Debugger.h"
200b57cec5SDimitry Andric #include "lldb/Core/ValueObjectRegister.h"
210b57cec5SDimitry Andric #include "lldb/Core/ValueObjectVariable.h"
2206c3fb27SDimitry Andric #include "lldb/Core/ValueObjectConstResult.h"
230b57cec5SDimitry Andric #include "lldb/Expression/ExpressionVariable.h"
240b57cec5SDimitry Andric #include "lldb/Expression/UserExpression.h"
250b57cec5SDimitry Andric #include "lldb/Host/Host.h"
260b57cec5SDimitry Andric #include "lldb/Symbol/Block.h"
270b57cec5SDimitry Andric #include "lldb/Symbol/Function.h"
280b57cec5SDimitry Andric #include "lldb/Symbol/Symbol.h"
290b57cec5SDimitry Andric #include "lldb/Symbol/SymbolContext.h"
300b57cec5SDimitry Andric #include "lldb/Symbol/Variable.h"
310b57cec5SDimitry Andric #include "lldb/Symbol/VariableList.h"
320b57cec5SDimitry Andric #include "lldb/Target/ExecutionContext.h"
330b57cec5SDimitry Andric #include "lldb/Target/Process.h"
340b57cec5SDimitry Andric #include "lldb/Target/RegisterContext.h"
350b57cec5SDimitry Andric #include "lldb/Target/StackFrame.h"
360b57cec5SDimitry Andric #include "lldb/Target/StackFrameRecognizer.h"
370b57cec5SDimitry Andric #include "lldb/Target/StackID.h"
380b57cec5SDimitry Andric #include "lldb/Target/Target.h"
390b57cec5SDimitry Andric #include "lldb/Target/Thread.h"
400b57cec5SDimitry Andric #include "lldb/Utility/ConstString.h"
4104eeddc0SDimitry Andric #include "lldb/Utility/Instrumentation.h"
4281ad6265SDimitry Andric #include "lldb/Utility/LLDBLog.h"
430b57cec5SDimitry Andric #include "lldb/Utility/Stream.h"
440b57cec5SDimitry Andric 
450b57cec5SDimitry Andric #include "lldb/API/SBAddress.h"
460b57cec5SDimitry Andric #include "lldb/API/SBDebugger.h"
470b57cec5SDimitry Andric #include "lldb/API/SBExpressionOptions.h"
485f757f3fSDimitry Andric #include "lldb/API/SBFormat.h"
490b57cec5SDimitry Andric #include "lldb/API/SBStream.h"
500b57cec5SDimitry Andric #include "lldb/API/SBSymbolContext.h"
510b57cec5SDimitry Andric #include "lldb/API/SBThread.h"
520b57cec5SDimitry Andric #include "lldb/API/SBValue.h"
530b57cec5SDimitry Andric #include "lldb/API/SBVariablesOptions.h"
540b57cec5SDimitry Andric 
550b57cec5SDimitry Andric #include "llvm/Support/PrettyStackTrace.h"
560b57cec5SDimitry Andric 
570b57cec5SDimitry Andric using namespace lldb;
580b57cec5SDimitry Andric using namespace lldb_private;
590b57cec5SDimitry Andric 
SBFrame()600b57cec5SDimitry Andric SBFrame::SBFrame() : m_opaque_sp(new ExecutionContextRef()) {
6104eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
620b57cec5SDimitry Andric }
630b57cec5SDimitry Andric 
SBFrame(const StackFrameSP & lldb_object_sp)640b57cec5SDimitry Andric SBFrame::SBFrame(const StackFrameSP &lldb_object_sp)
650b57cec5SDimitry Andric     : m_opaque_sp(new ExecutionContextRef(lldb_object_sp)) {
6604eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, lldb_object_sp);
670b57cec5SDimitry Andric }
680b57cec5SDimitry Andric 
SBFrame(const SBFrame & rhs)6904eeddc0SDimitry Andric SBFrame::SBFrame(const SBFrame &rhs) {
7004eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, rhs);
710b57cec5SDimitry Andric 
720b57cec5SDimitry Andric   m_opaque_sp = clone(rhs.m_opaque_sp);
730b57cec5SDimitry Andric }
740b57cec5SDimitry Andric 
750b57cec5SDimitry Andric SBFrame::~SBFrame() = default;
760b57cec5SDimitry Andric 
operator =(const SBFrame & rhs)770b57cec5SDimitry Andric const SBFrame &SBFrame::operator=(const SBFrame &rhs) {
7804eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, rhs);
790b57cec5SDimitry Andric 
800b57cec5SDimitry Andric   if (this != &rhs)
810b57cec5SDimitry Andric     m_opaque_sp = clone(rhs.m_opaque_sp);
8204eeddc0SDimitry Andric   return *this;
830b57cec5SDimitry Andric }
840b57cec5SDimitry Andric 
GetFrameSP() const850b57cec5SDimitry Andric StackFrameSP SBFrame::GetFrameSP() const {
860b57cec5SDimitry Andric   return (m_opaque_sp ? m_opaque_sp->GetFrameSP() : StackFrameSP());
870b57cec5SDimitry Andric }
880b57cec5SDimitry Andric 
SetFrameSP(const StackFrameSP & lldb_object_sp)890b57cec5SDimitry Andric void SBFrame::SetFrameSP(const StackFrameSP &lldb_object_sp) {
900b57cec5SDimitry Andric   return m_opaque_sp->SetFrameSP(lldb_object_sp);
910b57cec5SDimitry Andric }
920b57cec5SDimitry Andric 
IsValid() const930b57cec5SDimitry Andric bool SBFrame::IsValid() const {
9404eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
950b57cec5SDimitry Andric   return this->operator bool();
960b57cec5SDimitry Andric }
operator bool() const970b57cec5SDimitry Andric SBFrame::operator bool() const {
9804eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
990b57cec5SDimitry Andric 
1000b57cec5SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
1010b57cec5SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1020b57cec5SDimitry Andric 
1030b57cec5SDimitry Andric   Target *target = exe_ctx.GetTargetPtr();
1040b57cec5SDimitry Andric   Process *process = exe_ctx.GetProcessPtr();
1050b57cec5SDimitry Andric   if (target && process) {
1060b57cec5SDimitry Andric     Process::StopLocker stop_locker;
1070b57cec5SDimitry Andric     if (stop_locker.TryLock(&process->GetRunLock()))
1080b57cec5SDimitry Andric       return GetFrameSP().get() != nullptr;
1090b57cec5SDimitry Andric   }
1100b57cec5SDimitry Andric 
1110b57cec5SDimitry Andric   // Without a target & process we can't have a valid stack frame.
1120b57cec5SDimitry Andric   return false;
1130b57cec5SDimitry Andric }
1140b57cec5SDimitry Andric 
GetSymbolContext(uint32_t resolve_scope) const1150b57cec5SDimitry Andric SBSymbolContext SBFrame::GetSymbolContext(uint32_t resolve_scope) const {
11604eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, resolve_scope);
1170b57cec5SDimitry Andric 
1180b57cec5SDimitry Andric   SBSymbolContext sb_sym_ctx;
1190b57cec5SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
1200b57cec5SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1210b57cec5SDimitry Andric   SymbolContextItem scope = static_cast<SymbolContextItem>(resolve_scope);
1220b57cec5SDimitry Andric   Target *target = exe_ctx.GetTargetPtr();
1230b57cec5SDimitry Andric   Process *process = exe_ctx.GetProcessPtr();
1240b57cec5SDimitry Andric   if (target && process) {
1250b57cec5SDimitry Andric     Process::StopLocker stop_locker;
1260b57cec5SDimitry Andric     if (stop_locker.TryLock(&process->GetRunLock())) {
1270eae32dcSDimitry Andric       if (StackFrame *frame = exe_ctx.GetFramePtr())
1280eae32dcSDimitry Andric         sb_sym_ctx = frame->GetSymbolContext(scope);
1290b57cec5SDimitry Andric     }
1300b57cec5SDimitry Andric   }
1310b57cec5SDimitry Andric 
13204eeddc0SDimitry Andric   return sb_sym_ctx;
1330b57cec5SDimitry Andric }
1340b57cec5SDimitry Andric 
GetModule() const1350b57cec5SDimitry Andric SBModule SBFrame::GetModule() const {
13604eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
1370b57cec5SDimitry Andric 
1380b57cec5SDimitry Andric   SBModule sb_module;
1390b57cec5SDimitry Andric   ModuleSP module_sp;
1400b57cec5SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
1410b57cec5SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1420b57cec5SDimitry Andric 
1430b57cec5SDimitry Andric   StackFrame *frame = nullptr;
1440b57cec5SDimitry Andric   Target *target = exe_ctx.GetTargetPtr();
1450b57cec5SDimitry Andric   Process *process = exe_ctx.GetProcessPtr();
1460b57cec5SDimitry Andric   if (target && process) {
1470b57cec5SDimitry Andric     Process::StopLocker stop_locker;
1480b57cec5SDimitry Andric     if (stop_locker.TryLock(&process->GetRunLock())) {
1490b57cec5SDimitry Andric       frame = exe_ctx.GetFramePtr();
1500b57cec5SDimitry Andric       if (frame) {
1510b57cec5SDimitry Andric         module_sp = frame->GetSymbolContext(eSymbolContextModule).module_sp;
1520b57cec5SDimitry Andric         sb_module.SetSP(module_sp);
1530b57cec5SDimitry Andric       }
1540b57cec5SDimitry Andric     }
1550b57cec5SDimitry Andric   }
1560b57cec5SDimitry Andric 
15704eeddc0SDimitry Andric   return sb_module;
1580b57cec5SDimitry Andric }
1590b57cec5SDimitry Andric 
GetCompileUnit() const1600b57cec5SDimitry Andric SBCompileUnit SBFrame::GetCompileUnit() const {
16104eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
1620b57cec5SDimitry Andric 
1630b57cec5SDimitry Andric   SBCompileUnit sb_comp_unit;
1640b57cec5SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
1650b57cec5SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1660b57cec5SDimitry Andric 
1670b57cec5SDimitry Andric   StackFrame *frame = nullptr;
1680b57cec5SDimitry Andric   Target *target = exe_ctx.GetTargetPtr();
1690b57cec5SDimitry Andric   Process *process = exe_ctx.GetProcessPtr();
1700b57cec5SDimitry Andric   if (target && process) {
1710b57cec5SDimitry Andric     Process::StopLocker stop_locker;
1720b57cec5SDimitry Andric     if (stop_locker.TryLock(&process->GetRunLock())) {
1730b57cec5SDimitry Andric       frame = exe_ctx.GetFramePtr();
1740b57cec5SDimitry Andric       if (frame) {
1750b57cec5SDimitry Andric         sb_comp_unit.reset(
1760b57cec5SDimitry Andric             frame->GetSymbolContext(eSymbolContextCompUnit).comp_unit);
1770b57cec5SDimitry Andric       }
1780b57cec5SDimitry Andric     }
1790b57cec5SDimitry Andric   }
1800b57cec5SDimitry Andric 
18104eeddc0SDimitry Andric   return sb_comp_unit;
1820b57cec5SDimitry Andric }
1830b57cec5SDimitry Andric 
GetFunction() const1840b57cec5SDimitry Andric SBFunction SBFrame::GetFunction() const {
18504eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
1860b57cec5SDimitry Andric 
1870b57cec5SDimitry Andric   SBFunction sb_function;
1880b57cec5SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
1890b57cec5SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1900b57cec5SDimitry Andric 
1910b57cec5SDimitry Andric   StackFrame *frame = nullptr;
1920b57cec5SDimitry Andric   Target *target = exe_ctx.GetTargetPtr();
1930b57cec5SDimitry Andric   Process *process = exe_ctx.GetProcessPtr();
1940b57cec5SDimitry Andric   if (target && process) {
1950b57cec5SDimitry Andric     Process::StopLocker stop_locker;
1960b57cec5SDimitry Andric     if (stop_locker.TryLock(&process->GetRunLock())) {
1970b57cec5SDimitry Andric       frame = exe_ctx.GetFramePtr();
1980b57cec5SDimitry Andric       if (frame) {
1990b57cec5SDimitry Andric         sb_function.reset(
2000b57cec5SDimitry Andric             frame->GetSymbolContext(eSymbolContextFunction).function);
2010b57cec5SDimitry Andric       }
2020b57cec5SDimitry Andric     }
2030b57cec5SDimitry Andric   }
2040b57cec5SDimitry Andric 
20504eeddc0SDimitry Andric   return sb_function;
2060b57cec5SDimitry Andric }
2070b57cec5SDimitry Andric 
GetSymbol() const2080b57cec5SDimitry Andric SBSymbol SBFrame::GetSymbol() const {
20904eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
2100b57cec5SDimitry Andric 
2110b57cec5SDimitry Andric   SBSymbol sb_symbol;
2120b57cec5SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
2130b57cec5SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
2140b57cec5SDimitry Andric 
2150b57cec5SDimitry Andric   StackFrame *frame = nullptr;
2160b57cec5SDimitry Andric   Target *target = exe_ctx.GetTargetPtr();
2170b57cec5SDimitry Andric   Process *process = exe_ctx.GetProcessPtr();
2180b57cec5SDimitry Andric   if (target && process) {
2190b57cec5SDimitry Andric     Process::StopLocker stop_locker;
2200b57cec5SDimitry Andric     if (stop_locker.TryLock(&process->GetRunLock())) {
2210b57cec5SDimitry Andric       frame = exe_ctx.GetFramePtr();
2220b57cec5SDimitry Andric       if (frame) {
2230b57cec5SDimitry Andric         sb_symbol.reset(frame->GetSymbolContext(eSymbolContextSymbol).symbol);
2240b57cec5SDimitry Andric       }
2250b57cec5SDimitry Andric     }
2260b57cec5SDimitry Andric   }
2270b57cec5SDimitry Andric 
22804eeddc0SDimitry Andric   return sb_symbol;
2290b57cec5SDimitry Andric }
2300b57cec5SDimitry Andric 
GetBlock() const2310b57cec5SDimitry Andric SBBlock SBFrame::GetBlock() const {
23204eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
2330b57cec5SDimitry Andric 
2340b57cec5SDimitry Andric   SBBlock sb_block;
2350b57cec5SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
2360b57cec5SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
2370b57cec5SDimitry Andric 
2380b57cec5SDimitry Andric   StackFrame *frame = nullptr;
2390b57cec5SDimitry Andric   Target *target = exe_ctx.GetTargetPtr();
2400b57cec5SDimitry Andric   Process *process = exe_ctx.GetProcessPtr();
2410b57cec5SDimitry Andric   if (target && process) {
2420b57cec5SDimitry Andric     Process::StopLocker stop_locker;
2430b57cec5SDimitry Andric     if (stop_locker.TryLock(&process->GetRunLock())) {
2440b57cec5SDimitry Andric       frame = exe_ctx.GetFramePtr();
2450b57cec5SDimitry Andric       if (frame)
2460b57cec5SDimitry Andric         sb_block.SetPtr(frame->GetSymbolContext(eSymbolContextBlock).block);
2470b57cec5SDimitry Andric     }
2480b57cec5SDimitry Andric   }
24904eeddc0SDimitry Andric   return sb_block;
2500b57cec5SDimitry Andric }
2510b57cec5SDimitry Andric 
GetFrameBlock() const2520b57cec5SDimitry Andric SBBlock SBFrame::GetFrameBlock() const {
25304eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
2540b57cec5SDimitry Andric 
2550b57cec5SDimitry Andric   SBBlock sb_block;
2560b57cec5SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
2570b57cec5SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
2580b57cec5SDimitry Andric 
2590b57cec5SDimitry Andric   StackFrame *frame = nullptr;
2600b57cec5SDimitry Andric   Target *target = exe_ctx.GetTargetPtr();
2610b57cec5SDimitry Andric   Process *process = exe_ctx.GetProcessPtr();
2620b57cec5SDimitry Andric   if (target && process) {
2630b57cec5SDimitry Andric     Process::StopLocker stop_locker;
2640b57cec5SDimitry Andric     if (stop_locker.TryLock(&process->GetRunLock())) {
2650b57cec5SDimitry Andric       frame = exe_ctx.GetFramePtr();
2660b57cec5SDimitry Andric       if (frame)
2670b57cec5SDimitry Andric         sb_block.SetPtr(frame->GetFrameBlock());
2680b57cec5SDimitry Andric     }
2690b57cec5SDimitry Andric   }
27004eeddc0SDimitry Andric   return sb_block;
2710b57cec5SDimitry Andric }
2720b57cec5SDimitry Andric 
GetLineEntry() const2730b57cec5SDimitry Andric SBLineEntry SBFrame::GetLineEntry() const {
27404eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
2750b57cec5SDimitry Andric 
2760b57cec5SDimitry Andric   SBLineEntry sb_line_entry;
2770b57cec5SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
2780b57cec5SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
2790b57cec5SDimitry Andric 
2800b57cec5SDimitry Andric   StackFrame *frame = nullptr;
2810b57cec5SDimitry Andric   Target *target = exe_ctx.GetTargetPtr();
2820b57cec5SDimitry Andric   Process *process = exe_ctx.GetProcessPtr();
2830b57cec5SDimitry Andric   if (target && process) {
2840b57cec5SDimitry Andric     Process::StopLocker stop_locker;
2850b57cec5SDimitry Andric     if (stop_locker.TryLock(&process->GetRunLock())) {
2860b57cec5SDimitry Andric       frame = exe_ctx.GetFramePtr();
2870b57cec5SDimitry Andric       if (frame) {
2880b57cec5SDimitry Andric         sb_line_entry.SetLineEntry(
2890b57cec5SDimitry Andric             frame->GetSymbolContext(eSymbolContextLineEntry).line_entry);
2900b57cec5SDimitry Andric       }
2910b57cec5SDimitry Andric     }
2920b57cec5SDimitry Andric   }
29304eeddc0SDimitry Andric   return sb_line_entry;
2940b57cec5SDimitry Andric }
2950b57cec5SDimitry Andric 
GetFrameID() const2960b57cec5SDimitry Andric uint32_t SBFrame::GetFrameID() const {
29704eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
2980b57cec5SDimitry Andric 
2990b57cec5SDimitry Andric   uint32_t frame_idx = UINT32_MAX;
3000b57cec5SDimitry Andric 
3010b57cec5SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
3020b57cec5SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
3030b57cec5SDimitry Andric 
3040b57cec5SDimitry Andric   StackFrame *frame = exe_ctx.GetFramePtr();
3050b57cec5SDimitry Andric   if (frame)
3060b57cec5SDimitry Andric     frame_idx = frame->GetFrameIndex();
3070b57cec5SDimitry Andric 
3080b57cec5SDimitry Andric   return frame_idx;
3090b57cec5SDimitry Andric }
3100b57cec5SDimitry Andric 
GetCFA() const3110b57cec5SDimitry Andric lldb::addr_t SBFrame::GetCFA() const {
31204eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
3130b57cec5SDimitry Andric 
3140b57cec5SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
3150b57cec5SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
3160b57cec5SDimitry Andric 
3170b57cec5SDimitry Andric   StackFrame *frame = exe_ctx.GetFramePtr();
3180b57cec5SDimitry Andric   if (frame)
3190b57cec5SDimitry Andric     return frame->GetStackID().GetCallFrameAddress();
3200b57cec5SDimitry Andric   return LLDB_INVALID_ADDRESS;
3210b57cec5SDimitry Andric }
3220b57cec5SDimitry Andric 
GetPC() const3230b57cec5SDimitry Andric addr_t SBFrame::GetPC() const {
32404eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
3250b57cec5SDimitry Andric 
3260b57cec5SDimitry Andric   addr_t addr = LLDB_INVALID_ADDRESS;
3270b57cec5SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
3280b57cec5SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
3290b57cec5SDimitry Andric 
3300b57cec5SDimitry Andric   StackFrame *frame = nullptr;
3310b57cec5SDimitry Andric   Target *target = exe_ctx.GetTargetPtr();
3320b57cec5SDimitry Andric   Process *process = exe_ctx.GetProcessPtr();
3330b57cec5SDimitry Andric   if (target && process) {
3340b57cec5SDimitry Andric     Process::StopLocker stop_locker;
3350b57cec5SDimitry Andric     if (stop_locker.TryLock(&process->GetRunLock())) {
3360b57cec5SDimitry Andric       frame = exe_ctx.GetFramePtr();
3370b57cec5SDimitry Andric       if (frame) {
3380b57cec5SDimitry Andric         addr = frame->GetFrameCodeAddress().GetOpcodeLoadAddress(
3390b57cec5SDimitry Andric             target, AddressClass::eCode);
3400b57cec5SDimitry Andric       }
3410b57cec5SDimitry Andric     }
3420b57cec5SDimitry Andric   }
3430b57cec5SDimitry Andric 
3440b57cec5SDimitry Andric   return addr;
3450b57cec5SDimitry Andric }
3460b57cec5SDimitry Andric 
SetPC(addr_t new_pc)3470b57cec5SDimitry Andric bool SBFrame::SetPC(addr_t new_pc) {
34804eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, new_pc);
3490b57cec5SDimitry Andric 
3500b57cec5SDimitry Andric   bool ret_val = false;
3510b57cec5SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
3520b57cec5SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
3530b57cec5SDimitry Andric 
3540b57cec5SDimitry Andric   Target *target = exe_ctx.GetTargetPtr();
3550b57cec5SDimitry Andric   Process *process = exe_ctx.GetProcessPtr();
3560b57cec5SDimitry Andric   if (target && process) {
3570b57cec5SDimitry Andric     Process::StopLocker stop_locker;
3580b57cec5SDimitry Andric     if (stop_locker.TryLock(&process->GetRunLock())) {
3595ffd83dbSDimitry Andric       if (StackFrame *frame = exe_ctx.GetFramePtr()) {
3605ffd83dbSDimitry Andric         if (RegisterContextSP reg_ctx_sp = frame->GetRegisterContext()) {
3615ffd83dbSDimitry Andric           ret_val = reg_ctx_sp->SetPC(new_pc);
3625ffd83dbSDimitry Andric         }
3630b57cec5SDimitry Andric       }
3640b57cec5SDimitry Andric     }
3650b57cec5SDimitry Andric   }
3660b57cec5SDimitry Andric 
3670b57cec5SDimitry Andric   return ret_val;
3680b57cec5SDimitry Andric }
3690b57cec5SDimitry Andric 
GetSP() const3700b57cec5SDimitry Andric addr_t SBFrame::GetSP() const {
37104eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
3720b57cec5SDimitry Andric 
3730b57cec5SDimitry Andric   addr_t addr = LLDB_INVALID_ADDRESS;
3740b57cec5SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
3750b57cec5SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
3760b57cec5SDimitry Andric 
3770b57cec5SDimitry Andric   Target *target = exe_ctx.GetTargetPtr();
3780b57cec5SDimitry Andric   Process *process = exe_ctx.GetProcessPtr();
3790b57cec5SDimitry Andric   if (target && process) {
3800b57cec5SDimitry Andric     Process::StopLocker stop_locker;
3810b57cec5SDimitry Andric     if (stop_locker.TryLock(&process->GetRunLock())) {
3825ffd83dbSDimitry Andric       if (StackFrame *frame = exe_ctx.GetFramePtr()) {
3835ffd83dbSDimitry Andric         if (RegisterContextSP reg_ctx_sp = frame->GetRegisterContext()) {
3845ffd83dbSDimitry Andric           addr = reg_ctx_sp->GetSP();
3855ffd83dbSDimitry Andric         }
3860b57cec5SDimitry Andric       }
3870b57cec5SDimitry Andric     }
3880b57cec5SDimitry Andric   }
3890b57cec5SDimitry Andric 
3900b57cec5SDimitry Andric   return addr;
3910b57cec5SDimitry Andric }
3920b57cec5SDimitry Andric 
GetFP() const3930b57cec5SDimitry Andric addr_t SBFrame::GetFP() const {
39404eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
3950b57cec5SDimitry Andric 
3960b57cec5SDimitry Andric   addr_t addr = LLDB_INVALID_ADDRESS;
3970b57cec5SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
3980b57cec5SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
3990b57cec5SDimitry Andric 
4000b57cec5SDimitry Andric   Target *target = exe_ctx.GetTargetPtr();
4010b57cec5SDimitry Andric   Process *process = exe_ctx.GetProcessPtr();
4020b57cec5SDimitry Andric   if (target && process) {
4030b57cec5SDimitry Andric     Process::StopLocker stop_locker;
4040b57cec5SDimitry Andric     if (stop_locker.TryLock(&process->GetRunLock())) {
4055ffd83dbSDimitry Andric       if (StackFrame *frame = exe_ctx.GetFramePtr()) {
4065ffd83dbSDimitry Andric         if (RegisterContextSP reg_ctx_sp = frame->GetRegisterContext()) {
4075ffd83dbSDimitry Andric           addr = reg_ctx_sp->GetFP();
4085ffd83dbSDimitry Andric         }
4095ffd83dbSDimitry Andric       }
4100b57cec5SDimitry Andric     }
4110b57cec5SDimitry Andric   }
4120b57cec5SDimitry Andric 
4130b57cec5SDimitry Andric   return addr;
4140b57cec5SDimitry Andric }
4150b57cec5SDimitry Andric 
GetPCAddress() const4160b57cec5SDimitry Andric SBAddress SBFrame::GetPCAddress() const {
41704eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
4180b57cec5SDimitry Andric 
4190b57cec5SDimitry Andric   SBAddress sb_addr;
4200b57cec5SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
4210b57cec5SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
4220b57cec5SDimitry Andric 
4230b57cec5SDimitry Andric   StackFrame *frame = exe_ctx.GetFramePtr();
4240b57cec5SDimitry Andric   Target *target = exe_ctx.GetTargetPtr();
4250b57cec5SDimitry Andric   Process *process = exe_ctx.GetProcessPtr();
4260b57cec5SDimitry Andric   if (target && process) {
4270b57cec5SDimitry Andric     Process::StopLocker stop_locker;
4280b57cec5SDimitry Andric     if (stop_locker.TryLock(&process->GetRunLock())) {
4290b57cec5SDimitry Andric       frame = exe_ctx.GetFramePtr();
4300b57cec5SDimitry Andric       if (frame)
431e8d8bef9SDimitry Andric         sb_addr.SetAddress(frame->GetFrameCodeAddress());
4320b57cec5SDimitry Andric     }
4330b57cec5SDimitry Andric   }
43404eeddc0SDimitry Andric   return sb_addr;
4350b57cec5SDimitry Andric }
4360b57cec5SDimitry Andric 
Clear()4370b57cec5SDimitry Andric void SBFrame::Clear() {
43804eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
4390b57cec5SDimitry Andric 
4400b57cec5SDimitry Andric   m_opaque_sp->Clear();
4410b57cec5SDimitry Andric }
4420b57cec5SDimitry Andric 
GetValueForVariablePath(const char * var_path)4430b57cec5SDimitry Andric lldb::SBValue SBFrame::GetValueForVariablePath(const char *var_path) {
44404eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, var_path);
4450b57cec5SDimitry Andric 
4460b57cec5SDimitry Andric   SBValue sb_value;
4470b57cec5SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
4480b57cec5SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
4490b57cec5SDimitry Andric 
4500b57cec5SDimitry Andric   StackFrame *frame = exe_ctx.GetFramePtr();
4510b57cec5SDimitry Andric   Target *target = exe_ctx.GetTargetPtr();
4520b57cec5SDimitry Andric   if (frame && target) {
4530b57cec5SDimitry Andric     lldb::DynamicValueType use_dynamic =
4540b57cec5SDimitry Andric         frame->CalculateTarget()->GetPreferDynamicValue();
4550b57cec5SDimitry Andric     sb_value = GetValueForVariablePath(var_path, use_dynamic);
4560b57cec5SDimitry Andric   }
45704eeddc0SDimitry Andric   return sb_value;
4580b57cec5SDimitry Andric }
4590b57cec5SDimitry Andric 
GetValueForVariablePath(const char * var_path,DynamicValueType use_dynamic)4600b57cec5SDimitry Andric lldb::SBValue SBFrame::GetValueForVariablePath(const char *var_path,
4610b57cec5SDimitry Andric                                                DynamicValueType use_dynamic) {
46204eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, var_path, use_dynamic);
4630b57cec5SDimitry Andric 
4640b57cec5SDimitry Andric   SBValue sb_value;
4650b57cec5SDimitry Andric   if (var_path == nullptr || var_path[0] == '\0') {
46604eeddc0SDimitry Andric     return sb_value;
4670b57cec5SDimitry Andric   }
4680b57cec5SDimitry Andric 
4690b57cec5SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
4700b57cec5SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
4710b57cec5SDimitry Andric 
4720b57cec5SDimitry Andric   StackFrame *frame = nullptr;
4730b57cec5SDimitry Andric   Target *target = exe_ctx.GetTargetPtr();
4740b57cec5SDimitry Andric   Process *process = exe_ctx.GetProcessPtr();
4750b57cec5SDimitry Andric   if (target && process) {
4760b57cec5SDimitry Andric     Process::StopLocker stop_locker;
4770b57cec5SDimitry Andric     if (stop_locker.TryLock(&process->GetRunLock())) {
4780b57cec5SDimitry Andric       frame = exe_ctx.GetFramePtr();
4790b57cec5SDimitry Andric       if (frame) {
4800b57cec5SDimitry Andric         VariableSP var_sp;
4810b57cec5SDimitry Andric         Status error;
4820b57cec5SDimitry Andric         ValueObjectSP value_sp(frame->GetValueForVariableExpressionPath(
4830b57cec5SDimitry Andric             var_path, eNoDynamicValues,
4840b57cec5SDimitry Andric             StackFrame::eExpressionPathOptionCheckPtrVsMember |
4850b57cec5SDimitry Andric                 StackFrame::eExpressionPathOptionsAllowDirectIVarAccess,
4860b57cec5SDimitry Andric             var_sp, error));
4870b57cec5SDimitry Andric         sb_value.SetSP(value_sp, use_dynamic);
4880b57cec5SDimitry Andric       }
4890b57cec5SDimitry Andric     }
4900b57cec5SDimitry Andric   }
49104eeddc0SDimitry Andric   return sb_value;
4920b57cec5SDimitry Andric }
4930b57cec5SDimitry Andric 
FindVariable(const char * name)4940b57cec5SDimitry Andric SBValue SBFrame::FindVariable(const char *name) {
49504eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, name);
4960b57cec5SDimitry Andric 
4970b57cec5SDimitry Andric   SBValue value;
4980b57cec5SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
4990b57cec5SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
5000b57cec5SDimitry Andric 
5010b57cec5SDimitry Andric   StackFrame *frame = exe_ctx.GetFramePtr();
5020b57cec5SDimitry Andric   Target *target = exe_ctx.GetTargetPtr();
5030b57cec5SDimitry Andric   if (frame && target) {
5040b57cec5SDimitry Andric     lldb::DynamicValueType use_dynamic =
5050b57cec5SDimitry Andric         frame->CalculateTarget()->GetPreferDynamicValue();
5060b57cec5SDimitry Andric     value = FindVariable(name, use_dynamic);
5070b57cec5SDimitry Andric   }
50804eeddc0SDimitry Andric   return value;
5090b57cec5SDimitry Andric }
5100b57cec5SDimitry Andric 
FindVariable(const char * name,lldb::DynamicValueType use_dynamic)5110b57cec5SDimitry Andric SBValue SBFrame::FindVariable(const char *name,
5120b57cec5SDimitry Andric                               lldb::DynamicValueType use_dynamic) {
51304eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, name, use_dynamic);
5140b57cec5SDimitry Andric 
5150b57cec5SDimitry Andric   VariableSP var_sp;
5160b57cec5SDimitry Andric   SBValue sb_value;
5170b57cec5SDimitry Andric 
5180b57cec5SDimitry Andric   if (name == nullptr || name[0] == '\0') {
51904eeddc0SDimitry Andric     return sb_value;
5200b57cec5SDimitry Andric   }
5210b57cec5SDimitry Andric 
5220b57cec5SDimitry Andric   ValueObjectSP value_sp;
5230b57cec5SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
5240b57cec5SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
5250b57cec5SDimitry Andric 
5260b57cec5SDimitry Andric   StackFrame *frame = nullptr;
5270b57cec5SDimitry Andric   Target *target = exe_ctx.GetTargetPtr();
5280b57cec5SDimitry Andric   Process *process = exe_ctx.GetProcessPtr();
5290b57cec5SDimitry Andric   if (target && process) {
5300b57cec5SDimitry Andric     Process::StopLocker stop_locker;
5310b57cec5SDimitry Andric     if (stop_locker.TryLock(&process->GetRunLock())) {
5320b57cec5SDimitry Andric       frame = exe_ctx.GetFramePtr();
5330b57cec5SDimitry Andric       if (frame) {
5340b57cec5SDimitry Andric         value_sp = frame->FindVariable(ConstString(name));
5350b57cec5SDimitry Andric 
5360b57cec5SDimitry Andric         if (value_sp)
5370b57cec5SDimitry Andric           sb_value.SetSP(value_sp, use_dynamic);
5380b57cec5SDimitry Andric       }
5390b57cec5SDimitry Andric     }
5400b57cec5SDimitry Andric   }
5410b57cec5SDimitry Andric 
54204eeddc0SDimitry Andric   return sb_value;
5430b57cec5SDimitry Andric }
5440b57cec5SDimitry Andric 
FindValue(const char * name,ValueType value_type)5450b57cec5SDimitry Andric SBValue SBFrame::FindValue(const char *name, ValueType value_type) {
54604eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, name, value_type);
5470b57cec5SDimitry Andric 
5480b57cec5SDimitry Andric   SBValue value;
5490b57cec5SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
5500b57cec5SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
5510b57cec5SDimitry Andric 
5520b57cec5SDimitry Andric   StackFrame *frame = exe_ctx.GetFramePtr();
5530b57cec5SDimitry Andric   Target *target = exe_ctx.GetTargetPtr();
5540b57cec5SDimitry Andric   if (frame && target) {
5550b57cec5SDimitry Andric     lldb::DynamicValueType use_dynamic =
5560b57cec5SDimitry Andric         frame->CalculateTarget()->GetPreferDynamicValue();
5570b57cec5SDimitry Andric     value = FindValue(name, value_type, use_dynamic);
5580b57cec5SDimitry Andric   }
55904eeddc0SDimitry Andric   return value;
5600b57cec5SDimitry Andric }
5610b57cec5SDimitry Andric 
FindValue(const char * name,ValueType value_type,lldb::DynamicValueType use_dynamic)5620b57cec5SDimitry Andric SBValue SBFrame::FindValue(const char *name, ValueType value_type,
5630b57cec5SDimitry Andric                            lldb::DynamicValueType use_dynamic) {
56404eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, name, value_type, use_dynamic);
5650b57cec5SDimitry Andric 
5660b57cec5SDimitry Andric   SBValue sb_value;
5670b57cec5SDimitry Andric 
5680b57cec5SDimitry Andric   if (name == nullptr || name[0] == '\0') {
56904eeddc0SDimitry Andric     return sb_value;
5700b57cec5SDimitry Andric   }
5710b57cec5SDimitry Andric 
5720b57cec5SDimitry Andric   ValueObjectSP value_sp;
5730b57cec5SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
5740b57cec5SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
5750b57cec5SDimitry Andric 
5760b57cec5SDimitry Andric   StackFrame *frame = nullptr;
5770b57cec5SDimitry Andric   Target *target = exe_ctx.GetTargetPtr();
5780b57cec5SDimitry Andric   Process *process = exe_ctx.GetProcessPtr();
5790b57cec5SDimitry Andric   if (target && process) {
5800b57cec5SDimitry Andric     Process::StopLocker stop_locker;
5810b57cec5SDimitry Andric     if (stop_locker.TryLock(&process->GetRunLock())) {
5820b57cec5SDimitry Andric       frame = exe_ctx.GetFramePtr();
5830b57cec5SDimitry Andric       if (frame) {
5840b57cec5SDimitry Andric         VariableList variable_list;
5850b57cec5SDimitry Andric 
5860b57cec5SDimitry Andric         switch (value_type) {
5870b57cec5SDimitry Andric         case eValueTypeVariableGlobal:      // global variable
5880b57cec5SDimitry Andric         case eValueTypeVariableStatic:      // static variable
5890b57cec5SDimitry Andric         case eValueTypeVariableArgument:    // function argument variables
5900b57cec5SDimitry Andric         case eValueTypeVariableLocal:       // function local variables
5910b57cec5SDimitry Andric         case eValueTypeVariableThreadLocal: // thread local variables
5920b57cec5SDimitry Andric         {
5930b57cec5SDimitry Andric           SymbolContext sc(frame->GetSymbolContext(eSymbolContextBlock));
5940b57cec5SDimitry Andric 
5950b57cec5SDimitry Andric           const bool can_create = true;
5960b57cec5SDimitry Andric           const bool get_parent_variables = true;
5970b57cec5SDimitry Andric           const bool stop_if_block_is_inlined_function = true;
5980b57cec5SDimitry Andric 
5990b57cec5SDimitry Andric           if (sc.block)
6000b57cec5SDimitry Andric             sc.block->AppendVariables(
6010b57cec5SDimitry Andric                 can_create, get_parent_variables,
6020b57cec5SDimitry Andric                 stop_if_block_is_inlined_function,
6030b57cec5SDimitry Andric                 [frame](Variable *v) { return v->IsInScope(frame); },
6040b57cec5SDimitry Andric                 &variable_list);
60506c3fb27SDimitry Andric           if (value_type == eValueTypeVariableGlobal
60606c3fb27SDimitry Andric               || value_type == eValueTypeVariableStatic) {
6070b57cec5SDimitry Andric             const bool get_file_globals = true;
608bdd1243dSDimitry Andric             VariableList *frame_vars = frame->GetVariableList(get_file_globals,
609bdd1243dSDimitry Andric                                                               nullptr);
6100b57cec5SDimitry Andric             if (frame_vars)
6110b57cec5SDimitry Andric               frame_vars->AppendVariablesIfUnique(variable_list);
6120b57cec5SDimitry Andric           }
6130b57cec5SDimitry Andric           ConstString const_name(name);
6140b57cec5SDimitry Andric           VariableSP variable_sp(
6150b57cec5SDimitry Andric               variable_list.FindVariable(const_name, value_type));
6160b57cec5SDimitry Andric           if (variable_sp) {
6170b57cec5SDimitry Andric             value_sp = frame->GetValueObjectForFrameVariable(variable_sp,
6180b57cec5SDimitry Andric                                                              eNoDynamicValues);
6190b57cec5SDimitry Andric             sb_value.SetSP(value_sp, use_dynamic);
6200b57cec5SDimitry Andric           }
6210b57cec5SDimitry Andric         } break;
6220b57cec5SDimitry Andric 
6230b57cec5SDimitry Andric         case eValueTypeRegister: // stack frame register value
6240b57cec5SDimitry Andric         {
6250b57cec5SDimitry Andric           RegisterContextSP reg_ctx(frame->GetRegisterContext());
6260b57cec5SDimitry Andric           if (reg_ctx) {
627349cc55cSDimitry Andric             if (const RegisterInfo *reg_info =
628349cc55cSDimitry Andric                     reg_ctx->GetRegisterInfoByName(name)) {
629349cc55cSDimitry Andric               value_sp = ValueObjectRegister::Create(frame, reg_ctx, reg_info);
6300b57cec5SDimitry Andric               sb_value.SetSP(value_sp);
6310b57cec5SDimitry Andric             }
6320b57cec5SDimitry Andric           }
6330b57cec5SDimitry Andric         } break;
6340b57cec5SDimitry Andric 
6350b57cec5SDimitry Andric         case eValueTypeRegisterSet: // A collection of stack frame register
6360b57cec5SDimitry Andric                                     // values
6370b57cec5SDimitry Andric         {
6380b57cec5SDimitry Andric           RegisterContextSP reg_ctx(frame->GetRegisterContext());
6390b57cec5SDimitry Andric           if (reg_ctx) {
6400b57cec5SDimitry Andric             const uint32_t num_sets = reg_ctx->GetRegisterSetCount();
6410b57cec5SDimitry Andric             for (uint32_t set_idx = 0; set_idx < num_sets; ++set_idx) {
6420b57cec5SDimitry Andric               const RegisterSet *reg_set = reg_ctx->GetRegisterSet(set_idx);
6430b57cec5SDimitry Andric               if (reg_set &&
64481ad6265SDimitry Andric                   (llvm::StringRef(reg_set->name).equals_insensitive(name) ||
64581ad6265SDimitry Andric                    llvm::StringRef(reg_set->short_name)
64681ad6265SDimitry Andric                        .equals_insensitive(name))) {
6470b57cec5SDimitry Andric                 value_sp =
6480b57cec5SDimitry Andric                     ValueObjectRegisterSet::Create(frame, reg_ctx, set_idx);
6490b57cec5SDimitry Andric                 sb_value.SetSP(value_sp);
6500b57cec5SDimitry Andric                 break;
6510b57cec5SDimitry Andric               }
6520b57cec5SDimitry Andric             }
6530b57cec5SDimitry Andric           }
6540b57cec5SDimitry Andric         } break;
6550b57cec5SDimitry Andric 
6560b57cec5SDimitry Andric         case eValueTypeConstResult: // constant result variables
6570b57cec5SDimitry Andric         {
6580b57cec5SDimitry Andric           ConstString const_name(name);
6590b57cec5SDimitry Andric           ExpressionVariableSP expr_var_sp(
6600b57cec5SDimitry Andric               target->GetPersistentVariable(const_name));
6610b57cec5SDimitry Andric           if (expr_var_sp) {
6620b57cec5SDimitry Andric             value_sp = expr_var_sp->GetValueObject();
6630b57cec5SDimitry Andric             sb_value.SetSP(value_sp, use_dynamic);
6640b57cec5SDimitry Andric           }
6650b57cec5SDimitry Andric         } break;
6660b57cec5SDimitry Andric 
6670b57cec5SDimitry Andric         default:
6680b57cec5SDimitry Andric           break;
6690b57cec5SDimitry Andric         }
6700b57cec5SDimitry Andric       }
6710b57cec5SDimitry Andric     }
6720b57cec5SDimitry Andric   }
6730b57cec5SDimitry Andric 
67404eeddc0SDimitry Andric   return sb_value;
6750b57cec5SDimitry Andric }
6760b57cec5SDimitry Andric 
IsEqual(const SBFrame & that) const6770b57cec5SDimitry Andric bool SBFrame::IsEqual(const SBFrame &that) const {
67804eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, that);
6790b57cec5SDimitry Andric 
6800b57cec5SDimitry Andric   lldb::StackFrameSP this_sp = GetFrameSP();
6810b57cec5SDimitry Andric   lldb::StackFrameSP that_sp = that.GetFrameSP();
6820b57cec5SDimitry Andric   return (this_sp && that_sp && this_sp->GetStackID() == that_sp->GetStackID());
6830b57cec5SDimitry Andric }
6840b57cec5SDimitry Andric 
operator ==(const SBFrame & rhs) const6850b57cec5SDimitry Andric bool SBFrame::operator==(const SBFrame &rhs) const {
68604eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, rhs);
6870b57cec5SDimitry Andric 
6880b57cec5SDimitry Andric   return IsEqual(rhs);
6890b57cec5SDimitry Andric }
6900b57cec5SDimitry Andric 
operator !=(const SBFrame & rhs) const6910b57cec5SDimitry Andric bool SBFrame::operator!=(const SBFrame &rhs) const {
69204eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, rhs);
6930b57cec5SDimitry Andric 
6940b57cec5SDimitry Andric   return !IsEqual(rhs);
6950b57cec5SDimitry Andric }
6960b57cec5SDimitry Andric 
GetThread() const6970b57cec5SDimitry Andric SBThread SBFrame::GetThread() const {
69804eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
6990b57cec5SDimitry Andric 
7000b57cec5SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
7010b57cec5SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
7020b57cec5SDimitry Andric 
7030b57cec5SDimitry Andric   ThreadSP thread_sp(exe_ctx.GetThreadSP());
7040b57cec5SDimitry Andric   SBThread sb_thread(thread_sp);
7050b57cec5SDimitry Andric 
70604eeddc0SDimitry Andric   return sb_thread;
7070b57cec5SDimitry Andric }
7080b57cec5SDimitry Andric 
Disassemble() const7090b57cec5SDimitry Andric const char *SBFrame::Disassemble() const {
71004eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
7110b57cec5SDimitry Andric 
7120b57cec5SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
7130b57cec5SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
7140b57cec5SDimitry Andric   Target *target = exe_ctx.GetTargetPtr();
7150b57cec5SDimitry Andric   Process *process = exe_ctx.GetProcessPtr();
71606c3fb27SDimitry Andric   if (!target || !process)
71706c3fb27SDimitry Andric     return nullptr;
71806c3fb27SDimitry Andric 
7190b57cec5SDimitry Andric   Process::StopLocker stop_locker;
7200b57cec5SDimitry Andric   if (stop_locker.TryLock(&process->GetRunLock())) {
72106c3fb27SDimitry Andric     if (auto *frame = exe_ctx.GetFramePtr())
72206c3fb27SDimitry Andric       return ConstString(frame->Disassemble()).GetCString();
7230b57cec5SDimitry Andric   }
7240b57cec5SDimitry Andric 
72506c3fb27SDimitry Andric   return nullptr;
7260b57cec5SDimitry Andric }
7270b57cec5SDimitry Andric 
GetVariables(bool arguments,bool locals,bool statics,bool in_scope_only)7280b57cec5SDimitry Andric SBValueList SBFrame::GetVariables(bool arguments, bool locals, bool statics,
7290b57cec5SDimitry Andric                                   bool in_scope_only) {
73004eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, arguments, locals, statics, in_scope_only);
7310b57cec5SDimitry Andric 
7320b57cec5SDimitry Andric   SBValueList value_list;
7330b57cec5SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
7340b57cec5SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
7350b57cec5SDimitry Andric 
7360b57cec5SDimitry Andric   StackFrame *frame = exe_ctx.GetFramePtr();
7370b57cec5SDimitry Andric   Target *target = exe_ctx.GetTargetPtr();
7380b57cec5SDimitry Andric   if (frame && target) {
7390b57cec5SDimitry Andric     lldb::DynamicValueType use_dynamic =
7400b57cec5SDimitry Andric         frame->CalculateTarget()->GetPreferDynamicValue();
7410b57cec5SDimitry Andric     const bool include_runtime_support_values =
742bdd1243dSDimitry Andric         target->GetDisplayRuntimeSupportValues();
7430b57cec5SDimitry Andric 
7440b57cec5SDimitry Andric     SBVariablesOptions options;
7450b57cec5SDimitry Andric     options.SetIncludeArguments(arguments);
7460b57cec5SDimitry Andric     options.SetIncludeLocals(locals);
7470b57cec5SDimitry Andric     options.SetIncludeStatics(statics);
7480b57cec5SDimitry Andric     options.SetInScopeOnly(in_scope_only);
7490b57cec5SDimitry Andric     options.SetIncludeRuntimeSupportValues(include_runtime_support_values);
7500b57cec5SDimitry Andric     options.SetUseDynamic(use_dynamic);
7510b57cec5SDimitry Andric 
7520b57cec5SDimitry Andric     value_list = GetVariables(options);
7530b57cec5SDimitry Andric   }
75404eeddc0SDimitry Andric   return value_list;
7550b57cec5SDimitry Andric }
7560b57cec5SDimitry Andric 
GetVariables(bool arguments,bool locals,bool statics,bool in_scope_only,lldb::DynamicValueType use_dynamic)7570b57cec5SDimitry Andric lldb::SBValueList SBFrame::GetVariables(bool arguments, bool locals,
7580b57cec5SDimitry Andric                                         bool statics, bool in_scope_only,
7590b57cec5SDimitry Andric                                         lldb::DynamicValueType use_dynamic) {
76004eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, arguments, locals, statics, in_scope_only,
76104eeddc0SDimitry Andric                      use_dynamic);
7620b57cec5SDimitry Andric 
7630b57cec5SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
7640b57cec5SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
7650b57cec5SDimitry Andric 
7660b57cec5SDimitry Andric   Target *target = exe_ctx.GetTargetPtr();
7670b57cec5SDimitry Andric   const bool include_runtime_support_values =
7680b57cec5SDimitry Andric       target ? target->GetDisplayRuntimeSupportValues() : false;
7690b57cec5SDimitry Andric   SBVariablesOptions options;
7700b57cec5SDimitry Andric   options.SetIncludeArguments(arguments);
7710b57cec5SDimitry Andric   options.SetIncludeLocals(locals);
7720b57cec5SDimitry Andric   options.SetIncludeStatics(statics);
7730b57cec5SDimitry Andric   options.SetInScopeOnly(in_scope_only);
7740b57cec5SDimitry Andric   options.SetIncludeRuntimeSupportValues(include_runtime_support_values);
7750b57cec5SDimitry Andric   options.SetUseDynamic(use_dynamic);
77604eeddc0SDimitry Andric   return GetVariables(options);
7770b57cec5SDimitry Andric }
7780b57cec5SDimitry Andric 
GetVariables(const lldb::SBVariablesOptions & options)7790b57cec5SDimitry Andric SBValueList SBFrame::GetVariables(const lldb::SBVariablesOptions &options) {
78004eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, options);
7810b57cec5SDimitry Andric 
7820b57cec5SDimitry Andric   SBValueList value_list;
7830b57cec5SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
7840b57cec5SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
7850b57cec5SDimitry Andric 
7860b57cec5SDimitry Andric   StackFrame *frame = nullptr;
7870b57cec5SDimitry Andric   Target *target = exe_ctx.GetTargetPtr();
7880b57cec5SDimitry Andric 
7890b57cec5SDimitry Andric   const bool statics = options.GetIncludeStatics();
7900b57cec5SDimitry Andric   const bool arguments = options.GetIncludeArguments();
7910b57cec5SDimitry Andric   const bool recognized_arguments =
7920b57cec5SDimitry Andric         options.GetIncludeRecognizedArguments(SBTarget(exe_ctx.GetTargetSP()));
7930b57cec5SDimitry Andric   const bool locals = options.GetIncludeLocals();
7940b57cec5SDimitry Andric   const bool in_scope_only = options.GetInScopeOnly();
7950b57cec5SDimitry Andric   const bool include_runtime_support_values =
7960b57cec5SDimitry Andric       options.GetIncludeRuntimeSupportValues();
7970b57cec5SDimitry Andric   const lldb::DynamicValueType use_dynamic = options.GetUseDynamic();
7980b57cec5SDimitry Andric 
7990b57cec5SDimitry Andric 
8000b57cec5SDimitry Andric   std::set<VariableSP> variable_set;
8010b57cec5SDimitry Andric   Process *process = exe_ctx.GetProcessPtr();
8020b57cec5SDimitry Andric   if (target && process) {
8030b57cec5SDimitry Andric     Process::StopLocker stop_locker;
8040b57cec5SDimitry Andric     if (stop_locker.TryLock(&process->GetRunLock())) {
8050b57cec5SDimitry Andric       frame = exe_ctx.GetFramePtr();
8060b57cec5SDimitry Andric       if (frame) {
80706c3fb27SDimitry Andric         Debugger &dbg = process->GetTarget().GetDebugger();
8080b57cec5SDimitry Andric         VariableList *variable_list = nullptr;
809bdd1243dSDimitry Andric         Status var_error;
810bdd1243dSDimitry Andric         variable_list = frame->GetVariableList(true, &var_error);
811bdd1243dSDimitry Andric         if (var_error.Fail())
812bdd1243dSDimitry Andric           value_list.SetError(var_error);
8130b57cec5SDimitry Andric         if (variable_list) {
8140b57cec5SDimitry Andric           const size_t num_variables = variable_list->GetSize();
8150b57cec5SDimitry Andric           if (num_variables) {
81606c3fb27SDimitry Andric             size_t num_produced = 0;
817480093f4SDimitry Andric             for (const VariableSP &variable_sp : *variable_list) {
81806c3fb27SDimitry Andric               if (INTERRUPT_REQUESTED(dbg,
81906c3fb27SDimitry Andric                     "Interrupted getting frame variables with {0} of {1} "
82006c3fb27SDimitry Andric                     "produced.", num_produced, num_variables))
82106c3fb27SDimitry Andric                 return {};
82206c3fb27SDimitry Andric 
8230b57cec5SDimitry Andric               if (variable_sp) {
8240b57cec5SDimitry Andric                 bool add_variable = false;
8250b57cec5SDimitry Andric                 switch (variable_sp->GetScope()) {
8260b57cec5SDimitry Andric                 case eValueTypeVariableGlobal:
8270b57cec5SDimitry Andric                 case eValueTypeVariableStatic:
8280b57cec5SDimitry Andric                 case eValueTypeVariableThreadLocal:
8290b57cec5SDimitry Andric                   add_variable = statics;
8300b57cec5SDimitry Andric                   break;
8310b57cec5SDimitry Andric 
8320b57cec5SDimitry Andric                 case eValueTypeVariableArgument:
8330b57cec5SDimitry Andric                   add_variable = arguments;
8340b57cec5SDimitry Andric                   break;
8350b57cec5SDimitry Andric 
8360b57cec5SDimitry Andric                 case eValueTypeVariableLocal:
8370b57cec5SDimitry Andric                   add_variable = locals;
8380b57cec5SDimitry Andric                   break;
8390b57cec5SDimitry Andric 
8400b57cec5SDimitry Andric                 default:
8410b57cec5SDimitry Andric                   break;
8420b57cec5SDimitry Andric                 }
8430b57cec5SDimitry Andric                 if (add_variable) {
8440b57cec5SDimitry Andric                   // Only add variables once so we don't end up with duplicates
8450b57cec5SDimitry Andric                   if (variable_set.find(variable_sp) == variable_set.end())
8460b57cec5SDimitry Andric                     variable_set.insert(variable_sp);
8470b57cec5SDimitry Andric                   else
8480b57cec5SDimitry Andric                     continue;
8490b57cec5SDimitry Andric 
8500b57cec5SDimitry Andric                   if (in_scope_only && !variable_sp->IsInScope(frame))
8510b57cec5SDimitry Andric                     continue;
8520b57cec5SDimitry Andric 
8530b57cec5SDimitry Andric                   ValueObjectSP valobj_sp(frame->GetValueObjectForFrameVariable(
8540b57cec5SDimitry Andric                       variable_sp, eNoDynamicValues));
8550b57cec5SDimitry Andric 
8560b57cec5SDimitry Andric                   if (!include_runtime_support_values && valobj_sp != nullptr &&
8570b57cec5SDimitry Andric                       valobj_sp->IsRuntimeSupportValue())
8580b57cec5SDimitry Andric                     continue;
8590b57cec5SDimitry Andric 
8600b57cec5SDimitry Andric                   SBValue value_sb;
8610b57cec5SDimitry Andric                   value_sb.SetSP(valobj_sp, use_dynamic);
8620b57cec5SDimitry Andric                   value_list.Append(value_sb);
8630b57cec5SDimitry Andric                 }
8640b57cec5SDimitry Andric               }
8650b57cec5SDimitry Andric             }
86606c3fb27SDimitry Andric             num_produced++;
8670b57cec5SDimitry Andric           }
8680b57cec5SDimitry Andric         }
8690b57cec5SDimitry Andric         if (recognized_arguments) {
8700b57cec5SDimitry Andric           auto recognized_frame = frame->GetRecognizedFrame();
8710b57cec5SDimitry Andric           if (recognized_frame) {
8720b57cec5SDimitry Andric             ValueObjectListSP recognized_arg_list =
8730b57cec5SDimitry Andric                 recognized_frame->GetRecognizedArguments();
8740b57cec5SDimitry Andric             if (recognized_arg_list) {
8750b57cec5SDimitry Andric               for (auto &rec_value_sp : recognized_arg_list->GetObjects()) {
8760b57cec5SDimitry Andric                 SBValue value_sb;
8770b57cec5SDimitry Andric                 value_sb.SetSP(rec_value_sp, use_dynamic);
8780b57cec5SDimitry Andric                 value_list.Append(value_sb);
8790b57cec5SDimitry Andric               }
8800b57cec5SDimitry Andric             }
8810b57cec5SDimitry Andric           }
8820b57cec5SDimitry Andric         }
8830b57cec5SDimitry Andric       }
8840b57cec5SDimitry Andric     }
8850b57cec5SDimitry Andric   }
8860b57cec5SDimitry Andric 
88704eeddc0SDimitry Andric   return value_list;
8880b57cec5SDimitry Andric }
8890b57cec5SDimitry Andric 
GetRegisters()8900b57cec5SDimitry Andric SBValueList SBFrame::GetRegisters() {
89104eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
8920b57cec5SDimitry Andric 
8930b57cec5SDimitry Andric   SBValueList value_list;
8940b57cec5SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
8950b57cec5SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
8960b57cec5SDimitry Andric 
8970b57cec5SDimitry Andric   StackFrame *frame = nullptr;
8980b57cec5SDimitry Andric   Target *target = exe_ctx.GetTargetPtr();
8990b57cec5SDimitry Andric   Process *process = exe_ctx.GetProcessPtr();
9000b57cec5SDimitry Andric   if (target && process) {
9010b57cec5SDimitry Andric     Process::StopLocker stop_locker;
9020b57cec5SDimitry Andric     if (stop_locker.TryLock(&process->GetRunLock())) {
9030b57cec5SDimitry Andric       frame = exe_ctx.GetFramePtr();
9040b57cec5SDimitry Andric       if (frame) {
9050b57cec5SDimitry Andric         RegisterContextSP reg_ctx(frame->GetRegisterContext());
9060b57cec5SDimitry Andric         if (reg_ctx) {
9070b57cec5SDimitry Andric           const uint32_t num_sets = reg_ctx->GetRegisterSetCount();
9080b57cec5SDimitry Andric           for (uint32_t set_idx = 0; set_idx < num_sets; ++set_idx) {
9090b57cec5SDimitry Andric             value_list.Append(
9100b57cec5SDimitry Andric                 ValueObjectRegisterSet::Create(frame, reg_ctx, set_idx));
9110b57cec5SDimitry Andric           }
9120b57cec5SDimitry Andric         }
9130b57cec5SDimitry Andric       }
9140b57cec5SDimitry Andric     }
9150b57cec5SDimitry Andric   }
9160b57cec5SDimitry Andric 
91704eeddc0SDimitry Andric   return value_list;
9180b57cec5SDimitry Andric }
9190b57cec5SDimitry Andric 
FindRegister(const char * name)9200b57cec5SDimitry Andric SBValue SBFrame::FindRegister(const char *name) {
92104eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, name);
9220b57cec5SDimitry Andric 
9230b57cec5SDimitry Andric   SBValue result;
9240b57cec5SDimitry Andric   ValueObjectSP value_sp;
9250b57cec5SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
9260b57cec5SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
9270b57cec5SDimitry Andric 
9280b57cec5SDimitry Andric   StackFrame *frame = nullptr;
9290b57cec5SDimitry Andric   Target *target = exe_ctx.GetTargetPtr();
9300b57cec5SDimitry Andric   Process *process = exe_ctx.GetProcessPtr();
9310b57cec5SDimitry Andric   if (target && process) {
9320b57cec5SDimitry Andric     Process::StopLocker stop_locker;
9330b57cec5SDimitry Andric     if (stop_locker.TryLock(&process->GetRunLock())) {
9340b57cec5SDimitry Andric       frame = exe_ctx.GetFramePtr();
9350b57cec5SDimitry Andric       if (frame) {
9360b57cec5SDimitry Andric         RegisterContextSP reg_ctx(frame->GetRegisterContext());
9370b57cec5SDimitry Andric         if (reg_ctx) {
938349cc55cSDimitry Andric           if (const RegisterInfo *reg_info =
939349cc55cSDimitry Andric                   reg_ctx->GetRegisterInfoByName(name)) {
940349cc55cSDimitry Andric             value_sp = ValueObjectRegister::Create(frame, reg_ctx, reg_info);
9410b57cec5SDimitry Andric             result.SetSP(value_sp);
9420b57cec5SDimitry Andric           }
9430b57cec5SDimitry Andric         }
9440b57cec5SDimitry Andric       }
9450b57cec5SDimitry Andric     }
9460b57cec5SDimitry Andric   }
9470b57cec5SDimitry Andric 
94804eeddc0SDimitry Andric   return result;
9490b57cec5SDimitry Andric }
9500b57cec5SDimitry Andric 
GetDescriptionWithFormat(const SBFormat & format,SBStream & output)9515f757f3fSDimitry Andric SBError SBFrame::GetDescriptionWithFormat(const SBFormat &format,
9525f757f3fSDimitry Andric                                           SBStream &output) {
9535f757f3fSDimitry Andric   Stream &strm = output.ref();
9545f757f3fSDimitry Andric 
9555f757f3fSDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
9565f757f3fSDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
9575f757f3fSDimitry Andric 
9585f757f3fSDimitry Andric   StackFrame *frame = nullptr;
9595f757f3fSDimitry Andric   Target *target = exe_ctx.GetTargetPtr();
9605f757f3fSDimitry Andric   Process *process = exe_ctx.GetProcessPtr();
9615f757f3fSDimitry Andric   SBError error;
9625f757f3fSDimitry Andric 
9635f757f3fSDimitry Andric   if (!format) {
9645f757f3fSDimitry Andric     error.SetErrorString("The provided SBFormat object is invalid");
9655f757f3fSDimitry Andric     return error;
9665f757f3fSDimitry Andric   }
9675f757f3fSDimitry Andric 
9685f757f3fSDimitry Andric   if (target && process) {
9695f757f3fSDimitry Andric     Process::StopLocker stop_locker;
9705f757f3fSDimitry Andric     if (stop_locker.TryLock(&process->GetRunLock())) {
9715f757f3fSDimitry Andric       frame = exe_ctx.GetFramePtr();
9725f757f3fSDimitry Andric       if (frame &&
9735f757f3fSDimitry Andric           frame->DumpUsingFormat(strm, format.GetFormatEntrySP().get())) {
9745f757f3fSDimitry Andric         return error;
9755f757f3fSDimitry Andric       }
9765f757f3fSDimitry Andric     }
9775f757f3fSDimitry Andric   }
9785f757f3fSDimitry Andric   error.SetErrorStringWithFormat(
9795f757f3fSDimitry Andric       "It was not possible to generate a frame "
9805f757f3fSDimitry Andric       "description with the given format string '%s'",
9815f757f3fSDimitry Andric       format.GetFormatEntrySP()->string.c_str());
9825f757f3fSDimitry Andric   return error;
9835f757f3fSDimitry Andric }
9845f757f3fSDimitry Andric 
GetDescription(SBStream & description)9850b57cec5SDimitry Andric bool SBFrame::GetDescription(SBStream &description) {
98604eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, description);
9870b57cec5SDimitry Andric 
9880b57cec5SDimitry Andric   Stream &strm = description.ref();
9890b57cec5SDimitry Andric 
9900b57cec5SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
9910b57cec5SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
9920b57cec5SDimitry Andric 
9930b57cec5SDimitry Andric   StackFrame *frame;
9940b57cec5SDimitry Andric   Target *target = exe_ctx.GetTargetPtr();
9950b57cec5SDimitry Andric   Process *process = exe_ctx.GetProcessPtr();
9960b57cec5SDimitry Andric   if (target && process) {
9970b57cec5SDimitry Andric     Process::StopLocker stop_locker;
9980b57cec5SDimitry Andric     if (stop_locker.TryLock(&process->GetRunLock())) {
9990b57cec5SDimitry Andric       frame = exe_ctx.GetFramePtr();
10000b57cec5SDimitry Andric       if (frame) {
10010b57cec5SDimitry Andric         frame->DumpUsingSettingsFormat(&strm);
10020b57cec5SDimitry Andric       }
10030b57cec5SDimitry Andric     }
10040b57cec5SDimitry Andric 
10050b57cec5SDimitry Andric   } else
10060b57cec5SDimitry Andric     strm.PutCString("No value");
10070b57cec5SDimitry Andric 
10080b57cec5SDimitry Andric   return true;
10090b57cec5SDimitry Andric }
10100b57cec5SDimitry Andric 
EvaluateExpression(const char * expr)10110b57cec5SDimitry Andric SBValue SBFrame::EvaluateExpression(const char *expr) {
101204eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, expr);
10130b57cec5SDimitry Andric 
10140b57cec5SDimitry Andric   SBValue result;
10150b57cec5SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
10160b57cec5SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
10170b57cec5SDimitry Andric 
10180b57cec5SDimitry Andric   StackFrame *frame = exe_ctx.GetFramePtr();
10190b57cec5SDimitry Andric   Target *target = exe_ctx.GetTargetPtr();
10200b57cec5SDimitry Andric   if (frame && target) {
10210b57cec5SDimitry Andric     SBExpressionOptions options;
10220b57cec5SDimitry Andric     lldb::DynamicValueType fetch_dynamic_value =
10230b57cec5SDimitry Andric         frame->CalculateTarget()->GetPreferDynamicValue();
10240b57cec5SDimitry Andric     options.SetFetchDynamicValue(fetch_dynamic_value);
10250b57cec5SDimitry Andric     options.SetUnwindOnError(true);
10260b57cec5SDimitry Andric     options.SetIgnoreBreakpoints(true);
1027*0fca6ea1SDimitry Andric     SourceLanguage language = target->GetLanguage();
1028*0fca6ea1SDimitry Andric     if (!language)
1029*0fca6ea1SDimitry Andric       language = frame->GetLanguage();
1030*0fca6ea1SDimitry Andric     options.SetLanguage((SBSourceLanguageName)language.name, language.version);
103104eeddc0SDimitry Andric     return EvaluateExpression(expr, options);
103206c3fb27SDimitry Andric   } else {
103306c3fb27SDimitry Andric     Status error;
103406c3fb27SDimitry Andric     error.SetErrorString("can't evaluate expressions when the "
103506c3fb27SDimitry Andric                            "process is running.");
103606c3fb27SDimitry Andric     ValueObjectSP error_val_sp = ValueObjectConstResult::Create(nullptr, error);
103706c3fb27SDimitry Andric     result.SetSP(error_val_sp, false);
10380b57cec5SDimitry Andric   }
103904eeddc0SDimitry Andric   return result;
10400b57cec5SDimitry Andric }
10410b57cec5SDimitry Andric 
10420b57cec5SDimitry Andric SBValue
EvaluateExpression(const char * expr,lldb::DynamicValueType fetch_dynamic_value)10430b57cec5SDimitry Andric SBFrame::EvaluateExpression(const char *expr,
10440b57cec5SDimitry Andric                             lldb::DynamicValueType fetch_dynamic_value) {
104504eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, expr, fetch_dynamic_value);
10460b57cec5SDimitry Andric 
10470b57cec5SDimitry Andric   SBExpressionOptions options;
10480b57cec5SDimitry Andric   options.SetFetchDynamicValue(fetch_dynamic_value);
10490b57cec5SDimitry Andric   options.SetUnwindOnError(true);
10500b57cec5SDimitry Andric   options.SetIgnoreBreakpoints(true);
10510b57cec5SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
10520b57cec5SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
10530b57cec5SDimitry Andric 
10540b57cec5SDimitry Andric   StackFrame *frame = exe_ctx.GetFramePtr();
10550b57cec5SDimitry Andric   Target *target = exe_ctx.GetTargetPtr();
1056*0fca6ea1SDimitry Andric   SourceLanguage language;
1057*0fca6ea1SDimitry Andric   if (target)
1058*0fca6ea1SDimitry Andric     language = target->GetLanguage();
1059*0fca6ea1SDimitry Andric   if (!language && frame)
1060*0fca6ea1SDimitry Andric     language = frame->GetLanguage();
1061*0fca6ea1SDimitry Andric   options.SetLanguage((SBSourceLanguageName)language.name, language.version);
106204eeddc0SDimitry Andric   return EvaluateExpression(expr, options);
10630b57cec5SDimitry Andric }
10640b57cec5SDimitry Andric 
EvaluateExpression(const char * expr,lldb::DynamicValueType fetch_dynamic_value,bool unwind_on_error)10650b57cec5SDimitry Andric SBValue SBFrame::EvaluateExpression(const char *expr,
10660b57cec5SDimitry Andric                                     lldb::DynamicValueType fetch_dynamic_value,
10670b57cec5SDimitry Andric                                     bool unwind_on_error) {
106804eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, expr, fetch_dynamic_value, unwind_on_error);
10690b57cec5SDimitry Andric 
10700b57cec5SDimitry Andric   SBExpressionOptions options;
10710b57cec5SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
10720b57cec5SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
10730b57cec5SDimitry Andric 
10740b57cec5SDimitry Andric   options.SetFetchDynamicValue(fetch_dynamic_value);
10750b57cec5SDimitry Andric   options.SetUnwindOnError(unwind_on_error);
10760b57cec5SDimitry Andric   options.SetIgnoreBreakpoints(true);
10770b57cec5SDimitry Andric   StackFrame *frame = exe_ctx.GetFramePtr();
10780b57cec5SDimitry Andric   Target *target = exe_ctx.GetTargetPtr();
1079*0fca6ea1SDimitry Andric   SourceLanguage language;
1080*0fca6ea1SDimitry Andric   if (target)
1081*0fca6ea1SDimitry Andric     language = target->GetLanguage();
1082*0fca6ea1SDimitry Andric   if (!language && frame)
1083*0fca6ea1SDimitry Andric     language = frame->GetLanguage();
1084*0fca6ea1SDimitry Andric   options.SetLanguage((SBSourceLanguageName)language.name, language.version);
108504eeddc0SDimitry Andric   return EvaluateExpression(expr, options);
10860b57cec5SDimitry Andric }
10870b57cec5SDimitry Andric 
EvaluateExpression(const char * expr,const SBExpressionOptions & options)10880b57cec5SDimitry Andric lldb::SBValue SBFrame::EvaluateExpression(const char *expr,
10890b57cec5SDimitry Andric                                           const SBExpressionOptions &options) {
109004eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, expr, options);
10910b57cec5SDimitry Andric 
109281ad6265SDimitry Andric   Log *expr_log = GetLog(LLDBLog::Expressions);
10930b57cec5SDimitry Andric 
10940b57cec5SDimitry Andric   SBValue expr_result;
10950b57cec5SDimitry Andric 
10960b57cec5SDimitry Andric   if (expr == nullptr || expr[0] == '\0') {
109704eeddc0SDimitry Andric     return expr_result;
10980b57cec5SDimitry Andric   }
10990b57cec5SDimitry Andric 
11000b57cec5SDimitry Andric   ValueObjectSP expr_value_sp;
11010b57cec5SDimitry Andric 
11020b57cec5SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
11030b57cec5SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
11040b57cec5SDimitry Andric 
11050b57cec5SDimitry Andric   StackFrame *frame = nullptr;
11060b57cec5SDimitry Andric   Target *target = exe_ctx.GetTargetPtr();
11070b57cec5SDimitry Andric   Process *process = exe_ctx.GetProcessPtr();
11080b57cec5SDimitry Andric 
11090b57cec5SDimitry Andric   if (target && process) {
11100b57cec5SDimitry Andric     Process::StopLocker stop_locker;
11110b57cec5SDimitry Andric     if (stop_locker.TryLock(&process->GetRunLock())) {
11120b57cec5SDimitry Andric       frame = exe_ctx.GetFramePtr();
11130b57cec5SDimitry Andric       if (frame) {
11140b57cec5SDimitry Andric         std::unique_ptr<llvm::PrettyStackTraceFormat> stack_trace;
11150b57cec5SDimitry Andric         if (target->GetDisplayExpressionsInCrashlogs()) {
11160b57cec5SDimitry Andric           StreamString frame_description;
11170b57cec5SDimitry Andric           frame->DumpUsingSettingsFormat(&frame_description);
11189dba64beSDimitry Andric           stack_trace = std::make_unique<llvm::PrettyStackTraceFormat>(
11190b57cec5SDimitry Andric               "SBFrame::EvaluateExpression (expr = \"%s\", fetch_dynamic_value "
11200b57cec5SDimitry Andric               "= %u) %s",
11210b57cec5SDimitry Andric               expr, options.GetFetchDynamicValue(),
11220b57cec5SDimitry Andric               frame_description.GetData());
11230b57cec5SDimitry Andric         }
11240b57cec5SDimitry Andric 
11250b57cec5SDimitry Andric         target->EvaluateExpression(expr, frame, expr_value_sp, options.ref());
11260b57cec5SDimitry Andric         expr_result.SetSP(expr_value_sp, options.GetFetchDynamicValue());
11270b57cec5SDimitry Andric       }
112806c3fb27SDimitry Andric     } else {
112906c3fb27SDimitry Andric       Status error;
113006c3fb27SDimitry Andric       error.SetErrorString("can't evaluate expressions when the "
113106c3fb27SDimitry Andric                            "process is running.");
113206c3fb27SDimitry Andric       expr_value_sp = ValueObjectConstResult::Create(nullptr, error);
113306c3fb27SDimitry Andric       expr_result.SetSP(expr_value_sp, false);
11340b57cec5SDimitry Andric     }
113506c3fb27SDimitry Andric   } else {
113606c3fb27SDimitry Andric       Status error;
113706c3fb27SDimitry Andric       error.SetErrorString("sbframe object is not valid.");
113806c3fb27SDimitry Andric       expr_value_sp = ValueObjectConstResult::Create(nullptr, error);
113906c3fb27SDimitry Andric       expr_result.SetSP(expr_value_sp, false);
11400b57cec5SDimitry Andric   }
11410b57cec5SDimitry Andric 
114206c3fb27SDimitry Andric   if (expr_result.GetError().Success())
11439dba64beSDimitry Andric     LLDB_LOGF(expr_log,
11449dba64beSDimitry Andric               "** [SBFrame::EvaluateExpression] Expression result is "
11450b57cec5SDimitry Andric               "%s, summary %s **",
11460b57cec5SDimitry Andric               expr_result.GetValue(), expr_result.GetSummary());
114706c3fb27SDimitry Andric   else
114806c3fb27SDimitry Andric     LLDB_LOGF(expr_log,
114906c3fb27SDimitry Andric               "** [SBFrame::EvaluateExpression] Expression evaluation failed: "
115006c3fb27SDimitry Andric               "%s **",
115106c3fb27SDimitry Andric               expr_result.GetError().GetCString());
11520b57cec5SDimitry Andric 
115304eeddc0SDimitry Andric   return expr_result;
11540b57cec5SDimitry Andric }
11550b57cec5SDimitry Andric 
IsInlined()11560b57cec5SDimitry Andric bool SBFrame::IsInlined() {
115704eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
11580b57cec5SDimitry Andric 
11590b57cec5SDimitry Andric   return static_cast<const SBFrame *>(this)->IsInlined();
11600b57cec5SDimitry Andric }
11610b57cec5SDimitry Andric 
IsInlined() const11620b57cec5SDimitry Andric bool SBFrame::IsInlined() const {
116304eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
11640b57cec5SDimitry Andric 
11650b57cec5SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
11660b57cec5SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
11670b57cec5SDimitry Andric 
11680b57cec5SDimitry Andric   StackFrame *frame = nullptr;
11690b57cec5SDimitry Andric   Target *target = exe_ctx.GetTargetPtr();
11700b57cec5SDimitry Andric   Process *process = exe_ctx.GetProcessPtr();
11710b57cec5SDimitry Andric   if (target && process) {
11720b57cec5SDimitry Andric     Process::StopLocker stop_locker;
11730b57cec5SDimitry Andric     if (stop_locker.TryLock(&process->GetRunLock())) {
11740b57cec5SDimitry Andric       frame = exe_ctx.GetFramePtr();
11750b57cec5SDimitry Andric       if (frame) {
11760b57cec5SDimitry Andric 
11770b57cec5SDimitry Andric         Block *block = frame->GetSymbolContext(eSymbolContextBlock).block;
11780b57cec5SDimitry Andric         if (block)
11790b57cec5SDimitry Andric           return block->GetContainingInlinedBlock() != nullptr;
11800b57cec5SDimitry Andric       }
11810b57cec5SDimitry Andric     }
11820b57cec5SDimitry Andric   }
11830b57cec5SDimitry Andric   return false;
11840b57cec5SDimitry Andric }
11850b57cec5SDimitry Andric 
IsArtificial()11860b57cec5SDimitry Andric bool SBFrame::IsArtificial() {
118704eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
11880b57cec5SDimitry Andric 
11890b57cec5SDimitry Andric   return static_cast<const SBFrame *>(this)->IsArtificial();
11900b57cec5SDimitry Andric }
11910b57cec5SDimitry Andric 
IsArtificial() const11920b57cec5SDimitry Andric bool SBFrame::IsArtificial() const {
119304eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
11940b57cec5SDimitry Andric 
11950b57cec5SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
11960b57cec5SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
11970b57cec5SDimitry Andric 
11980b57cec5SDimitry Andric   StackFrame *frame = exe_ctx.GetFramePtr();
11990b57cec5SDimitry Andric   if (frame)
12000b57cec5SDimitry Andric     return frame->IsArtificial();
12010b57cec5SDimitry Andric 
12020b57cec5SDimitry Andric   return false;
12030b57cec5SDimitry Andric }
12040b57cec5SDimitry Andric 
GetFunctionName()12050b57cec5SDimitry Andric const char *SBFrame::GetFunctionName() {
120604eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
12070b57cec5SDimitry Andric 
12080b57cec5SDimitry Andric   return static_cast<const SBFrame *>(this)->GetFunctionName();
12090b57cec5SDimitry Andric }
12100b57cec5SDimitry Andric 
GuessLanguage() const12110b57cec5SDimitry Andric lldb::LanguageType SBFrame::GuessLanguage() const {
121204eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
12130b57cec5SDimitry Andric 
12140b57cec5SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
12150b57cec5SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
12160b57cec5SDimitry Andric 
12170b57cec5SDimitry Andric   StackFrame *frame = nullptr;
12180b57cec5SDimitry Andric   Target *target = exe_ctx.GetTargetPtr();
12190b57cec5SDimitry Andric   Process *process = exe_ctx.GetProcessPtr();
12200b57cec5SDimitry Andric   if (target && process) {
12210b57cec5SDimitry Andric     Process::StopLocker stop_locker;
12220b57cec5SDimitry Andric     if (stop_locker.TryLock(&process->GetRunLock())) {
12230b57cec5SDimitry Andric       frame = exe_ctx.GetFramePtr();
12240b57cec5SDimitry Andric       if (frame) {
1225*0fca6ea1SDimitry Andric         return frame->GuessLanguage().AsLanguageType();
12260b57cec5SDimitry Andric       }
12270b57cec5SDimitry Andric     }
12280b57cec5SDimitry Andric   }
12290b57cec5SDimitry Andric   return eLanguageTypeUnknown;
12300b57cec5SDimitry Andric }
12310b57cec5SDimitry Andric 
GetFunctionName() const12320b57cec5SDimitry Andric const char *SBFrame::GetFunctionName() const {
123304eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
12340b57cec5SDimitry Andric 
12350b57cec5SDimitry Andric   const char *name = nullptr;
12360b57cec5SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
12370b57cec5SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
12380b57cec5SDimitry Andric 
12390b57cec5SDimitry Andric   StackFrame *frame = nullptr;
12400b57cec5SDimitry Andric   Target *target = exe_ctx.GetTargetPtr();
12410b57cec5SDimitry Andric   Process *process = exe_ctx.GetProcessPtr();
12420b57cec5SDimitry Andric   if (target && process) {
12430b57cec5SDimitry Andric     Process::StopLocker stop_locker;
12440b57cec5SDimitry Andric     if (stop_locker.TryLock(&process->GetRunLock())) {
12450b57cec5SDimitry Andric       frame = exe_ctx.GetFramePtr();
12460b57cec5SDimitry Andric       if (frame) {
12470b57cec5SDimitry Andric         SymbolContext sc(frame->GetSymbolContext(eSymbolContextFunction |
12480b57cec5SDimitry Andric                                                  eSymbolContextBlock |
12490b57cec5SDimitry Andric                                                  eSymbolContextSymbol));
12500b57cec5SDimitry Andric         if (sc.block) {
12510b57cec5SDimitry Andric           Block *inlined_block = sc.block->GetContainingInlinedBlock();
12520b57cec5SDimitry Andric           if (inlined_block) {
12530b57cec5SDimitry Andric             const InlineFunctionInfo *inlined_info =
12540b57cec5SDimitry Andric                 inlined_block->GetInlinedFunctionInfo();
12555ffd83dbSDimitry Andric             name = inlined_info->GetName().AsCString();
12560b57cec5SDimitry Andric           }
12570b57cec5SDimitry Andric         }
12580b57cec5SDimitry Andric 
12590b57cec5SDimitry Andric         if (name == nullptr) {
12600b57cec5SDimitry Andric           if (sc.function)
12610b57cec5SDimitry Andric             name = sc.function->GetName().GetCString();
12620b57cec5SDimitry Andric         }
12630b57cec5SDimitry Andric 
12640b57cec5SDimitry Andric         if (name == nullptr) {
12650b57cec5SDimitry Andric           if (sc.symbol)
12660b57cec5SDimitry Andric             name = sc.symbol->GetName().GetCString();
12670b57cec5SDimitry Andric         }
12680b57cec5SDimitry Andric       }
12690b57cec5SDimitry Andric     }
12700b57cec5SDimitry Andric   }
12710b57cec5SDimitry Andric   return name;
12720b57cec5SDimitry Andric }
12730b57cec5SDimitry Andric 
GetDisplayFunctionName()12740b57cec5SDimitry Andric const char *SBFrame::GetDisplayFunctionName() {
127504eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
12760b57cec5SDimitry Andric 
12770b57cec5SDimitry Andric   const char *name = nullptr;
12780b57cec5SDimitry Andric 
12790b57cec5SDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
12800b57cec5SDimitry Andric   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
12810b57cec5SDimitry Andric 
12820b57cec5SDimitry Andric   StackFrame *frame = nullptr;
12830b57cec5SDimitry Andric   Target *target = exe_ctx.GetTargetPtr();
12840b57cec5SDimitry Andric   Process *process = exe_ctx.GetProcessPtr();
12850b57cec5SDimitry Andric   if (target && process) {
12860b57cec5SDimitry Andric     Process::StopLocker stop_locker;
12870b57cec5SDimitry Andric     if (stop_locker.TryLock(&process->GetRunLock())) {
12880b57cec5SDimitry Andric       frame = exe_ctx.GetFramePtr();
12890b57cec5SDimitry Andric       if (frame) {
12900b57cec5SDimitry Andric         SymbolContext sc(frame->GetSymbolContext(eSymbolContextFunction |
12910b57cec5SDimitry Andric                                                  eSymbolContextBlock |
12920b57cec5SDimitry Andric                                                  eSymbolContextSymbol));
12930b57cec5SDimitry Andric         if (sc.block) {
12940b57cec5SDimitry Andric           Block *inlined_block = sc.block->GetContainingInlinedBlock();
12950b57cec5SDimitry Andric           if (inlined_block) {
12960b57cec5SDimitry Andric             const InlineFunctionInfo *inlined_info =
12970b57cec5SDimitry Andric                 inlined_block->GetInlinedFunctionInfo();
12985ffd83dbSDimitry Andric             name = inlined_info->GetDisplayName().AsCString();
12990b57cec5SDimitry Andric           }
13000b57cec5SDimitry Andric         }
13010b57cec5SDimitry Andric 
13020b57cec5SDimitry Andric         if (name == nullptr) {
13030b57cec5SDimitry Andric           if (sc.function)
13040b57cec5SDimitry Andric             name = sc.function->GetDisplayName().GetCString();
13050b57cec5SDimitry Andric         }
13060b57cec5SDimitry Andric 
13070b57cec5SDimitry Andric         if (name == nullptr) {
13080b57cec5SDimitry Andric           if (sc.symbol)
13090b57cec5SDimitry Andric             name = sc.symbol->GetDisplayName().GetCString();
13100b57cec5SDimitry Andric         }
13110b57cec5SDimitry Andric       }
13120b57cec5SDimitry Andric     }
13130b57cec5SDimitry Andric   }
13140b57cec5SDimitry Andric   return name;
13150b57cec5SDimitry Andric }
1316