LLDB mainline
StackFrame.cpp
Go to the documentation of this file.
1//===-- StackFrame.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
10#include "lldb/Core/Debugger.h"
13#include "lldb/Core/Mangled.h"
14#include "lldb/Core/Module.h"
15#include "lldb/Core/Value.h"
18#include "lldb/Symbol/Symbol.h"
21#include "lldb/Symbol/Type.h"
23#include "lldb/Target/ABI.h"
26#include "lldb/Target/Process.h"
29#include "lldb/Target/Target.h"
30#include "lldb/Target/Thread.h"
32#include "lldb/Utility/Log.h"
40
42
43#include <memory>
44
45using namespace lldb;
46using namespace lldb_private;
47
48// LLVM RTTI support.
50
51// The first bits in the flags are reserved for the SymbolContext::Scope bits
52// so we know if we have tried to look up information in our internal symbol
53// context (m_sc) already.
54#define RESOLVED_FRAME_CODE_ADDR (uint32_t(eSymbolContextLastItem) << 1)
55#define RESOLVED_FRAME_ID_SYMBOL_SCOPE (RESOLVED_FRAME_CODE_ADDR << 1)
56#define GOT_FRAME_BASE (RESOLVED_FRAME_ID_SYMBOL_SCOPE << 1)
57#define RESOLVED_VARIABLES (GOT_FRAME_BASE << 1)
58#define RESOLVED_GLOBAL_VARIABLES (RESOLVED_VARIABLES << 1)
59
60StackFrame::StackFrame(const ThreadSP &thread_sp, user_id_t frame_idx,
61 user_id_t unwind_frame_index, addr_t cfa,
62 bool cfa_is_valid, addr_t pc, StackFrame::Kind kind,
63 bool artificial, bool behaves_like_zeroth_frame,
64 const SymbolContext *sc_ptr)
65 : m_thread_wp(thread_sp), m_frame_index(frame_idx),
66 m_concrete_frame_index(unwind_frame_index), m_reg_context_sp(),
67 m_id(pc, cfa, nullptr, thread_sp->GetProcess().get()),
69 m_frame_base_error(), m_cfa_is_valid(cfa_is_valid),
70 m_stack_frame_kind(kind), m_artificial(artificial),
71 m_behaves_like_zeroth_frame(behaves_like_zeroth_frame),
74 // If we don't have a CFA value, use the frame index for our StackID so that
75 // recursive functions properly aren't confused with one another on a history
76 // stack.
77 if (IsHistorical() && !m_cfa_is_valid) {
78 m_id.SetCFA(m_frame_index, thread_sp->GetProcess().get());
79 }
80
81 if (sc_ptr != nullptr) {
82 m_sc = *sc_ptr;
83 m_flags.Set(m_sc.GetResolvedMask());
84 }
85}
86
87StackFrame::StackFrame(const ThreadSP &thread_sp, user_id_t frame_idx,
88 user_id_t unwind_frame_index,
89 const RegisterContextSP &reg_context_sp, addr_t cfa,
90 addr_t pc, bool behaves_like_zeroth_frame,
91 const SymbolContext *sc_ptr)
92 : m_thread_wp(thread_sp), m_frame_index(frame_idx),
93 m_concrete_frame_index(unwind_frame_index),
94 m_reg_context_sp(reg_context_sp),
95 m_id(pc, cfa, nullptr, thread_sp->GetProcess().get()),
99 m_behaves_like_zeroth_frame(behaves_like_zeroth_frame),
102 if (sc_ptr != nullptr) {
103 m_sc = *sc_ptr;
104 m_flags.Set(m_sc.GetResolvedMask());
105 }
106
107 if (reg_context_sp && !m_sc.target_sp) {
108 m_sc.target_sp = reg_context_sp->CalculateTarget();
109 if (m_sc.target_sp)
110 m_flags.Set(eSymbolContextTarget);
111 }
112}
113
114StackFrame::StackFrame(const ThreadSP &thread_sp, user_id_t frame_idx,
115 user_id_t unwind_frame_index,
116 const RegisterContextSP &reg_context_sp, addr_t cfa,
117 const Address &pc_addr, bool behaves_like_zeroth_frame,
118 const SymbolContext *sc_ptr)
119 : m_thread_wp(thread_sp), m_frame_index(frame_idx),
120 m_concrete_frame_index(unwind_frame_index),
121 m_reg_context_sp(reg_context_sp),
122 m_id(pc_addr.GetLoadAddress(thread_sp->CalculateTarget().get()), cfa,
123 nullptr, thread_sp->GetProcess().get()),
124 m_frame_code_addr(pc_addr), m_sc(), m_flags(), m_frame_base(),
127 m_behaves_like_zeroth_frame(behaves_like_zeroth_frame),
130 if (sc_ptr != nullptr) {
131 m_sc = *sc_ptr;
132 m_flags.Set(m_sc.GetResolvedMask());
133 }
134
135 if (!m_sc.target_sp && reg_context_sp) {
136 m_sc.target_sp = reg_context_sp->CalculateTarget();
137 if (m_sc.target_sp)
138 m_flags.Set(eSymbolContextTarget);
139 }
140
141 ModuleSP pc_module_sp(pc_addr.GetModule());
142 if (!m_sc.module_sp || m_sc.module_sp != pc_module_sp) {
143 if (pc_module_sp) {
144 m_sc.module_sp = pc_module_sp;
145 m_flags.Set(eSymbolContextModule);
146 } else {
147 m_sc.module_sp.reset();
148 }
149 }
150}
151
152StackFrame::~StackFrame() = default;
153
155 std::lock_guard<std::recursive_mutex> guard(m_mutex);
156 // Make sure we have resolved the StackID object's symbol context scope if we
157 // already haven't looked it up.
158
160 if (m_id.GetSymbolContextScope()) {
161 // We already have a symbol context scope, we just don't have our flag
162 // bit set.
164 } else {
165 // Calculate the frame block and use this for the stack ID symbol context
166 // scope if we have one.
168 if (scope == nullptr) {
169 // We don't have a block, so use the symbol
170 if (m_flags.IsClear(eSymbolContextSymbol))
171 GetSymbolContext(eSymbolContextSymbol);
172
173 // It is ok if m_sc.symbol is nullptr here
174 scope = m_sc.symbol;
175 }
176 // Set the symbol context scope (the accessor will set the
177 // RESOLVED_FRAME_ID_SYMBOL_SCOPE bit in m_flags).
179 }
180 }
181 return m_id;
182}
183
185 ThreadSP thread_sp = GetThread();
186 if (thread_sp)
187 return thread_sp->GetStackFrameList()->GetVisibleStackFrameIndex(
189 else
190 return m_frame_index;
191}
192
194 std::lock_guard<std::recursive_mutex> guard(m_mutex);
196 m_id.SetSymbolContextScope(symbol_scope);
197}
198
200 std::lock_guard<std::recursive_mutex> guard(m_mutex);
201 if (m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR) &&
202 !m_frame_code_addr.IsSectionOffset()) {
204
205 // Resolve the PC into a temporary address because if ResolveLoadAddress
206 // fails to resolve the address, it will clear the address object...
207 ThreadSP thread_sp(GetThread());
208 if (thread_sp) {
209 TargetSP target_sp(thread_sp->CalculateTarget());
210 if (target_sp) {
211 const bool allow_section_end = true;
212 if (m_frame_code_addr.SetOpcodeLoadAddress(
213 m_frame_code_addr.GetOffset(), target_sp.get(),
214 AddressClass::eCode, allow_section_end)) {
215 ModuleSP module_sp(m_frame_code_addr.GetModule());
216 if (module_sp) {
217 m_sc.module_sp = module_sp;
218 m_flags.Set(eSymbolContextModule);
219 }
220 }
221 }
222 }
223 }
224 return m_frame_code_addr;
225}
226
227// This can't be rewritten into a call to
228// RegisterContext::GetPCForSymbolication because this
229// StackFrame may have been constructed with a special pc,
230// e.g. tail-call artificial frames.
232 Address lookup_addr(GetFrameCodeAddress());
233 if (!lookup_addr.IsValid())
234 return lookup_addr;
236 return lookup_addr;
237
238 addr_t offset = lookup_addr.GetOffset();
239 if (offset > 0) {
240 lookup_addr.SetOffset(offset - 1);
241 } else {
242 // lookup_addr is the start of a section. We need do the math on the
243 // actual load address and re-compute the section. We're working with
244 // a 'noreturn' function at the end of a section.
245 TargetSP target_sp = CalculateTarget();
246 if (target_sp) {
247 addr_t addr_minus_one = lookup_addr.GetOpcodeLoadAddress(
248 target_sp.get(), AddressClass::eCode) -
249 1;
250 lookup_addr.SetOpcodeLoadAddress(addr_minus_one, target_sp.get());
251 }
252 }
253 return lookup_addr;
254}
255
257 std::lock_guard<std::recursive_mutex> guard(m_mutex);
258 // We can't change the pc value of a history stack frame - it is immutable.
259 if (IsHistorical())
260 return false;
261 m_frame_code_addr.SetRawAddress(pc);
262 m_sc.Clear(false);
263 m_flags.Reset(0);
264 ThreadSP thread_sp(GetThread());
265 if (thread_sp)
266 thread_sp->ClearStackFrames();
267 return true;
268}
269
271 std::lock_guard<std::recursive_mutex> guard(m_mutex);
272
273 if (!m_disassembly.Empty())
274 return m_disassembly.GetData();
275
276 ExecutionContext exe_ctx(shared_from_this());
277 if (Target *target = exe_ctx.GetTargetPtr()) {
278 Disassembler::Disassemble(target->GetDebugger(), target->GetArchitecture(),
279 *this, m_disassembly);
280 }
281
282 return m_disassembly.Empty() ? nullptr : m_disassembly.GetData();
283}
284
286 if (m_sc.block == nullptr && m_flags.IsClear(eSymbolContextBlock))
287 GetSymbolContext(eSymbolContextBlock);
288
289 if (m_sc.block) {
290 Block *inline_block = m_sc.block->GetContainingInlinedBlock();
291 if (inline_block) {
292 // Use the block with the inlined function info as the frame block we
293 // want this frame to have only the variables for the inlined function
294 // and its non-inlined block child blocks.
295 return inline_block;
296 } else {
297 // This block is not contained within any inlined function blocks with so
298 // we want to use the top most function block.
299 return &m_sc.function->GetBlock(false);
300 }
301 }
302 return nullptr;
303}
304
305// Get the symbol context if we already haven't done so by resolving the
306// PC address as much as possible. This way when we pass around a
307// StackFrame object, everyone will have as much information as possible and no
308// one will ever have to look things up manually.
309const SymbolContext &
310StackFrame::GetSymbolContext(SymbolContextItem resolve_scope) {
311 std::lock_guard<std::recursive_mutex> guard(m_mutex);
312 // Copy our internal symbol context into "sc".
313 if ((m_flags.Get() & resolve_scope) != resolve_scope) {
314 uint32_t resolved = 0;
315
316 // If the target was requested add that:
317 if (!m_sc.target_sp) {
318 m_sc.target_sp = CalculateTarget();
319 if (m_sc.target_sp)
320 resolved |= eSymbolContextTarget;
321 }
322
323 // Resolve our PC to section offset if we haven't already done so and if we
324 // don't have a module. The resolved address section will contain the
325 // module to which it belongs
326 if (!m_sc.module_sp && m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR))
328
329 // If this is not frame zero, then we need to subtract 1 from the PC value
330 // when doing address lookups since the PC will be on the instruction
331 // following the function call instruction...
333
334 // For PC-less frames (e.g., scripted frames), skip PC-based symbol
335 // resolution and preserve any already-populated SymbolContext fields.
336 if (!lookup_addr.IsValid()) {
337 m_flags.Set(resolve_scope | resolved);
338 return m_sc;
339 }
340
341 if (m_sc.module_sp) {
342 // We have something in our stack frame symbol context, lets check if we
343 // haven't already tried to lookup one of those things. If we haven't
344 // then we will do the query.
345
346 SymbolContextItem actual_resolve_scope = SymbolContextItem(0);
347
348 if (resolve_scope & eSymbolContextCompUnit) {
349 if (m_flags.IsClear(eSymbolContextCompUnit)) {
350 if (m_sc.comp_unit)
351 resolved |= eSymbolContextCompUnit;
352 else
353 actual_resolve_scope |= eSymbolContextCompUnit;
354 }
355 }
356
357 if (resolve_scope & eSymbolContextFunction) {
358 if (m_flags.IsClear(eSymbolContextFunction)) {
359 if (m_sc.function)
360 resolved |= eSymbolContextFunction;
361 else
362 actual_resolve_scope |= eSymbolContextFunction;
363 }
364 }
365
366 if (resolve_scope & eSymbolContextBlock) {
367 if (m_flags.IsClear(eSymbolContextBlock)) {
368 if (m_sc.block)
369 resolved |= eSymbolContextBlock;
370 else
371 actual_resolve_scope |= eSymbolContextBlock;
372 }
373 }
374
375 if (resolve_scope & eSymbolContextSymbol) {
376 if (m_flags.IsClear(eSymbolContextSymbol)) {
377 if (m_sc.symbol)
378 resolved |= eSymbolContextSymbol;
379 else
380 actual_resolve_scope |= eSymbolContextSymbol;
381 }
382 }
383
384 if (resolve_scope & eSymbolContextLineEntry) {
385 if (m_flags.IsClear(eSymbolContextLineEntry)) {
386 if (m_sc.line_entry.IsValid())
387 resolved |= eSymbolContextLineEntry;
388 else
389 actual_resolve_scope |= eSymbolContextLineEntry;
390 }
391 }
392
393 if (actual_resolve_scope) {
394 // We might be resolving less information than what is already in our
395 // current symbol context so resolve into a temporary symbol context
396 // "sc" so we don't clear out data we have already found in "m_sc"
397 SymbolContext sc;
398 // Set flags that indicate what we have tried to resolve
399 resolved |= m_sc.module_sp->ResolveSymbolContextForAddress(
400 lookup_addr, actual_resolve_scope, sc);
401 // Only replace what we didn't already have as we may have information
402 // for an inlined function scope that won't match what a standard
403 // lookup by address would match
404 if ((resolved & eSymbolContextCompUnit) && m_sc.comp_unit == nullptr)
405 m_sc.comp_unit = sc.comp_unit;
406 if ((resolved & eSymbolContextFunction) && m_sc.function == nullptr)
407 m_sc.function = sc.function;
408 if ((resolved & eSymbolContextBlock) && m_sc.block == nullptr)
409 m_sc.block = sc.block;
410 if ((resolved & eSymbolContextSymbol) && m_sc.symbol == nullptr)
411 m_sc.symbol = sc.symbol;
412 if ((resolved & eSymbolContextLineEntry) &&
413 !m_sc.line_entry.IsValid()) {
414 m_sc.line_entry = sc.line_entry;
415 m_sc.line_entry.ApplyFileMappings(m_sc.target_sp);
416 }
417 }
418 } else {
419 // If we don't have a module, then we can't have the compile unit,
420 // function, block, line entry or symbol, so we can safely call
421 // ResolveSymbolContextForAddress with our symbol context member m_sc.
422 if (m_sc.target_sp) {
423 resolved |= m_sc.target_sp->GetImages().ResolveSymbolContextForAddress(
424 lookup_addr, resolve_scope, m_sc);
425 }
426 }
427
428 // Update our internal flags so we remember what we have tried to locate so
429 // we don't have to keep trying when more calls to this function are made.
430 // We might have dug up more information that was requested (for example if
431 // we were asked to only get the block, we will have gotten the compile
432 // unit, and function) so set any additional bits that we resolved
433 m_flags.Set(resolve_scope | resolved);
434 }
435
436 // Return the symbol context with everything that was possible to resolve
437 // resolved.
438 return m_sc;
439}
440
442 Status *error_ptr) {
443 std::lock_guard<std::recursive_mutex> guard(m_mutex);
444 if (m_flags.IsClear(RESOLVED_VARIABLES)) {
446 m_variable_list_sp = std::make_shared<VariableList>();
447
448 Block *frame_block = GetFrameBlock();
449
450 if (frame_block) {
451 const bool get_child_variables = true;
452 const bool can_create = true;
453 const bool stop_if_child_block_is_inlined_function = true;
454 frame_block->AppendBlockVariables(
455 can_create, get_child_variables,
456 stop_if_child_block_is_inlined_function,
457 [](Variable *v) { return true; }, m_variable_list_sp.get());
458 }
459 }
460
461 if (m_flags.IsClear(RESOLVED_GLOBAL_VARIABLES) && get_file_globals) {
463
464 if (m_flags.IsClear(eSymbolContextCompUnit))
465 GetSymbolContext(eSymbolContextCompUnit);
466
467 if (m_sc.comp_unit) {
468 VariableListSP global_variable_list_sp(
469 m_sc.comp_unit->GetVariableList(true));
471 m_variable_list_sp->AddVariables(global_variable_list_sp.get());
472 else
473 m_variable_list_sp = global_variable_list_sp;
474 }
475 }
476
477 if (error_ptr && m_variable_list_sp->GetSize() == 0) {
478 // Check with the symbol file to check if there is an error for why we
479 // don't have variables that the user might need to know about.
480 GetSymbolContext(eSymbolContextEverything);
481 if (m_sc.module_sp) {
482 SymbolFile *sym_file = m_sc.module_sp->GetSymbolFile();
483 if (sym_file)
484 *error_ptr = sym_file->GetFrameVariableError(*this);
485 }
486 }
487
488 return m_variable_list_sp.get();
489}
490
493 bool must_have_valid_location) {
494 std::lock_guard<std::recursive_mutex> guard(m_mutex);
495 // We can't fetch variable information for a history stack frame.
496 if (IsHistorical())
497 return VariableListSP();
498
499 VariableListSP var_list_sp(new VariableList);
500 GetSymbolContext(eSymbolContextCompUnit | eSymbolContextBlock);
501
502 if (m_sc.block) {
503 const bool can_create = true;
504 const bool get_parent_variables = true;
505 const bool stop_if_block_is_inlined_function = true;
506 m_sc.block->AppendVariables(
507 can_create, get_parent_variables, stop_if_block_is_inlined_function,
508 [this, must_have_valid_location](Variable *v) {
509 return v->IsInScope(this) && (!must_have_valid_location ||
510 v->LocationIsValidForFrame(this));
511 },
512 var_list_sp.get());
513 }
514
515 if (m_sc.comp_unit && get_file_globals) {
516 VariableListSP global_variable_list_sp(
517 m_sc.comp_unit->GetVariableList(true));
518 if (global_variable_list_sp)
519 var_list_sp->AddVariables(global_variable_list_sp.get());
520 }
521
522 return var_list_sp;
523}
524
526 llvm::StringRef var_expr, DynamicValueType use_dynamic, uint32_t options,
527 VariableSP &var_sp, Status &error, lldb::DILMode mode) {
528 ExecutionContext exe_ctx;
530 bool use_DIL = exe_ctx.GetTargetRef().GetUseDIL(&exe_ctx);
531 if (use_DIL)
532 return DILGetValueForVariableExpressionPath(var_expr, use_dynamic, options,
533 var_sp, error, mode);
534
535 return LegacyGetValueForVariableExpressionPath(var_expr, use_dynamic, options,
536 var_sp, error);
537}
538
540 llvm::StringRef var_expr, lldb::DynamicValueType use_dynamic,
541 uint32_t options, lldb::VariableSP &var_sp, Status &error,
542 lldb::DILMode mode) {
543
544 const bool check_ptr_vs_member =
546 const bool no_fragile_ivar =
548 const bool no_synth_child =
550
551 // Lex the expression.
552 auto lex_or_err = dil::DILLexer::Create(var_expr, mode);
553 if (!lex_or_err) {
554 error = Status::FromError(lex_or_err.takeError());
555 return ValueObjectConstResult::Create(nullptr, std::move(error));
556 }
557
558 // Parse the expression.
559 auto tree_or_error = dil::DILParser::Parse(
560 var_expr, std::move(*lex_or_err), shared_from_this(), use_dynamic,
561 !no_synth_child, !no_fragile_ivar, check_ptr_vs_member);
562 if (!tree_or_error) {
563 error = Status::FromError(tree_or_error.takeError());
564 return ValueObjectConstResult::Create(nullptr, std::move(error));
565 }
566
567 // Evaluate the parsed expression.
568 lldb::TargetSP target = this->CalculateTarget();
569 dil::Interpreter interpreter(target, var_expr, shared_from_this(),
570 use_dynamic, !no_synth_child, !no_fragile_ivar,
571 check_ptr_vs_member);
572
573 auto valobj_or_error = interpreter.Evaluate(**tree_or_error);
574 if (!valobj_or_error) {
575 error = Status::FromError(valobj_or_error.takeError());
576 return ValueObjectConstResult::Create(nullptr, std::move(error));
577 }
578
579 var_sp = (*valobj_or_error)->GetVariable();
580 return *valobj_or_error;
581}
582
584 llvm::StringRef var_expr, DynamicValueType use_dynamic, uint32_t options,
585 VariableSP &var_sp, Status &error) {
586 llvm::StringRef original_var_expr = var_expr;
587 // We can't fetch variable information for a history stack frame.
588 if (IsHistorical())
589 return ValueObjectSP();
590
591 if (var_expr.empty()) {
592 error = Status::FromErrorStringWithFormatv("invalid variable path '{0}'",
593 var_expr);
594 return ValueObjectSP();
595 }
596
597 const bool check_ptr_vs_member =
599 const bool no_fragile_ivar =
601 const bool no_synth_child =
603 // const bool no_synth_array = (options &
604 // eExpressionPathOptionsNoSyntheticArrayRange) != 0;
605 error.Clear();
606 bool deref = false;
607 bool address_of = false;
608 ValueObjectSP valobj_sp;
609 const bool get_file_globals = true;
610 // When looking up a variable for an expression, we need only consider the
611 // variables that are in scope.
612 VariableListSP var_list_sp(GetInScopeVariableList(get_file_globals));
613 VariableList *variable_list = var_list_sp.get();
614
615 if (!variable_list)
616 return ValueObjectSP();
617
618 // If first character is a '*', then show pointer contents
619 std::string var_expr_storage;
620 if (var_expr[0] == '*') {
621 deref = true;
622 var_expr = var_expr.drop_front(); // Skip the '*'
623 } else if (var_expr[0] == '&') {
624 address_of = true;
625 var_expr = var_expr.drop_front(); // Skip the '&'
626 }
627
628 size_t separator_idx = var_expr.find_first_of(".-[=+~|&^%#@!/?,<>{}");
629 StreamString var_expr_path_strm;
630
631 ConstString name_const_string(var_expr.substr(0, separator_idx));
632
633 var_sp = variable_list->FindVariable(name_const_string, false);
634
635 bool synthetically_added_instance_object = false;
636
637 if (var_sp) {
638 var_expr = var_expr.drop_front(name_const_string.GetLength());
639 }
640
641 if (!var_sp && (options & eExpressionPathOptionsAllowDirectIVarAccess)) {
642 // Check for direct ivars access which helps us with implicit access to
643 // ivars using "this" or "self".
644 GetSymbolContext(eSymbolContextFunction | eSymbolContextBlock);
645 llvm::StringRef instance_var_name = m_sc.GetInstanceVariableName();
646 if (!instance_var_name.empty()) {
647 var_sp = variable_list->FindVariable(ConstString(instance_var_name));
648 if (var_sp) {
649 separator_idx = 0;
650 if (Type *var_type = var_sp->GetType())
651 if (auto compiler_type = var_type->GetForwardCompilerType())
652 if (!compiler_type.IsPointerType())
653 var_expr_storage = ".";
654
655 if (var_expr_storage.empty())
656 var_expr_storage = "->";
657 var_expr_storage += var_expr;
658 var_expr = var_expr_storage;
659 synthetically_added_instance_object = true;
660 }
661 }
662 }
663
664 if (!var_sp && (options & eExpressionPathOptionsInspectAnonymousUnions)) {
665 // Check if any anonymous unions are there which contain a variable with
666 // the name we need
667 for (const VariableSP &variable_sp : *variable_list) {
668 if (!variable_sp)
669 continue;
670 if (!variable_sp->GetName().IsEmpty())
671 continue;
672
673 Type *var_type = variable_sp->GetType();
674 if (!var_type)
675 continue;
676
677 if (!var_type->GetForwardCompilerType().IsAnonymousType())
678 continue;
679 valobj_sp = GetValueObjectForFrameVariable(variable_sp, use_dynamic);
680 if (!valobj_sp)
681 return valobj_sp;
682 valobj_sp = valobj_sp->GetChildMemberWithName(name_const_string);
683 if (valobj_sp)
684 break;
685 }
686 }
687
688 if (var_sp && !valobj_sp) {
689 valobj_sp = GetValueObjectForFrameVariable(var_sp, use_dynamic);
690 if (!valobj_sp)
691 return valobj_sp;
692 }
693 if (!valobj_sp) {
695 "no variable named '{0}' found in this frame", name_const_string);
696 return ValueObjectSP();
697 }
698
699 // We are dumping at least one child
700 while (!var_expr.empty()) {
701 // Calculate the next separator index ahead of time
702 ValueObjectSP child_valobj_sp;
703 const char separator_type = var_expr[0];
704 bool expr_is_ptr = false;
705 switch (separator_type) {
706 case '-':
707 expr_is_ptr = true;
708 if (var_expr.size() >= 2 && var_expr[1] != '>')
709 return ValueObjectSP();
710
711 if (no_fragile_ivar) {
712 // Make sure we aren't trying to deref an objective
713 // C ivar if this is not allowed
714 const uint32_t pointer_type_flags =
715 valobj_sp->GetCompilerType().GetTypeInfo(nullptr);
716 if ((pointer_type_flags & eTypeIsObjC) &&
717 (pointer_type_flags & eTypeIsPointer)) {
718 // This was an objective C object pointer and it was requested we
719 // skip any fragile ivars so return nothing here
720 return ValueObjectSP();
721 }
722 }
723
724 // If we have a non-pointer type with a synthetic value then lets check if
725 // we have a synthetic dereference specified.
726 if (!valobj_sp->IsPointerType() && valobj_sp->HasSyntheticValue()) {
727 Status deref_error;
728 if (ValueObjectSP synth_deref_sp =
729 valobj_sp->GetSyntheticValue()->Dereference(deref_error);
730 synth_deref_sp && deref_error.Success()) {
731 valobj_sp = std::move(synth_deref_sp);
732 }
733 if (!valobj_sp || deref_error.Fail()) {
735 "Failed to dereference synthetic value: {0}", deref_error);
736 return ValueObjectSP();
737 }
738
739 // Some synthetic plug-ins fail to set the error in Dereference
740 if (!valobj_sp) {
741 error =
742 Status::FromErrorString("Failed to dereference synthetic value");
743 return ValueObjectSP();
744 }
745 expr_is_ptr = false;
746 }
747
748 var_expr = var_expr.drop_front(); // Remove the '-'
749 [[fallthrough]];
750 case '.': {
751 var_expr = var_expr.drop_front(); // Remove the '.' or '>'
752 separator_idx = var_expr.find_first_of(".-[");
753 ConstString child_name(var_expr.substr(0, var_expr.find_first_of(".-[")));
754
755 if (check_ptr_vs_member) {
756 // We either have a pointer type and need to verify valobj_sp is a
757 // pointer, or we have a member of a class/union/struct being accessed
758 // with the . syntax and need to verify we don't have a pointer.
759 const bool actual_is_ptr = valobj_sp->IsPointerType();
760
761 if (actual_is_ptr != expr_is_ptr) {
762 // Incorrect use of "." with a pointer, or "->" with a
763 // class/union/struct instance or reference.
764 valobj_sp->GetExpressionPath(var_expr_path_strm);
765 if (actual_is_ptr)
767 "\"%s\" is a pointer and . was used to attempt to access "
768 "\"%s\". Did you mean \"%s->%s\"?",
769 var_expr_path_strm.GetData(), child_name.GetCString(),
770 var_expr_path_strm.GetData(), var_expr.str().c_str());
771 else
773 "\"%s\" is not a pointer and -> was used to attempt to "
774 "access \"%s\". Did you mean \"%s.%s\"?",
775 var_expr_path_strm.GetData(), child_name.GetCString(),
776 var_expr_path_strm.GetData(), var_expr.str().c_str());
777 return ValueObjectSP();
778 }
779 }
780 child_valobj_sp = valobj_sp->GetChildMemberWithName(child_name);
781 if (!child_valobj_sp) {
782 if (!no_synth_child) {
783 child_valobj_sp = valobj_sp->GetSyntheticValue();
784 if (child_valobj_sp)
785 child_valobj_sp =
786 child_valobj_sp->GetChildMemberWithName(child_name);
787 }
788
789 if (no_synth_child || !child_valobj_sp) {
790 // No child member with name "child_name"
791 if (synthetically_added_instance_object) {
792 // We added a "this->" or "self->" to the beginning of the
793 // expression and this is the first pointer ivar access, so just
794 // return the normal error
796 "no variable or instance variable named '%s' found in "
797 "this frame",
798 name_const_string.GetCString());
799 } else {
800 valobj_sp->GetExpressionPath(var_expr_path_strm);
801 if (child_name) {
803 "\"%s\" is not a member of \"(%s) %s\"",
804 child_name.GetCString(),
805 valobj_sp->GetTypeName().AsCString("<invalid type>"),
806 var_expr_path_strm.GetData());
807 } else {
809 "incomplete expression path after \"%s\" in \"%s\"",
810 var_expr_path_strm.GetData(),
811 original_var_expr.str().c_str());
812 }
813 }
814 return ValueObjectSP();
815 }
816 }
817 synthetically_added_instance_object = false;
818 // Remove the child name from the path
819 var_expr = var_expr.drop_front(child_name.GetLength());
820 if (use_dynamic != eNoDynamicValues) {
821 ValueObjectSP dynamic_value_sp(
822 child_valobj_sp->GetDynamicValue(use_dynamic));
823 if (dynamic_value_sp)
824 child_valobj_sp = dynamic_value_sp;
825 }
826 } break;
827
828 case '[': {
829 // Array member access, or treating pointer as an array Need at least two
830 // brackets and a number
831 if (var_expr.size() <= 2) {
833 "invalid square bracket encountered after \"%s\" in \"%s\"",
834 var_expr_path_strm.GetData(), var_expr.str().c_str());
835 return ValueObjectSP();
836 }
837
838 // Drop the open brace.
839 var_expr = var_expr.drop_front();
840 long child_index = 0;
841
842 // If there's no closing brace, this is an invalid expression.
843 size_t end_pos = var_expr.find_first_of(']');
844 if (end_pos == llvm::StringRef::npos) {
846 "missing closing square bracket in expression \"%s\"",
847 var_expr_path_strm.GetData());
848 return ValueObjectSP();
849 }
850 llvm::StringRef index_expr = var_expr.take_front(end_pos);
851 llvm::StringRef original_index_expr = index_expr;
852 // Drop all of "[index_expr]"
853 var_expr = var_expr.drop_front(end_pos + 1);
854
855 if (index_expr.consumeInteger(0, child_index)) {
856 // If there was no integer anywhere in the index expression, this is
857 // erroneous expression.
859 "invalid index expression \"%s\"", index_expr.str().c_str());
860 return ValueObjectSP();
861 }
862
863 if (index_expr.empty()) {
864 // The entire index expression was a single integer.
865
866 if (valobj_sp->GetCompilerType().IsPointerToScalarType() && deref) {
867 // what we have is *ptr[low]. the most similar C++ syntax is to deref
868 // ptr and extract bit low out of it. reading array item low would be
869 // done by saying ptr[low], without a deref * sign
870 Status deref_error;
871 ValueObjectSP temp(valobj_sp->Dereference(deref_error));
872 if (!temp || deref_error.Fail()) {
873 valobj_sp->GetExpressionPath(var_expr_path_strm);
875 "could not dereference \"(%s) %s\"",
876 valobj_sp->GetTypeName().AsCString("<invalid type>"),
877 var_expr_path_strm.GetData());
878 return ValueObjectSP();
879 }
880 valobj_sp = temp;
881 deref = false;
882 } else if (valobj_sp->GetCompilerType().IsArrayOfScalarType() &&
883 deref) {
884 // what we have is *arr[low]. the most similar C++ syntax is to get
885 // arr[0] (an operation that is equivalent to deref-ing arr) and
886 // extract bit low out of it. reading array item low would be done by
887 // saying arr[low], without a deref * sign
888 ValueObjectSP temp(valobj_sp->GetChildAtIndex(0));
889 if (!temp) {
890 valobj_sp->GetExpressionPath(var_expr_path_strm);
892 "could not get item 0 for \"(%s) %s\"",
893 valobj_sp->GetTypeName().AsCString("<invalid type>"),
894 var_expr_path_strm.GetData());
895 return ValueObjectSP();
896 }
897 valobj_sp = temp;
898 deref = false;
899 }
900
901 bool is_incomplete_array = false;
902 if (valobj_sp->IsPointerType()) {
903 bool is_objc_pointer = true;
904
905 if (valobj_sp->GetCompilerType().GetMinimumLanguage() !=
907 is_objc_pointer = false;
908 else if (!valobj_sp->GetCompilerType().IsPointerType())
909 is_objc_pointer = false;
910
911 if (no_synth_child && is_objc_pointer) {
913 "\"(%s) %s\" is an Objective-C pointer, and cannot be "
914 "subscripted",
915 valobj_sp->GetTypeName().AsCString("<invalid type>"),
916 var_expr_path_strm.GetData());
917
918 return ValueObjectSP();
919 } else if (is_objc_pointer) {
920 // dereferencing ObjC variables is not valid.. so let's try and
921 // recur to synthetic children
922 ValueObjectSP synthetic = valobj_sp->GetSyntheticValue();
923 if (!synthetic /* no synthetic */
924 || synthetic == valobj_sp) /* synthetic is the same as
925 the original object */
926 {
927 valobj_sp->GetExpressionPath(var_expr_path_strm);
929 "\"(%s) %s\" is not an array type",
930 valobj_sp->GetTypeName().AsCString("<invalid type>"),
931 var_expr_path_strm.GetData());
932 } else if (static_cast<uint32_t>(child_index) >=
933 synthetic
934 ->GetNumChildrenIgnoringErrors() /* synthetic does
935 not have that
936 many values */) {
937 valobj_sp->GetExpressionPath(var_expr_path_strm);
939 "array index %ld is not valid for \"(%s) %s\"", child_index,
940 valobj_sp->GetTypeName().AsCString("<invalid type>"),
941 var_expr_path_strm.GetData());
942 } else {
943 child_valobj_sp = synthetic->GetChildAtIndex(child_index);
944 if (!child_valobj_sp) {
945 valobj_sp->GetExpressionPath(var_expr_path_strm);
947 "array index %ld is not valid for \"(%s) %s\"", child_index,
948 valobj_sp->GetTypeName().AsCString("<invalid type>"),
949 var_expr_path_strm.GetData());
950 }
951 }
952 } else {
953 child_valobj_sp =
954 valobj_sp->GetSyntheticArrayMember(child_index, true);
955 if (!child_valobj_sp) {
956 valobj_sp->GetExpressionPath(var_expr_path_strm);
958 "failed to use pointer as array for index %ld for "
959 "\"(%s) %s\"",
960 child_index,
961 valobj_sp->GetTypeName().AsCString("<invalid type>"),
962 var_expr_path_strm.GetData());
963 }
964 }
965 } else if (valobj_sp->GetCompilerType().IsArrayType(
966 nullptr, nullptr, &is_incomplete_array)) {
967 // Pass false to dynamic_value here so we can tell the difference
968 // between no dynamic value and no member of this type...
969 child_valobj_sp = valobj_sp->GetChildAtIndex(child_index);
970 if (!child_valobj_sp && (is_incomplete_array || !no_synth_child))
971 child_valobj_sp =
972 valobj_sp->GetSyntheticArrayMember(child_index, true);
973
974 if (!child_valobj_sp) {
975 valobj_sp->GetExpressionPath(var_expr_path_strm);
977 "array index %ld is not valid for \"(%s) %s\"", child_index,
978 valobj_sp->GetTypeName().AsCString("<invalid type>"),
979 var_expr_path_strm.GetData());
980 }
981 } else if (valobj_sp->GetCompilerType().IsScalarType()) {
982 // this is a bitfield asking to display just one bit
983 child_valobj_sp = valobj_sp->GetSyntheticBitFieldChild(
984 child_index, child_index, true);
985 if (!child_valobj_sp) {
986 valobj_sp->GetExpressionPath(var_expr_path_strm);
988 "bitfield range %ld-%ld is not valid for \"(%s) %s\"",
989 child_index, child_index,
990 valobj_sp->GetTypeName().AsCString("<invalid type>"),
991 var_expr_path_strm.GetData());
992 }
993 } else {
994 ValueObjectSP synthetic = valobj_sp->GetSyntheticValue();
995 if (no_synth_child /* synthetic is forbidden */ ||
996 !synthetic /* no synthetic */
997 || synthetic == valobj_sp) /* synthetic is the same as the
998 original object */
999 {
1000 valobj_sp->GetExpressionPath(var_expr_path_strm);
1002 "\"(%s) %s\" is not an array type",
1003 valobj_sp->GetTypeName().AsCString("<invalid type>"),
1004 var_expr_path_strm.GetData());
1005 } else if (static_cast<uint32_t>(child_index) >=
1006 synthetic->GetNumChildrenIgnoringErrors() /* synthetic
1007 does not have that many values */) {
1008 valobj_sp->GetExpressionPath(var_expr_path_strm);
1010 "array index %ld is not valid for \"(%s) %s\"", child_index,
1011 valobj_sp->GetTypeName().AsCString("<invalid type>"),
1012 var_expr_path_strm.GetData());
1013 } else {
1014 child_valobj_sp = synthetic->GetChildAtIndex(child_index);
1015 if (!child_valobj_sp) {
1016 valobj_sp->GetExpressionPath(var_expr_path_strm);
1018 "array index %ld is not valid for \"(%s) %s\"", child_index,
1019 valobj_sp->GetTypeName().AsCString("<invalid type>"),
1020 var_expr_path_strm.GetData());
1021 }
1022 }
1023 }
1024
1025 if (!child_valobj_sp) {
1026 // Invalid array index...
1027 return ValueObjectSP();
1028 }
1029
1030 if (use_dynamic != eNoDynamicValues) {
1031 ValueObjectSP dynamic_value_sp(
1032 child_valobj_sp->GetDynamicValue(use_dynamic));
1033 if (dynamic_value_sp)
1034 child_valobj_sp = dynamic_value_sp;
1035 }
1036 // Break out early from the switch since we were able to find the child
1037 // member
1038 break;
1039 }
1040
1041 // this is most probably a BitField, let's take a look
1042 if (index_expr.front() != '-') {
1044 "invalid range expression \"'%s'\"",
1045 original_index_expr.str().c_str());
1046 return ValueObjectSP();
1047 }
1048
1049 index_expr = index_expr.drop_front();
1050 long final_index = 0;
1051 if (index_expr.getAsInteger(0, final_index)) {
1053 "invalid range expression \"'%s'\"",
1054 original_index_expr.str().c_str());
1055 return ValueObjectSP();
1056 }
1057
1058 // if the format given is [high-low], swap range
1059 if (child_index > final_index) {
1060 long temp = child_index;
1061 child_index = final_index;
1062 final_index = temp;
1063 }
1064
1065 if (valobj_sp->GetCompilerType().IsPointerToScalarType() && deref) {
1066 // what we have is *ptr[low-high]. the most similar C++ syntax is to
1067 // deref ptr and extract bits low thru high out of it. reading array
1068 // items low thru high would be done by saying ptr[low-high], without a
1069 // deref * sign
1070 Status deref_error;
1071 ValueObjectSP temp(valobj_sp->Dereference(deref_error));
1072 if (!temp || deref_error.Fail()) {
1073 valobj_sp->GetExpressionPath(var_expr_path_strm);
1075 "could not dereference \"(%s) %s\"",
1076 valobj_sp->GetTypeName().AsCString("<invalid type>"),
1077 var_expr_path_strm.GetData());
1078 return ValueObjectSP();
1079 }
1080 valobj_sp = temp;
1081 deref = false;
1082 } else if (valobj_sp->GetCompilerType().IsArrayOfScalarType() && deref) {
1083 // what we have is *arr[low-high]. the most similar C++ syntax is to
1084 // get arr[0] (an operation that is equivalent to deref-ing arr) and
1085 // extract bits low thru high out of it. reading array items low thru
1086 // high would be done by saying arr[low-high], without a deref * sign
1087 ValueObjectSP temp(valobj_sp->GetChildAtIndex(0));
1088 if (!temp) {
1089 valobj_sp->GetExpressionPath(var_expr_path_strm);
1091 "could not get item 0 for \"(%s) %s\"",
1092 valobj_sp->GetTypeName().AsCString("<invalid type>"),
1093 var_expr_path_strm.GetData());
1094 return ValueObjectSP();
1095 }
1096 valobj_sp = temp;
1097 deref = false;
1098 }
1099
1100 child_valobj_sp =
1101 valobj_sp->GetSyntheticBitFieldChild(child_index, final_index, true);
1102 if (!child_valobj_sp) {
1103 valobj_sp->GetExpressionPath(var_expr_path_strm);
1105 "bitfield range %ld-%ld is not valid for \"(%s) %s\"", child_index,
1106 final_index, valobj_sp->GetTypeName().AsCString("<invalid type>"),
1107 var_expr_path_strm.GetData());
1108 }
1109
1110 if (!child_valobj_sp) {
1111 // Invalid bitfield range...
1112 return ValueObjectSP();
1113 }
1114
1115 if (use_dynamic != eNoDynamicValues) {
1116 ValueObjectSP dynamic_value_sp(
1117 child_valobj_sp->GetDynamicValue(use_dynamic));
1118 if (dynamic_value_sp)
1119 child_valobj_sp = dynamic_value_sp;
1120 }
1121 // Break out early from the switch since we were able to find the child
1122 // member
1123 break;
1124 }
1125 default:
1126 // Failure...
1127 {
1128 valobj_sp->GetExpressionPath(var_expr_path_strm);
1130 "unexpected char '%c' encountered after \"%s\" in \"%s\"",
1131 separator_type, var_expr_path_strm.GetData(),
1132 var_expr.str().c_str());
1133
1134 return ValueObjectSP();
1135 }
1136 }
1137
1138 if (child_valobj_sp)
1139 valobj_sp = child_valobj_sp;
1140 }
1141 if (valobj_sp) {
1142 if (deref) {
1143 ValueObjectSP deref_valobj_sp(valobj_sp->Dereference(error));
1144 if (!deref_valobj_sp && !no_synth_child) {
1145 if (ValueObjectSP synth_obj_sp = valobj_sp->GetSyntheticValue()) {
1146 error.Clear();
1147 deref_valobj_sp = synth_obj_sp->Dereference(error);
1148 }
1149 }
1150 valobj_sp = deref_valobj_sp;
1151 } else if (address_of) {
1152 ValueObjectSP address_of_valobj_sp(valobj_sp->AddressOf(error));
1153 valobj_sp = address_of_valobj_sp;
1154 }
1155 }
1156 return valobj_sp;
1157}
1158
1159llvm::Error StackFrame::GetFrameBaseValue(Scalar &frame_base) {
1160 std::lock_guard<std::recursive_mutex> guard(m_mutex);
1161 if (!m_cfa_is_valid) {
1163 "No frame base available for this historical stack frame.");
1164 return m_frame_base_error.ToError();
1165 }
1166
1167 if (m_flags.IsClear(GOT_FRAME_BASE)) {
1168 if (m_sc.function) {
1169 m_frame_base.Clear();
1170 m_frame_base_error.Clear();
1171
1173 ExecutionContext exe_ctx(shared_from_this());
1174 addr_t loclist_base_addr = LLDB_INVALID_ADDRESS;
1175 if (!m_sc.function->GetFrameBaseExpression().IsAlwaysValidSingleExpr())
1176 loclist_base_addr =
1177 m_sc.function->GetAddress().GetLoadAddress(exe_ctx.GetTargetPtr());
1178
1179 llvm::Expected<Value> expr_value =
1180 m_sc.function->GetFrameBaseExpression().Evaluate(
1181 &exe_ctx, nullptr, loclist_base_addr, nullptr, nullptr);
1182 if (!expr_value)
1183 m_frame_base_error = Status::FromError(expr_value.takeError());
1184 else
1185 m_frame_base = expr_value->ResolveValue(&exe_ctx);
1186 } else {
1188 Status::FromErrorString("No function in symbol context.");
1189 }
1190 }
1191
1192 if (m_frame_base_error.Fail())
1193 return m_frame_base_error.ToError();
1194
1195 frame_base = m_frame_base;
1196 return llvm::Error::success();
1197}
1198
1200 if (!m_sc.function) {
1201 if (error_ptr) {
1202 *error_ptr = Status::FromErrorString("No function in symbol context.");
1203 }
1204 return nullptr;
1205 }
1206
1207 return &m_sc.function->GetFrameBaseExpression();
1208}
1209
1211 std::lock_guard<std::recursive_mutex> guard(m_mutex);
1212 if (!m_reg_context_sp) {
1213 ThreadSP thread_sp(GetThread());
1214 if (thread_sp)
1215 m_reg_context_sp = thread_sp->CreateRegisterContextForFrame(this);
1216 }
1217 return m_reg_context_sp;
1218}
1219
1221 GetSymbolContext(eSymbolContextLineEntry);
1222 return m_sc.line_entry.IsValid();
1223}
1224
1227 DynamicValueType use_dynamic) {
1228 ValueObjectSP valobj_sp;
1229 { // Scope for stack frame mutex. We need to drop this mutex before we figure
1230 // out the dynamic value. That will require converting the StackID in the
1231 // VO back to a StackFrame, which will in turn require locking the
1232 // StackFrameList. If we still hold the StackFrame mutex, we could suffer
1233 // lock inversion against the pattern of getting the StackFrameList and
1234 // then the stack frame, which is fairly common.
1235 std::lock_guard<std::recursive_mutex> guard(m_mutex);
1236 if (IsHistorical()) {
1237 return valobj_sp;
1238 }
1239 VariableList *var_list = GetVariableList(true, nullptr);
1240 if (var_list) {
1241 // Make sure the variable is a frame variable
1242 const uint32_t var_idx =
1243 var_list->FindIndexForVariable(variable_sp.get());
1244 const uint32_t num_variables = var_list->GetSize();
1245 if (var_idx < num_variables) {
1246 valobj_sp =
1247 m_variable_list_value_objects.GetValueObjectAtIndex(var_idx);
1248 if (!valobj_sp) {
1249 if (m_variable_list_value_objects.GetSize() < num_variables)
1250 m_variable_list_value_objects.Resize(num_variables);
1251 valobj_sp = ValueObjectVariable::Create(this, variable_sp);
1252 m_variable_list_value_objects.SetValueObjectAtIndex(var_idx,
1253 valobj_sp);
1254 }
1255 }
1256 }
1257 } // End of StackFrame mutex scope.
1258 if (use_dynamic != eNoDynamicValues && valobj_sp) {
1259 ValueObjectSP dynamic_sp = valobj_sp->GetDynamicValue(use_dynamic);
1260 if (dynamic_sp)
1261 return dynamic_sp;
1262 }
1263 return valobj_sp;
1264}
1265
1267 if (m_sc.block == nullptr)
1268 GetSymbolContext(eSymbolContextBlock);
1269 if (m_sc.block)
1270 return m_sc.block->GetContainingInlinedBlock() != nullptr;
1271 return false;
1272}
1273
1277
1281
1283
1285 if (auto recognized_frame_sp = GetRecognizedFrame())
1286 return recognized_frame_sp->ShouldHide();
1287 return false;
1288}
1289
1291 auto process_sp = CalculateProcess();
1292 SourceLanguage language = GetLanguage();
1293 if (!language)
1294 return {};
1295 if (auto runtime_sp =
1296 process_sp->GetLanguageRuntime(language.AsLanguageType()))
1297 return runtime_sp->GetLanguageSpecificData(
1298 GetSymbolContext(eSymbolContextFunction));
1299 return {};
1300}
1301
1303 const char *name = nullptr;
1305 eSymbolContextFunction | eSymbolContextBlock | eSymbolContextSymbol);
1306 if (sc.block) {
1307 Block *inlined_block = sc.block->GetContainingInlinedBlock();
1308 if (inlined_block) {
1309 const InlineFunctionInfo *inlined_info =
1310 inlined_block->GetInlinedFunctionInfo();
1311 if (inlined_info)
1312 name = inlined_info->GetName().AsCString();
1313 }
1314 }
1315
1316 if (name == nullptr) {
1317 if (sc.function)
1318 name = sc.function->GetName().GetCString();
1319 }
1320
1321 if (name == nullptr) {
1322 if (sc.symbol)
1323 name = sc.symbol->GetName().GetCString();
1324 }
1325
1326 return name;
1327}
1328
1330 const char *name = nullptr;
1332 eSymbolContextFunction | eSymbolContextBlock | eSymbolContextSymbol);
1333 if (sc.block) {
1334 Block *inlined_block = sc.block->GetContainingInlinedBlock();
1335 if (inlined_block) {
1336 const InlineFunctionInfo *inlined_info =
1337 inlined_block->GetInlinedFunctionInfo();
1338 if (inlined_info)
1339 name = inlined_info->GetDisplayName().AsCString();
1340 }
1341 }
1342
1343 if (name == nullptr) {
1344 if (sc.function)
1345 name = sc.function->GetDisplayName().GetCString();
1346 }
1347
1348 if (name == nullptr) {
1349 if (sc.symbol)
1350 name = sc.symbol->GetDisplayName().GetCString();
1351 }
1352 return name;
1353}
1354
1356 CompileUnit *cu = GetSymbolContext(eSymbolContextCompUnit).comp_unit;
1357 if (cu)
1358 return SourceLanguage{cu->GetLanguage()};
1359 return {};
1360}
1361
1363 SourceLanguage lang_type = GetLanguage();
1364
1365 if (!lang_type) {
1366 SymbolContext sc =
1367 GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol);
1368 if (sc.function)
1369 lang_type = SourceLanguage(sc.function->GetMangled().GuessLanguage());
1370 else if (sc.symbol)
1371 lang_type = SourceLanguage(sc.symbol->GetMangled().GuessLanguage());
1372 }
1373
1374 return lang_type;
1375}
1376
1377namespace {
1378std::pair<const Instruction::Operand *, int64_t>
1379GetBaseExplainingValue(const Instruction::Operand &operand,
1380 RegisterContext &register_context, lldb::addr_t value) {
1381 switch (operand.m_type) {
1386 // These are not currently interesting
1387 return std::make_pair(nullptr, 0);
1389 const Instruction::Operand *immediate_child = nullptr;
1390 const Instruction::Operand *variable_child = nullptr;
1391 if (operand.m_children[0].m_type == Instruction::Operand::Type::Immediate) {
1392 immediate_child = &operand.m_children[0];
1393 variable_child = &operand.m_children[1];
1394 } else if (operand.m_children[1].m_type ==
1396 immediate_child = &operand.m_children[1];
1397 variable_child = &operand.m_children[0];
1398 }
1399 if (!immediate_child) {
1400 return std::make_pair(nullptr, 0);
1401 }
1402 lldb::addr_t adjusted_value = value;
1403 if (immediate_child->m_negative) {
1404 adjusted_value += immediate_child->m_immediate;
1405 } else {
1406 adjusted_value -= immediate_child->m_immediate;
1407 }
1408 std::pair<const Instruction::Operand *, int64_t> base_and_offset =
1409 GetBaseExplainingValue(*variable_child, register_context,
1410 adjusted_value);
1411 if (!base_and_offset.first) {
1412 return std::make_pair(nullptr, 0);
1413 }
1414 if (immediate_child->m_negative) {
1415 base_and_offset.second -= immediate_child->m_immediate;
1416 } else {
1417 base_and_offset.second += immediate_child->m_immediate;
1418 }
1419 return base_and_offset;
1420 }
1422 const RegisterInfo *info =
1423 register_context.GetRegisterInfoByName(operand.m_register.AsCString());
1424 if (!info) {
1425 return std::make_pair(nullptr, 0);
1426 }
1427 RegisterValue reg_value;
1428 if (!register_context.ReadRegister(info, reg_value)) {
1429 return std::make_pair(nullptr, 0);
1430 }
1431 if (reg_value.GetAsUInt64() == value) {
1432 return std::make_pair(&operand, 0);
1433 } else {
1434 return std::make_pair(nullptr, 0);
1435 }
1436 }
1437 }
1438 return std::make_pair(nullptr, 0);
1439}
1440
1441std::pair<const Instruction::Operand *, int64_t>
1442GetBaseExplainingDereference(const Instruction::Operand &operand,
1443 RegisterContext &register_context,
1444 lldb::addr_t addr) {
1446 return GetBaseExplainingValue(operand.m_children[0], register_context,
1447 addr);
1448 }
1449 return std::make_pair(nullptr, 0);
1450}
1451} // namespace
1452
1454 TargetSP target_sp = CalculateTarget();
1455
1456 const ArchSpec &target_arch = target_sp->GetArchitecture();
1457
1458 AddressRange pc_range;
1459 pc_range.GetBaseAddress() = GetFrameCodeAddress();
1460 pc_range.SetByteSize(target_arch.GetMaximumOpcodeByteSize());
1461
1462 const char *plugin_name = nullptr;
1463 const char *flavor = nullptr;
1464 const char *cpu = nullptr;
1465 const char *features = nullptr;
1466 const bool force_live_memory = true;
1467
1469 target_arch, plugin_name, flavor, cpu, features, *target_sp, pc_range,
1470 force_live_memory);
1471
1472 if (!disassembler_sp || !disassembler_sp->GetInstructionList().GetSize()) {
1473 return ValueObjectSP();
1474 }
1475
1476 InstructionSP instruction_sp =
1477 disassembler_sp->GetInstructionList().GetInstructionAtIndex(0);
1478
1479 llvm::SmallVector<Instruction::Operand, 3> operands;
1480
1481 if (!instruction_sp->ParseOperands(operands)) {
1482 return ValueObjectSP();
1483 }
1484
1485 RegisterContextSP register_context_sp = GetRegisterContext();
1486
1487 if (!register_context_sp) {
1488 return ValueObjectSP();
1489 }
1490
1491 for (const Instruction::Operand &operand : operands) {
1492 std::pair<const Instruction::Operand *, int64_t> base_and_offset =
1493 GetBaseExplainingDereference(operand, *register_context_sp, addr);
1494
1495 if (!base_and_offset.first) {
1496 continue;
1497 }
1498
1499 switch (base_and_offset.first->m_type) {
1502 if (target_sp->ResolveLoadAddress(base_and_offset.first->m_immediate +
1503 base_and_offset.second,
1504 addr)) {
1505 auto c_type_system_or_err =
1506 target_sp->GetScratchTypeSystemForLanguage(eLanguageTypeC);
1507 if (auto err = c_type_system_or_err.takeError()) {
1508 LLDB_LOG_ERROR(GetLog(LLDBLog::Thread), std::move(err),
1509 "Unable to guess value for given address: {0}");
1510 return ValueObjectSP();
1511 } else {
1512 auto ts = *c_type_system_or_err;
1513 if (!ts)
1514 return {};
1515 CompilerType void_ptr_type =
1517 .GetPointerType();
1518 return ValueObjectMemory::Create(this, "", addr, void_ptr_type);
1519 }
1520 } else {
1521 return ValueObjectSP();
1522 }
1523 break;
1524 }
1526 return GuessValueForRegisterAndOffset(base_and_offset.first->m_register,
1527 base_and_offset.second);
1528 }
1529 default:
1530 return ValueObjectSP();
1531 }
1532 }
1533
1534 return ValueObjectSP();
1535}
1536
1537namespace {
1538ValueObjectSP GetValueForOffset(StackFrame &frame, ValueObjectSP &parent,
1539 int64_t offset) {
1540 if (offset < 0 ||
1541 uint64_t(offset) >=
1542 llvm::expectedToOptional(parent->GetByteSize()).value_or(0)) {
1543 return ValueObjectSP();
1544 }
1545
1546 if (parent->IsPointerOrReferenceType()) {
1547 return parent;
1548 }
1549
1550 for (int ci = 0, ce = parent->GetNumChildrenIgnoringErrors(); ci != ce;
1551 ++ci) {
1552 ValueObjectSP child_sp = parent->GetChildAtIndex(ci);
1553
1554 if (!child_sp) {
1555 return ValueObjectSP();
1556 }
1557
1558 int64_t child_offset = child_sp->GetByteOffset();
1559 int64_t child_size =
1560 llvm::expectedToOptional(child_sp->GetByteSize()).value_or(0);
1561
1562 if (offset >= child_offset && offset < (child_offset + child_size)) {
1563 return GetValueForOffset(frame, child_sp, offset - child_offset);
1564 }
1565 }
1566
1567 if (offset == 0) {
1568 return parent;
1569 } else {
1570 return ValueObjectSP();
1571 }
1572}
1573
1574ValueObjectSP GetValueForDereferincingOffset(StackFrame &frame,
1575 ValueObjectSP &base,
1576 int64_t offset) {
1577 // base is a pointer to something
1578 // offset is the thing to add to the pointer We return the most sensible
1579 // ValueObject for the result of *(base+offset)
1580
1581 if (!base->IsPointerOrReferenceType()) {
1582 return ValueObjectSP();
1583 }
1584
1585 Status error;
1586 ValueObjectSP pointee = base->Dereference(error);
1587
1588 if (!pointee) {
1589 return ValueObjectSP();
1590 }
1591
1592 if (offset >= 0 &&
1593 uint64_t(offset) >=
1594 llvm::expectedToOptional(pointee->GetByteSize()).value_or(0)) {
1595 uint64_t size =
1596 llvm::expectedToOptional(pointee->GetByteSize()).value_or(1);
1597 int64_t index = offset / size;
1598 offset = offset % size;
1599 const bool can_create = true;
1600 pointee = base->GetSyntheticArrayMember(index, can_create);
1601 }
1602
1603 if (!pointee || error.Fail()) {
1604 return ValueObjectSP();
1605 }
1606
1607 return GetValueForOffset(frame, pointee, offset);
1608}
1609
1610/// Attempt to reconstruct the ValueObject for the address contained in a
1611/// given register plus an offset.
1612///
1613/// \param [in] frame
1614/// The current stack frame.
1615///
1616/// \param [in] reg
1617/// The register.
1618///
1619/// \param [in] offset
1620/// The offset from the register.
1621///
1622/// \param [in] disassembler
1623/// A disassembler containing instructions valid up to the current PC.
1624///
1625/// \param [in] variables
1626/// The variable list from the current frame,
1627///
1628/// \param [in] pc
1629/// The program counter for the instruction considered the 'user'.
1630///
1631/// \return
1632/// A string describing the base for the ExpressionPath. This could be a
1633/// variable, a register value, an argument, or a function return value.
1634/// The ValueObject if found. If valid, it has a valid ExpressionPath.
1635lldb::ValueObjectSP DoGuessValueAt(StackFrame &frame, ConstString reg,
1636 int64_t offset, Disassembler &disassembler,
1637 VariableList &variables, const Address &pc) {
1638 // Example of operation for Intel:
1639 //
1640 // +14: movq -0x8(%rbp), %rdi
1641 // +18: movq 0x8(%rdi), %rdi
1642 // +22: addl 0x4(%rdi), %eax
1643 //
1644 // f, a pointer to a struct, is known to be at -0x8(%rbp).
1645 //
1646 // DoGuessValueAt(frame, rdi, 4, dis, vars, 0x22) finds the instruction at
1647 // +18 that assigns to rdi, and calls itself recursively for that dereference
1648 // DoGuessValueAt(frame, rdi, 8, dis, vars, 0x18) finds the instruction at
1649 // +14 that assigns to rdi, and calls itself recursively for that
1650 // dereference
1651 // DoGuessValueAt(frame, rbp, -8, dis, vars, 0x14) finds "f" in the
1652 // variable list.
1653 // Returns a ValueObject for f. (That's what was stored at rbp-8 at +14)
1654 // Returns a ValueObject for *(f+8) or f->b (That's what was stored at rdi+8
1655 // at +18)
1656 // Returns a ValueObject for *(f->b+4) or f->b->a (That's what was stored at
1657 // rdi+4 at +22)
1658
1659 // First, check the variable list to see if anything is at the specified
1660 // location.
1661
1662 using namespace OperandMatchers;
1663
1664 const RegisterInfo *reg_info =
1665 frame.GetRegisterContext()->GetRegisterInfoByName(reg.AsCString());
1666 if (!reg_info) {
1667 return ValueObjectSP();
1668 }
1669
1675 : Instruction::Operand::BuildDereference(
1676 Instruction::Operand::BuildRegister(reg));
1677
1678 for (VariableSP var_sp : variables) {
1679 if (var_sp->LocationExpressionList().MatchesOperand(frame, op))
1681 }
1682
1683 const uint32_t current_inst =
1684 disassembler.GetInstructionList().GetIndexOfInstructionAtAddress(pc);
1685 if (current_inst == UINT32_MAX) {
1686 return ValueObjectSP();
1687 }
1688
1689 for (uint32_t ii = current_inst - 1; ii != (uint32_t)-1; --ii) {
1690 // This is not an exact algorithm, and it sacrifices accuracy for
1691 // generality. Recognizing "mov" and "ld" instructions –– and which
1692 // are their source and destination operands -- is something the
1693 // disassembler should do for us.
1694 InstructionSP instruction_sp =
1695 disassembler.GetInstructionList().GetInstructionAtIndex(ii);
1696
1697 if (instruction_sp->IsCall()) {
1698 ABISP abi_sp = frame.CalculateProcess()->GetABI();
1699 if (!abi_sp) {
1700 continue;
1701 }
1702
1703 const char *return_register_name;
1704 if (!abi_sp->GetPointerReturnRegister(return_register_name)) {
1705 continue;
1706 }
1707
1708 const RegisterInfo *return_register_info =
1709 frame.GetRegisterContext()->GetRegisterInfoByName(
1710 return_register_name);
1711 if (!return_register_info) {
1712 continue;
1713 }
1714
1715 int64_t offset = 0;
1716
1718 MatchRegOp(*return_register_info))(op) &&
1719 !MatchUnaryOp(
1722 MatchRegOp(*return_register_info),
1723 FetchImmOp(offset)))(op)) {
1724 continue;
1725 }
1726
1727 llvm::SmallVector<Instruction::Operand, 1> operands;
1728 if (!instruction_sp->ParseOperands(operands) || operands.size() != 1) {
1729 continue;
1730 }
1731
1732 switch (operands[0].m_type) {
1733 default:
1734 break;
1736 SymbolContext sc;
1737 if (!pc.GetModule())
1738 break;
1739 Address address(operands[0].m_immediate,
1740 pc.GetModule()->GetSectionList());
1741 if (!address.IsValid())
1742 break;
1743 frame.CalculateTarget()->GetImages().ResolveSymbolContextForAddress(
1744 address, eSymbolContextFunction, sc);
1745 if (!sc.function) {
1746 break;
1747 }
1748 CompilerType function_type = sc.function->GetCompilerType();
1749 if (!function_type.IsFunctionType()) {
1750 break;
1751 }
1752 CompilerType return_type = function_type.GetFunctionReturnType();
1753 RegisterValue return_value;
1754 if (!frame.GetRegisterContext()->ReadRegister(return_register_info,
1755 return_value)) {
1756 break;
1757 }
1758 std::string name_str(
1759 sc.function->GetName().AsCString("<unknown function>"));
1760 name_str.append("()");
1761 Address return_value_address(return_value.GetAsUInt64());
1762 ValueObjectSP return_value_sp = ValueObjectMemory::Create(
1763 &frame, name_str, return_value_address, return_type);
1764 return GetValueForDereferincingOffset(frame, return_value_sp, offset);
1765 }
1766 }
1767
1768 continue;
1769 }
1770
1771 llvm::SmallVector<Instruction::Operand, 2> operands;
1772 if (!instruction_sp->ParseOperands(operands) || operands.size() != 2) {
1773 continue;
1774 }
1775
1776 Instruction::Operand *origin_operand = nullptr;
1777 auto clobbered_reg_matcher = [reg_info](const Instruction::Operand &op) {
1778 return MatchRegOp(*reg_info)(op) && op.m_clobbered;
1779 };
1780
1781 if (clobbered_reg_matcher(operands[0])) {
1782 origin_operand = &operands[1];
1783 } else if (clobbered_reg_matcher(operands[1])) {
1784 origin_operand = &operands[0];
1785 } else {
1786 continue;
1787 }
1788
1789 // We have an origin operand. Can we track its value down?
1790 ValueObjectSP source_path;
1791 ConstString origin_register;
1792 int64_t origin_offset = 0;
1793
1794 if (FetchRegOp(origin_register)(*origin_operand)) {
1795 source_path = DoGuessValueAt(frame, origin_register, 0, disassembler,
1796 variables, instruction_sp->GetAddress());
1797 } else if (MatchUnaryOp(
1799 FetchRegOp(origin_register))(*origin_operand) ||
1803 FetchRegOp(origin_register),
1804 FetchImmOp(origin_offset)))(*origin_operand)) {
1805 source_path =
1806 DoGuessValueAt(frame, origin_register, origin_offset, disassembler,
1807 variables, instruction_sp->GetAddress());
1808 if (!source_path) {
1809 continue;
1810 }
1811 source_path = GetValueForDereferincingOffset(frame, source_path, offset);
1812 }
1813
1814 if (source_path) {
1815 return source_path;
1816 }
1817 }
1818
1819 return ValueObjectSP();
1820}
1821} // namespace
1822
1824 int64_t offset) {
1825 TargetSP target_sp = CalculateTarget();
1826
1827 const ArchSpec &target_arch = target_sp->GetArchitecture();
1828
1829 Block *frame_block = GetFrameBlock();
1830
1831 if (!frame_block) {
1832 return ValueObjectSP();
1833 }
1834
1835 Function *function = frame_block->CalculateSymbolContextFunction();
1836 if (!function) {
1837 return ValueObjectSP();
1838 }
1839
1840 AddressRange unused_range;
1841 if (!function->GetRangeContainingLoadAddress(
1842 GetFrameCodeAddress().GetLoadAddress(target_sp.get()), *target_sp,
1843 unused_range))
1844 return ValueObjectSP();
1845
1846 const char *plugin_name = nullptr;
1847 const char *flavor = nullptr;
1848 const char *cpu = nullptr;
1849 const char *features = nullptr;
1850 const bool force_live_memory = true;
1852 target_arch, plugin_name, flavor, cpu, features, *target_sp,
1853 function->GetAddressRanges(), force_live_memory);
1854
1855 if (!disassembler_sp || !disassembler_sp->GetInstructionList().GetSize()) {
1856 return ValueObjectSP();
1857 }
1858
1859 const bool get_file_globals = false;
1860 VariableList *variables = GetVariableList(get_file_globals, nullptr);
1861
1862 if (!variables) {
1863 return ValueObjectSP();
1864 }
1865
1866 return DoGuessValueAt(*this, reg, offset, *disassembler_sp, *variables,
1868}
1869
1871 ValueObjectSP value_sp;
1872
1873 if (!name)
1874 return value_sp;
1875
1876 TargetSP target_sp = CalculateTarget();
1877 ProcessSP process_sp = CalculateProcess();
1878
1879 if (!target_sp && !process_sp)
1880 return value_sp;
1881
1882 VariableList variable_list;
1883 VariableSP var_sp;
1884 SymbolContext sc(GetSymbolContext(eSymbolContextBlock));
1885
1886 if (sc.block) {
1887 const bool can_create = true;
1888 const bool get_parent_variables = true;
1889 const bool stop_if_block_is_inlined_function = true;
1890
1891 if (sc.block->AppendVariables(
1892 can_create, get_parent_variables, stop_if_block_is_inlined_function,
1893 [this](Variable *v) { return v->IsInScope(this); },
1894 &variable_list)) {
1895 var_sp = variable_list.FindVariable(name);
1896 }
1897
1898 if (var_sp)
1900 }
1901
1902 return value_sp;
1903}
1904
1906 TargetSP target_sp;
1907 ThreadSP thread_sp(GetThread());
1908 if (thread_sp) {
1909 ProcessSP process_sp(thread_sp->CalculateProcess());
1910 if (process_sp)
1911 target_sp = process_sp->CalculateTarget();
1912 }
1913 return target_sp;
1914}
1915
1917 ProcessSP process_sp;
1918 ThreadSP thread_sp(GetThread());
1919 if (thread_sp)
1920 process_sp = thread_sp->CalculateProcess();
1921 return process_sp;
1922}
1923
1925
1926StackFrameSP StackFrame::CalculateStackFrame() { return shared_from_this(); }
1927
1929 exe_ctx.SetContext(shared_from_this());
1930}
1931
1933 const FormatEntity::Entry *format,
1934 llvm::StringRef frame_marker) {
1935 GetSymbolContext(eSymbolContextEverything);
1936 ExecutionContext exe_ctx(shared_from_this());
1937 StreamString s;
1938 s.PutCString(frame_marker);
1939
1940 if (format && FormatEntity::Formatter(&m_sc, &exe_ctx, nullptr, false, false)
1941 .Format(*format, s)) {
1942 strm.PutCString(s.GetString());
1943 return true;
1944 }
1945 return false;
1946}
1947
1948void StackFrame::DumpUsingSettingsFormat(Stream *strm, bool show_unique,
1949 const llvm::StringRef frame_marker) {
1950 if (strm == nullptr)
1951 return;
1952
1953 ExecutionContext exe_ctx(shared_from_this());
1954
1955 const FormatEntity::Entry *frame_format = nullptr;
1956 FormatEntity::Entry format_entry;
1957 Target *target = exe_ctx.GetTargetPtr();
1958 if (target) {
1959 if (show_unique) {
1960 format_entry = target->GetDebugger().GetFrameFormatUnique();
1961 frame_format = &format_entry;
1962 } else {
1963 format_entry = target->GetDebugger().GetFrameFormat();
1964 frame_format = &format_entry;
1965 }
1966 }
1967 if (!DumpUsingFormat(*strm, frame_format, frame_marker)) {
1968 Dump(strm, true, false);
1969 strm->EOL();
1970 }
1971}
1972
1973void StackFrame::Dump(Stream *strm, bool show_frame_index,
1974 bool show_fullpaths) {
1975 if (strm == nullptr)
1976 return;
1977
1978 if (show_frame_index)
1979 strm->Printf("frame #%u: ", m_frame_index);
1980 ExecutionContext exe_ctx(shared_from_this());
1981 Target *target = exe_ctx.GetTargetPtr();
1982 strm->Printf("0x%0*" PRIx64 " ",
1983 target ? (target->GetArchitecture().GetAddressByteSize() * 2)
1984 : 16,
1985 GetFrameCodeAddress().GetLoadAddress(target));
1986 GetSymbolContext(eSymbolContextEverything);
1987 const bool show_module = true;
1988 const bool show_inline = true;
1989 const bool show_function_arguments = true;
1990 const bool show_function_name = true;
1991 m_sc.DumpStopContext(strm, exe_ctx.GetBestExecutionContextScope(),
1992 GetFrameCodeAddress(), show_fullpaths, show_module,
1993 show_inline, show_function_arguments,
1994 show_function_name);
1995}
1996
1998 std::lock_guard<std::recursive_mutex> guard(m_mutex);
1999 assert(GetStackID() ==
2000 prev_frame.GetStackID()); // TODO: remove this after some testing
2003 if (!m_disassembly.GetString().empty()) {
2004 m_disassembly.Clear();
2005 m_disassembly.PutCString(prev_frame.m_disassembly.GetString());
2006 }
2007}
2008
2010 std::lock_guard<std::recursive_mutex> guard(m_mutex);
2011 assert(GetStackID() ==
2012 curr_frame.GetStackID()); // TODO: remove this after some testing
2013 m_id.SetPC(
2014 curr_frame.m_id.GetPC(),
2015 curr_frame.CalculateProcess().get()); // Update the Stack ID PC value
2016 assert(GetThread() == curr_frame.GetThread());
2017 m_frame_index = curr_frame.m_frame_index;
2022 assert(!m_sc.target_sp || !curr_frame.m_sc.target_sp ||
2023 m_sc.target_sp.get() == curr_frame.m_sc.target_sp.get());
2024 assert(!m_sc.module_sp || !curr_frame.m_sc.module_sp ||
2025 m_sc.module_sp.get() == curr_frame.m_sc.module_sp.get());
2026 assert(m_sc.comp_unit == nullptr || curr_frame.m_sc.comp_unit == nullptr ||
2027 m_sc.comp_unit == curr_frame.m_sc.comp_unit);
2028 assert(m_sc.function == nullptr || curr_frame.m_sc.function == nullptr ||
2029 m_sc.function == curr_frame.m_sc.function);
2030 m_sc = curr_frame.m_sc;
2031 m_flags.Clear(GOT_FRAME_BASE | eSymbolContextEverything);
2032 m_flags.Set(m_sc.GetResolvedMask());
2033 m_frame_base.Clear();
2034 m_frame_base_error.Clear();
2035}
2036
2039 return true;
2040 if (m_variable_list_value_objects.GetSize() > 0)
2041 return true;
2042 if (!m_disassembly.GetString().empty())
2043 return true;
2044 return false;
2045}
2046
2047bool StackFrame::GetStatus(Stream &strm, bool show_frame_info, bool show_source,
2048 bool show_unique,
2049 const llvm::StringRef frame_marker) {
2050 if (show_frame_info) {
2051 strm.Indent();
2052 DumpUsingSettingsFormat(&strm, show_unique, frame_marker);
2053 }
2054
2055 if (show_source) {
2056 ExecutionContext exe_ctx(shared_from_this());
2057 bool have_source = false, have_debuginfo = false;
2059 Target *target = exe_ctx.GetTargetPtr();
2060 if (target) {
2061 Debugger &debugger = target->GetDebugger();
2062 const uint32_t source_lines_before =
2063 debugger.GetStopSourceLineCount(true);
2064 const uint32_t source_lines_after =
2065 debugger.GetStopSourceLineCount(false);
2066 disasm_display = debugger.GetStopDisassemblyDisplay();
2067
2068 GetSymbolContext(eSymbolContextCompUnit | eSymbolContextLineEntry);
2069 if (m_sc.comp_unit || m_sc.line_entry.IsValid()) {
2070 have_debuginfo = true;
2071 if (source_lines_before > 0 || source_lines_after > 0) {
2072 SupportFileNSP source_file_sp = m_sc.line_entry.file_sp;
2073 uint32_t start_line = m_sc.line_entry.line;
2074 if (!start_line && m_sc.function) {
2075 m_sc.function->GetStartLineSourceInfo(source_file_sp, start_line);
2076 }
2077
2078 size_t num_lines =
2080 source_file_sp, start_line, m_sc.line_entry.column,
2081 source_lines_before, source_lines_after, "->", &strm,
2082 /*bp_locs=*/nullptr, GetLanguage().AsLanguageType());
2083 if (num_lines != 0)
2084 have_source = true;
2085 // TODO: Give here a one time warning if source file is missing.
2086 if (!m_sc.line_entry.line)
2087 strm << "note: This address is not associated with a specific line "
2088 "of code. This may be due to compiler optimizations.\n";
2089 }
2090 }
2091 switch (disasm_display) {
2093 break;
2094
2096 if (have_debuginfo)
2097 break;
2098 [[fallthrough]];
2099
2101 if (have_source)
2102 break;
2103 [[fallthrough]];
2104
2106 if (target) {
2107 const uint32_t disasm_lines = debugger.GetDisassemblyLineCount();
2108 if (disasm_lines > 0) {
2109 const ArchSpec &target_arch = target->GetArchitecture();
2110 const char *plugin_name = nullptr;
2111 const char *flavor = nullptr;
2112 const bool mixed_source_and_assembly = false;
2114 target->GetDebugger(), target_arch, plugin_name, flavor,
2115 target->GetDisassemblyCPU(), target->GetDisassemblyFeatures(),
2116 exe_ctx, GetFrameCodeAddress(),
2117 {Disassembler::Limit::Instructions, disasm_lines},
2118 mixed_source_and_assembly, 0,
2120 }
2121 }
2122 break;
2123 }
2124 }
2125 }
2126 return true;
2127}
2128
2130 auto process = GetThread()->GetProcess();
2131 if (!process)
2132 return {};
2133 // If recognizer list has been modified, discard cache.
2134 auto &manager = process->GetTarget().GetFrameRecognizerManager();
2135 auto new_generation = manager.GetGeneration();
2136 if (m_frame_recognizer_generation != new_generation)
2137 m_recognized_frame_sp.reset();
2138 m_frame_recognizer_generation = new_generation;
2139 if (!m_recognized_frame_sp.has_value())
2140 m_recognized_frame_sp = manager.RecognizeFrame(CalculateStackFrame());
2141 return m_recognized_frame_sp.value();
2142}
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOG_ERROR(log, error,...)
Definition Log.h:392
#define GOT_FRAME_BASE
#define RESOLVED_GLOBAL_VARIABLES
#define RESOLVED_FRAME_ID_SYMBOL_SCOPE
#define RESOLVED_FRAME_CODE_ADDR
#define RESOLVED_VARIABLES
A section + offset based address range class.
Address & GetBaseAddress()
Get accessor for the base address of the range.
void SetByteSize(lldb::addr_t byte_size)
Set accessor for the byte size of this range.
A section + offset based address class.
Definition Address.h:62
lldb::addr_t GetOpcodeLoadAddress(Target *target, AddressClass addr_class=AddressClass::eInvalid) const
Get the load address as an opcode load address.
Definition Address.cpp:358
bool SetOpcodeLoadAddress(lldb::addr_t load_addr, Target *target, AddressClass addr_class=AddressClass::eInvalid, bool allow_section_end=false)
Definition Address.cpp:369
lldb::ModuleSP GetModule() const
Get accessor for the module for this address.
Definition Address.cpp:273
lldb::addr_t GetOffset() const
Get the section relative offset value.
Definition Address.h:329
bool IsValid() const
Check if the object state is valid.
Definition Address.h:355
bool SetOffset(lldb::addr_t offset)
Set accessor for the offset.
Definition Address.h:441
An architecture specification class.
Definition ArchSpec.h:32
uint32_t GetAddressByteSize() const
Returns the size in bytes of an address of the current architecture.
Definition ArchSpec.cpp:681
uint32_t GetMaximumOpcodeByteSize() const
Definition ArchSpec.cpp:929
A class that describes a single lexical block.
Definition Block.h:41
Block * GetContainingInlinedBlock()
Get the inlined block that contains this block.
Definition Block.cpp:206
const InlineFunctionInfo * GetInlinedFunctionInfo() const
Get const accessor for any inlined function information.
Definition Block.h:268
Function * CalculateSymbolContextFunction() override
Definition Block.cpp:150
uint32_t AppendVariables(bool can_create, bool get_parent_variables, bool stop_if_block_is_inlined_function, const std::function< bool(Variable *)> &filter, VariableList *variable_list)
Appends the variables from this block, and optionally from all parent blocks, to variable_list.
Definition Block.cpp:436
uint32_t AppendBlockVariables(bool can_create, bool get_child_block_variables, bool stop_if_child_block_is_inlined_function, const std::function< bool(Variable *)> &filter, VariableList *variable_list)
Get the variable list for this block and optionally all child blocks if get_child_variables is true.
Definition Block.cpp:406
A class that describes a compilation unit.
Definition CompileUnit.h:43
lldb::LanguageType GetLanguage()
Generic representation of a type in a programming language.
CompilerType GetBasicTypeFromAST(lldb::BasicType basic_type) const
Create related types using the current type's AST.
CompilerType GetPointerType() const
Return a new CompilerType that is a pointer to this type.
CompilerType GetFunctionReturnType() const
A uniqued constant string class.
Definition ConstString.h:40
const char * AsCString(const char *value_if_empty=nullptr) const
Get the string value as a C string.
size_t GetLength() const
Get the length in bytes of string value.
const char * GetCString() const
Get the string value as a C string.
"lldb/Expression/DWARFExpressionList.h" Encapsulates a range map from file address range to a single ...
A class to manage flag bits.
Definition Debugger.h:87
uint64_t GetDisassemblyLineCount() const
Definition Debugger.cpp:673
FormatEntity::Entry GetFrameFormatUnique() const
Definition Debugger.cpp:340
uint64_t GetStopSourceLineCount(bool before) const
Definition Debugger.cpp:659
FormatEntity::Entry GetFrameFormat() const
Definition Debugger.cpp:335
lldb::StopDisassemblyType GetStopDisassemblyDisplay() const
Definition Debugger.cpp:666
static lldb::DisassemblerSP DisassembleRange(const ArchSpec &arch, const char *plugin_name, const char *flavor, const char *cpu, const char *features, Target &target, llvm::ArrayRef< AddressRange > disasm_ranges, bool force_live_memory=false)
static bool Disassemble(Debugger &debugger, const ArchSpec &arch, const char *plugin_name, const char *flavor, const char *cpu, const char *features, const ExecutionContext &exe_ctx, const Address &start, Limit limit, bool mixed_source_and_assembly, uint32_t num_mixed_context_lines, uint32_t options, Stream &strm)
InstructionList & GetInstructionList()
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
ExecutionContextScope * GetBestExecutionContextScope() const
void SetContext(const lldb::TargetSP &target_sp, bool get_process)
Target * GetTargetPtr() const
Returns a pointer to the target object.
Target & GetTargetRef() const
Returns a reference to the target object.
A class that describes a function.
Definition Function.h:400
CompilerType GetCompilerType()
Definition Function.cpp:572
bool GetRangeContainingLoadAddress(lldb::addr_t load_addr, Target &target, AddressRange &range)
Definition Function.h:455
ConstString GetName() const
Definition Function.cpp:709
const Mangled & GetMangled() const
Definition Function.h:534
AddressRanges GetAddressRanges()
Definition Function.h:448
ConstString GetDisplayName() const
Definition Function.cpp:533
A class that describes information for an inlined function.
Definition Function.h:126
ConstString GetDisplayName() const
Definition Function.cpp:103
ConstString GetName() const
Definition Function.cpp:97
lldb::InstructionSP GetInstructionAtIndex(size_t idx) const
lldb::LanguageType GuessLanguage() const
Try to guess the language from the mangling.
Definition Mangled.cpp:425
const RegisterInfo * GetRegisterInfoByName(llvm::StringRef reg_name, uint32_t start_idx=0)
virtual bool ReadRegister(const RegisterInfo *reg_info, RegisterValue &reg_value)=0
uint64_t GetAsUInt64(uint64_t fail_value=UINT64_MAX, bool *success_ptr=nullptr) const
size_t DisplaySourceLinesWithLineNumbers(SupportFileNSP support_file_nsp, uint32_t line, uint32_t column, uint32_t context_before, uint32_t context_after, const char *current_line_cstr, Stream *s, const SymbolContextList *bp_locs=nullptr, lldb::LanguageType language_type=lldb::eLanguageTypeUnknown)
This base class provides an interface to stack frames.
Definition StackFrame.h:44
virtual lldb::ValueObjectSP GetValueForVariableExpressionPath(llvm::StringRef var_expr, lldb::DynamicValueType use_dynamic, uint32_t options, lldb::VariableSP &var_sp, Status &error, lldb::DILMode mode=lldb::eDILModeFull)
Create a ValueObject for a variable name / pathname, possibly including simple dereference/child sele...
void SetSymbolContextScope(SymbolContextScope *symbol_scope)
uint16_t m_frame_recognizer_generation
Definition StackFrame.h:592
lldb::VariableListSP m_variable_list_sp
Definition StackFrame.h:607
void UpdatePreviousFrameFromCurrentFrame(StackFrame &curr_frame)
bool m_artificial
Is this an artificial stack frame (e.g.
Definition StackFrame.h:599
lldb::ThreadSP GetThread() const
Definition StackFrame.h:135
Address m_frame_code_addr
The frame code address (might not be the same as the actual PC for inlined frames) as a section/offse...
Definition StackFrame.h:587
@ eExpressionPathOptionsInspectAnonymousUnions
Definition StackFrame.h:59
@ eExpressionPathOptionsAllowDirectIVarAccess
Definition StackFrame.h:58
virtual const char * GetFunctionName()
Get the frame's demangled name.
virtual bool IsHidden()
Query whether this frame should be hidden from backtraces.
virtual VariableList * GetVariableList(bool get_file_globals, Status *error_ptr)
Retrieve the list of variables whose scope either:
virtual bool IsSynthetic() const
Query whether this frame is synthetic.
virtual DWARFExpressionList * GetFrameBaseExpression(Status *error_ptr)
Get the DWARFExpressionList corresponding to the Canonical Frame Address.
void UpdateCurrentFrameFromPreviousFrame(StackFrame &prev_frame)
ValueObjectList m_variable_list_value_objects
Value objects for each variable in m_variable_list_sp.
Definition StackFrame.h:609
bool m_cfa_is_valid
Does this frame have a CFA? Different from CFA == LLDB_INVALID_ADDRESS.
Definition StackFrame.h:594
virtual llvm::Error GetFrameBaseValue(Scalar &value)
Return the Canonical Frame Address (DWARF term) for this frame.
lldb::ThreadWP m_thread_wp
For StackFrame and derived classes only.
Definition StackFrame.h:578
std::optional< lldb::RecognizedStackFrameSP > m_recognized_frame_sp
Definition StackFrame.h:610
virtual bool IsInlined()
Query whether this frame is a concrete frame on the call stack, or if it is an inlined frame derived ...
lldb::ValueObjectSP DILGetValueForVariableExpressionPath(llvm::StringRef var_expr, lldb::DynamicValueType use_dynamic, uint32_t options, lldb::VariableSP &var_sp, Status &error, lldb::DILMode mode=lldb::eDILModeFull)
virtual SourceLanguage GuessLanguage()
Similar to GetLanguage(), but is allowed to take a potentially incorrect guess if exact information i...
virtual lldb::RegisterContextSP GetRegisterContext()
Get the RegisterContext for this frame, if possible.
lldb::RegisterContextSP m_reg_context_sp
Definition StackFrame.h:581
static char ID
LLVM RTTI support.
Definition StackFrame.h:48
virtual lldb::ValueObjectSP GuessValueForRegisterAndOffset(ConstString reg, int64_t offset)
Attempt to reconstruct the ValueObject for the address contained in a given register plus an offset.
virtual lldb::VariableListSP GetInScopeVariableList(bool get_file_globals, bool must_have_valid_location=false)
Retrieve the list of variables that are in scope at this StackFrame's pc.
virtual StructuredData::ObjectSP GetLanguageSpecificData()
Language plugins can use this API to report language-specific runtime information about this compile ...
virtual Address GetFrameCodeAddressForSymbolication()
Get the current code Address suitable for symbolication, may not be the same as GetFrameCodeAddress()...
@ History
A historical stack frame – possibly without CFA or registers or local variables.
Definition StackFrame.h:68
@ Regular
A regular stack frame with access to registers and local variables.
Definition StackFrame.h:64
@ Synthetic
An synthetic stack frame (e.g.
Definition StackFrame.h:72
bool m_behaves_like_zeroth_frame
Whether this frame behaves like the zeroth frame, in the sense that its pc value might not immediatel...
Definition StackFrame.h:605
virtual StackID & GetStackID()
virtual lldb::ValueObjectSP GuessValueForAddress(lldb::addr_t addr)
Attempt to econstruct the ValueObject for a given raw address touched by the current instruction.
virtual bool GetStatus(Stream &strm, bool show_frame_info, bool show_source, bool show_unique=false, const llvm::StringRef frame_marker="")
Print a description of this stack frame and/or the source context/assembly for this stack frame.
virtual bool ChangePC(lldb::addr_t pc)
Change the pc value for a given thread.
lldb::ValueObjectSP LegacyGetValueForVariableExpressionPath(llvm::StringRef var_expr, lldb::DynamicValueType use_dynamic, uint32_t options, lldb::VariableSP &var_sp, Status &error)
Private methods, called from GetValueForVariableExpressionPath.
lldb::ThreadSP CalculateThread() override
virtual SourceLanguage GetLanguage()
Query this frame to determine what the default language should be when parsing expressions given the ...
virtual lldb::ValueObjectSP GetValueObjectForFrameVariable(const lldb::VariableSP &variable_sp, lldb::DynamicValueType use_dynamic)
Create a ValueObject for a given Variable in this StackFrame.
StreamString m_disassembly
Definition StackFrame.h:611
lldb::StackFrameSP CalculateStackFrame() override
virtual const SymbolContext & GetSymbolContext(lldb::SymbolContextItem resolve_scope)
Provide a SymbolContext for this StackFrame's current pc value.
virtual const char * GetDisplayFunctionName()
Get the frame's demangled display name.
virtual bool IsHistorical() const
Query whether this frame is part of a historical backtrace.
virtual const char * Disassemble()
Return the disassembly for the instructions of this StackFrame's function as a single C string.
virtual bool IsArtificial() const
Query whether this frame is artificial (e.g a synthesized result of inferring missing tail call frame...
void CalculateExecutionContext(ExecutionContext &exe_ctx) override
Reconstruct the object's execution context into sc.
virtual void Dump(Stream *strm, bool show_frame_index, bool show_fullpaths)
Print a description for this frame using a default format.
virtual uint32_t GetFrameIndex() const
Query this frame to find what frame it is in this Thread's StackFrameList.
virtual bool HasDebugInformation()
Determine whether this StackFrame has debug information available or not.
virtual void DumpUsingSettingsFormat(Stream *strm, bool show_unique=false, const llvm::StringRef frame_marker="")
Print a description for this frame using the frame-format formatter settings.
StackFrame(const lldb::ThreadSP &thread_sp, lldb::user_id_t frame_idx, lldb::user_id_t concrete_frame_idx, lldb::addr_t cfa, bool cfa_is_valid, lldb::addr_t pc, Kind frame_kind, bool artificial, bool behaves_like_zeroth_frame, const SymbolContext *sc_ptr)
Construct a StackFrame object without supplying a RegisterContextSP.
virtual Block * GetFrameBlock()
Get the current lexical scope block for this StackFrame, if possible.
virtual bool DumpUsingFormat(Stream &strm, const lldb_private::FormatEntity::Entry *format, llvm::StringRef frame_marker={})
Print a description of this frame using the provided frame format.
lldb::ProcessSP CalculateProcess() override
virtual lldb::RecognizedStackFrameSP GetRecognizedFrame()
std::recursive_mutex m_mutex
Definition StackFrame.h:612
virtual lldb::ValueObjectSP FindVariable(ConstString name)
Attempt to reconstruct the ValueObject for a variable with a given name from within the current Stack...
virtual const Address & GetFrameCodeAddress()
Get an Address for the current pc value in this StackFrame.
lldb::TargetSP CalculateTarget() override
lldb::addr_t GetPC() const
Definition StackID.h:27
An error handling class.
Definition Status.h:118
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
Definition Status.cpp:106
static Status FromErrorString(const char *str)
Definition Status.h:141
bool Fail() const
Test for error condition.
Definition Status.cpp:293
static Status static Status FromErrorStringWithFormatv(const char *format, Args &&...args)
Definition Status.h:151
static Status FromError(llvm::Error error)
Avoid using this in new code. Migrate APIs to llvm::Expected instead.
Definition Status.cpp:136
bool Success() const
Test for success condition.
Definition Status.cpp:303
const char * GetData() const
llvm::StringRef GetString() const
A stream class that can stream formatted output to a file.
Definition Stream.h:28
size_t Indent(llvm::StringRef s="")
Indent the current line in the stream.
Definition Stream.cpp:157
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition Stream.cpp:134
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
Definition Stream.cpp:65
size_t EOL()
Output and End of Line character to the stream.
Definition Stream.cpp:155
std::shared_ptr< Object > ObjectSP
"lldb/Symbol/SymbolContextScope.h" Inherit from this if your object is part of a symbol context and c...
Defines a symbol context baton that can be handed other debug core functions.
Function * function
The Function for a given query.
Block * block
The Block for a given query.
lldb::ModuleSP module_sp
The Module for a given query.
CompileUnit * comp_unit
The CompileUnit for a given query.
Symbol * symbol
The Symbol for a given query.
lldb::TargetSP target_sp
The Target for a given query.
LineEntry line_entry
The LineEntry for a given query.
Provides public interface for all SymbolFiles.
Definition SymbolFile.h:51
Status GetFrameVariableError(StackFrame &frame)
Get an error that describes why variables might be missing for a given symbol context.
Definition SymbolFile.h:280
Mangled & GetMangled()
Definition Symbol.h:147
ConstString GetName() const
Definition Symbol.cpp:511
ConstString GetDisplayName() const
Definition Symbol.cpp:169
const char * GetDisassemblyFeatures() const
Definition Target.cpp:4697
const char * GetDisassemblyCPU() const
Definition Target.cpp:4690
bool GetUseDIL(ExecutionContext *exe_ctx) const
Definition Target.cpp:4558
SourceManager & GetSourceManager()
Definition Target.cpp:3042
Debugger & GetDebugger() const
Definition Target.h:1224
const ArchSpec & GetArchitecture() const
Definition Target.h:1183
CompilerType GetForwardCompilerType()
Definition Type.cpp:782
static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope, lldb::ByteOrder byte_order, uint32_t addr_byte_size, lldb::addr_t address=LLDB_INVALID_ADDRESS)
static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope, llvm::StringRef name, const Address &address, lldb::TypeSP &type_sp)
static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope, const lldb::VariableSP &var_sp)
lldb::VariableSP FindVariable(ConstString name, bool include_static_members=true)
uint32_t FindIndexForVariable(Variable *variable)
bool IsInScope(StackFrame *frame)
Definition Variable.cpp:282
bool LocationIsValidForFrame(StackFrame *frame)
Definition Variable.cpp:224
static llvm::Expected< DILLexer > Create(llvm::StringRef expr, lldb::DILMode mode=lldb::eDILModeFull)
Lexes all the tokens in expr and calls the private constructor with the lexed tokens.
Definition DILLexer.cpp:139
static llvm::Expected< ASTNodeUP > Parse(llvm::StringRef dil_input_expr, DILLexer lexer, std::shared_ptr< StackFrame > frame_sp, lldb::DynamicValueType use_dynamic, bool use_synthetic, bool fragile_ivar, bool check_ptr_vs_member)
Definition DILParser.cpp:90
llvm::Expected< lldb::ValueObjectSP > Evaluate(const ASTNode &node)
Evaluate an ASTNode.
Definition DILEval.cpp:398
#define LLDB_INVALID_ADDRESS
#define UINT32_MAX
std::function< bool(const Instruction::Operand &)> MatchRegOp(const RegisterInfo &info)
std::function< bool(const Instruction::Operand &)> FetchRegOp(ConstString &reg)
std::function< bool(const Instruction::Operand &)> FetchImmOp(int64_t &imm)
std::function< bool(const Instruction::Operand &)> MatchOpType(Instruction::Operand::Type type)
std::function< bool(const Instruction::Operand &)> MatchBinaryOp(std::function< bool(const Instruction::Operand &)> base, std::function< bool(const Instruction::Operand &)> left, std::function< bool(const Instruction::Operand &)> right)
std::function< bool(const Instruction::Operand &)> MatchUnaryOp(std::function< bool(const Instruction::Operand &)> base, std::function< bool(const Instruction::Operand &)> child)
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition Log.h:332
NonNullSharedPtr< lldb_private::SupportFile > SupportFileNSP
Definition SupportFile.h:80
std::shared_ptr< lldb_private::ABI > ABISP
std::shared_ptr< lldb_private::StackFrame > StackFrameSP
std::shared_ptr< lldb_private::RecognizedStackFrame > RecognizedStackFrameSP
std::shared_ptr< lldb_private::Thread > ThreadSP
std::shared_ptr< lldb_private::ValueObject > ValueObjectSP
Format
Display format definitions.
@ eLanguageTypeC
Non-standardized C, such as K&R.
@ eLanguageTypeObjC
Objective-C.
std::shared_ptr< lldb_private::Instruction > InstructionSP
std::shared_ptr< lldb_private::Process > ProcessSP
StopDisassemblyType
Used to determine when to show disassembly.
@ eStopDisassemblyTypeNever
@ eStopDisassemblyTypeNoSource
@ eStopDisassemblyTypeAlways
@ eStopDisassemblyTypeNoDebugInfo
std::shared_ptr< lldb_private::Disassembler > DisassemblerSP
std::shared_ptr< lldb_private::VariableList > VariableListSP
std::shared_ptr< lldb_private::Variable > VariableSP
uint64_t user_id_t
Definition lldb-types.h:82
uint64_t addr_t
Definition lldb-types.h:80
std::shared_ptr< lldb_private::Target > TargetSP
std::shared_ptr< lldb_private::RegisterContext > RegisterContextSP
DILMode
Data Inspection Language (DIL) evaluation modes.
std::shared_ptr< lldb_private::Module > ModuleSP
enum lldb_private::Instruction::Operand::Type m_type
static Operand BuildImmediate(lldb::addr_t imm, bool neg)
static Operand BuildDereference(const Operand &ref)
std::vector< Operand > m_children
static Operand BuildSum(const Operand &lhs, const Operand &rhs)
static Operand BuildRegister(ConstString &r)
Every register is described in detail including its name, alternate name (optional),...
A type-erased pair of llvm::dwarf::SourceLanguageName and version.
lldb::LanguageType AsLanguageType() const
Definition Language.cpp:614