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