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