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