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