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.Slide(-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 bool include_synthetic_vars,
443 Status *error_ptr) {
444 // We don't have 'synthetic variables' in the base stack frame.
445 (void)include_synthetic_vars;
446
447 std::lock_guard<std::recursive_mutex> guard(m_mutex);
448 if (m_flags.IsClear(RESOLVED_VARIABLES)) {
450 m_variable_list_sp = std::make_shared<VariableList>();
451
452 Block *frame_block = GetFrameBlock();
453
454 if (frame_block) {
455 const bool get_child_variables = true;
456 const bool can_create = true;
457 const bool stop_if_child_block_is_inlined_function = true;
458 frame_block->AppendBlockVariables(
459 can_create, get_child_variables,
460 stop_if_child_block_is_inlined_function,
461 [](Variable *v) { return true; }, m_variable_list_sp.get());
462 }
463 }
464
465 if (m_flags.IsClear(RESOLVED_GLOBAL_VARIABLES) && get_file_globals) {
467
468 if (m_flags.IsClear(eSymbolContextCompUnit))
469 GetSymbolContext(eSymbolContextCompUnit);
470
471 if (m_sc.comp_unit) {
472 VariableListSP global_variable_list_sp(
473 m_sc.comp_unit->GetVariableList(true));
475 m_variable_list_sp->AddVariables(global_variable_list_sp.get());
476 else
477 m_variable_list_sp = global_variable_list_sp;
478 }
479 }
480
481 if (error_ptr && m_variable_list_sp->GetSize() == 0) {
482 // Check with the symbol file to check if there is an error for why we
483 // don't have variables that the user might need to know about.
484 GetSymbolContext(eSymbolContextEverything);
485 if (m_sc.module_sp) {
486 SymbolFile *sym_file = m_sc.module_sp->GetSymbolFile();
487 if (sym_file)
488 *error_ptr = sym_file->GetFrameVariableError(*this);
489 }
490 }
491
492 return m_variable_list_sp.get();
493}
494
497 bool include_synthetic_vars,
498 bool must_have_valid_location) {
499 // We don't have synthetic variables in the base stack frame.
500 (void)include_synthetic_vars;
501
502 std::lock_guard<std::recursive_mutex> guard(m_mutex);
503 // We can't fetch variable information for a history stack frame.
504 if (IsHistorical())
505 return VariableListSP();
506
507 VariableListSP var_list_sp(new VariableList);
508 GetSymbolContext(eSymbolContextCompUnit | eSymbolContextBlock);
509
510 if (m_sc.block) {
511 const bool can_create = true;
512 const bool get_parent_variables = true;
513 const bool stop_if_block_is_inlined_function = true;
514 m_sc.block->AppendVariables(
515 can_create, get_parent_variables, stop_if_block_is_inlined_function,
516 [this, must_have_valid_location](Variable *v) {
517 return v->IsInScope(this) && (!must_have_valid_location ||
518 v->LocationIsValidForFrame(this));
519 },
520 var_list_sp.get());
521 }
522
523 if (m_sc.comp_unit && get_file_globals) {
524 VariableListSP global_variable_list_sp(
525 m_sc.comp_unit->GetVariableList(true));
526 if (global_variable_list_sp)
527 var_list_sp->AddVariables(global_variable_list_sp.get());
528 }
529
530 return var_list_sp;
531}
532
534 llvm::StringRef var_expr, DynamicValueType use_dynamic, uint32_t options,
535 VariableSP &var_sp, Status &error, lldb::DILMode mode) {
536 ExecutionContext exe_ctx;
538 bool use_DIL = exe_ctx.GetTargetRef().GetUseDIL(&exe_ctx);
539 if (use_DIL)
540 return DILGetValueForVariableExpressionPath(var_expr, use_dynamic, options,
541 var_sp, error, mode);
542
543 return LegacyGetValueForVariableExpressionPath(var_expr, use_dynamic, options,
544 var_sp, error);
545}
546
548 llvm::StringRef var_expr, lldb::DynamicValueType use_dynamic,
549 uint32_t options, lldb::VariableSP &var_sp, Status &error,
550 lldb::DILMode mode) {
551
552 // Lex the expression.
553 auto lex_or_err = dil::DILLexer::Create(var_expr, mode);
554 if (!lex_or_err) {
555 error = Status::FromError(lex_or_err.takeError());
556 return ValueObjectConstResult::Create(nullptr, error.Clone());
557 }
558
559 // Parse the expression.
560 auto tree_or_error = dil::DILParser::Parse(
561 var_expr, std::move(*lex_or_err), shared_from_this(), use_dynamic, mode);
562 if (!tree_or_error) {
563 error = Status::FromError(tree_or_error.takeError());
564 return ValueObjectConstResult::Create(nullptr, error.Clone());
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, options);
571
572 auto valobj_or_error = interpreter.Evaluate(**tree_or_error);
573 if (!valobj_or_error) {
574 error = Status::FromError(valobj_or_error.takeError());
575 return ValueObjectConstResult::Create(nullptr, error.Clone());
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->GetScalar();
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(
1239 /*get_file_globals=*/true, /*include_synthetic_vars=*/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(nullptr);
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(nullptr);
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 = register_context.GetRegisterInfoByName(
1423 operand.m_register.AsCString(nullptr));
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(nullptr));
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 // Keep this as 'false' here because if we're inspecting a register, it's
1861 // HIGHLY unlikely that we have an synthetic variable. Indeed, since we're not
1862 // in a synthetic frame, it's probably actually impossible here.
1863 const bool include_synthetic_vars = false;
1864 VariableList *variables =
1865 GetVariableList(get_file_globals, include_synthetic_vars, nullptr);
1866
1867 if (!variables) {
1868 return ValueObjectSP();
1869 }
1870
1871 return DoGuessValueAt(*this, reg, offset, *disassembler_sp, *variables,
1873}
1874
1876 ValueObjectSP value_sp;
1877
1878 if (!name)
1879 return value_sp;
1880
1881 TargetSP target_sp = CalculateTarget();
1882 ProcessSP process_sp = CalculateProcess();
1883
1884 if (!target_sp && !process_sp)
1885 return value_sp;
1886
1887 VariableList variable_list;
1888 VariableSP var_sp;
1889 SymbolContext sc(GetSymbolContext(eSymbolContextBlock));
1890
1891 if (sc.block) {
1892 const bool can_create = true;
1893 const bool get_parent_variables = true;
1894 const bool stop_if_block_is_inlined_function = true;
1895
1896 if (sc.block->AppendVariables(
1897 can_create, get_parent_variables, stop_if_block_is_inlined_function,
1898 [this](Variable *v) { return v->IsInScope(this); },
1899 &variable_list)) {
1900 var_sp = variable_list.FindVariable(name);
1901 }
1902
1903 if (var_sp)
1905 }
1906
1907 return value_sp;
1908}
1909
1911 TargetSP target_sp;
1912 ThreadSP thread_sp(GetThread());
1913 if (thread_sp) {
1914 ProcessSP process_sp(thread_sp->CalculateProcess());
1915 if (process_sp)
1916 target_sp = process_sp->CalculateTarget();
1917 }
1918 return target_sp;
1919}
1920
1922 ProcessSP process_sp;
1923 ThreadSP thread_sp(GetThread());
1924 if (thread_sp)
1925 process_sp = thread_sp->CalculateProcess();
1926 return process_sp;
1927}
1928
1930
1931StackFrameSP StackFrame::CalculateStackFrame() { return shared_from_this(); }
1932
1934 exe_ctx.SetContext(shared_from_this());
1935}
1936
1938 const FormatEntity::Entry *format,
1939 llvm::StringRef frame_marker) {
1940 GetSymbolContext(eSymbolContextEverything);
1941 ExecutionContext exe_ctx(shared_from_this());
1942 StreamString s;
1943 s.PutCString(frame_marker);
1944
1945 if (format && FormatEntity::Formatter(&m_sc, &exe_ctx, nullptr, false, false)
1946 .Format(*format, s)) {
1947 strm.PutCString(s.GetString());
1948 return true;
1949 }
1950 return false;
1951}
1952
1953void StackFrame::DumpUsingSettingsFormat(Stream *strm, bool show_unique,
1954 const llvm::StringRef frame_marker) {
1955 if (strm == nullptr)
1956 return;
1957
1958 ExecutionContext exe_ctx(shared_from_this());
1959
1960 const FormatEntity::Entry *frame_format = nullptr;
1961 FormatEntity::Entry format_entry;
1962 Target *target = exe_ctx.GetTargetPtr();
1963 if (target) {
1964 if (show_unique) {
1965 format_entry = target->GetDebugger().GetFrameFormatUnique();
1966 frame_format = &format_entry;
1967 } else {
1968 format_entry = target->GetDebugger().GetFrameFormat();
1969 frame_format = &format_entry;
1970 }
1971 }
1972 if (!DumpUsingFormat(*strm, frame_format, frame_marker)) {
1973 Dump(strm, true, false);
1974 strm->EOL();
1975 }
1976}
1977
1978void StackFrame::Dump(Stream *strm, bool show_frame_index,
1979 bool show_fullpaths) {
1980 if (strm == nullptr)
1981 return;
1982
1983 if (show_frame_index)
1984 strm->Printf("frame #%u: ", m_frame_index);
1985 ExecutionContext exe_ctx(shared_from_this());
1986 Target *target = exe_ctx.GetTargetPtr();
1987 strm->Printf("0x%0*" PRIx64 " ",
1988 target ? (target->GetArchitecture().GetAddressByteSize() * 2)
1989 : 16,
1990 GetFrameCodeAddress().GetLoadAddress(target));
1991 GetSymbolContext(eSymbolContextEverything);
1992 const bool show_module = true;
1993 const bool show_inline = true;
1994 const bool show_function_arguments = true;
1995 const bool show_function_name = true;
1996 m_sc.DumpStopContext(strm, exe_ctx.GetBestExecutionContextScope(),
1997 GetFrameCodeAddress(), show_fullpaths, show_module,
1998 show_inline, show_function_arguments,
1999 show_function_name);
2000}
2001
2003 std::lock_guard<std::recursive_mutex> guard(m_mutex);
2004 assert(GetStackID() ==
2005 prev_frame.GetStackID()); // TODO: remove this after some testing
2008 if (!m_disassembly.GetString().empty()) {
2009 m_disassembly.Clear();
2010 m_disassembly.PutCString(prev_frame.m_disassembly.GetString());
2011 }
2012}
2013
2015 std::lock_guard<std::recursive_mutex> guard(m_mutex);
2016 assert(GetStackID() ==
2017 curr_frame.GetStackID()); // TODO: remove this after some testing
2018 m_id.SetPC(
2019 curr_frame.m_id.GetPC(),
2020 curr_frame.CalculateProcess().get()); // Update the Stack ID PC value
2021 assert(GetThread() == curr_frame.GetThread());
2022 m_frame_index = curr_frame.m_frame_index;
2027 assert(!m_sc.target_sp || !curr_frame.m_sc.target_sp ||
2028 m_sc.target_sp.get() == curr_frame.m_sc.target_sp.get());
2029 assert(!m_sc.module_sp || !curr_frame.m_sc.module_sp ||
2030 m_sc.module_sp.get() == curr_frame.m_sc.module_sp.get());
2031 assert(m_sc.comp_unit == nullptr || curr_frame.m_sc.comp_unit == nullptr ||
2032 m_sc.comp_unit == curr_frame.m_sc.comp_unit);
2033 assert(m_sc.function == nullptr || curr_frame.m_sc.function == nullptr ||
2034 m_sc.function == curr_frame.m_sc.function);
2035 m_sc = curr_frame.m_sc;
2036 m_flags.Clear(GOT_FRAME_BASE | eSymbolContextEverything);
2037 m_flags.Set(m_sc.GetResolvedMask());
2038 m_frame_base.Clear();
2039 m_frame_base_error.Clear();
2040}
2041
2044 return true;
2045 if (m_variable_list_value_objects.GetSize() > 0)
2046 return true;
2047 if (!m_disassembly.GetString().empty())
2048 return true;
2049 return false;
2050}
2051
2052bool StackFrame::GetStatus(Stream &strm, bool show_frame_info, bool show_source,
2053 bool show_unique,
2054 const llvm::StringRef frame_marker) {
2055 if (show_frame_info) {
2056 strm.Indent();
2057 DumpUsingSettingsFormat(&strm, show_unique, frame_marker);
2058 }
2059
2060 if (show_source) {
2061 ExecutionContext exe_ctx(shared_from_this());
2062 bool have_source = false, have_debuginfo = false;
2064 Target *target = exe_ctx.GetTargetPtr();
2065 if (target) {
2066 Debugger &debugger = target->GetDebugger();
2067 const uint32_t source_lines_before =
2068 debugger.GetStopSourceLineCount(true);
2069 const uint32_t source_lines_after =
2070 debugger.GetStopSourceLineCount(false);
2071 disasm_display = debugger.GetStopDisassemblyDisplay();
2072
2073 GetSymbolContext(eSymbolContextCompUnit | eSymbolContextLineEntry);
2074 if (m_sc.comp_unit || m_sc.line_entry.IsValid()) {
2075 have_debuginfo = true;
2076 if (source_lines_before > 0 || source_lines_after > 0) {
2077 SupportFileNSP source_file_sp = m_sc.line_entry.file_sp;
2078 uint32_t start_line = m_sc.line_entry.line;
2079 if (!start_line && m_sc.function) {
2080 m_sc.function->GetStartLineSourceInfo(source_file_sp, start_line);
2081 }
2082
2083 size_t num_lines =
2085 source_file_sp, start_line, m_sc.line_entry.column,
2086 source_lines_before, source_lines_after, "->", &strm,
2087 /*bp_locs=*/nullptr, GetLanguage().AsLanguageType());
2088 if (num_lines != 0)
2089 have_source = true;
2090 // TODO: Give here a one time warning if source file is missing.
2091 if (!m_sc.line_entry.line)
2092 strm << "note: This address is not associated with a specific line "
2093 "of code. This may be due to compiler optimizations.\n";
2094 }
2095 }
2096 switch (disasm_display) {
2098 break;
2099
2101 if (have_debuginfo)
2102 break;
2103 [[fallthrough]];
2104
2106 if (have_source)
2107 break;
2108 [[fallthrough]];
2109
2111 if (target) {
2112 const uint32_t disasm_lines = debugger.GetDisassemblyLineCount();
2113 if (disasm_lines > 0) {
2114 const ArchSpec &target_arch = target->GetArchitecture();
2115 const char *plugin_name = nullptr;
2116 const char *flavor = nullptr;
2117 const bool mixed_source_and_assembly = false;
2119 target->GetDebugger(), target_arch, plugin_name, flavor,
2120 target->GetDisassemblyCPU(), target->GetDisassemblyFeatures(),
2121 exe_ctx, GetFrameCodeAddress(),
2122 {Disassembler::Limit::Instructions, disasm_lines},
2123 mixed_source_and_assembly, 0,
2125 }
2126 }
2127 break;
2128 }
2129 }
2130 }
2131 return true;
2132}
2133
2135 auto process = GetThread()->GetProcess();
2136 if (!process)
2137 return {};
2138 // If recognizer list has been modified, discard cache.
2139 auto &manager = process->GetTarget().GetFrameRecognizerManager();
2140 auto new_generation = manager.GetGeneration();
2141 if (m_frame_recognizer_generation != new_generation)
2142 m_recognized_frame_sp.reset();
2143 m_frame_recognizer_generation = new_generation;
2144 if (!m_recognized_frame_sp.has_value())
2145 m_recognized_frame_sp = manager.RecognizeFrame(CalculateStackFrame());
2146 return m_recognized_frame_sp.value();
2147}
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOG_ERROR(log, error,...)
Definition Log.h:394
#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
bool Slide(int64_t offset)
Definition Address.h:452
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
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
size_t GetLength() const
Get the length in bytes of string value.
const char * GetCString() const
Get the string value as a C string.
const char * AsCString(const char *value_if_empty) 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:100
uint64_t GetDisassemblyLineCount() const
Definition Debugger.cpp:714
FormatEntity::Entry GetFrameFormatUnique() const
Definition Debugger.cpp:381
uint64_t GetStopSourceLineCount(bool before) const
Definition Debugger.cpp:700
FormatEntity::Entry GetFrameFormat() const
Definition Debugger.cpp:376
lldb::StopDisassemblyType GetStopDisassemblyDisplay() const
Definition Debugger.cpp:707
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:423
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:610
lldb::VariableListSP m_variable_list_sp
Definition StackFrame.h:625
void UpdatePreviousFrameFromCurrentFrame(StackFrame &curr_frame)
bool m_artificial
Is this an artificial stack frame (e.g.
Definition StackFrame.h:617
lldb::ThreadSP GetThread() const
Definition StackFrame.h:137
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:605
@ 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 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:627
bool m_cfa_is_valid
Does this frame have a CFA? Different from CFA == LLDB_INVALID_ADDRESS.
Definition StackFrame.h:612
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:596
std::optional< lldb::RecognizedStackFrameSP > m_recognized_frame_sp
Definition StackFrame.h:628
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:599
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 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:70
@ Regular
A regular stack frame with access to registers and local variables.
Definition StackFrame.h:66
@ Synthetic
An synthetic stack frame (e.g.
Definition StackFrame.h:74
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:623
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.
virtual VariableList * GetVariableList(bool get_file_globals, bool include_synthetic_vars, Status *error_ptr)
Retrieve the list of variables whose scope either:
StreamString m_disassembly
Definition StackFrame.h:629
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.
virtual lldb::VariableListSP GetInScopeVariableList(bool get_file_globals, bool include_synthetic_vars=true, bool must_have_valid_location=false)
Retrieve the list of variables that are in scope at this StackFrame's pc.
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:630
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:155
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition Stream.cpp:132
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
Definition Stream.cpp:63
size_t EOL()
Output and End of Line character to the stream.
Definition Stream.cpp:153
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:4726
const char * GetDisassemblyCPU() const
Definition Target.cpp:4719
bool GetUseDIL(ExecutionContext *exe_ctx) const
Definition Target.cpp:4587
SourceManager & GetSourceManager()
Definition Target.cpp:3039
Debugger & GetDebugger() const
Definition Target.h:1240
const ArchSpec & GetArchitecture() const
Definition Target.h:1199
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:143
static llvm::Expected< ASTNodeUP > Parse(llvm::StringRef dil_input_expr, DILLexer lexer, std::shared_ptr< StackFrame > frame_sp, lldb::DynamicValueType use_dynamic, lldb::DILMode mode)
Definition DILParser.cpp:93
llvm::Expected< lldb::ValueObjectSP > Evaluate(const ASTNode &node)
Evaluate an ASTNode.
Definition DILEval.cpp:395
#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:327
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