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