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) {
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);
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
543 const bool check_ptr_vs_member =
545 const bool no_fragile_ivar =
547 const bool no_synth_child =
549
550 // Lex the expression.
551 auto lex_or_err = dil::DILLexer::Create(var_expr);
552 if (!lex_or_err) {
553 error = Status::FromError(lex_or_err.takeError());
554 return ValueObjectConstResult::Create(nullptr, std::move(error));
555 }
556
557 // Parse the expression.
558 auto tree_or_error = dil::DILParser::Parse(
559 var_expr, std::move(*lex_or_err), shared_from_this(), use_dynamic,
560 !no_synth_child, !no_fragile_ivar, check_ptr_vs_member);
561 if (!tree_or_error) {
562 error = Status::FromError(tree_or_error.takeError());
563 return ValueObjectConstResult::Create(nullptr, std::move(error));
564 }
565
566 // Evaluate the parsed expression.
567 lldb::TargetSP target = this->CalculateTarget();
568 dil::Interpreter interpreter(target, var_expr, shared_from_this(),
569 use_dynamic, !no_synth_child, !no_fragile_ivar,
570 check_ptr_vs_member);
571
572 auto valobj_or_error = interpreter.Evaluate((*tree_or_error).get());
573 if (!valobj_or_error) {
574 error = Status::FromError(valobj_or_error.takeError());
575 return ValueObjectConstResult::Create(nullptr, std::move(error));
576 }
577
578 var_sp = (*valobj_or_error)->GetVariable();
579 return *valobj_or_error;
580}
581
583 llvm::StringRef var_expr, DynamicValueType use_dynamic, uint32_t options,
584 VariableSP &var_sp, Status &error) {
585 llvm::StringRef original_var_expr = var_expr;
586 // We can't fetch variable information for a history stack frame.
587 if (IsHistorical())
588 return ValueObjectSP();
589
590 if (var_expr.empty()) {
591 error = Status::FromErrorStringWithFormatv("invalid variable path '{0}'",
592 var_expr);
593 return ValueObjectSP();
594 }
595
596 const bool check_ptr_vs_member =
598 const bool no_fragile_ivar =
600 const bool no_synth_child =
602 // const bool no_synth_array = (options &
603 // eExpressionPathOptionsNoSyntheticArrayRange) != 0;
604 error.Clear();
605 bool deref = false;
606 bool address_of = false;
607 ValueObjectSP valobj_sp;
608 const bool get_file_globals = true;
609 // When looking up a variable for an expression, we need only consider the
610 // variables that are in scope.
611 VariableListSP var_list_sp(GetInScopeVariableList(get_file_globals));
612 VariableList *variable_list = var_list_sp.get();
613
614 if (!variable_list)
615 return ValueObjectSP();
616
617 // If first character is a '*', then show pointer contents
618 std::string var_expr_storage;
619 if (var_expr[0] == '*') {
620 deref = true;
621 var_expr = var_expr.drop_front(); // Skip the '*'
622 } else if (var_expr[0] == '&') {
623 address_of = true;
624 var_expr = var_expr.drop_front(); // Skip the '&'
625 }
626
627 size_t separator_idx = var_expr.find_first_of(".-[=+~|&^%#@!/?,<>{}");
628 StreamString var_expr_path_strm;
629
630 ConstString name_const_string(var_expr.substr(0, separator_idx));
631
632 var_sp = variable_list->FindVariable(name_const_string, false);
633
634 bool synthetically_added_instance_object = false;
635
636 if (var_sp) {
637 var_expr = var_expr.drop_front(name_const_string.GetLength());
638 }
639
640 if (!var_sp && (options & eExpressionPathOptionsAllowDirectIVarAccess)) {
641 // Check for direct ivars access which helps us with implicit access to
642 // ivars using "this" or "self".
643 GetSymbolContext(eSymbolContextFunction | eSymbolContextBlock);
644 llvm::StringRef instance_var_name = m_sc.GetInstanceVariableName();
645 if (!instance_var_name.empty()) {
646 var_sp = variable_list->FindVariable(ConstString(instance_var_name));
647 if (var_sp) {
648 separator_idx = 0;
649 if (Type *var_type = var_sp->GetType())
650 if (auto compiler_type = var_type->GetForwardCompilerType())
651 if (!compiler_type.IsPointerType())
652 var_expr_storage = ".";
653
654 if (var_expr_storage.empty())
655 var_expr_storage = "->";
656 var_expr_storage += var_expr;
657 var_expr = var_expr_storage;
658 synthetically_added_instance_object = true;
659 }
660 }
661 }
662
663 if (!var_sp && (options & eExpressionPathOptionsInspectAnonymousUnions)) {
664 // Check if any anonymous unions are there which contain a variable with
665 // the name we need
666 for (const VariableSP &variable_sp : *variable_list) {
667 if (!variable_sp)
668 continue;
669 if (!variable_sp->GetName().IsEmpty())
670 continue;
671
672 Type *var_type = variable_sp->GetType();
673 if (!var_type)
674 continue;
675
676 if (!var_type->GetForwardCompilerType().IsAnonymousType())
677 continue;
678 valobj_sp = GetValueObjectForFrameVariable(variable_sp, use_dynamic);
679 if (!valobj_sp)
680 return valobj_sp;
681 valobj_sp = valobj_sp->GetChildMemberWithName(name_const_string);
682 if (valobj_sp)
683 break;
684 }
685 }
686
687 if (var_sp && !valobj_sp) {
688 valobj_sp = GetValueObjectForFrameVariable(var_sp, use_dynamic);
689 if (!valobj_sp)
690 return valobj_sp;
691 }
692 if (!valobj_sp) {
694 "no variable named '{0}' found in this frame", name_const_string);
695 return ValueObjectSP();
696 }
697
698 // We are dumping at least one child
699 while (!var_expr.empty()) {
700 // Calculate the next separator index ahead of time
701 ValueObjectSP child_valobj_sp;
702 const char separator_type = var_expr[0];
703 bool expr_is_ptr = false;
704 switch (separator_type) {
705 case '-':
706 expr_is_ptr = true;
707 if (var_expr.size() >= 2 && var_expr[1] != '>')
708 return ValueObjectSP();
709
710 if (no_fragile_ivar) {
711 // Make sure we aren't trying to deref an objective
712 // C ivar if this is not allowed
713 const uint32_t pointer_type_flags =
714 valobj_sp->GetCompilerType().GetTypeInfo(nullptr);
715 if ((pointer_type_flags & eTypeIsObjC) &&
716 (pointer_type_flags & eTypeIsPointer)) {
717 // This was an objective C object pointer and it was requested we
718 // skip any fragile ivars so return nothing here
719 return ValueObjectSP();
720 }
721 }
722
723 // If we have a non-pointer type with a synthetic value then lets check if
724 // we have a synthetic dereference specified.
725 if (!valobj_sp->IsPointerType() && valobj_sp->HasSyntheticValue()) {
726 Status deref_error;
727 if (ValueObjectSP synth_deref_sp =
728 valobj_sp->GetSyntheticValue()->Dereference(deref_error);
729 synth_deref_sp && deref_error.Success()) {
730 valobj_sp = std::move(synth_deref_sp);
731 }
732 if (!valobj_sp || deref_error.Fail()) {
734 "Failed to dereference synthetic value: {0}", deref_error);
735 return ValueObjectSP();
736 }
737
738 // Some synthetic plug-ins fail to set the error in Dereference
739 if (!valobj_sp) {
740 error =
741 Status::FromErrorString("Failed to dereference synthetic value");
742 return ValueObjectSP();
743 }
744 expr_is_ptr = false;
745 }
746
747 var_expr = var_expr.drop_front(); // Remove the '-'
748 [[fallthrough]];
749 case '.': {
750 var_expr = var_expr.drop_front(); // Remove the '.' or '>'
751 separator_idx = var_expr.find_first_of(".-[");
752 ConstString child_name(var_expr.substr(0, var_expr.find_first_of(".-[")));
753
754 if (check_ptr_vs_member) {
755 // We either have a pointer type and need to verify valobj_sp is a
756 // pointer, or we have a member of a class/union/struct being accessed
757 // with the . syntax and need to verify we don't have a pointer.
758 const bool actual_is_ptr = valobj_sp->IsPointerType();
759
760 if (actual_is_ptr != expr_is_ptr) {
761 // Incorrect use of "." with a pointer, or "->" with a
762 // class/union/struct instance or reference.
763 valobj_sp->GetExpressionPath(var_expr_path_strm);
764 if (actual_is_ptr)
766 "\"%s\" is a pointer and . was used to attempt to access "
767 "\"%s\". Did you mean \"%s->%s\"?",
768 var_expr_path_strm.GetData(), child_name.GetCString(),
769 var_expr_path_strm.GetData(), var_expr.str().c_str());
770 else
772 "\"%s\" is not a pointer and -> was used to attempt to "
773 "access \"%s\". Did you mean \"%s.%s\"?",
774 var_expr_path_strm.GetData(), child_name.GetCString(),
775 var_expr_path_strm.GetData(), var_expr.str().c_str());
776 return ValueObjectSP();
777 }
778 }
779 child_valobj_sp = valobj_sp->GetChildMemberWithName(child_name);
780 if (!child_valobj_sp) {
781 if (!no_synth_child) {
782 child_valobj_sp = valobj_sp->GetSyntheticValue();
783 if (child_valobj_sp)
784 child_valobj_sp =
785 child_valobj_sp->GetChildMemberWithName(child_name);
786 }
787
788 if (no_synth_child || !child_valobj_sp) {
789 // No child member with name "child_name"
790 if (synthetically_added_instance_object) {
791 // We added a "this->" or "self->" to the beginning of the
792 // expression and this is the first pointer ivar access, so just
793 // return the normal error
795 "no variable or instance variable named '%s' found in "
796 "this frame",
797 name_const_string.GetCString());
798 } else {
799 valobj_sp->GetExpressionPath(var_expr_path_strm);
800 if (child_name) {
802 "\"%s\" is not a member of \"(%s) %s\"",
803 child_name.GetCString(),
804 valobj_sp->GetTypeName().AsCString("<invalid type>"),
805 var_expr_path_strm.GetData());
806 } else {
808 "incomplete expression path after \"%s\" in \"%s\"",
809 var_expr_path_strm.GetData(),
810 original_var_expr.str().c_str());
811 }
812 }
813 return ValueObjectSP();
814 }
815 }
816 synthetically_added_instance_object = false;
817 // Remove the child name from the path
818 var_expr = var_expr.drop_front(child_name.GetLength());
819 if (use_dynamic != eNoDynamicValues) {
820 ValueObjectSP dynamic_value_sp(
821 child_valobj_sp->GetDynamicValue(use_dynamic));
822 if (dynamic_value_sp)
823 child_valobj_sp = dynamic_value_sp;
824 }
825 } break;
826
827 case '[': {
828 // Array member access, or treating pointer as an array Need at least two
829 // brackets and a number
830 if (var_expr.size() <= 2) {
832 "invalid square bracket encountered after \"%s\" in \"%s\"",
833 var_expr_path_strm.GetData(), var_expr.str().c_str());
834 return ValueObjectSP();
835 }
836
837 // Drop the open brace.
838 var_expr = var_expr.drop_front();
839 long child_index = 0;
840
841 // If there's no closing brace, this is an invalid expression.
842 size_t end_pos = var_expr.find_first_of(']');
843 if (end_pos == llvm::StringRef::npos) {
845 "missing closing square bracket in expression \"%s\"",
846 var_expr_path_strm.GetData());
847 return ValueObjectSP();
848 }
849 llvm::StringRef index_expr = var_expr.take_front(end_pos);
850 llvm::StringRef original_index_expr = index_expr;
851 // Drop all of "[index_expr]"
852 var_expr = var_expr.drop_front(end_pos + 1);
853
854 if (index_expr.consumeInteger(0, child_index)) {
855 // If there was no integer anywhere in the index expression, this is
856 // erroneous expression.
858 "invalid index expression \"%s\"", index_expr.str().c_str());
859 return ValueObjectSP();
860 }
861
862 if (index_expr.empty()) {
863 // The entire index expression was a single integer.
864
865 if (valobj_sp->GetCompilerType().IsPointerToScalarType() && deref) {
866 // what we have is *ptr[low]. the most similar C++ syntax is to deref
867 // ptr and extract bit low out of it. reading array item low would be
868 // done by saying ptr[low], without a deref * sign
869 Status deref_error;
870 ValueObjectSP temp(valobj_sp->Dereference(deref_error));
871 if (!temp || deref_error.Fail()) {
872 valobj_sp->GetExpressionPath(var_expr_path_strm);
874 "could not dereference \"(%s) %s\"",
875 valobj_sp->GetTypeName().AsCString("<invalid type>"),
876 var_expr_path_strm.GetData());
877 return ValueObjectSP();
878 }
879 valobj_sp = temp;
880 deref = false;
881 } else if (valobj_sp->GetCompilerType().IsArrayOfScalarType() &&
882 deref) {
883 // what we have is *arr[low]. the most similar C++ syntax is to get
884 // arr[0] (an operation that is equivalent to deref-ing arr) and
885 // extract bit low out of it. reading array item low would be done by
886 // saying arr[low], without a deref * sign
887 ValueObjectSP temp(valobj_sp->GetChildAtIndex(0));
888 if (!temp) {
889 valobj_sp->GetExpressionPath(var_expr_path_strm);
891 "could not get item 0 for \"(%s) %s\"",
892 valobj_sp->GetTypeName().AsCString("<invalid type>"),
893 var_expr_path_strm.GetData());
894 return ValueObjectSP();
895 }
896 valobj_sp = temp;
897 deref = false;
898 }
899
900 bool is_incomplete_array = false;
901 if (valobj_sp->IsPointerType()) {
902 bool is_objc_pointer = true;
903
904 if (valobj_sp->GetCompilerType().GetMinimumLanguage() !=
906 is_objc_pointer = false;
907 else if (!valobj_sp->GetCompilerType().IsPointerType())
908 is_objc_pointer = false;
909
910 if (no_synth_child && is_objc_pointer) {
912 "\"(%s) %s\" is an Objective-C pointer, and cannot be "
913 "subscripted",
914 valobj_sp->GetTypeName().AsCString("<invalid type>"),
915 var_expr_path_strm.GetData());
916
917 return ValueObjectSP();
918 } else if (is_objc_pointer) {
919 // dereferencing ObjC variables is not valid.. so let's try and
920 // recur to synthetic children
921 ValueObjectSP synthetic = valobj_sp->GetSyntheticValue();
922 if (!synthetic /* no synthetic */
923 || synthetic == valobj_sp) /* synthetic is the same as
924 the original object */
925 {
926 valobj_sp->GetExpressionPath(var_expr_path_strm);
928 "\"(%s) %s\" is not an array type",
929 valobj_sp->GetTypeName().AsCString("<invalid type>"),
930 var_expr_path_strm.GetData());
931 } else if (static_cast<uint32_t>(child_index) >=
932 synthetic
933 ->GetNumChildrenIgnoringErrors() /* synthetic does
934 not have that
935 many values */) {
936 valobj_sp->GetExpressionPath(var_expr_path_strm);
938 "array index %ld is not valid for \"(%s) %s\"", child_index,
939 valobj_sp->GetTypeName().AsCString("<invalid type>"),
940 var_expr_path_strm.GetData());
941 } else {
942 child_valobj_sp = synthetic->GetChildAtIndex(child_index);
943 if (!child_valobj_sp) {
944 valobj_sp->GetExpressionPath(var_expr_path_strm);
946 "array index %ld is not valid for \"(%s) %s\"", child_index,
947 valobj_sp->GetTypeName().AsCString("<invalid type>"),
948 var_expr_path_strm.GetData());
949 }
950 }
951 } else {
952 child_valobj_sp =
953 valobj_sp->GetSyntheticArrayMember(child_index, true);
954 if (!child_valobj_sp) {
955 valobj_sp->GetExpressionPath(var_expr_path_strm);
957 "failed to use pointer as array for index %ld for "
958 "\"(%s) %s\"",
959 child_index,
960 valobj_sp->GetTypeName().AsCString("<invalid type>"),
961 var_expr_path_strm.GetData());
962 }
963 }
964 } else if (valobj_sp->GetCompilerType().IsArrayType(
965 nullptr, nullptr, &is_incomplete_array)) {
966 // Pass false to dynamic_value here so we can tell the difference
967 // between no dynamic value and no member of this type...
968 child_valobj_sp = valobj_sp->GetChildAtIndex(child_index);
969 if (!child_valobj_sp && (is_incomplete_array || !no_synth_child))
970 child_valobj_sp =
971 valobj_sp->GetSyntheticArrayMember(child_index, true);
972
973 if (!child_valobj_sp) {
974 valobj_sp->GetExpressionPath(var_expr_path_strm);
976 "array index %ld is not valid for \"(%s) %s\"", child_index,
977 valobj_sp->GetTypeName().AsCString("<invalid type>"),
978 var_expr_path_strm.GetData());
979 }
980 } else if (valobj_sp->GetCompilerType().IsScalarType()) {
981 // this is a bitfield asking to display just one bit
982 child_valobj_sp = valobj_sp->GetSyntheticBitFieldChild(
983 child_index, child_index, true);
984 if (!child_valobj_sp) {
985 valobj_sp->GetExpressionPath(var_expr_path_strm);
987 "bitfield range %ld-%ld is not valid for \"(%s) %s\"",
988 child_index, child_index,
989 valobj_sp->GetTypeName().AsCString("<invalid type>"),
990 var_expr_path_strm.GetData());
991 }
992 } else {
993 ValueObjectSP synthetic = valobj_sp->GetSyntheticValue();
994 if (no_synth_child /* synthetic is forbidden */ ||
995 !synthetic /* no synthetic */
996 || synthetic == valobj_sp) /* synthetic is the same as the
997 original object */
998 {
999 valobj_sp->GetExpressionPath(var_expr_path_strm);
1001 "\"(%s) %s\" is not an array type",
1002 valobj_sp->GetTypeName().AsCString("<invalid type>"),
1003 var_expr_path_strm.GetData());
1004 } else if (static_cast<uint32_t>(child_index) >=
1005 synthetic->GetNumChildrenIgnoringErrors() /* synthetic
1006 does not have that many values */) {
1007 valobj_sp->GetExpressionPath(var_expr_path_strm);
1009 "array index %ld is not valid for \"(%s) %s\"", child_index,
1010 valobj_sp->GetTypeName().AsCString("<invalid type>"),
1011 var_expr_path_strm.GetData());
1012 } else {
1013 child_valobj_sp = synthetic->GetChildAtIndex(child_index);
1014 if (!child_valobj_sp) {
1015 valobj_sp->GetExpressionPath(var_expr_path_strm);
1017 "array index %ld is not valid for \"(%s) %s\"", child_index,
1018 valobj_sp->GetTypeName().AsCString("<invalid type>"),
1019 var_expr_path_strm.GetData());
1020 }
1021 }
1022 }
1023
1024 if (!child_valobj_sp) {
1025 // Invalid array index...
1026 return ValueObjectSP();
1027 }
1028
1029 if (use_dynamic != eNoDynamicValues) {
1030 ValueObjectSP dynamic_value_sp(
1031 child_valobj_sp->GetDynamicValue(use_dynamic));
1032 if (dynamic_value_sp)
1033 child_valobj_sp = dynamic_value_sp;
1034 }
1035 // Break out early from the switch since we were able to find the child
1036 // member
1037 break;
1038 }
1039
1040 // this is most probably a BitField, let's take a look
1041 if (index_expr.front() != '-') {
1043 "invalid range expression \"'%s'\"",
1044 original_index_expr.str().c_str());
1045 return ValueObjectSP();
1046 }
1047
1048 index_expr = index_expr.drop_front();
1049 long final_index = 0;
1050 if (index_expr.getAsInteger(0, final_index)) {
1052 "invalid range expression \"'%s'\"",
1053 original_index_expr.str().c_str());
1054 return ValueObjectSP();
1055 }
1056
1057 // if the format given is [high-low], swap range
1058 if (child_index > final_index) {
1059 long temp = child_index;
1060 child_index = final_index;
1061 final_index = temp;
1062 }
1063
1064 if (valobj_sp->GetCompilerType().IsPointerToScalarType() && deref) {
1065 // what we have is *ptr[low-high]. the most similar C++ syntax is to
1066 // deref ptr and extract bits low thru high out of it. reading array
1067 // items low thru high would be done by saying ptr[low-high], without a
1068 // deref * sign
1069 Status deref_error;
1070 ValueObjectSP temp(valobj_sp->Dereference(deref_error));
1071 if (!temp || deref_error.Fail()) {
1072 valobj_sp->GetExpressionPath(var_expr_path_strm);
1074 "could not dereference \"(%s) %s\"",
1075 valobj_sp->GetTypeName().AsCString("<invalid type>"),
1076 var_expr_path_strm.GetData());
1077 return ValueObjectSP();
1078 }
1079 valobj_sp = temp;
1080 deref = false;
1081 } else if (valobj_sp->GetCompilerType().IsArrayOfScalarType() && deref) {
1082 // what we have is *arr[low-high]. the most similar C++ syntax is to
1083 // get arr[0] (an operation that is equivalent to deref-ing arr) and
1084 // extract bits low thru high out of it. reading array items low thru
1085 // high would be done by saying arr[low-high], without a deref * sign
1086 ValueObjectSP temp(valobj_sp->GetChildAtIndex(0));
1087 if (!temp) {
1088 valobj_sp->GetExpressionPath(var_expr_path_strm);
1090 "could not get item 0 for \"(%s) %s\"",
1091 valobj_sp->GetTypeName().AsCString("<invalid type>"),
1092 var_expr_path_strm.GetData());
1093 return ValueObjectSP();
1094 }
1095 valobj_sp = temp;
1096 deref = false;
1097 }
1098
1099 child_valobj_sp =
1100 valobj_sp->GetSyntheticBitFieldChild(child_index, final_index, true);
1101 if (!child_valobj_sp) {
1102 valobj_sp->GetExpressionPath(var_expr_path_strm);
1104 "bitfield range %ld-%ld is not valid for \"(%s) %s\"", child_index,
1105 final_index, valobj_sp->GetTypeName().AsCString("<invalid type>"),
1106 var_expr_path_strm.GetData());
1107 }
1108
1109 if (!child_valobj_sp) {
1110 // Invalid bitfield range...
1111 return ValueObjectSP();
1112 }
1113
1114 if (use_dynamic != eNoDynamicValues) {
1115 ValueObjectSP dynamic_value_sp(
1116 child_valobj_sp->GetDynamicValue(use_dynamic));
1117 if (dynamic_value_sp)
1118 child_valobj_sp = dynamic_value_sp;
1119 }
1120 // Break out early from the switch since we were able to find the child
1121 // member
1122 break;
1123 }
1124 default:
1125 // Failure...
1126 {
1127 valobj_sp->GetExpressionPath(var_expr_path_strm);
1129 "unexpected char '%c' encountered after \"%s\" in \"%s\"",
1130 separator_type, var_expr_path_strm.GetData(),
1131 var_expr.str().c_str());
1132
1133 return ValueObjectSP();
1134 }
1135 }
1136
1137 if (child_valobj_sp)
1138 valobj_sp = child_valobj_sp;
1139 }
1140 if (valobj_sp) {
1141 if (deref) {
1142 ValueObjectSP deref_valobj_sp(valobj_sp->Dereference(error));
1143 if (!deref_valobj_sp && !no_synth_child) {
1144 if (ValueObjectSP synth_obj_sp = valobj_sp->GetSyntheticValue()) {
1145 error.Clear();
1146 deref_valobj_sp = synth_obj_sp->Dereference(error);
1147 }
1148 }
1149 valobj_sp = deref_valobj_sp;
1150 } else if (address_of) {
1151 ValueObjectSP address_of_valobj_sp(valobj_sp->AddressOf(error));
1152 valobj_sp = address_of_valobj_sp;
1153 }
1154 }
1155 return valobj_sp;
1156}
1157
1158llvm::Error StackFrame::GetFrameBaseValue(Scalar &frame_base) {
1159 std::lock_guard<std::recursive_mutex> guard(m_mutex);
1160 if (!m_cfa_is_valid) {
1162 "No frame base available for this historical stack frame.");
1163 return m_frame_base_error.ToError();
1164 }
1165
1166 if (m_flags.IsClear(GOT_FRAME_BASE)) {
1167 if (m_sc.function) {
1168 m_frame_base.Clear();
1169 m_frame_base_error.Clear();
1170
1172 ExecutionContext exe_ctx(shared_from_this());
1173 addr_t loclist_base_addr = LLDB_INVALID_ADDRESS;
1174 if (!m_sc.function->GetFrameBaseExpression().IsAlwaysValidSingleExpr())
1175 loclist_base_addr =
1176 m_sc.function->GetAddress().GetLoadAddress(exe_ctx.GetTargetPtr());
1177
1178 llvm::Expected<Value> expr_value =
1179 m_sc.function->GetFrameBaseExpression().Evaluate(
1180 &exe_ctx, nullptr, loclist_base_addr, nullptr, nullptr);
1181 if (!expr_value)
1182 m_frame_base_error = Status::FromError(expr_value.takeError());
1183 else
1184 m_frame_base = expr_value->ResolveValue(&exe_ctx);
1185 } else {
1187 Status::FromErrorString("No function in symbol context.");
1188 }
1189 }
1190
1191 if (m_frame_base_error.Fail())
1192 return m_frame_base_error.ToError();
1193
1194 frame_base = m_frame_base;
1195 return llvm::Error::success();
1196}
1197
1199 if (!m_sc.function) {
1200 if (error_ptr) {
1201 *error_ptr = Status::FromErrorString("No function in symbol context.");
1202 }
1203 return nullptr;
1204 }
1205
1206 return &m_sc.function->GetFrameBaseExpression();
1207}
1208
1210 std::lock_guard<std::recursive_mutex> guard(m_mutex);
1211 if (!m_reg_context_sp) {
1212 ThreadSP thread_sp(GetThread());
1213 if (thread_sp)
1214 m_reg_context_sp = thread_sp->CreateRegisterContextForFrame(this);
1215 }
1216 return m_reg_context_sp;
1217}
1218
1220 GetSymbolContext(eSymbolContextLineEntry);
1221 return m_sc.line_entry.IsValid();
1222}
1223
1226 DynamicValueType use_dynamic) {
1227 ValueObjectSP valobj_sp;
1228 { // Scope for stack frame mutex. We need to drop this mutex before we figure
1229 // out the dynamic value. That will require converting the StackID in the
1230 // VO back to a StackFrame, which will in turn require locking the
1231 // StackFrameList. If we still hold the StackFrame mutex, we could suffer
1232 // lock inversion against the pattern of getting the StackFrameList and
1233 // then the stack frame, which is fairly common.
1234 std::lock_guard<std::recursive_mutex> guard(m_mutex);
1235 if (IsHistorical()) {
1236 return valobj_sp;
1237 }
1238 VariableList *var_list = GetVariableList(true, nullptr);
1239 if (var_list) {
1240 // Make sure the variable is a frame variable
1241 const uint32_t var_idx =
1242 var_list->FindIndexForVariable(variable_sp.get());
1243 const uint32_t num_variables = var_list->GetSize();
1244 if (var_idx < num_variables) {
1245 valobj_sp =
1246 m_variable_list_value_objects.GetValueObjectAtIndex(var_idx);
1247 if (!valobj_sp) {
1248 if (m_variable_list_value_objects.GetSize() < num_variables)
1249 m_variable_list_value_objects.Resize(num_variables);
1250 valobj_sp = ValueObjectVariable::Create(this, variable_sp);
1251 m_variable_list_value_objects.SetValueObjectAtIndex(var_idx,
1252 valobj_sp);
1253 }
1254 }
1255 }
1256 } // End of StackFrame mutex scope.
1257 if (use_dynamic != eNoDynamicValues && valobj_sp) {
1258 ValueObjectSP dynamic_sp = valobj_sp->GetDynamicValue(use_dynamic);
1259 if (dynamic_sp)
1260 return dynamic_sp;
1261 }
1262 return valobj_sp;
1263}
1264
1266 if (m_sc.block == nullptr)
1267 GetSymbolContext(eSymbolContextBlock);
1268 if (m_sc.block)
1269 return m_sc.block->GetContainingInlinedBlock() != nullptr;
1270 return false;
1271}
1272
1276
1280
1282
1284 if (auto recognized_frame_sp = GetRecognizedFrame())
1285 return recognized_frame_sp->ShouldHide();
1286 return false;
1287}
1288
1290 auto process_sp = CalculateProcess();
1291 SourceLanguage language = GetLanguage();
1292 if (!language)
1293 return {};
1294 if (auto runtime_sp =
1295 process_sp->GetLanguageRuntime(language.AsLanguageType()))
1296 return runtime_sp->GetLanguageSpecificData(
1297 GetSymbolContext(eSymbolContextFunction));
1298 return {};
1299}
1300
1302 const char *name = nullptr;
1304 eSymbolContextFunction | eSymbolContextBlock | eSymbolContextSymbol);
1305 if (sc.block) {
1306 Block *inlined_block = sc.block->GetContainingInlinedBlock();
1307 if (inlined_block) {
1308 const InlineFunctionInfo *inlined_info =
1309 inlined_block->GetInlinedFunctionInfo();
1310 if (inlined_info)
1311 name = inlined_info->GetName().AsCString();
1312 }
1313 }
1314
1315 if (name == nullptr) {
1316 if (sc.function)
1317 name = sc.function->GetName().GetCString();
1318 }
1319
1320 if (name == nullptr) {
1321 if (sc.symbol)
1322 name = sc.symbol->GetName().GetCString();
1323 }
1324
1325 return name;
1326}
1327
1329 const char *name = nullptr;
1331 eSymbolContextFunction | eSymbolContextBlock | eSymbolContextSymbol);
1332 if (sc.block) {
1333 Block *inlined_block = sc.block->GetContainingInlinedBlock();
1334 if (inlined_block) {
1335 const InlineFunctionInfo *inlined_info =
1336 inlined_block->GetInlinedFunctionInfo();
1337 if (inlined_info)
1338 name = inlined_info->GetDisplayName().AsCString();
1339 }
1340 }
1341
1342 if (name == nullptr) {
1343 if (sc.function)
1344 name = sc.function->GetDisplayName().GetCString();
1345 }
1346
1347 if (name == nullptr) {
1348 if (sc.symbol)
1349 name = sc.symbol->GetDisplayName().GetCString();
1350 }
1351 return name;
1352}
1353
1355 CompileUnit *cu = GetSymbolContext(eSymbolContextCompUnit).comp_unit;
1356 if (cu)
1357 return SourceLanguage{cu->GetLanguage()};
1358 return {};
1359}
1360
1362 SourceLanguage lang_type = GetLanguage();
1363
1364 if (!lang_type) {
1365 SymbolContext sc =
1366 GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol);
1367 if (sc.function)
1368 lang_type = SourceLanguage(sc.function->GetMangled().GuessLanguage());
1369 else if (sc.symbol)
1370 lang_type = SourceLanguage(sc.symbol->GetMangled().GuessLanguage());
1371 }
1372
1373 return lang_type;
1374}
1375
1376namespace {
1377std::pair<const Instruction::Operand *, int64_t>
1378GetBaseExplainingValue(const Instruction::Operand &operand,
1379 RegisterContext &register_context, lldb::addr_t value) {
1380 switch (operand.m_type) {
1385 // These are not currently interesting
1386 return std::make_pair(nullptr, 0);
1388 const Instruction::Operand *immediate_child = nullptr;
1389 const Instruction::Operand *variable_child = nullptr;
1390 if (operand.m_children[0].m_type == Instruction::Operand::Type::Immediate) {
1391 immediate_child = &operand.m_children[0];
1392 variable_child = &operand.m_children[1];
1393 } else if (operand.m_children[1].m_type ==
1395 immediate_child = &operand.m_children[1];
1396 variable_child = &operand.m_children[0];
1397 }
1398 if (!immediate_child) {
1399 return std::make_pair(nullptr, 0);
1400 }
1401 lldb::addr_t adjusted_value = value;
1402 if (immediate_child->m_negative) {
1403 adjusted_value += immediate_child->m_immediate;
1404 } else {
1405 adjusted_value -= immediate_child->m_immediate;
1406 }
1407 std::pair<const Instruction::Operand *, int64_t> base_and_offset =
1408 GetBaseExplainingValue(*variable_child, register_context,
1409 adjusted_value);
1410 if (!base_and_offset.first) {
1411 return std::make_pair(nullptr, 0);
1412 }
1413 if (immediate_child->m_negative) {
1414 base_and_offset.second -= immediate_child->m_immediate;
1415 } else {
1416 base_and_offset.second += immediate_child->m_immediate;
1417 }
1418 return base_and_offset;
1419 }
1421 const RegisterInfo *info =
1422 register_context.GetRegisterInfoByName(operand.m_register.AsCString());
1423 if (!info) {
1424 return std::make_pair(nullptr, 0);
1425 }
1426 RegisterValue reg_value;
1427 if (!register_context.ReadRegister(info, reg_value)) {
1428 return std::make_pair(nullptr, 0);
1429 }
1430 if (reg_value.GetAsUInt64() == value) {
1431 return std::make_pair(&operand, 0);
1432 } else {
1433 return std::make_pair(nullptr, 0);
1434 }
1435 }
1436 }
1437 return std::make_pair(nullptr, 0);
1438}
1439
1440std::pair<const Instruction::Operand *, int64_t>
1441GetBaseExplainingDereference(const Instruction::Operand &operand,
1442 RegisterContext &register_context,
1443 lldb::addr_t addr) {
1445 return GetBaseExplainingValue(operand.m_children[0], register_context,
1446 addr);
1447 }
1448 return std::make_pair(nullptr, 0);
1449}
1450} // namespace
1451
1453 TargetSP target_sp = CalculateTarget();
1454
1455 const ArchSpec &target_arch = target_sp->GetArchitecture();
1456
1457 AddressRange pc_range;
1458 pc_range.GetBaseAddress() = GetFrameCodeAddress();
1459 pc_range.SetByteSize(target_arch.GetMaximumOpcodeByteSize());
1460
1461 const char *plugin_name = nullptr;
1462 const char *flavor = nullptr;
1463 const char *cpu = nullptr;
1464 const char *features = nullptr;
1465 const bool force_live_memory = true;
1466
1468 target_arch, plugin_name, flavor, cpu, features, *target_sp, pc_range,
1469 force_live_memory);
1470
1471 if (!disassembler_sp || !disassembler_sp->GetInstructionList().GetSize()) {
1472 return ValueObjectSP();
1473 }
1474
1475 InstructionSP instruction_sp =
1476 disassembler_sp->GetInstructionList().GetInstructionAtIndex(0);
1477
1478 llvm::SmallVector<Instruction::Operand, 3> operands;
1479
1480 if (!instruction_sp->ParseOperands(operands)) {
1481 return ValueObjectSP();
1482 }
1483
1484 RegisterContextSP register_context_sp = GetRegisterContext();
1485
1486 if (!register_context_sp) {
1487 return ValueObjectSP();
1488 }
1489
1490 for (const Instruction::Operand &operand : operands) {
1491 std::pair<const Instruction::Operand *, int64_t> base_and_offset =
1492 GetBaseExplainingDereference(operand, *register_context_sp, addr);
1493
1494 if (!base_and_offset.first) {
1495 continue;
1496 }
1497
1498 switch (base_and_offset.first->m_type) {
1501 if (target_sp->ResolveLoadAddress(base_and_offset.first->m_immediate +
1502 base_and_offset.second,
1503 addr)) {
1504 auto c_type_system_or_err =
1505 target_sp->GetScratchTypeSystemForLanguage(eLanguageTypeC);
1506 if (auto err = c_type_system_or_err.takeError()) {
1507 LLDB_LOG_ERROR(GetLog(LLDBLog::Thread), std::move(err),
1508 "Unable to guess value for given address: {0}");
1509 return ValueObjectSP();
1510 } else {
1511 auto ts = *c_type_system_or_err;
1512 if (!ts)
1513 return {};
1514 CompilerType void_ptr_type =
1516 .GetPointerType();
1517 return ValueObjectMemory::Create(this, "", addr, void_ptr_type);
1518 }
1519 } else {
1520 return ValueObjectSP();
1521 }
1522 break;
1523 }
1525 return GuessValueForRegisterAndOffset(base_and_offset.first->m_register,
1526 base_and_offset.second);
1527 }
1528 default:
1529 return ValueObjectSP();
1530 }
1531 }
1532
1533 return ValueObjectSP();
1534}
1535
1536namespace {
1537ValueObjectSP GetValueForOffset(StackFrame &frame, ValueObjectSP &parent,
1538 int64_t offset) {
1539 if (offset < 0 ||
1540 uint64_t(offset) >=
1541 llvm::expectedToOptional(parent->GetByteSize()).value_or(0)) {
1542 return ValueObjectSP();
1543 }
1544
1545 if (parent->IsPointerOrReferenceType()) {
1546 return parent;
1547 }
1548
1549 for (int ci = 0, ce = parent->GetNumChildrenIgnoringErrors(); ci != ce;
1550 ++ci) {
1551 ValueObjectSP child_sp = parent->GetChildAtIndex(ci);
1552
1553 if (!child_sp) {
1554 return ValueObjectSP();
1555 }
1556
1557 int64_t child_offset = child_sp->GetByteOffset();
1558 int64_t child_size =
1559 llvm::expectedToOptional(child_sp->GetByteSize()).value_or(0);
1560
1561 if (offset >= child_offset && offset < (child_offset + child_size)) {
1562 return GetValueForOffset(frame, child_sp, offset - child_offset);
1563 }
1564 }
1565
1566 if (offset == 0) {
1567 return parent;
1568 } else {
1569 return ValueObjectSP();
1570 }
1571}
1572
1573ValueObjectSP GetValueForDereferincingOffset(StackFrame &frame,
1574 ValueObjectSP &base,
1575 int64_t offset) {
1576 // base is a pointer to something
1577 // offset is the thing to add to the pointer We return the most sensible
1578 // ValueObject for the result of *(base+offset)
1579
1580 if (!base->IsPointerOrReferenceType()) {
1581 return ValueObjectSP();
1582 }
1583
1584 Status error;
1585 ValueObjectSP pointee = base->Dereference(error);
1586
1587 if (!pointee) {
1588 return ValueObjectSP();
1589 }
1590
1591 if (offset >= 0 &&
1592 uint64_t(offset) >=
1593 llvm::expectedToOptional(pointee->GetByteSize()).value_or(0)) {
1594 uint64_t size =
1595 llvm::expectedToOptional(pointee->GetByteSize()).value_or(1);
1596 int64_t index = offset / size;
1597 offset = offset % size;
1598 const bool can_create = true;
1599 pointee = base->GetSyntheticArrayMember(index, can_create);
1600 }
1601
1602 if (!pointee || error.Fail()) {
1603 return ValueObjectSP();
1604 }
1605
1606 return GetValueForOffset(frame, pointee, offset);
1607}
1608
1609/// Attempt to reconstruct the ValueObject for the address contained in a
1610/// given register plus an offset.
1611///
1612/// \param [in] frame
1613/// The current stack frame.
1614///
1615/// \param [in] reg
1616/// The register.
1617///
1618/// \param [in] offset
1619/// The offset from the register.
1620///
1621/// \param [in] disassembler
1622/// A disassembler containing instructions valid up to the current PC.
1623///
1624/// \param [in] variables
1625/// The variable list from the current frame,
1626///
1627/// \param [in] pc
1628/// The program counter for the instruction considered the 'user'.
1629///
1630/// \return
1631/// A string describing the base for the ExpressionPath. This could be a
1632/// variable, a register value, an argument, or a function return value.
1633/// The ValueObject if found. If valid, it has a valid ExpressionPath.
1634lldb::ValueObjectSP DoGuessValueAt(StackFrame &frame, ConstString reg,
1635 int64_t offset, Disassembler &disassembler,
1636 VariableList &variables, const Address &pc) {
1637 // Example of operation for Intel:
1638 //
1639 // +14: movq -0x8(%rbp), %rdi
1640 // +18: movq 0x8(%rdi), %rdi
1641 // +22: addl 0x4(%rdi), %eax
1642 //
1643 // f, a pointer to a struct, is known to be at -0x8(%rbp).
1644 //
1645 // DoGuessValueAt(frame, rdi, 4, dis, vars, 0x22) finds the instruction at
1646 // +18 that assigns to rdi, and calls itself recursively for that dereference
1647 // DoGuessValueAt(frame, rdi, 8, dis, vars, 0x18) finds the instruction at
1648 // +14 that assigns to rdi, and calls itself recursively for that
1649 // dereference
1650 // DoGuessValueAt(frame, rbp, -8, dis, vars, 0x14) finds "f" in the
1651 // variable list.
1652 // Returns a ValueObject for f. (That's what was stored at rbp-8 at +14)
1653 // Returns a ValueObject for *(f+8) or f->b (That's what was stored at rdi+8
1654 // at +18)
1655 // Returns a ValueObject for *(f->b+4) or f->b->a (That's what was stored at
1656 // rdi+4 at +22)
1657
1658 // First, check the variable list to see if anything is at the specified
1659 // location.
1660
1661 using namespace OperandMatchers;
1662
1663 const RegisterInfo *reg_info =
1664 frame.GetRegisterContext()->GetRegisterInfoByName(reg.AsCString());
1665 if (!reg_info) {
1666 return ValueObjectSP();
1667 }
1668
1674 : Instruction::Operand::BuildDereference(
1675 Instruction::Operand::BuildRegister(reg));
1676
1677 for (VariableSP var_sp : variables) {
1678 if (var_sp->LocationExpressionList().MatchesOperand(frame, op))
1680 }
1681
1682 const uint32_t current_inst =
1683 disassembler.GetInstructionList().GetIndexOfInstructionAtAddress(pc);
1684 if (current_inst == UINT32_MAX) {
1685 return ValueObjectSP();
1686 }
1687
1688 for (uint32_t ii = current_inst - 1; ii != (uint32_t)-1; --ii) {
1689 // This is not an exact algorithm, and it sacrifices accuracy for
1690 // generality. Recognizing "mov" and "ld" instructions –– and which
1691 // are their source and destination operands -- is something the
1692 // disassembler should do for us.
1693 InstructionSP instruction_sp =
1694 disassembler.GetInstructionList().GetInstructionAtIndex(ii);
1695
1696 if (instruction_sp->IsCall()) {
1697 ABISP abi_sp = frame.CalculateProcess()->GetABI();
1698 if (!abi_sp) {
1699 continue;
1700 }
1701
1702 const char *return_register_name;
1703 if (!abi_sp->GetPointerReturnRegister(return_register_name)) {
1704 continue;
1705 }
1706
1707 const RegisterInfo *return_register_info =
1708 frame.GetRegisterContext()->GetRegisterInfoByName(
1709 return_register_name);
1710 if (!return_register_info) {
1711 continue;
1712 }
1713
1714 int64_t offset = 0;
1715
1717 MatchRegOp(*return_register_info))(op) &&
1718 !MatchUnaryOp(
1721 MatchRegOp(*return_register_info),
1722 FetchImmOp(offset)))(op)) {
1723 continue;
1724 }
1725
1726 llvm::SmallVector<Instruction::Operand, 1> operands;
1727 if (!instruction_sp->ParseOperands(operands) || operands.size() != 1) {
1728 continue;
1729 }
1730
1731 switch (operands[0].m_type) {
1732 default:
1733 break;
1735 SymbolContext sc;
1736 if (!pc.GetModule())
1737 break;
1738 Address address(operands[0].m_immediate,
1739 pc.GetModule()->GetSectionList());
1740 if (!address.IsValid())
1741 break;
1742 frame.CalculateTarget()->GetImages().ResolveSymbolContextForAddress(
1743 address, eSymbolContextFunction, sc);
1744 if (!sc.function) {
1745 break;
1746 }
1747 CompilerType function_type = sc.function->GetCompilerType();
1748 if (!function_type.IsFunctionType()) {
1749 break;
1750 }
1751 CompilerType return_type = function_type.GetFunctionReturnType();
1752 RegisterValue return_value;
1753 if (!frame.GetRegisterContext()->ReadRegister(return_register_info,
1754 return_value)) {
1755 break;
1756 }
1757 std::string name_str(
1758 sc.function->GetName().AsCString("<unknown function>"));
1759 name_str.append("()");
1760 Address return_value_address(return_value.GetAsUInt64());
1761 ValueObjectSP return_value_sp = ValueObjectMemory::Create(
1762 &frame, name_str, return_value_address, return_type);
1763 return GetValueForDereferincingOffset(frame, return_value_sp, offset);
1764 }
1765 }
1766
1767 continue;
1768 }
1769
1770 llvm::SmallVector<Instruction::Operand, 2> operands;
1771 if (!instruction_sp->ParseOperands(operands) || operands.size() != 2) {
1772 continue;
1773 }
1774
1775 Instruction::Operand *origin_operand = nullptr;
1776 auto clobbered_reg_matcher = [reg_info](const Instruction::Operand &op) {
1777 return MatchRegOp(*reg_info)(op) && op.m_clobbered;
1778 };
1779
1780 if (clobbered_reg_matcher(operands[0])) {
1781 origin_operand = &operands[1];
1782 } else if (clobbered_reg_matcher(operands[1])) {
1783 origin_operand = &operands[0];
1784 } else {
1785 continue;
1786 }
1787
1788 // We have an origin operand. Can we track its value down?
1789 ValueObjectSP source_path;
1790 ConstString origin_register;
1791 int64_t origin_offset = 0;
1792
1793 if (FetchRegOp(origin_register)(*origin_operand)) {
1794 source_path = DoGuessValueAt(frame, origin_register, 0, disassembler,
1795 variables, instruction_sp->GetAddress());
1796 } else if (MatchUnaryOp(
1798 FetchRegOp(origin_register))(*origin_operand) ||
1802 FetchRegOp(origin_register),
1803 FetchImmOp(origin_offset)))(*origin_operand)) {
1804 source_path =
1805 DoGuessValueAt(frame, origin_register, origin_offset, disassembler,
1806 variables, instruction_sp->GetAddress());
1807 if (!source_path) {
1808 continue;
1809 }
1810 source_path = GetValueForDereferincingOffset(frame, source_path, offset);
1811 }
1812
1813 if (source_path) {
1814 return source_path;
1815 }
1816 }
1817
1818 return ValueObjectSP();
1819}
1820} // namespace
1821
1823 int64_t offset) {
1824 TargetSP target_sp = CalculateTarget();
1825
1826 const ArchSpec &target_arch = target_sp->GetArchitecture();
1827
1828 Block *frame_block = GetFrameBlock();
1829
1830 if (!frame_block) {
1831 return ValueObjectSP();
1832 }
1833
1834 Function *function = frame_block->CalculateSymbolContextFunction();
1835 if (!function) {
1836 return ValueObjectSP();
1837 }
1838
1839 AddressRange unused_range;
1840 if (!function->GetRangeContainingLoadAddress(
1841 GetFrameCodeAddress().GetLoadAddress(target_sp.get()), *target_sp,
1842 unused_range))
1843 return ValueObjectSP();
1844
1845 const char *plugin_name = nullptr;
1846 const char *flavor = nullptr;
1847 const char *cpu = nullptr;
1848 const char *features = nullptr;
1849 const bool force_live_memory = true;
1851 target_arch, plugin_name, flavor, cpu, features, *target_sp,
1852 function->GetAddressRanges(), force_live_memory);
1853
1854 if (!disassembler_sp || !disassembler_sp->GetInstructionList().GetSize()) {
1855 return ValueObjectSP();
1856 }
1857
1858 const bool get_file_globals = false;
1859 VariableList *variables = GetVariableList(get_file_globals, nullptr);
1860
1861 if (!variables) {
1862 return ValueObjectSP();
1863 }
1864
1865 return DoGuessValueAt(*this, reg, offset, *disassembler_sp, *variables,
1867}
1868
1870 ValueObjectSP value_sp;
1871
1872 if (!name)
1873 return value_sp;
1874
1875 TargetSP target_sp = CalculateTarget();
1876 ProcessSP process_sp = CalculateProcess();
1877
1878 if (!target_sp && !process_sp)
1879 return value_sp;
1880
1881 VariableList variable_list;
1882 VariableSP var_sp;
1883 SymbolContext sc(GetSymbolContext(eSymbolContextBlock));
1884
1885 if (sc.block) {
1886 const bool can_create = true;
1887 const bool get_parent_variables = true;
1888 const bool stop_if_block_is_inlined_function = true;
1889
1890 if (sc.block->AppendVariables(
1891 can_create, get_parent_variables, stop_if_block_is_inlined_function,
1892 [this](Variable *v) { return v->IsInScope(this); },
1893 &variable_list)) {
1894 var_sp = variable_list.FindVariable(name);
1895 }
1896
1897 if (var_sp)
1899 }
1900
1901 return value_sp;
1902}
1903
1905 TargetSP target_sp;
1906 ThreadSP thread_sp(GetThread());
1907 if (thread_sp) {
1908 ProcessSP process_sp(thread_sp->CalculateProcess());
1909 if (process_sp)
1910 target_sp = process_sp->CalculateTarget();
1911 }
1912 return target_sp;
1913}
1914
1916 ProcessSP process_sp;
1917 ThreadSP thread_sp(GetThread());
1918 if (thread_sp)
1919 process_sp = thread_sp->CalculateProcess();
1920 return process_sp;
1921}
1922
1924
1925StackFrameSP StackFrame::CalculateStackFrame() { return shared_from_this(); }
1926
1928 exe_ctx.SetContext(shared_from_this());
1929}
1930
1932 const FormatEntity::Entry *format,
1933 llvm::StringRef frame_marker) {
1934 GetSymbolContext(eSymbolContextEverything);
1935 ExecutionContext exe_ctx(shared_from_this());
1936 StreamString s;
1937 s.PutCString(frame_marker);
1938
1939 if (format && FormatEntity::Format(*format, s, &m_sc, &exe_ctx, nullptr,
1940 nullptr, false, false)) {
1941 strm.PutCString(s.GetString());
1942 return true;
1943 }
1944 return false;
1945}
1946
1947void StackFrame::DumpUsingSettingsFormat(Stream *strm, bool show_unique,
1948 const char *frame_marker) {
1949 if (strm == nullptr)
1950 return;
1951
1952 ExecutionContext exe_ctx(shared_from_this());
1953
1954 const FormatEntity::Entry *frame_format = nullptr;
1955 FormatEntity::Entry format_entry;
1956 Target *target = exe_ctx.GetTargetPtr();
1957 if (target) {
1958 if (show_unique) {
1959 format_entry = target->GetDebugger().GetFrameFormatUnique();
1960 frame_format = &format_entry;
1961 } else {
1962 format_entry = target->GetDebugger().GetFrameFormat();
1963 frame_format = &format_entry;
1964 }
1965 }
1966 if (!DumpUsingFormat(*strm, frame_format, frame_marker)) {
1967 Dump(strm, true, false);
1968 strm->EOL();
1969 }
1970}
1971
1972void StackFrame::Dump(Stream *strm, bool show_frame_index,
1973 bool show_fullpaths) {
1974 if (strm == nullptr)
1975 return;
1976
1977 if (show_frame_index)
1978 strm->Printf("frame #%u: ", m_frame_index);
1979 ExecutionContext exe_ctx(shared_from_this());
1980 Target *target = exe_ctx.GetTargetPtr();
1981 strm->Printf("0x%0*" PRIx64 " ",
1982 target ? (target->GetArchitecture().GetAddressByteSize() * 2)
1983 : 16,
1984 GetFrameCodeAddress().GetLoadAddress(target));
1985 GetSymbolContext(eSymbolContextEverything);
1986 const bool show_module = true;
1987 const bool show_inline = true;
1988 const bool show_function_arguments = true;
1989 const bool show_function_name = true;
1990 m_sc.DumpStopContext(strm, exe_ctx.GetBestExecutionContextScope(),
1991 GetFrameCodeAddress(), show_fullpaths, show_module,
1992 show_inline, show_function_arguments,
1993 show_function_name);
1994}
1995
1997 std::lock_guard<std::recursive_mutex> guard(m_mutex);
1998 assert(GetStackID() ==
1999 prev_frame.GetStackID()); // TODO: remove this after some testing
2002 if (!m_disassembly.GetString().empty()) {
2003 m_disassembly.Clear();
2004 m_disassembly.PutCString(prev_frame.m_disassembly.GetString());
2005 }
2006}
2007
2009 std::lock_guard<std::recursive_mutex> guard(m_mutex);
2010 assert(GetStackID() ==
2011 curr_frame.GetStackID()); // TODO: remove this after some testing
2012 m_id.SetPC(
2013 curr_frame.m_id.GetPC(),
2014 curr_frame.CalculateProcess().get()); // Update the Stack ID PC value
2015 assert(GetThread() == curr_frame.GetThread());
2016 m_frame_index = curr_frame.m_frame_index;
2021 assert(!m_sc.target_sp || !curr_frame.m_sc.target_sp ||
2022 m_sc.target_sp.get() == curr_frame.m_sc.target_sp.get());
2023 assert(!m_sc.module_sp || !curr_frame.m_sc.module_sp ||
2024 m_sc.module_sp.get() == curr_frame.m_sc.module_sp.get());
2025 assert(m_sc.comp_unit == nullptr || curr_frame.m_sc.comp_unit == nullptr ||
2026 m_sc.comp_unit == curr_frame.m_sc.comp_unit);
2027 assert(m_sc.function == nullptr || curr_frame.m_sc.function == nullptr ||
2028 m_sc.function == curr_frame.m_sc.function);
2029 m_sc = curr_frame.m_sc;
2030 m_flags.Clear(GOT_FRAME_BASE | eSymbolContextEverything);
2031 m_flags.Set(m_sc.GetResolvedMask());
2032 m_frame_base.Clear();
2033 m_frame_base_error.Clear();
2034}
2035
2038 return true;
2039 if (m_variable_list_value_objects.GetSize() > 0)
2040 return true;
2041 if (!m_disassembly.GetString().empty())
2042 return true;
2043 return false;
2044}
2045
2046bool StackFrame::GetStatus(Stream &strm, bool show_frame_info, bool show_source,
2047 bool show_unique, const char *frame_marker) {
2048 if (show_frame_info) {
2049 strm.Indent();
2050 DumpUsingSettingsFormat(&strm, show_unique, frame_marker);
2051 }
2052
2053 if (show_source) {
2054 ExecutionContext exe_ctx(shared_from_this());
2055 bool have_source = false, have_debuginfo = false;
2057 Target *target = exe_ctx.GetTargetPtr();
2058 if (target) {
2059 Debugger &debugger = target->GetDebugger();
2060 const uint32_t source_lines_before =
2061 debugger.GetStopSourceLineCount(true);
2062 const uint32_t source_lines_after =
2063 debugger.GetStopSourceLineCount(false);
2064 disasm_display = debugger.GetStopDisassemblyDisplay();
2065
2066 GetSymbolContext(eSymbolContextCompUnit | eSymbolContextLineEntry);
2067 if (m_sc.comp_unit || m_sc.line_entry.IsValid()) {
2068 have_debuginfo = true;
2069 if (source_lines_before > 0 || source_lines_after > 0) {
2070 SupportFileNSP source_file_sp = m_sc.line_entry.file_sp;
2071 uint32_t start_line = m_sc.line_entry.line;
2072 if (!start_line && m_sc.function) {
2073 m_sc.function->GetStartLineSourceInfo(source_file_sp, start_line);
2074 }
2075
2076 size_t num_lines =
2078 source_file_sp, start_line, m_sc.line_entry.column,
2079 source_lines_before, source_lines_after, "->", &strm);
2080 if (num_lines != 0)
2081 have_source = true;
2082 // TODO: Give here a one time warning if source file is missing.
2083 if (!m_sc.line_entry.line)
2084 strm << "note: This address is not associated with a specific line "
2085 "of code. This may be due to compiler optimizations.\n";
2086 }
2087 }
2088 switch (disasm_display) {
2090 break;
2091
2093 if (have_debuginfo)
2094 break;
2095 [[fallthrough]];
2096
2098 if (have_source)
2099 break;
2100 [[fallthrough]];
2101
2103 if (target) {
2104 const uint32_t disasm_lines = debugger.GetDisassemblyLineCount();
2105 if (disasm_lines > 0) {
2106 const ArchSpec &target_arch = target->GetArchitecture();
2107 const char *plugin_name = nullptr;
2108 const char *flavor = nullptr;
2109 const bool mixed_source_and_assembly = false;
2111 target->GetDebugger(), target_arch, plugin_name, flavor,
2112 target->GetDisassemblyCPU(), target->GetDisassemblyFeatures(),
2113 exe_ctx, GetFrameCodeAddress(),
2114 {Disassembler::Limit::Instructions, disasm_lines},
2115 mixed_source_and_assembly, 0,
2117 }
2118 }
2119 break;
2120 }
2121 }
2122 }
2123 return true;
2124}
2125
2127 auto process = GetThread()->GetProcess();
2128 if (!process)
2129 return {};
2130 // If recognizer list has been modified, discard cache.
2131 auto &manager = process->GetTarget().GetFrameRecognizerManager();
2132 auto new_generation = manager.GetGeneration();
2133 if (m_frame_recognizer_generation != new_generation)
2134 m_recognized_frame_sp.reset();
2135 m_frame_recognizer_generation = new_generation;
2136 if (!m_recognized_frame_sp.has_value())
2137 m_recognized_frame_sp = manager.RecognizeFrame(CalculateStackFrame());
2138 return m_recognized_frame_sp.value();
2139}
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:31
uint32_t GetAddressByteSize() const
Returns the size in bytes of an address of the current architecture.
Definition ArchSpec.cpp:685
uint32_t GetMaximumOpcodeByteSize() const
Definition ArchSpec.cpp:931
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:80
uint64_t GetDisassemblyLineCount() const
Definition Debugger.cpp:638
FormatEntity::Entry GetFrameFormatUnique() const
Definition Debugger.cpp:312
uint64_t GetStopSourceLineCount(bool before) const
Definition Debugger.cpp:624
FormatEntity::Entry GetFrameFormat() const
Definition Debugger.cpp:307
lldb::StopDisassemblyType GetStopDisassemblyDisplay() const
Definition Debugger.cpp:631
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:571
bool GetRangeContainingLoadAddress(lldb::addr_t load_addr, Target &target, AddressRange &range)
Definition Function.h:455
ConstString GetName() const
Definition Function.cpp:708
const Mangled & GetMangled() const
Definition Function.h:534
AddressRanges GetAddressRanges()
Definition Function.h:448
ConstString GetDisplayName() const
Definition Function.cpp:532
A class that describes information for an inlined function.
Definition Function.h:126
ConstString GetDisplayName() const
Definition Function.cpp:102
ConstString GetName() const
Definition Function.cpp:96
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)
This base class provides an interface to stack frames.
Definition StackFrame.h:44
void SetSymbolContextScope(SymbolContextScope *symbol_scope)
uint16_t m_frame_recognizer_generation
Definition StackFrame.h:587
lldb::VariableListSP m_variable_list_sp
Definition StackFrame.h:601
void UpdatePreviousFrameFromCurrentFrame(StackFrame &curr_frame)
bool m_artificial
Is this an artificial stack frame (e.g.
Definition StackFrame.h:594
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:582
@ 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:604
bool m_cfa_is_valid
Does this frame have a CFA? Different from CFA == LLDB_INVALID_ADDRESS.
Definition StackFrame.h:589
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:573
std::optional< lldb::RecognizedStackFrameSP > m_recognized_frame_sp
Definition StackFrame.h:605
virtual void DumpUsingSettingsFormat(Stream *strm, bool show_unique=false, const char *frame_marker=nullptr)
Print a description for this frame using the frame-format formatter settings.
virtual bool IsInlined()
Query whether this frame is a concrete frame on the call stack, or if it is an inlined frame derived ...
virtual lldb::ValueObjectSP GetValueForVariableExpressionPath(llvm::StringRef var_expr, lldb::DynamicValueType use_dynamic, uint32_t options, lldb::VariableSP &var_sp, Status &error)
Create a ValueObject for a variable name / pathname, possibly including simple dereference/child sele...
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:576
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
lldb::ValueObjectSP DILGetValueForVariableExpressionPath(llvm::StringRef var_expr, lldb::DynamicValueType use_dynamic, uint32_t options, lldb::VariableSP &var_sp, Status &error)
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:600
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 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:606
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 bool GetStatus(Stream &strm, bool show_frame_info, bool show_source, bool show_unique=false, const char *frame_marker=nullptr)
Print a description of this stack frame and/or the source context/assembly for this stack frame.
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:607
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:294
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:137
bool Success() const
Test for success condition.
Definition Status.cpp:304
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:4685
const char * GetDisassemblyCPU() const
Definition Target.cpp:4678
bool GetUseDIL(ExecutionContext *exe_ctx) const
Definition Target.cpp:4546
SourceManager & GetSourceManager()
Definition Target.cpp:3043
Debugger & GetDebugger() const
Definition Target.h:1194
const ArchSpec & GetArchitecture() const
Definition Target.h:1153
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:274
bool LocationIsValidForFrame(StackFrame *frame)
Definition Variable.cpp:216
static llvm::Expected< DILLexer > Create(llvm::StringRef expr)
Lexes all the tokens in expr and calls the private constructor with the lexed tokens.
Definition DILLexer.cpp:112
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:48
llvm::Expected< lldb::ValueObjectSP > Evaluate(const ASTNode *node)
Definition DILEval.cpp:242
#define LLDB_INVALID_ADDRESS
#define UINT32_MAX
bool Format(const Entry &entry, Stream &s, const SymbolContext *sc, const ExecutionContext *exe_ctx, const Address *addr, ValueObject *valobj, bool function_changed, bool initial_function)
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
@ 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
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:618