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