xref: /freebsd/contrib/llvm-project/lldb/source/API/SBFrame.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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 
57 using namespace lldb;
58 using namespace lldb_private;
59 
SBFrame()60 SBFrame::SBFrame() : m_opaque_sp(new ExecutionContextRef()) {
61   LLDB_INSTRUMENT_VA(this);
62 }
63 
SBFrame(const StackFrameSP & lldb_object_sp)64 SBFrame::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 
SBFrame(const SBFrame & rhs)69 SBFrame::SBFrame(const SBFrame &rhs) {
70   LLDB_INSTRUMENT_VA(this, rhs);
71 
72   m_opaque_sp = clone(rhs.m_opaque_sp);
73 }
74 
75 SBFrame::~SBFrame() = default;
76 
operator =(const SBFrame & rhs)77 const 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 
GetFrameSP() const85 StackFrameSP SBFrame::GetFrameSP() const {
86   return (m_opaque_sp ? m_opaque_sp->GetFrameSP() : StackFrameSP());
87 }
88 
SetFrameSP(const StackFrameSP & lldb_object_sp)89 void SBFrame::SetFrameSP(const StackFrameSP &lldb_object_sp) {
90   return m_opaque_sp->SetFrameSP(lldb_object_sp);
91 }
92 
IsValid() const93 bool SBFrame::IsValid() const {
94   LLDB_INSTRUMENT_VA(this);
95   return this->operator bool();
96 }
operator bool() const97 SBFrame::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 
GetSymbolContext(uint32_t resolve_scope) const115 SBSymbolContext 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 
GetModule() const135 SBModule 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 
GetCompileUnit() const160 SBCompileUnit 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 
GetFunction() const184 SBFunction 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 
GetSymbol() const208 SBSymbol 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 
GetBlock() const231 SBBlock 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 
GetFrameBlock() const252 SBBlock 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 
GetLineEntry() const273 SBLineEntry 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 
GetFrameID() const296 uint32_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 
GetCFA() const311 lldb::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 
GetPC() const323 addr_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 
SetPC(addr_t new_pc)347 bool 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 
GetSP() const370 addr_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 
GetFP() const393 addr_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 
GetPCAddress() const416 SBAddress 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 
Clear()437 void SBFrame::Clear() {
438   LLDB_INSTRUMENT_VA(this);
439 
440   m_opaque_sp->Clear();
441 }
442 
GetValueForVariablePath(const char * var_path)443 lldb::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 
GetValueForVariablePath(const char * var_path,DynamicValueType use_dynamic)460 lldb::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 
FindVariable(const char * name)494 SBValue 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 
FindVariable(const char * name,lldb::DynamicValueType use_dynamic)511 SBValue 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 
FindValue(const char * name,ValueType value_type)545 SBValue 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 
FindValue(const char * name,ValueType value_type,lldb::DynamicValueType use_dynamic)562 SBValue 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 
IsEqual(const SBFrame & that) const677 bool 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 
operator ==(const SBFrame & rhs) const685 bool SBFrame::operator==(const SBFrame &rhs) const {
686   LLDB_INSTRUMENT_VA(this, rhs);
687 
688   return IsEqual(rhs);
689 }
690 
operator !=(const SBFrame & rhs) const691 bool SBFrame::operator!=(const SBFrame &rhs) const {
692   LLDB_INSTRUMENT_VA(this, rhs);
693 
694   return !IsEqual(rhs);
695 }
696 
GetThread() const697 SBThread 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 
Disassemble() const709 const 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 
GetVariables(bool arguments,bool locals,bool statics,bool in_scope_only)728 SBValueList 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 
GetVariables(bool arguments,bool locals,bool statics,bool in_scope_only,lldb::DynamicValueType use_dynamic)757 lldb::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 
GetVariables(const lldb::SBVariablesOptions & options)779 SBValueList 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 
GetRegisters()890 SBValueList 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 
FindRegister(const char * name)920 SBValue 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 
GetDescriptionWithFormat(const SBFormat & format,SBStream & output)951 SBError 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 
GetDescription(SBStream & description)985 bool 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 
EvaluateExpression(const char * expr)1011 SBValue 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     SourceLanguage language = target->GetLanguage();
1028     if (!language)
1029       language = frame->GetLanguage();
1030     options.SetLanguage((SBSourceLanguageName)language.name, language.version);
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 
1042 SBValue
EvaluateExpression(const char * expr,lldb::DynamicValueType fetch_dynamic_value)1043 SBFrame::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   SourceLanguage language;
1057   if (target)
1058     language = target->GetLanguage();
1059   if (!language && frame)
1060     language = frame->GetLanguage();
1061   options.SetLanguage((SBSourceLanguageName)language.name, language.version);
1062   return EvaluateExpression(expr, options);
1063 }
1064 
EvaluateExpression(const char * expr,lldb::DynamicValueType fetch_dynamic_value,bool unwind_on_error)1065 SBValue SBFrame::EvaluateExpression(const char *expr,
1066                                     lldb::DynamicValueType fetch_dynamic_value,
1067                                     bool unwind_on_error) {
1068   LLDB_INSTRUMENT_VA(this, expr, fetch_dynamic_value, unwind_on_error);
1069 
1070   SBExpressionOptions options;
1071   std::unique_lock<std::recursive_mutex> lock;
1072   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1073 
1074   options.SetFetchDynamicValue(fetch_dynamic_value);
1075   options.SetUnwindOnError(unwind_on_error);
1076   options.SetIgnoreBreakpoints(true);
1077   StackFrame *frame = exe_ctx.GetFramePtr();
1078   Target *target = exe_ctx.GetTargetPtr();
1079   SourceLanguage language;
1080   if (target)
1081     language = target->GetLanguage();
1082   if (!language && frame)
1083     language = frame->GetLanguage();
1084   options.SetLanguage((SBSourceLanguageName)language.name, language.version);
1085   return EvaluateExpression(expr, options);
1086 }
1087 
EvaluateExpression(const char * expr,const SBExpressionOptions & options)1088 lldb::SBValue SBFrame::EvaluateExpression(const char *expr,
1089                                           const SBExpressionOptions &options) {
1090   LLDB_INSTRUMENT_VA(this, expr, options);
1091 
1092   Log *expr_log = GetLog(LLDBLog::Expressions);
1093 
1094   SBValue expr_result;
1095 
1096   if (expr == nullptr || expr[0] == '\0') {
1097     return expr_result;
1098   }
1099 
1100   ValueObjectSP expr_value_sp;
1101 
1102   std::unique_lock<std::recursive_mutex> lock;
1103   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1104 
1105   StackFrame *frame = nullptr;
1106   Target *target = exe_ctx.GetTargetPtr();
1107   Process *process = exe_ctx.GetProcessPtr();
1108 
1109   if (target && process) {
1110     Process::StopLocker stop_locker;
1111     if (stop_locker.TryLock(&process->GetRunLock())) {
1112       frame = exe_ctx.GetFramePtr();
1113       if (frame) {
1114         std::unique_ptr<llvm::PrettyStackTraceFormat> stack_trace;
1115         if (target->GetDisplayExpressionsInCrashlogs()) {
1116           StreamString frame_description;
1117           frame->DumpUsingSettingsFormat(&frame_description);
1118           stack_trace = std::make_unique<llvm::PrettyStackTraceFormat>(
1119               "SBFrame::EvaluateExpression (expr = \"%s\", fetch_dynamic_value "
1120               "= %u) %s",
1121               expr, options.GetFetchDynamicValue(),
1122               frame_description.GetData());
1123         }
1124 
1125         target->EvaluateExpression(expr, frame, expr_value_sp, options.ref());
1126         expr_result.SetSP(expr_value_sp, options.GetFetchDynamicValue());
1127       }
1128     } else {
1129       Status error;
1130       error.SetErrorString("can't evaluate expressions when the "
1131                            "process is running.");
1132       expr_value_sp = ValueObjectConstResult::Create(nullptr, error);
1133       expr_result.SetSP(expr_value_sp, false);
1134     }
1135   } else {
1136       Status error;
1137       error.SetErrorString("sbframe object is not valid.");
1138       expr_value_sp = ValueObjectConstResult::Create(nullptr, error);
1139       expr_result.SetSP(expr_value_sp, false);
1140   }
1141 
1142   if (expr_result.GetError().Success())
1143     LLDB_LOGF(expr_log,
1144               "** [SBFrame::EvaluateExpression] Expression result is "
1145               "%s, summary %s **",
1146               expr_result.GetValue(), expr_result.GetSummary());
1147   else
1148     LLDB_LOGF(expr_log,
1149               "** [SBFrame::EvaluateExpression] Expression evaluation failed: "
1150               "%s **",
1151               expr_result.GetError().GetCString());
1152 
1153   return expr_result;
1154 }
1155 
IsInlined()1156 bool SBFrame::IsInlined() {
1157   LLDB_INSTRUMENT_VA(this);
1158 
1159   return static_cast<const SBFrame *>(this)->IsInlined();
1160 }
1161 
IsInlined() const1162 bool SBFrame::IsInlined() const {
1163   LLDB_INSTRUMENT_VA(this);
1164 
1165   std::unique_lock<std::recursive_mutex> lock;
1166   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1167 
1168   StackFrame *frame = nullptr;
1169   Target *target = exe_ctx.GetTargetPtr();
1170   Process *process = exe_ctx.GetProcessPtr();
1171   if (target && process) {
1172     Process::StopLocker stop_locker;
1173     if (stop_locker.TryLock(&process->GetRunLock())) {
1174       frame = exe_ctx.GetFramePtr();
1175       if (frame) {
1176 
1177         Block *block = frame->GetSymbolContext(eSymbolContextBlock).block;
1178         if (block)
1179           return block->GetContainingInlinedBlock() != nullptr;
1180       }
1181     }
1182   }
1183   return false;
1184 }
1185 
IsArtificial()1186 bool SBFrame::IsArtificial() {
1187   LLDB_INSTRUMENT_VA(this);
1188 
1189   return static_cast<const SBFrame *>(this)->IsArtificial();
1190 }
1191 
IsArtificial() const1192 bool SBFrame::IsArtificial() const {
1193   LLDB_INSTRUMENT_VA(this);
1194 
1195   std::unique_lock<std::recursive_mutex> lock;
1196   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1197 
1198   StackFrame *frame = exe_ctx.GetFramePtr();
1199   if (frame)
1200     return frame->IsArtificial();
1201 
1202   return false;
1203 }
1204 
GetFunctionName()1205 const char *SBFrame::GetFunctionName() {
1206   LLDB_INSTRUMENT_VA(this);
1207 
1208   return static_cast<const SBFrame *>(this)->GetFunctionName();
1209 }
1210 
GuessLanguage() const1211 lldb::LanguageType SBFrame::GuessLanguage() const {
1212   LLDB_INSTRUMENT_VA(this);
1213 
1214   std::unique_lock<std::recursive_mutex> lock;
1215   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1216 
1217   StackFrame *frame = nullptr;
1218   Target *target = exe_ctx.GetTargetPtr();
1219   Process *process = exe_ctx.GetProcessPtr();
1220   if (target && process) {
1221     Process::StopLocker stop_locker;
1222     if (stop_locker.TryLock(&process->GetRunLock())) {
1223       frame = exe_ctx.GetFramePtr();
1224       if (frame) {
1225         return frame->GuessLanguage().AsLanguageType();
1226       }
1227     }
1228   }
1229   return eLanguageTypeUnknown;
1230 }
1231 
GetFunctionName() const1232 const char *SBFrame::GetFunctionName() const {
1233   LLDB_INSTRUMENT_VA(this);
1234 
1235   const char *name = nullptr;
1236   std::unique_lock<std::recursive_mutex> lock;
1237   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1238 
1239   StackFrame *frame = nullptr;
1240   Target *target = exe_ctx.GetTargetPtr();
1241   Process *process = exe_ctx.GetProcessPtr();
1242   if (target && process) {
1243     Process::StopLocker stop_locker;
1244     if (stop_locker.TryLock(&process->GetRunLock())) {
1245       frame = exe_ctx.GetFramePtr();
1246       if (frame) {
1247         SymbolContext sc(frame->GetSymbolContext(eSymbolContextFunction |
1248                                                  eSymbolContextBlock |
1249                                                  eSymbolContextSymbol));
1250         if (sc.block) {
1251           Block *inlined_block = sc.block->GetContainingInlinedBlock();
1252           if (inlined_block) {
1253             const InlineFunctionInfo *inlined_info =
1254                 inlined_block->GetInlinedFunctionInfo();
1255             name = inlined_info->GetName().AsCString();
1256           }
1257         }
1258 
1259         if (name == nullptr) {
1260           if (sc.function)
1261             name = sc.function->GetName().GetCString();
1262         }
1263 
1264         if (name == nullptr) {
1265           if (sc.symbol)
1266             name = sc.symbol->GetName().GetCString();
1267         }
1268       }
1269     }
1270   }
1271   return name;
1272 }
1273 
GetDisplayFunctionName()1274 const char *SBFrame::GetDisplayFunctionName() {
1275   LLDB_INSTRUMENT_VA(this);
1276 
1277   const char *name = nullptr;
1278 
1279   std::unique_lock<std::recursive_mutex> lock;
1280   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1281 
1282   StackFrame *frame = nullptr;
1283   Target *target = exe_ctx.GetTargetPtr();
1284   Process *process = exe_ctx.GetProcessPtr();
1285   if (target && process) {
1286     Process::StopLocker stop_locker;
1287     if (stop_locker.TryLock(&process->GetRunLock())) {
1288       frame = exe_ctx.GetFramePtr();
1289       if (frame) {
1290         SymbolContext sc(frame->GetSymbolContext(eSymbolContextFunction |
1291                                                  eSymbolContextBlock |
1292                                                  eSymbolContextSymbol));
1293         if (sc.block) {
1294           Block *inlined_block = sc.block->GetContainingInlinedBlock();
1295           if (inlined_block) {
1296             const InlineFunctionInfo *inlined_info =
1297                 inlined_block->GetInlinedFunctionInfo();
1298             name = inlined_info->GetDisplayName().AsCString();
1299           }
1300         }
1301 
1302         if (name == nullptr) {
1303           if (sc.function)
1304             name = sc.function->GetDisplayName().GetCString();
1305         }
1306 
1307         if (name == nullptr) {
1308           if (sc.symbol)
1309             name = sc.symbol->GetDisplayName().GetCString();
1310         }
1311       }
1312     }
1313   }
1314   return name;
1315 }
1316