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