1//===-- SBFrame.cpp -------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include <algorithm>
10#include <set>
11#include <string>
12
13#include "lldb/API/SBFrame.h"
14
15#include "lldb/lldb-types.h"
16
17#include "Utils.h"
18#include "lldb/Core/Address.h"
19#include "lldb/Core/Debugger.h"
20#include "lldb/Core/ValueObjectRegister.h"
21#include "lldb/Core/ValueObjectVariable.h"
22#include "lldb/Core/ValueObjectConstResult.h"
23#include "lldb/Expression/ExpressionVariable.h"
24#include "lldb/Expression/UserExpression.h"
25#include "lldb/Host/Host.h"
26#include "lldb/Symbol/Block.h"
27#include "lldb/Symbol/Function.h"
28#include "lldb/Symbol/Symbol.h"
29#include "lldb/Symbol/SymbolContext.h"
30#include "lldb/Symbol/Variable.h"
31#include "lldb/Symbol/VariableList.h"
32#include "lldb/Target/ExecutionContext.h"
33#include "lldb/Target/Process.h"
34#include "lldb/Target/RegisterContext.h"
35#include "lldb/Target/StackFrame.h"
36#include "lldb/Target/StackFrameRecognizer.h"
37#include "lldb/Target/StackID.h"
38#include "lldb/Target/Target.h"
39#include "lldb/Target/Thread.h"
40#include "lldb/Utility/ConstString.h"
41#include "lldb/Utility/Instrumentation.h"
42#include "lldb/Utility/LLDBLog.h"
43#include "lldb/Utility/Stream.h"
44
45#include "lldb/API/SBAddress.h"
46#include "lldb/API/SBDebugger.h"
47#include "lldb/API/SBExpressionOptions.h"
48#include "lldb/API/SBFormat.h"
49#include "lldb/API/SBStream.h"
50#include "lldb/API/SBSymbolContext.h"
51#include "lldb/API/SBThread.h"
52#include "lldb/API/SBValue.h"
53#include "lldb/API/SBVariablesOptions.h"
54
55#include "llvm/Support/PrettyStackTrace.h"
56
57using namespace lldb;
58using namespace lldb_private;
59
60SBFrame::SBFrame() : m_opaque_sp(new ExecutionContextRef()) {
61  LLDB_INSTRUMENT_VA(this);
62}
63
64SBFrame::SBFrame(const StackFrameSP &lldb_object_sp)
65    : m_opaque_sp(new ExecutionContextRef(lldb_object_sp)) {
66  LLDB_INSTRUMENT_VA(this, lldb_object_sp);
67}
68
69SBFrame::SBFrame(const SBFrame &rhs) {
70  LLDB_INSTRUMENT_VA(this, rhs);
71
72  m_opaque_sp = clone(rhs.m_opaque_sp);
73}
74
75SBFrame::~SBFrame() = default;
76
77const SBFrame &SBFrame::operator=(const SBFrame &rhs) {
78  LLDB_INSTRUMENT_VA(this, rhs);
79
80  if (this != &rhs)
81    m_opaque_sp = clone(rhs.m_opaque_sp);
82  return *this;
83}
84
85StackFrameSP SBFrame::GetFrameSP() const {
86  return (m_opaque_sp ? m_opaque_sp->GetFrameSP() : StackFrameSP());
87}
88
89void SBFrame::SetFrameSP(const StackFrameSP &lldb_object_sp) {
90  return m_opaque_sp->SetFrameSP(lldb_object_sp);
91}
92
93bool SBFrame::IsValid() const {
94  LLDB_INSTRUMENT_VA(this);
95  return this->operator bool();
96}
97SBFrame::operator bool() const {
98  LLDB_INSTRUMENT_VA(this);
99
100  std::unique_lock<std::recursive_mutex> lock;
101  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
102
103  Target *target = exe_ctx.GetTargetPtr();
104  Process *process = exe_ctx.GetProcessPtr();
105  if (target && process) {
106    Process::StopLocker stop_locker;
107    if (stop_locker.TryLock(&process->GetRunLock()))
108      return GetFrameSP().get() != nullptr;
109  }
110
111  // Without a target & process we can't have a valid stack frame.
112  return false;
113}
114
115SBSymbolContext SBFrame::GetSymbolContext(uint32_t resolve_scope) const {
116  LLDB_INSTRUMENT_VA(this, resolve_scope);
117
118  SBSymbolContext sb_sym_ctx;
119  std::unique_lock<std::recursive_mutex> lock;
120  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
121  SymbolContextItem scope = static_cast<SymbolContextItem>(resolve_scope);
122  Target *target = exe_ctx.GetTargetPtr();
123  Process *process = exe_ctx.GetProcessPtr();
124  if (target && process) {
125    Process::StopLocker stop_locker;
126    if (stop_locker.TryLock(&process->GetRunLock())) {
127      if (StackFrame *frame = exe_ctx.GetFramePtr())
128        sb_sym_ctx = frame->GetSymbolContext(scope);
129    }
130  }
131
132  return sb_sym_ctx;
133}
134
135SBModule SBFrame::GetModule() const {
136  LLDB_INSTRUMENT_VA(this);
137
138  SBModule sb_module;
139  ModuleSP module_sp;
140  std::unique_lock<std::recursive_mutex> lock;
141  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
142
143  StackFrame *frame = nullptr;
144  Target *target = exe_ctx.GetTargetPtr();
145  Process *process = exe_ctx.GetProcessPtr();
146  if (target && process) {
147    Process::StopLocker stop_locker;
148    if (stop_locker.TryLock(&process->GetRunLock())) {
149      frame = exe_ctx.GetFramePtr();
150      if (frame) {
151        module_sp = frame->GetSymbolContext(eSymbolContextModule).module_sp;
152        sb_module.SetSP(module_sp);
153      }
154    }
155  }
156
157  return sb_module;
158}
159
160SBCompileUnit SBFrame::GetCompileUnit() const {
161  LLDB_INSTRUMENT_VA(this);
162
163  SBCompileUnit sb_comp_unit;
164  std::unique_lock<std::recursive_mutex> lock;
165  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
166
167  StackFrame *frame = nullptr;
168  Target *target = exe_ctx.GetTargetPtr();
169  Process *process = exe_ctx.GetProcessPtr();
170  if (target && process) {
171    Process::StopLocker stop_locker;
172    if (stop_locker.TryLock(&process->GetRunLock())) {
173      frame = exe_ctx.GetFramePtr();
174      if (frame) {
175        sb_comp_unit.reset(
176            frame->GetSymbolContext(eSymbolContextCompUnit).comp_unit);
177      }
178    }
179  }
180
181  return sb_comp_unit;
182}
183
184SBFunction SBFrame::GetFunction() const {
185  LLDB_INSTRUMENT_VA(this);
186
187  SBFunction sb_function;
188  std::unique_lock<std::recursive_mutex> lock;
189  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
190
191  StackFrame *frame = nullptr;
192  Target *target = exe_ctx.GetTargetPtr();
193  Process *process = exe_ctx.GetProcessPtr();
194  if (target && process) {
195    Process::StopLocker stop_locker;
196    if (stop_locker.TryLock(&process->GetRunLock())) {
197      frame = exe_ctx.GetFramePtr();
198      if (frame) {
199        sb_function.reset(
200            frame->GetSymbolContext(eSymbolContextFunction).function);
201      }
202    }
203  }
204
205  return sb_function;
206}
207
208SBSymbol SBFrame::GetSymbol() const {
209  LLDB_INSTRUMENT_VA(this);
210
211  SBSymbol sb_symbol;
212  std::unique_lock<std::recursive_mutex> lock;
213  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
214
215  StackFrame *frame = nullptr;
216  Target *target = exe_ctx.GetTargetPtr();
217  Process *process = exe_ctx.GetProcessPtr();
218  if (target && process) {
219    Process::StopLocker stop_locker;
220    if (stop_locker.TryLock(&process->GetRunLock())) {
221      frame = exe_ctx.GetFramePtr();
222      if (frame) {
223        sb_symbol.reset(frame->GetSymbolContext(eSymbolContextSymbol).symbol);
224      }
225    }
226  }
227
228  return sb_symbol;
229}
230
231SBBlock SBFrame::GetBlock() const {
232  LLDB_INSTRUMENT_VA(this);
233
234  SBBlock sb_block;
235  std::unique_lock<std::recursive_mutex> lock;
236  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
237
238  StackFrame *frame = nullptr;
239  Target *target = exe_ctx.GetTargetPtr();
240  Process *process = exe_ctx.GetProcessPtr();
241  if (target && process) {
242    Process::StopLocker stop_locker;
243    if (stop_locker.TryLock(&process->GetRunLock())) {
244      frame = exe_ctx.GetFramePtr();
245      if (frame)
246        sb_block.SetPtr(frame->GetSymbolContext(eSymbolContextBlock).block);
247    }
248  }
249  return sb_block;
250}
251
252SBBlock SBFrame::GetFrameBlock() const {
253  LLDB_INSTRUMENT_VA(this);
254
255  SBBlock sb_block;
256  std::unique_lock<std::recursive_mutex> lock;
257  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
258
259  StackFrame *frame = nullptr;
260  Target *target = exe_ctx.GetTargetPtr();
261  Process *process = exe_ctx.GetProcessPtr();
262  if (target && process) {
263    Process::StopLocker stop_locker;
264    if (stop_locker.TryLock(&process->GetRunLock())) {
265      frame = exe_ctx.GetFramePtr();
266      if (frame)
267        sb_block.SetPtr(frame->GetFrameBlock());
268    }
269  }
270  return sb_block;
271}
272
273SBLineEntry SBFrame::GetLineEntry() const {
274  LLDB_INSTRUMENT_VA(this);
275
276  SBLineEntry sb_line_entry;
277  std::unique_lock<std::recursive_mutex> lock;
278  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
279
280  StackFrame *frame = nullptr;
281  Target *target = exe_ctx.GetTargetPtr();
282  Process *process = exe_ctx.GetProcessPtr();
283  if (target && process) {
284    Process::StopLocker stop_locker;
285    if (stop_locker.TryLock(&process->GetRunLock())) {
286      frame = exe_ctx.GetFramePtr();
287      if (frame) {
288        sb_line_entry.SetLineEntry(
289            frame->GetSymbolContext(eSymbolContextLineEntry).line_entry);
290      }
291    }
292  }
293  return sb_line_entry;
294}
295
296uint32_t SBFrame::GetFrameID() const {
297  LLDB_INSTRUMENT_VA(this);
298
299  uint32_t frame_idx = UINT32_MAX;
300
301  std::unique_lock<std::recursive_mutex> lock;
302  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
303
304  StackFrame *frame = exe_ctx.GetFramePtr();
305  if (frame)
306    frame_idx = frame->GetFrameIndex();
307
308  return frame_idx;
309}
310
311lldb::addr_t SBFrame::GetCFA() const {
312  LLDB_INSTRUMENT_VA(this);
313
314  std::unique_lock<std::recursive_mutex> lock;
315  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
316
317  StackFrame *frame = exe_ctx.GetFramePtr();
318  if (frame)
319    return frame->GetStackID().GetCallFrameAddress();
320  return LLDB_INVALID_ADDRESS;
321}
322
323addr_t SBFrame::GetPC() const {
324  LLDB_INSTRUMENT_VA(this);
325
326  addr_t addr = LLDB_INVALID_ADDRESS;
327  std::unique_lock<std::recursive_mutex> lock;
328  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
329
330  StackFrame *frame = nullptr;
331  Target *target = exe_ctx.GetTargetPtr();
332  Process *process = exe_ctx.GetProcessPtr();
333  if (target && process) {
334    Process::StopLocker stop_locker;
335    if (stop_locker.TryLock(&process->GetRunLock())) {
336      frame = exe_ctx.GetFramePtr();
337      if (frame) {
338        addr = frame->GetFrameCodeAddress().GetOpcodeLoadAddress(
339            target, AddressClass::eCode);
340      }
341    }
342  }
343
344  return addr;
345}
346
347bool SBFrame::SetPC(addr_t new_pc) {
348  LLDB_INSTRUMENT_VA(this, new_pc);
349
350  bool ret_val = false;
351  std::unique_lock<std::recursive_mutex> lock;
352  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
353
354  Target *target = exe_ctx.GetTargetPtr();
355  Process *process = exe_ctx.GetProcessPtr();
356  if (target && process) {
357    Process::StopLocker stop_locker;
358    if (stop_locker.TryLock(&process->GetRunLock())) {
359      if (StackFrame *frame = exe_ctx.GetFramePtr()) {
360        if (RegisterContextSP reg_ctx_sp = frame->GetRegisterContext()) {
361          ret_val = reg_ctx_sp->SetPC(new_pc);
362        }
363      }
364    }
365  }
366
367  return ret_val;
368}
369
370addr_t SBFrame::GetSP() const {
371  LLDB_INSTRUMENT_VA(this);
372
373  addr_t addr = LLDB_INVALID_ADDRESS;
374  std::unique_lock<std::recursive_mutex> lock;
375  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
376
377  Target *target = exe_ctx.GetTargetPtr();
378  Process *process = exe_ctx.GetProcessPtr();
379  if (target && process) {
380    Process::StopLocker stop_locker;
381    if (stop_locker.TryLock(&process->GetRunLock())) {
382      if (StackFrame *frame = exe_ctx.GetFramePtr()) {
383        if (RegisterContextSP reg_ctx_sp = frame->GetRegisterContext()) {
384          addr = reg_ctx_sp->GetSP();
385        }
386      }
387    }
388  }
389
390  return addr;
391}
392
393addr_t SBFrame::GetFP() const {
394  LLDB_INSTRUMENT_VA(this);
395
396  addr_t addr = LLDB_INVALID_ADDRESS;
397  std::unique_lock<std::recursive_mutex> lock;
398  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
399
400  Target *target = exe_ctx.GetTargetPtr();
401  Process *process = exe_ctx.GetProcessPtr();
402  if (target && process) {
403    Process::StopLocker stop_locker;
404    if (stop_locker.TryLock(&process->GetRunLock())) {
405      if (StackFrame *frame = exe_ctx.GetFramePtr()) {
406        if (RegisterContextSP reg_ctx_sp = frame->GetRegisterContext()) {
407          addr = reg_ctx_sp->GetFP();
408        }
409      }
410    }
411  }
412
413  return addr;
414}
415
416SBAddress SBFrame::GetPCAddress() const {
417  LLDB_INSTRUMENT_VA(this);
418
419  SBAddress sb_addr;
420  std::unique_lock<std::recursive_mutex> lock;
421  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
422
423  StackFrame *frame = exe_ctx.GetFramePtr();
424  Target *target = exe_ctx.GetTargetPtr();
425  Process *process = exe_ctx.GetProcessPtr();
426  if (target && process) {
427    Process::StopLocker stop_locker;
428    if (stop_locker.TryLock(&process->GetRunLock())) {
429      frame = exe_ctx.GetFramePtr();
430      if (frame)
431        sb_addr.SetAddress(frame->GetFrameCodeAddress());
432    }
433  }
434  return sb_addr;
435}
436
437void SBFrame::Clear() {
438  LLDB_INSTRUMENT_VA(this);
439
440  m_opaque_sp->Clear();
441}
442
443lldb::SBValue SBFrame::GetValueForVariablePath(const char *var_path) {
444  LLDB_INSTRUMENT_VA(this, var_path);
445
446  SBValue sb_value;
447  std::unique_lock<std::recursive_mutex> lock;
448  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
449
450  StackFrame *frame = exe_ctx.GetFramePtr();
451  Target *target = exe_ctx.GetTargetPtr();
452  if (frame && target) {
453    lldb::DynamicValueType use_dynamic =
454        frame->CalculateTarget()->GetPreferDynamicValue();
455    sb_value = GetValueForVariablePath(var_path, use_dynamic);
456  }
457  return sb_value;
458}
459
460lldb::SBValue SBFrame::GetValueForVariablePath(const char *var_path,
461                                               DynamicValueType use_dynamic) {
462  LLDB_INSTRUMENT_VA(this, var_path, use_dynamic);
463
464  SBValue sb_value;
465  if (var_path == nullptr || var_path[0] == '\0') {
466    return sb_value;
467  }
468
469  std::unique_lock<std::recursive_mutex> lock;
470  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
471
472  StackFrame *frame = nullptr;
473  Target *target = exe_ctx.GetTargetPtr();
474  Process *process = exe_ctx.GetProcessPtr();
475  if (target && process) {
476    Process::StopLocker stop_locker;
477    if (stop_locker.TryLock(&process->GetRunLock())) {
478      frame = exe_ctx.GetFramePtr();
479      if (frame) {
480        VariableSP var_sp;
481        Status error;
482        ValueObjectSP value_sp(frame->GetValueForVariableExpressionPath(
483            var_path, eNoDynamicValues,
484            StackFrame::eExpressionPathOptionCheckPtrVsMember |
485                StackFrame::eExpressionPathOptionsAllowDirectIVarAccess,
486            var_sp, error));
487        sb_value.SetSP(value_sp, use_dynamic);
488      }
489    }
490  }
491  return sb_value;
492}
493
494SBValue SBFrame::FindVariable(const char *name) {
495  LLDB_INSTRUMENT_VA(this, name);
496
497  SBValue value;
498  std::unique_lock<std::recursive_mutex> lock;
499  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
500
501  StackFrame *frame = exe_ctx.GetFramePtr();
502  Target *target = exe_ctx.GetTargetPtr();
503  if (frame && target) {
504    lldb::DynamicValueType use_dynamic =
505        frame->CalculateTarget()->GetPreferDynamicValue();
506    value = FindVariable(name, use_dynamic);
507  }
508  return value;
509}
510
511SBValue SBFrame::FindVariable(const char *name,
512                              lldb::DynamicValueType use_dynamic) {
513  LLDB_INSTRUMENT_VA(this, name, use_dynamic);
514
515  VariableSP var_sp;
516  SBValue sb_value;
517
518  if (name == nullptr || name[0] == '\0') {
519    return sb_value;
520  }
521
522  ValueObjectSP value_sp;
523  std::unique_lock<std::recursive_mutex> lock;
524  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
525
526  StackFrame *frame = nullptr;
527  Target *target = exe_ctx.GetTargetPtr();
528  Process *process = exe_ctx.GetProcessPtr();
529  if (target && process) {
530    Process::StopLocker stop_locker;
531    if (stop_locker.TryLock(&process->GetRunLock())) {
532      frame = exe_ctx.GetFramePtr();
533      if (frame) {
534        value_sp = frame->FindVariable(ConstString(name));
535
536        if (value_sp)
537          sb_value.SetSP(value_sp, use_dynamic);
538      }
539    }
540  }
541
542  return sb_value;
543}
544
545SBValue SBFrame::FindValue(const char *name, ValueType value_type) {
546  LLDB_INSTRUMENT_VA(this, name, value_type);
547
548  SBValue value;
549  std::unique_lock<std::recursive_mutex> lock;
550  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
551
552  StackFrame *frame = exe_ctx.GetFramePtr();
553  Target *target = exe_ctx.GetTargetPtr();
554  if (frame && target) {
555    lldb::DynamicValueType use_dynamic =
556        frame->CalculateTarget()->GetPreferDynamicValue();
557    value = FindValue(name, value_type, use_dynamic);
558  }
559  return value;
560}
561
562SBValue SBFrame::FindValue(const char *name, ValueType value_type,
563                           lldb::DynamicValueType use_dynamic) {
564  LLDB_INSTRUMENT_VA(this, name, value_type, use_dynamic);
565
566  SBValue sb_value;
567
568  if (name == nullptr || name[0] == '\0') {
569    return sb_value;
570  }
571
572  ValueObjectSP value_sp;
573  std::unique_lock<std::recursive_mutex> lock;
574  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
575
576  StackFrame *frame = nullptr;
577  Target *target = exe_ctx.GetTargetPtr();
578  Process *process = exe_ctx.GetProcessPtr();
579  if (target && process) {
580    Process::StopLocker stop_locker;
581    if (stop_locker.TryLock(&process->GetRunLock())) {
582      frame = exe_ctx.GetFramePtr();
583      if (frame) {
584        VariableList variable_list;
585
586        switch (value_type) {
587        case eValueTypeVariableGlobal:      // global variable
588        case eValueTypeVariableStatic:      // static variable
589        case eValueTypeVariableArgument:    // function argument variables
590        case eValueTypeVariableLocal:       // function local variables
591        case eValueTypeVariableThreadLocal: // thread local variables
592        {
593          SymbolContext sc(frame->GetSymbolContext(eSymbolContextBlock));
594
595          const bool can_create = true;
596          const bool get_parent_variables = true;
597          const bool stop_if_block_is_inlined_function = true;
598
599          if (sc.block)
600            sc.block->AppendVariables(
601                can_create, get_parent_variables,
602                stop_if_block_is_inlined_function,
603                [frame](Variable *v) { return v->IsInScope(frame); },
604                &variable_list);
605          if (value_type == eValueTypeVariableGlobal
606              || value_type == eValueTypeVariableStatic) {
607            const bool get_file_globals = true;
608            VariableList *frame_vars = frame->GetVariableList(get_file_globals,
609                                                              nullptr);
610            if (frame_vars)
611              frame_vars->AppendVariablesIfUnique(variable_list);
612          }
613          ConstString const_name(name);
614          VariableSP variable_sp(
615              variable_list.FindVariable(const_name, value_type));
616          if (variable_sp) {
617            value_sp = frame->GetValueObjectForFrameVariable(variable_sp,
618                                                             eNoDynamicValues);
619            sb_value.SetSP(value_sp, use_dynamic);
620          }
621        } break;
622
623        case eValueTypeRegister: // stack frame register value
624        {
625          RegisterContextSP reg_ctx(frame->GetRegisterContext());
626          if (reg_ctx) {
627            if (const RegisterInfo *reg_info =
628                    reg_ctx->GetRegisterInfoByName(name)) {
629              value_sp = ValueObjectRegister::Create(frame, reg_ctx, reg_info);
630              sb_value.SetSP(value_sp);
631            }
632          }
633        } break;
634
635        case eValueTypeRegisterSet: // A collection of stack frame register
636                                    // values
637        {
638          RegisterContextSP reg_ctx(frame->GetRegisterContext());
639          if (reg_ctx) {
640            const uint32_t num_sets = reg_ctx->GetRegisterSetCount();
641            for (uint32_t set_idx = 0; set_idx < num_sets; ++set_idx) {
642              const RegisterSet *reg_set = reg_ctx->GetRegisterSet(set_idx);
643              if (reg_set &&
644                  (llvm::StringRef(reg_set->name).equals_insensitive(name) ||
645                   llvm::StringRef(reg_set->short_name)
646                       .equals_insensitive(name))) {
647                value_sp =
648                    ValueObjectRegisterSet::Create(frame, reg_ctx, set_idx);
649                sb_value.SetSP(value_sp);
650                break;
651              }
652            }
653          }
654        } break;
655
656        case eValueTypeConstResult: // constant result variables
657        {
658          ConstString const_name(name);
659          ExpressionVariableSP expr_var_sp(
660              target->GetPersistentVariable(const_name));
661          if (expr_var_sp) {
662            value_sp = expr_var_sp->GetValueObject();
663            sb_value.SetSP(value_sp, use_dynamic);
664          }
665        } break;
666
667        default:
668          break;
669        }
670      }
671    }
672  }
673
674  return sb_value;
675}
676
677bool SBFrame::IsEqual(const SBFrame &that) const {
678  LLDB_INSTRUMENT_VA(this, that);
679
680  lldb::StackFrameSP this_sp = GetFrameSP();
681  lldb::StackFrameSP that_sp = that.GetFrameSP();
682  return (this_sp && that_sp && this_sp->GetStackID() == that_sp->GetStackID());
683}
684
685bool SBFrame::operator==(const SBFrame &rhs) const {
686  LLDB_INSTRUMENT_VA(this, rhs);
687
688  return IsEqual(rhs);
689}
690
691bool SBFrame::operator!=(const SBFrame &rhs) const {
692  LLDB_INSTRUMENT_VA(this, rhs);
693
694  return !IsEqual(rhs);
695}
696
697SBThread SBFrame::GetThread() const {
698  LLDB_INSTRUMENT_VA(this);
699
700  std::unique_lock<std::recursive_mutex> lock;
701  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
702
703  ThreadSP thread_sp(exe_ctx.GetThreadSP());
704  SBThread sb_thread(thread_sp);
705
706  return sb_thread;
707}
708
709const char *SBFrame::Disassemble() const {
710  LLDB_INSTRUMENT_VA(this);
711
712  std::unique_lock<std::recursive_mutex> lock;
713  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
714  Target *target = exe_ctx.GetTargetPtr();
715  Process *process = exe_ctx.GetProcessPtr();
716  if (!target || !process)
717    return nullptr;
718
719  Process::StopLocker stop_locker;
720  if (stop_locker.TryLock(&process->GetRunLock())) {
721    if (auto *frame = exe_ctx.GetFramePtr())
722      return ConstString(frame->Disassemble()).GetCString();
723  }
724
725  return nullptr;
726}
727
728SBValueList SBFrame::GetVariables(bool arguments, bool locals, bool statics,
729                                  bool in_scope_only) {
730  LLDB_INSTRUMENT_VA(this, arguments, locals, statics, in_scope_only);
731
732  SBValueList value_list;
733  std::unique_lock<std::recursive_mutex> lock;
734  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
735
736  StackFrame *frame = exe_ctx.GetFramePtr();
737  Target *target = exe_ctx.GetTargetPtr();
738  if (frame && target) {
739    lldb::DynamicValueType use_dynamic =
740        frame->CalculateTarget()->GetPreferDynamicValue();
741    const bool include_runtime_support_values =
742        target->GetDisplayRuntimeSupportValues();
743
744    SBVariablesOptions options;
745    options.SetIncludeArguments(arguments);
746    options.SetIncludeLocals(locals);
747    options.SetIncludeStatics(statics);
748    options.SetInScopeOnly(in_scope_only);
749    options.SetIncludeRuntimeSupportValues(include_runtime_support_values);
750    options.SetUseDynamic(use_dynamic);
751
752    value_list = GetVariables(options);
753  }
754  return value_list;
755}
756
757lldb::SBValueList SBFrame::GetVariables(bool arguments, bool locals,
758                                        bool statics, bool in_scope_only,
759                                        lldb::DynamicValueType use_dynamic) {
760  LLDB_INSTRUMENT_VA(this, arguments, locals, statics, in_scope_only,
761                     use_dynamic);
762
763  std::unique_lock<std::recursive_mutex> lock;
764  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
765
766  Target *target = exe_ctx.GetTargetPtr();
767  const bool include_runtime_support_values =
768      target ? target->GetDisplayRuntimeSupportValues() : false;
769  SBVariablesOptions options;
770  options.SetIncludeArguments(arguments);
771  options.SetIncludeLocals(locals);
772  options.SetIncludeStatics(statics);
773  options.SetInScopeOnly(in_scope_only);
774  options.SetIncludeRuntimeSupportValues(include_runtime_support_values);
775  options.SetUseDynamic(use_dynamic);
776  return GetVariables(options);
777}
778
779SBValueList SBFrame::GetVariables(const lldb::SBVariablesOptions &options) {
780  LLDB_INSTRUMENT_VA(this, options);
781
782  SBValueList value_list;
783  std::unique_lock<std::recursive_mutex> lock;
784  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
785
786  StackFrame *frame = nullptr;
787  Target *target = exe_ctx.GetTargetPtr();
788
789  const bool statics = options.GetIncludeStatics();
790  const bool arguments = options.GetIncludeArguments();
791  const bool recognized_arguments =
792        options.GetIncludeRecognizedArguments(SBTarget(exe_ctx.GetTargetSP()));
793  const bool locals = options.GetIncludeLocals();
794  const bool in_scope_only = options.GetInScopeOnly();
795  const bool include_runtime_support_values =
796      options.GetIncludeRuntimeSupportValues();
797  const lldb::DynamicValueType use_dynamic = options.GetUseDynamic();
798
799
800  std::set<VariableSP> variable_set;
801  Process *process = exe_ctx.GetProcessPtr();
802  if (target && process) {
803    Process::StopLocker stop_locker;
804    if (stop_locker.TryLock(&process->GetRunLock())) {
805      frame = exe_ctx.GetFramePtr();
806      if (frame) {
807        Debugger &dbg = process->GetTarget().GetDebugger();
808        VariableList *variable_list = nullptr;
809        Status var_error;
810        variable_list = frame->GetVariableList(true, &var_error);
811        if (var_error.Fail())
812          value_list.SetError(var_error);
813        if (variable_list) {
814          const size_t num_variables = variable_list->GetSize();
815          if (num_variables) {
816            size_t num_produced = 0;
817            for (const VariableSP &variable_sp : *variable_list) {
818              if (INTERRUPT_REQUESTED(dbg,
819                    "Interrupted getting frame variables with {0} of {1} "
820                    "produced.", num_produced, num_variables))
821                return {};
822
823              if (variable_sp) {
824                bool add_variable = false;
825                switch (variable_sp->GetScope()) {
826                case eValueTypeVariableGlobal:
827                case eValueTypeVariableStatic:
828                case eValueTypeVariableThreadLocal:
829                  add_variable = statics;
830                  break;
831
832                case eValueTypeVariableArgument:
833                  add_variable = arguments;
834                  break;
835
836                case eValueTypeVariableLocal:
837                  add_variable = locals;
838                  break;
839
840                default:
841                  break;
842                }
843                if (add_variable) {
844                  // Only add variables once so we don't end up with duplicates
845                  if (variable_set.find(variable_sp) == variable_set.end())
846                    variable_set.insert(variable_sp);
847                  else
848                    continue;
849
850                  if (in_scope_only && !variable_sp->IsInScope(frame))
851                    continue;
852
853                  ValueObjectSP valobj_sp(frame->GetValueObjectForFrameVariable(
854                      variable_sp, eNoDynamicValues));
855
856                  if (!include_runtime_support_values && valobj_sp != nullptr &&
857                      valobj_sp->IsRuntimeSupportValue())
858                    continue;
859
860                  SBValue value_sb;
861                  value_sb.SetSP(valobj_sp, use_dynamic);
862                  value_list.Append(value_sb);
863                }
864              }
865            }
866            num_produced++;
867          }
868        }
869        if (recognized_arguments) {
870          auto recognized_frame = frame->GetRecognizedFrame();
871          if (recognized_frame) {
872            ValueObjectListSP recognized_arg_list =
873                recognized_frame->GetRecognizedArguments();
874            if (recognized_arg_list) {
875              for (auto &rec_value_sp : recognized_arg_list->GetObjects()) {
876                SBValue value_sb;
877                value_sb.SetSP(rec_value_sp, use_dynamic);
878                value_list.Append(value_sb);
879              }
880            }
881          }
882        }
883      }
884    }
885  }
886
887  return value_list;
888}
889
890SBValueList SBFrame::GetRegisters() {
891  LLDB_INSTRUMENT_VA(this);
892
893  SBValueList value_list;
894  std::unique_lock<std::recursive_mutex> lock;
895  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
896
897  StackFrame *frame = nullptr;
898  Target *target = exe_ctx.GetTargetPtr();
899  Process *process = exe_ctx.GetProcessPtr();
900  if (target && process) {
901    Process::StopLocker stop_locker;
902    if (stop_locker.TryLock(&process->GetRunLock())) {
903      frame = exe_ctx.GetFramePtr();
904      if (frame) {
905        RegisterContextSP reg_ctx(frame->GetRegisterContext());
906        if (reg_ctx) {
907          const uint32_t num_sets = reg_ctx->GetRegisterSetCount();
908          for (uint32_t set_idx = 0; set_idx < num_sets; ++set_idx) {
909            value_list.Append(
910                ValueObjectRegisterSet::Create(frame, reg_ctx, set_idx));
911          }
912        }
913      }
914    }
915  }
916
917  return value_list;
918}
919
920SBValue SBFrame::FindRegister(const char *name) {
921  LLDB_INSTRUMENT_VA(this, name);
922
923  SBValue result;
924  ValueObjectSP value_sp;
925  std::unique_lock<std::recursive_mutex> lock;
926  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
927
928  StackFrame *frame = nullptr;
929  Target *target = exe_ctx.GetTargetPtr();
930  Process *process = exe_ctx.GetProcessPtr();
931  if (target && process) {
932    Process::StopLocker stop_locker;
933    if (stop_locker.TryLock(&process->GetRunLock())) {
934      frame = exe_ctx.GetFramePtr();
935      if (frame) {
936        RegisterContextSP reg_ctx(frame->GetRegisterContext());
937        if (reg_ctx) {
938          if (const RegisterInfo *reg_info =
939                  reg_ctx->GetRegisterInfoByName(name)) {
940            value_sp = ValueObjectRegister::Create(frame, reg_ctx, reg_info);
941            result.SetSP(value_sp);
942          }
943        }
944      }
945    }
946  }
947
948  return result;
949}
950
951SBError SBFrame::GetDescriptionWithFormat(const SBFormat &format,
952                                          SBStream &output) {
953  Stream &strm = output.ref();
954
955  std::unique_lock<std::recursive_mutex> lock;
956  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
957
958  StackFrame *frame = nullptr;
959  Target *target = exe_ctx.GetTargetPtr();
960  Process *process = exe_ctx.GetProcessPtr();
961  SBError error;
962
963  if (!format) {
964    error.SetErrorString("The provided SBFormat object is invalid");
965    return error;
966  }
967
968  if (target && process) {
969    Process::StopLocker stop_locker;
970    if (stop_locker.TryLock(&process->GetRunLock())) {
971      frame = exe_ctx.GetFramePtr();
972      if (frame &&
973          frame->DumpUsingFormat(strm, format.GetFormatEntrySP().get())) {
974        return error;
975      }
976    }
977  }
978  error.SetErrorStringWithFormat(
979      "It was not possible to generate a frame "
980      "description with the given format string '%s'",
981      format.GetFormatEntrySP()->string.c_str());
982  return error;
983}
984
985bool SBFrame::GetDescription(SBStream &description) {
986  LLDB_INSTRUMENT_VA(this, description);
987
988  Stream &strm = description.ref();
989
990  std::unique_lock<std::recursive_mutex> lock;
991  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
992
993  StackFrame *frame;
994  Target *target = exe_ctx.GetTargetPtr();
995  Process *process = exe_ctx.GetProcessPtr();
996  if (target && process) {
997    Process::StopLocker stop_locker;
998    if (stop_locker.TryLock(&process->GetRunLock())) {
999      frame = exe_ctx.GetFramePtr();
1000      if (frame) {
1001        frame->DumpUsingSettingsFormat(&strm);
1002      }
1003    }
1004
1005  } else
1006    strm.PutCString("No value");
1007
1008  return true;
1009}
1010
1011SBValue SBFrame::EvaluateExpression(const char *expr) {
1012  LLDB_INSTRUMENT_VA(this, expr);
1013
1014  SBValue result;
1015  std::unique_lock<std::recursive_mutex> lock;
1016  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1017
1018  StackFrame *frame = exe_ctx.GetFramePtr();
1019  Target *target = exe_ctx.GetTargetPtr();
1020  if (frame && target) {
1021    SBExpressionOptions options;
1022    lldb::DynamicValueType fetch_dynamic_value =
1023        frame->CalculateTarget()->GetPreferDynamicValue();
1024    options.SetFetchDynamicValue(fetch_dynamic_value);
1025    options.SetUnwindOnError(true);
1026    options.SetIgnoreBreakpoints(true);
1027    if (target->GetLanguage() != eLanguageTypeUnknown)
1028      options.SetLanguage(target->GetLanguage());
1029    else
1030      options.SetLanguage(frame->GetLanguage());
1031    return EvaluateExpression(expr, options);
1032  } else {
1033    Status error;
1034    error.SetErrorString("can't evaluate expressions when the "
1035                           "process is running.");
1036    ValueObjectSP error_val_sp = ValueObjectConstResult::Create(nullptr, error);
1037    result.SetSP(error_val_sp, false);
1038  }
1039  return result;
1040}
1041
1042SBValue
1043SBFrame::EvaluateExpression(const char *expr,
1044                            lldb::DynamicValueType fetch_dynamic_value) {
1045  LLDB_INSTRUMENT_VA(this, expr, fetch_dynamic_value);
1046
1047  SBExpressionOptions options;
1048  options.SetFetchDynamicValue(fetch_dynamic_value);
1049  options.SetUnwindOnError(true);
1050  options.SetIgnoreBreakpoints(true);
1051  std::unique_lock<std::recursive_mutex> lock;
1052  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1053
1054  StackFrame *frame = exe_ctx.GetFramePtr();
1055  Target *target = exe_ctx.GetTargetPtr();
1056  if (target && target->GetLanguage() != eLanguageTypeUnknown)
1057    options.SetLanguage(target->GetLanguage());
1058  else if (frame)
1059    options.SetLanguage(frame->GetLanguage());
1060  return EvaluateExpression(expr, options);
1061}
1062
1063SBValue SBFrame::EvaluateExpression(const char *expr,
1064                                    lldb::DynamicValueType fetch_dynamic_value,
1065                                    bool unwind_on_error) {
1066  LLDB_INSTRUMENT_VA(this, expr, fetch_dynamic_value, unwind_on_error);
1067
1068  SBExpressionOptions options;
1069  std::unique_lock<std::recursive_mutex> lock;
1070  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1071
1072  options.SetFetchDynamicValue(fetch_dynamic_value);
1073  options.SetUnwindOnError(unwind_on_error);
1074  options.SetIgnoreBreakpoints(true);
1075  StackFrame *frame = exe_ctx.GetFramePtr();
1076  Target *target = exe_ctx.GetTargetPtr();
1077  if (target && target->GetLanguage() != eLanguageTypeUnknown)
1078    options.SetLanguage(target->GetLanguage());
1079  else if (frame)
1080    options.SetLanguage(frame->GetLanguage());
1081  return EvaluateExpression(expr, options);
1082}
1083
1084lldb::SBValue SBFrame::EvaluateExpression(const char *expr,
1085                                          const SBExpressionOptions &options) {
1086  LLDB_INSTRUMENT_VA(this, expr, options);
1087
1088  Log *expr_log = GetLog(LLDBLog::Expressions);
1089
1090  SBValue expr_result;
1091
1092  if (expr == nullptr || expr[0] == '\0') {
1093    return expr_result;
1094  }
1095
1096  ValueObjectSP expr_value_sp;
1097
1098  std::unique_lock<std::recursive_mutex> lock;
1099  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1100
1101  StackFrame *frame = nullptr;
1102  Target *target = exe_ctx.GetTargetPtr();
1103  Process *process = exe_ctx.GetProcessPtr();
1104
1105  if (target && process) {
1106    Process::StopLocker stop_locker;
1107    if (stop_locker.TryLock(&process->GetRunLock())) {
1108      frame = exe_ctx.GetFramePtr();
1109      if (frame) {
1110        std::unique_ptr<llvm::PrettyStackTraceFormat> stack_trace;
1111        if (target->GetDisplayExpressionsInCrashlogs()) {
1112          StreamString frame_description;
1113          frame->DumpUsingSettingsFormat(&frame_description);
1114          stack_trace = std::make_unique<llvm::PrettyStackTraceFormat>(
1115              "SBFrame::EvaluateExpression (expr = \"%s\", fetch_dynamic_value "
1116              "= %u) %s",
1117              expr, options.GetFetchDynamicValue(),
1118              frame_description.GetData());
1119        }
1120
1121        target->EvaluateExpression(expr, frame, expr_value_sp, options.ref());
1122        expr_result.SetSP(expr_value_sp, options.GetFetchDynamicValue());
1123      }
1124    } else {
1125      Status error;
1126      error.SetErrorString("can't evaluate expressions when the "
1127                           "process is running.");
1128      expr_value_sp = ValueObjectConstResult::Create(nullptr, error);
1129      expr_result.SetSP(expr_value_sp, false);
1130    }
1131  } else {
1132      Status error;
1133      error.SetErrorString("sbframe object is not valid.");
1134      expr_value_sp = ValueObjectConstResult::Create(nullptr, error);
1135      expr_result.SetSP(expr_value_sp, false);
1136  }
1137
1138  if (expr_result.GetError().Success())
1139    LLDB_LOGF(expr_log,
1140              "** [SBFrame::EvaluateExpression] Expression result is "
1141              "%s, summary %s **",
1142              expr_result.GetValue(), expr_result.GetSummary());
1143  else
1144    LLDB_LOGF(expr_log,
1145              "** [SBFrame::EvaluateExpression] Expression evaluation failed: "
1146              "%s **",
1147              expr_result.GetError().GetCString());
1148
1149  return expr_result;
1150}
1151
1152bool SBFrame::IsInlined() {
1153  LLDB_INSTRUMENT_VA(this);
1154
1155  return static_cast<const SBFrame *>(this)->IsInlined();
1156}
1157
1158bool SBFrame::IsInlined() const {
1159  LLDB_INSTRUMENT_VA(this);
1160
1161  std::unique_lock<std::recursive_mutex> lock;
1162  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1163
1164  StackFrame *frame = nullptr;
1165  Target *target = exe_ctx.GetTargetPtr();
1166  Process *process = exe_ctx.GetProcessPtr();
1167  if (target && process) {
1168    Process::StopLocker stop_locker;
1169    if (stop_locker.TryLock(&process->GetRunLock())) {
1170      frame = exe_ctx.GetFramePtr();
1171      if (frame) {
1172
1173        Block *block = frame->GetSymbolContext(eSymbolContextBlock).block;
1174        if (block)
1175          return block->GetContainingInlinedBlock() != nullptr;
1176      }
1177    }
1178  }
1179  return false;
1180}
1181
1182bool SBFrame::IsArtificial() {
1183  LLDB_INSTRUMENT_VA(this);
1184
1185  return static_cast<const SBFrame *>(this)->IsArtificial();
1186}
1187
1188bool SBFrame::IsArtificial() const {
1189  LLDB_INSTRUMENT_VA(this);
1190
1191  std::unique_lock<std::recursive_mutex> lock;
1192  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1193
1194  StackFrame *frame = exe_ctx.GetFramePtr();
1195  if (frame)
1196    return frame->IsArtificial();
1197
1198  return false;
1199}
1200
1201const char *SBFrame::GetFunctionName() {
1202  LLDB_INSTRUMENT_VA(this);
1203
1204  return static_cast<const SBFrame *>(this)->GetFunctionName();
1205}
1206
1207lldb::LanguageType SBFrame::GuessLanguage() const {
1208  LLDB_INSTRUMENT_VA(this);
1209
1210  std::unique_lock<std::recursive_mutex> lock;
1211  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1212
1213  StackFrame *frame = nullptr;
1214  Target *target = exe_ctx.GetTargetPtr();
1215  Process *process = exe_ctx.GetProcessPtr();
1216  if (target && process) {
1217    Process::StopLocker stop_locker;
1218    if (stop_locker.TryLock(&process->GetRunLock())) {
1219      frame = exe_ctx.GetFramePtr();
1220      if (frame) {
1221        return frame->GuessLanguage();
1222      }
1223    }
1224  }
1225  return eLanguageTypeUnknown;
1226}
1227
1228const char *SBFrame::GetFunctionName() const {
1229  LLDB_INSTRUMENT_VA(this);
1230
1231  const char *name = nullptr;
1232  std::unique_lock<std::recursive_mutex> lock;
1233  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1234
1235  StackFrame *frame = nullptr;
1236  Target *target = exe_ctx.GetTargetPtr();
1237  Process *process = exe_ctx.GetProcessPtr();
1238  if (target && process) {
1239    Process::StopLocker stop_locker;
1240    if (stop_locker.TryLock(&process->GetRunLock())) {
1241      frame = exe_ctx.GetFramePtr();
1242      if (frame) {
1243        SymbolContext sc(frame->GetSymbolContext(eSymbolContextFunction |
1244                                                 eSymbolContextBlock |
1245                                                 eSymbolContextSymbol));
1246        if (sc.block) {
1247          Block *inlined_block = sc.block->GetContainingInlinedBlock();
1248          if (inlined_block) {
1249            const InlineFunctionInfo *inlined_info =
1250                inlined_block->GetInlinedFunctionInfo();
1251            name = inlined_info->GetName().AsCString();
1252          }
1253        }
1254
1255        if (name == nullptr) {
1256          if (sc.function)
1257            name = sc.function->GetName().GetCString();
1258        }
1259
1260        if (name == nullptr) {
1261          if (sc.symbol)
1262            name = sc.symbol->GetName().GetCString();
1263        }
1264      }
1265    }
1266  }
1267  return name;
1268}
1269
1270const char *SBFrame::GetDisplayFunctionName() {
1271  LLDB_INSTRUMENT_VA(this);
1272
1273  const char *name = nullptr;
1274
1275  std::unique_lock<std::recursive_mutex> lock;
1276  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1277
1278  StackFrame *frame = nullptr;
1279  Target *target = exe_ctx.GetTargetPtr();
1280  Process *process = exe_ctx.GetProcessPtr();
1281  if (target && process) {
1282    Process::StopLocker stop_locker;
1283    if (stop_locker.TryLock(&process->GetRunLock())) {
1284      frame = exe_ctx.GetFramePtr();
1285      if (frame) {
1286        SymbolContext sc(frame->GetSymbolContext(eSymbolContextFunction |
1287                                                 eSymbolContextBlock |
1288                                                 eSymbolContextSymbol));
1289        if (sc.block) {
1290          Block *inlined_block = sc.block->GetContainingInlinedBlock();
1291          if (inlined_block) {
1292            const InlineFunctionInfo *inlined_info =
1293                inlined_block->GetInlinedFunctionInfo();
1294            name = inlined_info->GetDisplayName().AsCString();
1295          }
1296        }
1297
1298        if (name == nullptr) {
1299          if (sc.function)
1300            name = sc.function->GetDisplayName().GetCString();
1301        }
1302
1303        if (name == nullptr) {
1304          if (sc.symbol)
1305            name = sc.symbol->GetDisplayName().GetCString();
1306        }
1307      }
1308    }
1309  }
1310  return name;
1311}
1312