LLDB mainline
CommandObjectFrame.cpp
Go to the documentation of this file.
1//===-- CommandObjectFrame.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//===----------------------------------------------------------------------===//
12#include "lldb/Host/Config.h"
29#include "lldb/Target/Target.h"
30#include "lldb/Target/Thread.h"
31#include "lldb/Utility/Args.h"
35#include "llvm/ADT/StringExtras.h"
36#include "llvm/ADT/StringRef.h"
37
38#include <memory>
39#include <optional>
40#include <string>
41
42using namespace lldb;
43using namespace lldb_private;
44
45#pragma mark CommandObjectFrameDiagnose
46
47// CommandObjectFrameInfo
48
49// CommandObjectFrameDiagnose
50
51#define LLDB_OPTIONS_frame_diag
52#include "CommandOptions.inc"
53
55public:
56 class CommandOptions : public Options {
57 public:
59
60 ~CommandOptions() override = default;
61
62 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
63 ExecutionContext *execution_context) override {
65 const int short_option = m_getopt_table[option_idx].val;
66 switch (short_option) {
67 case 'r':
68 reg = ConstString(option_arg);
69 break;
70
71 case 'a': {
72 address.emplace();
73 if (option_arg.getAsInteger(0, *address)) {
74 address.reset();
76 "invalid address argument '%s'", option_arg.str().c_str());
77 }
78 } break;
79
80 case 'o': {
81 offset.emplace();
82 if (option_arg.getAsInteger(0, *offset)) {
83 offset.reset();
85 "invalid offset argument '%s'", option_arg.str().c_str());
86 }
87 } break;
88
89 default:
90 llvm_unreachable("Unimplemented option");
91 }
92
93 return error;
94 }
95
96 void OptionParsingStarting(ExecutionContext *execution_context) override {
97 address.reset();
98 reg.reset();
99 offset.reset();
100 }
101
102 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
103 return llvm::ArrayRef(g_frame_diag_options);
104 }
105
106 // Options.
107 std::optional<lldb::addr_t> address;
108 std::optional<ConstString> reg;
109 std::optional<int64_t> offset;
110 };
111
113 : CommandObjectParsed(interpreter, "frame diagnose",
114 "Try to determine what path the current stop "
115 "location used to get to a register or address",
116 nullptr,
117 eCommandRequiresThread | eCommandTryTargetAPILock |
118 eCommandProcessMustBeLaunched |
119 eCommandProcessMustBePaused) {
121 }
122
123 ~CommandObjectFrameDiagnose() override = default;
124
125 Options *GetOptions() override { return &m_options; }
126
127protected:
128 void DoExecute(Args &command, CommandReturnObject &result) override {
129 Thread *thread = m_exe_ctx.GetThreadPtr();
130 StackFrameSP frame_sp = thread->GetSelectedFrame(SelectMostRelevantFrame);
131
132 ValueObjectSP valobj_sp;
133
134 if (m_options.address) {
135 if (m_options.reg || m_options.offset) {
136 result.AppendError(
137 "`frame diagnose --address` is incompatible with other arguments.");
138 return;
139 }
140 valobj_sp = frame_sp->GuessValueForAddress(*m_options.address);
141 } else if (m_options.reg) {
142 valobj_sp = frame_sp->GuessValueForRegisterAndOffset(
143 *m_options.reg, m_options.offset.value_or(0));
144 } else {
145 StopInfoSP stop_info_sp = thread->GetStopInfo();
146 if (!stop_info_sp) {
147 result.AppendError("no arguments provided, and no stop info");
148 return;
149 }
150
151 valobj_sp = StopInfo::GetCrashingDereference(stop_info_sp);
152 }
153
154 if (!valobj_sp) {
155 result.AppendError("no diagnosis available");
156 return;
157 }
158
159 result.GetValueObjectList().Append(valobj_sp);
161 [&valobj_sp](ConstString type, ConstString var,
162 const DumpValueObjectOptions &opts,
163 Stream &stream) -> bool {
164 const ValueObject::GetExpressionPathFormat format = ValueObject::
165 GetExpressionPathFormat::eGetExpressionPathFormatHonorPointers;
166 valobj_sp->GetExpressionPath(stream, format);
167 stream.PutCString(" =");
168 return true;
169 };
170
172 options.SetDeclPrintingHelper(helper);
173 // We've already handled the case where the value object sp is null, so
174 // this is just to make sure future changes don't skip that:
175 assert(valobj_sp.get() && "Must have a valid ValueObject to print");
176 ValueObjectPrinter printer(*valobj_sp, &result.GetOutputStream(), options);
177 if (llvm::Error error = printer.PrintValueObject())
178 result.AppendError(toString(std::move(error)));
179 else
181 }
182
184};
185
186#pragma mark CommandObjectFrameInfo
187
188// CommandObjectFrameInfo
189
191public:
193 : CommandObjectParsed(interpreter, "frame info",
194 "List information about the current "
195 "stack frame in the current thread.",
196 "frame info",
197 eCommandRequiresFrame | eCommandTryTargetAPILock |
198 eCommandProcessMustBeLaunched |
199 eCommandProcessMustBePaused) {}
200
201 ~CommandObjectFrameInfo() override = default;
202
203protected:
204 void DoExecute(Args &command, CommandReturnObject &result) override {
205 m_exe_ctx.GetFrameRef().DumpUsingSettingsFormat(&result.GetOutputStream());
207 }
208};
209
210#pragma mark CommandObjectFrameSelect
211
212// CommandObjectFrameSelect
213
214#define LLDB_OPTIONS_frame_select
215#include "CommandOptions.inc"
216
218public:
219 class CommandOptions : public Options {
220 public:
222
223 ~CommandOptions() override = default;
224
225 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
226 ExecutionContext *execution_context) override {
228 const int short_option = m_getopt_table[option_idx].val;
229 switch (short_option) {
230 case 'r': {
231 int32_t offset = 0;
232 if (option_arg.getAsInteger(0, offset) || offset == INT32_MIN) {
234 "invalid frame offset argument '%s'", option_arg.str().c_str());
235 } else
236 relative_frame_offset = offset;
237 break;
238 }
239
240 default:
241 llvm_unreachable("Unimplemented option");
242 }
243
244 return error;
245 }
246
247 void OptionParsingStarting(ExecutionContext *execution_context) override {
248 relative_frame_offset.reset();
249 }
250
251 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
252 return llvm::ArrayRef(g_frame_select_options);
253 }
254
255 std::optional<int32_t> relative_frame_offset;
256 };
257
259 : CommandObjectParsed(interpreter, "frame select",
260 "Select the current stack frame by "
261 "index from within the current thread "
262 "(see 'thread backtrace'.)",
263 nullptr,
264 eCommandRequiresThread | eCommandTryTargetAPILock |
265 eCommandProcessMustBeLaunched |
266 eCommandProcessMustBePaused) {
268 }
269
270 ~CommandObjectFrameSelect() override = default;
271
272 Options *GetOptions() override { return &m_options; }
273
274private:
275 void SkipHiddenFrames(Thread &thread, uint32_t frame_idx) {
276 uint32_t candidate_idx = frame_idx;
277 const unsigned max_depth = 12;
278 for (unsigned num_try = 0; num_try < max_depth; ++num_try) {
279 if (candidate_idx == 0 && *m_options.relative_frame_offset == -1) {
280 candidate_idx = UINT32_MAX;
281 break;
282 }
283 candidate_idx += *m_options.relative_frame_offset;
284 if (auto candidate_sp = thread.GetStackFrameAtIndex(candidate_idx)) {
285 if (candidate_sp->IsHidden())
286 continue;
287 // Now candidate_idx is the first non-hidden frame.
288 break;
289 }
290 candidate_idx = UINT32_MAX;
291 break;
292 };
293 if (candidate_idx != UINT32_MAX)
294 m_options.relative_frame_offset = candidate_idx - frame_idx;
295 }
296
297protected:
298 void DoExecute(Args &command, CommandReturnObject &result) override {
299 // No need to check "thread" for validity as eCommandRequiresThread ensures
300 // it is valid
301 Thread *thread = m_exe_ctx.GetThreadPtr();
302
303 uint32_t frame_idx = UINT32_MAX;
304 if (m_options.relative_frame_offset) {
305 // The one and only argument is a signed relative frame index
306 frame_idx = thread->GetSelectedFrameIndex(SelectMostRelevantFrame);
307 if (frame_idx == UINT32_MAX)
308 frame_idx = 0;
309
310 // If moving up/down by one, skip over hidden frames, unless we started
311 // in a hidden frame.
312 if ((*m_options.relative_frame_offset == 1 ||
313 *m_options.relative_frame_offset == -1)) {
314 if (auto current_frame_sp = thread->GetStackFrameAtIndex(frame_idx);
315 !current_frame_sp->IsHidden())
316 SkipHiddenFrames(*thread, frame_idx);
317 }
318
319 if (*m_options.relative_frame_offset < 0) {
320 if (static_cast<int32_t>(frame_idx) >=
321 -*m_options.relative_frame_offset)
322 frame_idx += *m_options.relative_frame_offset;
323 else {
324 if (frame_idx == 0) {
325 // If you are already at the bottom of the stack, then just warn
326 // and don't reset the frame.
327 result.AppendError("already at the bottom of the stack");
328 return;
329 } else
330 frame_idx = 0;
331 }
332 } else if (*m_options.relative_frame_offset > 0) {
333 // I don't want "up 20" where "20" takes you past the top of the stack
334 // to produce an error, but rather to just go to the top. OTOH, start
335 // by seeing if the requested frame exists, in which case we can avoid
336 // counting the stack here...
337 const uint32_t frame_requested =
338 frame_idx + *m_options.relative_frame_offset;
339 StackFrameSP frame_sp = thread->GetStackFrameAtIndex(frame_requested);
340 if (frame_sp)
341 frame_idx = frame_requested;
342 else {
343 // The request went past the stack, so handle that case:
344 const uint32_t num_frames = thread->GetStackFrameCount();
345 if (static_cast<int32_t>(num_frames - frame_idx) >
346 *m_options.relative_frame_offset) {
347 frame_idx += *m_options.relative_frame_offset;
348 } else {
349 if (frame_idx == num_frames - 1) {
350 // If we are already at the top of the stack, just warn and don't
351 // reset the frame.
352 result.AppendError("already at the top of the stack");
353 return;
354 } else
355 frame_idx = num_frames - 1;
356 }
357 }
358 }
359 } else {
360 if (command.GetArgumentCount() > 1) {
362 "too many arguments; expected frame-index, saw '%s'",
363 command[0].c_str());
364 m_options.GenerateOptionUsage(
365 result.GetErrorStream(), *this,
366 GetCommandInterpreter().GetDebugger().GetTerminalWidth(),
367 GetCommandInterpreter().GetDebugger().GetUseColor());
368 return;
369 }
370
371 if (command.GetArgumentCount() == 1) {
372 if (command[0].ref().getAsInteger(0, frame_idx)) {
373 result.AppendErrorWithFormat("invalid frame index argument '%s'",
374 command[0].c_str());
375 return;
376 }
377 } else if (command.GetArgumentCount() == 0) {
378 frame_idx = thread->GetSelectedFrameIndex(SelectMostRelevantFrame);
379 if (frame_idx == UINT32_MAX) {
380 frame_idx = 0;
381 }
382 }
383 }
384
385 bool success = thread->SetSelectedFrameByIndexNoisily(
386 frame_idx, result.GetOutputStream());
387 if (success) {
388 m_exe_ctx.SetFrameSP(thread->GetSelectedFrame(SelectMostRelevantFrame));
390 } else {
391 result.AppendErrorWithFormat("Frame index (%u) out of range", frame_idx);
392 }
393 }
394
396};
397
398#pragma mark CommandObjectFrameVariable
399// List images with associated information
401public:
404 interpreter, "frame variable",
405 "Show variables for the current stack frame. Defaults to all "
406 "arguments and local variables in scope. Names of argument, "
407 "local, file static and file global variables can be specified.",
408 nullptr,
409 eCommandRequiresFrame | eCommandTryTargetAPILock |
410 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused |
411 eCommandRequiresProcess),
413 true), // Include the frame specific options by passing "true"
415 SetHelpLong(R"(
416Children of aggregate variables can be specified such as 'var->child.x'. In
417'frame variable', the operators -> and [] do not invoke operator overloads if
418they exist, but directly access the specified element. If you want to trigger
419operator overloads use the expression command to print the variable instead.
420
421It is worth noting that except for overloaded operators, when printing local
422variables 'expr local_var' and 'frame var local_var' produce the same results.
423However, 'frame variable' is more efficient, since it uses debug information and
424memory reads directly, rather than parsing and evaluating an expression, which
425may even involve JITing and running code in the target program.)");
426
435 m_option_group.Finalize();
436 }
437
438 ~CommandObjectFrameVariable() override = default;
439
440 Options *GetOptions() override { return &m_option_group; }
441
442 // `frame variable` repeats by incrementing the printing depth. When the depth
443 // is too shallow, hitting enter a few times will quickly expand the data.
444 std::optional<std::string> GetRepeatCommand(Args &current_command_args,
445 uint32_t index) override {
446 llvm::StringRef depth_opt = "--depth";
447
448 Args repeat_args;
449 auto increment_option =
450 [&](llvm::StringRef option) -> std::optional<std::string> {
451 uint32_t num;
452 bool failed = option.getAsInteger(10, num);
453 if (failed)
454 return std::nullopt;
455 return llvm::utostr(num + 1);
456 };
457
458 bool has_depth_option = false;
459 bool increment_next_arg = false;
460 for (const auto &entry : current_command_args) {
461 llvm::StringRef arg = entry.ref();
462
463 if (arg == "-" || arg == "--") {
464 repeat_args.AppendArgument(arg);
465 continue;
466 }
467
468 if (increment_next_arg) {
469 increment_next_arg = false;
470 if (auto maybe_opt = increment_option(arg)) {
471 repeat_args.AppendArgument(*maybe_opt);
472 continue;
473 }
474 }
475
476 if (depth_opt.starts_with(arg) || arg == "-D") {
477 repeat_args.AppendArgument(arg);
478 increment_next_arg = true;
479 has_depth_option = true;
480 continue;
481 }
482 if (arg.consume_front("-D")) {
483 if (auto maybe_opt = increment_option(arg)) {
484 repeat_args.AppendArgument(llvm::formatv("-D{0}", *maybe_opt).str());
485 has_depth_option = true;
486 continue;
487 }
488 }
489
490 repeat_args.AppendArgument(arg);
491 }
492
493 if (!has_depth_option) {
494 // Access the default max-depth from the target. This is because
495 // GetRepeatCommand is called before ParseOptions, which is when
496 // m_varobj_options.max_depth becomes assigned.
497 if (auto target_sp = GetDebugger().GetSelectedTarget()) {
498 auto [default_depth, _] =
499 target_sp->GetMaximumDepthOfChildrenToDisplay();
500 // Insert the depth after `frame variable`, before positional args.
501 assert(repeat_args[0].ref() == "frame" && "expects resolved command");
502 repeat_args.InsertArgumentAtIndex(2, "--depth");
503 repeat_args.InsertArgumentAtIndex(3, llvm::utostr(default_depth + 1));
505 }
506
507 std::string repeat_command;
508 if (!repeat_args.GetQuotedCommandString(repeat_command))
509 return std::nullopt;
510 return repeat_command;
511 }
512
513protected:
514 llvm::StringRef GetScopeString(VariableSP var_sp) {
515 if (!var_sp)
516 return llvm::StringRef();
517
518 auto vt = var_sp->GetScope();
519 bool is_synthetic = IsSyntheticValueType(vt);
520 // Clear the bit so the rest works correctly.
521 if (is_synthetic)
522 vt = GetBaseValueType(vt);
523
524 switch (vt) {
526 return is_synthetic ? "(synthetic) GLOBAL: " : "GLOBAL: ";
528 return is_synthetic ? "(synthetic) STATIC: " : "STATIC: ";
530 return is_synthetic ? "(synthetic) ARG: " : "ARG: ";
532 return is_synthetic ? "(synthetic) LOCAL: " : "LOCAL: ";
534 return is_synthetic ? "(synthetic) THREAD: " : "THREAD: ";
535 default:
536 break;
537 }
538
539 return llvm::StringRef();
540 }
541
542 /// Returns true if `scope` matches any of the options in `m_option_variable`.
543 bool ScopeRequested(lldb::ValueType scope) {
544 // If it's a synthetic variable, check if we want to show those first.
545 bool is_synthetic = IsSyntheticValueType(scope);
546 if (is_synthetic) {
547 if (!m_option_variable.show_synthetic)
548 return false;
549
550 scope = GetBaseValueType(scope);
551 }
552 switch (scope) {
555 return m_option_variable.show_globals;
557 return m_option_variable.show_args;
559 return m_option_variable.show_locals;
565 case eValueTypeVTable:
567 // The default for all other value types is is_synthetic. Aside from the
568 // modifiers above that should apply equally to synthetic and normal
569 // variables, any other synthetic variable we should default to showing.
570 return is_synthetic;
571 }
572 llvm_unreachable("Unexpected scope value");
573 }
574
575 /// Finds all the variables in `all_variables` whose name matches `regex`,
576 /// inserting them into `matches`. Variables already contained in `matches`
577 /// are not inserted again.
578 /// Nullopt is returned in case of no matches.
579 /// A sub-range of `matches` with all newly inserted variables is returned.
580 /// This may be empty if all matches were already contained in `matches`.
581 std::optional<llvm::ArrayRef<VariableSP>>
583 VariableList &matches,
584 const VariableList &all_variables) {
585 bool any_matches = false;
586 const size_t previous_num_vars = matches.GetSize();
587
588 for (const VariableSP &var : all_variables) {
589 if (!var->NameMatches(regex) || !ScopeRequested(var->GetScope()))
590 continue;
591 any_matches = true;
592 matches.AddVariableIfUnique(var);
593 }
594
595 if (any_matches)
596 return matches.toArrayRef().drop_front(previous_num_vars);
597 return std::nullopt;
598 }
599
600 void DoExecute(Args &command, CommandReturnObject &result) override {
601 // No need to check "frame" for validity as eCommandRequiresFrame ensures
602 // it is valid
603 StackFrame *frame = m_exe_ctx.GetFramePtr();
604
605 Stream &s = result.GetOutputStream();
606
607 // Using a regex should behave like looking for an exact name match: it
608 // also finds globals.
609 m_option_variable.show_globals |= m_option_variable.use_regex;
610
611 // Be careful about the stack frame, if any summary formatter runs code, it
612 // might clear the StackFrameList for the thread. So hold onto a shared
613 // pointer to the frame so it stays alive.
614
616 VariableList *variable_list =
617 frame->GetVariableList(m_option_variable.show_globals,
618 m_option_variable.show_synthetic, &error);
619
620 if (error.Fail() && (!variable_list || variable_list->GetSize() == 0)) {
621 result.AppendError(error.AsCString());
622 }
623
624 ValueObjectSP valobj_sp;
625
626 TypeSummaryImplSP summary_format_sp;
627 if (!m_option_variable.summary.IsCurrentValueEmpty())
629 ConstString(m_option_variable.summary.GetCurrentValue()),
630 summary_format_sp);
631 else if (!m_option_variable.summary_string.IsCurrentValueEmpty())
632 summary_format_sp = std::make_shared<StringSummaryFormat>(
633 TypeSummaryImpl::Flags(),
634 m_option_variable.summary_string.GetCurrentValue());
635
636 DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions(
638 summary_format_sp));
639
640 const SymbolContext &sym_ctx =
641 frame->GetSymbolContext(eSymbolContextFunction);
642 if (sym_ctx.function && sym_ctx.function->IsTopLevelFunction())
643 m_option_variable.show_globals = true;
644
645 if (variable_list) {
646 const Format format = m_option_format.GetFormat();
647 options.SetFormat(format);
648
649 if (!command.empty()) {
650 VariableList regex_var_list;
651
652 // If we have any args to the variable command, we will make variable
653 // objects from them...
654 for (auto &entry : command) {
655 if (m_option_variable.use_regex) {
656 llvm::StringRef name_str = entry.ref();
657 RegularExpression regex(name_str);
658 if (regex.IsValid()) {
659 std::optional<llvm::ArrayRef<VariableSP>> results =
660 findUniqueRegexMatches(regex, regex_var_list, *variable_list);
661 if (!results) {
663 "no variables matched the regular expression '%s'",
664 entry.c_str());
665 continue;
666 }
667 for (const VariableSP &var_sp : *results) {
668 valobj_sp = frame->GetValueObjectForFrameVariable(
669 var_sp, m_varobj_options.use_dynamic);
670 if (valobj_sp) {
671 result.GetValueObjectList().Append(valobj_sp);
672
673 std::string scope_string;
674 if (m_option_variable.show_scope)
675 scope_string = GetScopeString(var_sp).str();
676
677 if (!scope_string.empty())
678 s.PutCString(scope_string);
679
680 if (m_option_variable.show_decl &&
681 var_sp->GetDeclaration().GetFile()) {
682 bool show_fullpaths = false;
683 bool show_module = true;
684 if (var_sp->DumpDeclaration(&s, show_fullpaths,
685 show_module))
686 s.PutCString(": ");
687 }
688 auto &strm = result.GetOutputStream();
689 if (llvm::Error error = valobj_sp->Dump(strm, options))
690 result.AppendError(toString(std::move(error)));
691 }
692 }
693 } else {
694 if (llvm::Error err = regex.GetError())
695 result.AppendError(llvm::toString(std::move(err)));
696 else
698 "unknown regex error when compiling '%s'", entry.c_str());
699 }
700 } else // No regex, either exact variable names or variable
701 // expressions.
702 {
704 uint32_t expr_path_options =
709 lldb::VariableSP var_sp;
710 valobj_sp = frame->GetValueForVariableExpressionPath(
711 entry.ref(), m_varobj_options.use_dynamic, expr_path_options,
712 var_sp, error);
713 if (valobj_sp) {
714 result.GetValueObjectList().Append(valobj_sp);
715
716 std::string scope_string;
717 if (m_option_variable.show_scope)
718 scope_string = GetScopeString(var_sp).str();
719
720 if (!scope_string.empty())
721 s.PutCString(scope_string);
722 if (m_option_variable.show_decl && var_sp &&
723 var_sp->GetDeclaration().GetFile()) {
724 var_sp->GetDeclaration().DumpStopContext(&s, false);
725 s.PutCString(": ");
726 }
727
728 options.SetFormat(format);
729 options.SetVariableFormatDisplayLanguage(
730 valobj_sp->GetPreferredDisplayLanguage());
731
732 Stream &output_stream = result.GetOutputStream();
733 options.SetRootValueObjectName(
734 valobj_sp->GetParent() ? entry.c_str() : nullptr);
735 // Check only the `error` argument, because doing
736 // `valobj_sp->GetError()` will update the value and potentially
737 // return a new error that happens during the update, even if
738 // `GetValueForVariableExpressionPath` reported no errors.
739 if (error.Fail()) {
741 result.SetError(error.takeError());
742 } else {
743 // If there is an error while updating the value, it will be
744 // printed here as the contents of the value, e.g.
745 // `(int) *((int*)0) = <parent is NULL>`
746 if (llvm::Error error = valobj_sp->Dump(output_stream, options))
747 result.AppendError(toString(std::move(error)));
748 }
749
750 } else {
751 if (auto error_cstr = error.AsCString(nullptr))
752 result.AppendError(error_cstr);
753 else
755 "unable to find any variable expression path that matches "
756 "'%s'",
757 entry.c_str());
758 }
759 }
760 }
761 } else // No command arg specified. Use variable_list, instead.
762 {
763 const size_t num_variables = variable_list->GetSize();
764 if (num_variables > 0) {
765 for (size_t i = 0; i < num_variables; i++) {
766 VariableSP var_sp = variable_list->GetVariableAtIndex(i);
767 if (!ScopeRequested(var_sp->GetScope()))
768 continue;
769 std::string scope_string;
770 if (m_option_variable.show_scope)
771 scope_string = GetScopeString(var_sp).str();
772
773 // Use the variable object code to make sure we are using the same
774 // APIs as the public API will be using...
775 valobj_sp = frame->GetValueObjectForFrameVariable(
776 var_sp, m_varobj_options.use_dynamic);
777 if (valobj_sp) {
778 result.GetValueObjectList().Append(valobj_sp);
779
780 // When dumping all variables, don't print any variables that are
781 // not in scope to avoid extra unneeded output
782 if (valobj_sp->IsInScope()) {
783 if (!valobj_sp->GetTargetSP()
784 ->GetDisplayRuntimeSupportValues() &&
785 valobj_sp->IsRuntimeSupportValue())
786 continue;
787
788 if (!scope_string.empty())
789 s.PutCString(scope_string);
790
791 if (m_option_variable.show_decl &&
792 var_sp->GetDeclaration().GetFile()) {
793 var_sp->GetDeclaration().DumpStopContext(&s, false);
794 s.PutCString(": ");
795 }
796
797 options.SetFormat(format);
798 options.SetVariableFormatDisplayLanguage(
799 valobj_sp->GetPreferredDisplayLanguage());
800 options.SetRootValueObjectName(
801 var_sp ? var_sp->GetName().AsCString(nullptr) : nullptr);
802 if (llvm::Error error =
803 valobj_sp->Dump(result.GetOutputStream(), options))
804 result.AppendError(toString(std::move(error)));
805 }
806 }
807 }
808 }
809 }
810 if (result.GetStatus() != eReturnStatusFailed)
812 }
813
814 if (m_option_variable.show_recognized_args) {
815 auto recognized_frame = frame->GetRecognizedFrame();
816 if (recognized_frame) {
817 ValueObjectListSP recognized_arg_list =
818 recognized_frame->GetRecognizedArguments();
819 if (recognized_arg_list) {
820 for (auto &rec_value_sp : recognized_arg_list->GetObjects()) {
821 result.GetValueObjectList().Append(rec_value_sp);
822 options.SetFormat(m_option_format.GetFormat());
823 options.SetVariableFormatDisplayLanguage(
824 rec_value_sp->GetPreferredDisplayLanguage());
825 options.SetRootValueObjectName(
826 rec_value_sp->GetName().AsCString(nullptr));
827 if (llvm::Error error =
828 rec_value_sp->Dump(result.GetOutputStream(), options))
829 result.AppendError(toString(std::move(error)));
830 }
831 }
832 }
833 }
834
835 m_interpreter.PrintWarningsIfNecessary(result.GetOutputStream(),
838 // Increment statistics.
840 if (result.Succeeded())
841 target_stats.GetFrameVariableStats().NotifySuccess();
842 else
843 target_stats.GetFrameVariableStats().NotifyFailure();
844 }
845
850};
851
852#pragma mark CommandObjectFrameRecognizer
853
854#define LLDB_OPTIONS_frame_recognizer_add
855#include "CommandOptions.inc"
856
858private:
859 class CommandOptions : public Options {
860 public:
861 CommandOptions() = default;
862 ~CommandOptions() override = default;
863
864 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
865 ExecutionContext *execution_context) override {
867 const int short_option = m_getopt_table[option_idx].val;
868
869 switch (short_option) {
870 case 'f': {
871 bool value, success;
872 value = OptionArgParser::ToBoolean(option_arg, true, &success);
873 if (success) {
875 } else {
877 "invalid boolean value '%s' passed for -f option",
878 option_arg.str().c_str());
879 }
880 } break;
881 case 'l':
882 m_class_name = std::string(option_arg);
883 break;
884 case 's':
885 m_module = std::string(option_arg);
886 break;
887 case 'n':
888 m_symbols.push_back(std::string(option_arg));
889 break;
890 case 'x':
891 m_regex = true;
892 break;
893 default:
894 llvm_unreachable("Unimplemented option");
895 }
896
897 return error;
898 }
899
900 void OptionParsingStarting(ExecutionContext *execution_context) override {
901 m_module = "";
902 m_symbols.clear();
903 m_class_name = "";
904 m_regex = false;
906 }
907
908 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
909 return llvm::ArrayRef(g_frame_recognizer_add_options);
910 }
911
912 // Instance variables to hold the values for command options.
913 std::string m_class_name;
914 std::string m_module;
915 std::vector<std::string> m_symbols;
918 };
919
921
922 Options *GetOptions() override { return &m_options; }
923
924protected:
925 void DoExecute(Args &command, CommandReturnObject &result) override;
926
927public:
929 : CommandObjectParsed(interpreter, "frame recognizer add",
930 "Add a new frame recognizer.", nullptr) {
931 SetHelpLong(R"(
932Frame recognizers allow for retrieving information about special frames based on
933ABI, arguments or other special properties of that frame, even without source
934code or debug info. Currently, one use case is to extract function arguments
935that would otherwise be unaccesible, or augment existing arguments.
936
937Adding a custom frame recognizer is possible by implementing a Python class
938and using the 'frame recognizer add' command. The Python class should have a
939'get_recognized_arguments' method and it will receive an argument of type
940lldb.SBFrame representing the current frame that we are trying to recognize.
941The method should return a (possibly empty) list of lldb.SBValue objects that
942represent the recognized arguments.
943
944An example of a recognizer that retrieves the file descriptor values from libc
945functions 'read', 'write' and 'close' follows:
946
947 class LibcFdRecognizer(object):
948 def get_recognized_arguments(self, frame):
949 if frame.name in ["read", "write", "close"]:
950 fd = frame.EvaluateExpression("$arg1").unsigned
951 target = frame.thread.process.target
952 value = target.CreateValueFromExpression("fd", "(int)%d" % fd)
953 return [value]
954 return []
955
956The file containing this implementation can be imported via 'command script
957import' and then we can register this recognizer with 'frame recognizer add'.
958It's important to restrict the recognizer to the libc library (which is
959libsystem_kernel.dylib on macOS) to avoid matching functions with the same name
960in other modules:
961
962(lldb) command script import .../fd_recognizer.py
963(lldb) frame recognizer add -l fd_recognizer.LibcFdRecognizer -n read -s libsystem_kernel.dylib
964
965When the program is stopped at the beginning of the 'read' function in libc, we
966can view the recognizer arguments in 'frame variable':
967
968(lldb) b read
969(lldb) r
970Process 1234 stopped
971* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.3
972 frame #0: 0x00007fff06013ca0 libsystem_kernel.dylib`read
973(lldb) frame variable
974(int) fd = 3
975
976 )");
977 }
978 ~CommandObjectFrameRecognizerAdd() override = default;
979};
980
982 CommandReturnObject &result) {
983#if LLDB_ENABLE_PYTHON
984 if (m_options.m_class_name.empty()) {
985 result.AppendErrorWithFormat("%s needs a Python class name (-l argument)",
986 m_cmd_name.c_str());
987 return;
988 }
989
990 if (m_options.m_module.empty()) {
991 result.AppendErrorWithFormat("%s needs a module name (-s argument)",
992 m_cmd_name.c_str());
993 return;
994 }
995
996 if (m_options.m_symbols.empty()) {
998 "%s needs at least one symbol name (-n argument)", m_cmd_name.c_str());
999 return;
1000 }
1001
1002 if (m_options.m_regex && m_options.m_symbols.size() > 1) {
1003 result.AppendErrorWithFormat(
1004 "%s needs only one symbol regular expression (-n argument)",
1005 m_cmd_name.c_str());
1006 return;
1007 }
1008
1010
1011 if (interpreter &&
1012 !interpreter->CheckObjectExists(m_options.m_class_name.c_str())) {
1013 result.AppendWarning("the provided class does not exist - please define it "
1014 "before attempting to use this frame recognizer");
1015 }
1016
1017 StackFrameRecognizerSP recognizer_sp =
1019 interpreter, m_options.m_class_name.c_str()));
1020 if (m_options.m_regex) {
1021 auto module = std::make_shared<RegularExpression>(m_options.m_module);
1022 auto func =
1023 std::make_shared<RegularExpression>(m_options.m_symbols.front());
1025 recognizer_sp, module, func, Mangled::NamePreference::ePreferDemangled,
1026 m_options.m_first_instruction_only);
1027 } else {
1028 auto module = ConstString(m_options.m_module);
1029 std::vector<ConstString> symbols(m_options.m_symbols.begin(),
1030 m_options.m_symbols.end());
1032 recognizer_sp, module, symbols,
1034 m_options.m_first_instruction_only);
1035 }
1036#endif
1037
1039}
1040
1042public:
1044 : CommandObjectParsed(interpreter, "frame recognizer clear",
1045 "Delete all frame recognizers.", nullptr) {}
1046
1048
1049protected:
1054};
1055
1056static void
1057PrintRecognizerDetails(Stream &strm, const std::string &name, bool enabled,
1058 const std::string &module,
1059 llvm::ArrayRef<lldb_private::ConstString> symbols,
1060 Mangled::NamePreference symbol_mangling, bool regexp) {
1061 if (!enabled)
1062 strm << "[disabled] ";
1063
1064 strm << name << ", ";
1065
1066 if (!module.empty())
1067 strm << "module " << module << ", ";
1068
1069 switch (symbol_mangling) {
1070 case Mangled::NamePreference ::ePreferMangled:
1071 strm << "mangled symbol ";
1072 break;
1073 case Mangled::NamePreference ::ePreferDemangled:
1074 strm << "demangled symbol ";
1075 break;
1076 case Mangled::NamePreference ::ePreferDemangledWithoutArguments:
1077 strm << "demangled (no args) symbol ";
1078 break;
1079 }
1080
1081 if (regexp)
1082 strm << "regex ";
1083
1084 llvm::interleaveComma(symbols, strm);
1085}
1086
1087// Base class for commands which accept a single frame recognizer as an argument
1089public:
1091 const char *name,
1092 const char *help = nullptr,
1093 const char *syntax = nullptr,
1094 uint32_t flags = 0)
1095 : CommandObjectParsed(interpreter, name, help, syntax, flags) {
1097 }
1098
1099 void
1101 OptionElementVector &opt_element_vector) override {
1102 if (request.GetCursorIndex() != 0)
1103 return;
1104
1106 [&request](uint32_t rid, bool enabled, std::string rname,
1107 std::string module,
1108 llvm::ArrayRef<lldb_private::ConstString> symbols,
1109 Mangled::NamePreference symbol_mangling, bool regexp) {
1110 StreamString strm;
1111 if (rname.empty())
1112 rname = "(internal)";
1113
1114 PrintRecognizerDetails(strm, rname, enabled, module, symbols,
1115 symbol_mangling, regexp);
1116
1117 request.TryCompleteCurrentArg(std::to_string(rid), strm.GetString());
1118 });
1119 }
1120
1122 uint32_t recognizer_id) = 0;
1123
1124 void DoExecute(Args &command, CommandReturnObject &result) override {
1125 uint32_t recognizer_id;
1126 if (!llvm::to_integer(command.GetArgumentAtIndex(0), recognizer_id)) {
1127 result.AppendErrorWithFormat("'%s' is not a valid recognizer id",
1128 command.GetArgumentAtIndex(0));
1129 return;
1130 }
1131
1132 DoExecuteWithId(result, recognizer_id);
1133 }
1134};
1135
1138public:
1141 interpreter, "frame recognizer enable",
1142 "Enable a frame recognizer by id.", nullptr) {
1144 }
1145
1147
1148protected:
1150 uint32_t recognizer_id) override {
1151 auto &recognizer_mgr = GetTarget().GetFrameRecognizerManager();
1152 if (!recognizer_mgr.SetEnabledForID(recognizer_id, true)) {
1153 result.AppendErrorWithFormat("'%u' is not a valid recognizer id",
1154 recognizer_id);
1155 return;
1156 }
1158 }
1159};
1160
1163public:
1166 interpreter, "frame recognizer disable",
1167 "Disable a frame recognizer by id.", nullptr) {
1169 }
1170
1172
1173protected:
1175 uint32_t recognizer_id) override {
1176 auto &recognizer_mgr = GetTarget().GetFrameRecognizerManager();
1177 if (!recognizer_mgr.SetEnabledForID(recognizer_id, false)) {
1178 result.AppendErrorWithFormat("'%u' is not a valid recognizer id",
1179 recognizer_id);
1180 return;
1181 }
1183 }
1184};
1185
1188public:
1191 interpreter, "frame recognizer delete",
1192 "Delete an existing frame recognizer by id.", nullptr) {
1194 }
1195
1197
1198protected:
1200 uint32_t recognizer_id) override {
1201 auto &recognizer_mgr = GetTarget().GetFrameRecognizerManager();
1202 if (!recognizer_mgr.RemoveRecognizerWithID(recognizer_id)) {
1203 result.AppendErrorWithFormat("'%u' is not a valid recognizer id",
1204 recognizer_id);
1205 return;
1206 }
1208 }
1209};
1210
1212public:
1214 : CommandObjectParsed(interpreter, "frame recognizer list",
1215 "Show a list of active frame recognizers.",
1216 nullptr) {}
1217
1219
1220protected:
1221 void DoExecute(Args &command, CommandReturnObject &result) override {
1222 bool any_printed = false;
1224 [&result,
1225 &any_printed](uint32_t recognizer_id, bool enabled, std::string name,
1226 std::string module, llvm::ArrayRef<ConstString> symbols,
1227 Mangled::NamePreference symbol_mangling, bool regexp) {
1228 Stream &stream = result.GetOutputStream();
1229
1230 if (name.empty())
1231 name = "(internal)";
1232
1233 stream << std::to_string(recognizer_id) << ": ";
1234 PrintRecognizerDetails(stream, name, enabled, module, symbols,
1235 symbol_mangling, regexp);
1236
1237 stream.EOL();
1238 stream.Flush();
1239
1240 any_printed = true;
1241 });
1242
1243 if (any_printed)
1245 else {
1246 result.GetOutputStream().PutCString("no matching results found.\n");
1248 }
1249 }
1250};
1251
1253public:
1256 interpreter, "frame recognizer info",
1257 "Show which frame recognizer is applied a stack frame (if any).",
1258 nullptr) {
1260 }
1261
1263
1264protected:
1265 void DoExecute(Args &command, CommandReturnObject &result) override {
1266 const char *frame_index_str = command.GetArgumentAtIndex(0);
1267 uint32_t frame_index;
1268 if (!llvm::to_integer(frame_index_str, frame_index)) {
1269 result.AppendErrorWithFormat("'%s' is not a valid frame index",
1270 frame_index_str);
1271 return;
1272 }
1273
1274 Process *process = m_exe_ctx.GetProcessPtr();
1275 if (process == nullptr) {
1276 result.AppendError("no process");
1277 return;
1278 }
1279 Thread *thread = m_exe_ctx.GetThreadPtr();
1280 if (thread == nullptr) {
1281 result.AppendError("no thread");
1282 return;
1283 }
1284 if (command.GetArgumentCount() != 1) {
1285 result.AppendErrorWithFormat(
1286 "'%s' takes exactly one frame index argument", m_cmd_name.c_str());
1287 return;
1288 }
1289
1290 StackFrameSP frame_sp = thread->GetStackFrameAtIndex(frame_index);
1291 if (!frame_sp) {
1292 result.AppendErrorWithFormat("no frame with index %u", frame_index);
1293 return;
1294 }
1295
1296 auto recognizer =
1298
1299 Stream &output_stream = result.GetOutputStream();
1300 output_stream.Printf("frame %d ", frame_index);
1301 if (recognizer) {
1302 output_stream << "is recognized by ";
1303 output_stream << recognizer->GetName();
1304 } else {
1305 output_stream << "not recognized by any recognizer";
1306 }
1307 output_stream.EOL();
1309 }
1310};
1311
1313public:
1316 interpreter, "frame recognizer",
1317 "Commands for editing and viewing frame recognizers.",
1318 "frame recognizer [<sub-command-options>] ") {
1320 interpreter)));
1322 interpreter)));
1324 interpreter)));
1326 "enable",
1329 "disable",
1332 "delete",
1335 "clear",
1337 }
1338
1339 ~CommandObjectFrameRecognizer() override = default;
1340};
1341
1342#pragma mark CommandObjectMultiwordFrame
1343
1344// CommandObjectMultiwordFrame
1345
1347 CommandInterpreter &interpreter)
1348 : CommandObjectMultiword(interpreter, "frame",
1349 "Commands for selecting and "
1350 "examining the current "
1351 "thread's stack frames.",
1352 "frame <subcommand> [<subcommand-options>]") {
1353 LoadSubCommand("diagnose",
1355 LoadSubCommand("info",
1356 CommandObjectSP(new CommandObjectFrameInfo(interpreter)));
1357 LoadSubCommand("select",
1358 CommandObjectSP(new CommandObjectFrameSelect(interpreter)));
1359 LoadSubCommand("variable",
1361#if LLDB_ENABLE_PYTHON
1363 interpreter)));
1364#endif
1365}
1366
static void PrintRecognizerDetails(Stream &strm, const std::string &name, bool enabled, const std::string &module, llvm::ArrayRef< lldb_private::ConstString > symbols, Mangled::NamePreference symbol_mangling, bool regexp)
static llvm::raw_ostream & error(Stream &strm)
void OptionParsingStarting(ExecutionContext *execution_context) override
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
~CommandObjectFrameDiagnose() override=default
CommandObjectFrameDiagnose(CommandInterpreter &interpreter)
void DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectFrameInfo(CommandInterpreter &interpreter)
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectFrameInfo() override=default
void OptionParsingStarting(ExecutionContext *execution_context) override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
CommandObjectFrameRecognizerAdd(CommandInterpreter &interpreter)
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectFrameRecognizerAdd() override=default
CommandObjectFrameRecognizerClear(CommandInterpreter &interpreter)
~CommandObjectFrameRecognizerClear() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectFrameRecognizerDelete() override=default
CommandObjectFrameRecognizerDelete(CommandInterpreter &interpreter)
void DoExecuteWithId(CommandReturnObject &result, uint32_t recognizer_id) override
CommandObjectFrameRecognizerDisable(CommandInterpreter &interpreter)
void DoExecuteWithId(CommandReturnObject &result, uint32_t recognizer_id) override
~CommandObjectFrameRecognizerDisable() override=default
void DoExecuteWithId(CommandReturnObject &result, uint32_t recognizer_id) override
CommandObjectFrameRecognizerEnable(CommandInterpreter &interpreter)
~CommandObjectFrameRecognizerEnable() override=default
CommandObjectFrameRecognizerInfo(CommandInterpreter &interpreter)
~CommandObjectFrameRecognizerInfo() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectFrameRecognizerList(CommandInterpreter &interpreter)
~CommandObjectFrameRecognizerList() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectFrameRecognizer() override=default
CommandObjectFrameRecognizer(CommandInterpreter &interpreter)
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
void OptionParsingStarting(ExecutionContext *execution_context) override
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
void SkipHiddenFrames(Thread &thread, uint32_t frame_idx)
~CommandObjectFrameSelect() override=default
CommandObjectFrameSelect(CommandInterpreter &interpreter)
Options * GetOptions() override
void DoExecute(Args &command, CommandReturnObject &result) override
OptionGroupVariable m_option_variable
OptionGroupValueObjectDisplay m_varobj_options
std::optional< std::string > GetRepeatCommand(Args &current_command_args, uint32_t index) override
Get the command that appropriate for a "repeat" of the current command.
bool ScopeRequested(lldb::ValueType scope)
Returns true if scope matches any of the options in m_option_variable.
llvm::StringRef GetScopeString(VariableSP var_sp)
std::optional< llvm::ArrayRef< VariableSP > > findUniqueRegexMatches(RegularExpression &regex, VariableList &matches, const VariableList &all_variables)
Finds all the variables in all_variables whose name matches regex, inserting them into matches.
~CommandObjectFrameVariable() override=default
CommandObjectFrameVariable(CommandInterpreter &interpreter)
void DoExecute(Args &command, CommandReturnObject &result) override
void DoExecute(Args &command, CommandReturnObject &result) override
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The default version handles argument definitions that have only one argument type,...
CommandObjectWithFrameRecognizerArg(CommandInterpreter &interpreter, const char *name, const char *help=nullptr, const char *syntax=nullptr, uint32_t flags=0)
virtual void DoExecuteWithId(CommandReturnObject &result, uint32_t recognizer_id)=0
A command line argument class.
Definition Args.h:33
size_t GetArgumentCount() const
Gets the number of arguments left in this command object.
Definition Args.h:120
void AppendArgument(llvm::StringRef arg_str, char quote_char='\0')
Appends a new argument to the end of the list argument list.
Definition Args.cpp:332
const char * GetArgumentAtIndex(size_t idx) const
Gets the NULL terminated C string argument pointer for the argument at index idx.
Definition Args.cpp:273
void InsertArgumentAtIndex(size_t idx, llvm::StringRef arg_str, char quote_char='\0')
Insert the argument value at index idx to arg_str.
Definition Args.cpp:336
bool empty() const
Definition Args.h:122
bool GetQuotedCommandString(std::string &command) const
Definition Args.cpp:232
CommandObjectMultiwordFrame(CommandInterpreter &interpreter)
bool LoadSubCommand(llvm::StringRef cmd_name, const lldb::CommandObjectSP &command_obj) override
CommandObjectMultiword(CommandInterpreter &interpreter, const char *name, const char *help=nullptr, const char *syntax=nullptr, uint32_t flags=0)
CommandObjectParsed(CommandInterpreter &interpreter, const char *name, const char *help=nullptr, const char *syntax=nullptr, uint32_t flags=0)
virtual void SetHelpLong(llvm::StringRef str)
void AddSimpleArgumentList(lldb::CommandArgumentType arg_type, ArgumentRepetitionType repetition_type=eArgRepeatPlain)
CommandInterpreter & GetCommandInterpreter()
CommandInterpreter & m_interpreter
void AppendError(llvm::StringRef in_string)
const ValueObjectList & GetValueObjectList() const
void SetStatus(lldb::ReturnStatus status)
void AppendErrorWithFormat(const char *format,...) __attribute__((format(printf
void AppendWarning(llvm::StringRef in_string)
"lldb/Utility/ArgCompletionRequest.h"
void TryCompleteCurrentArg(llvm::StringRef completion, llvm::StringRef description="")
Adds a possible completion string if the completion would complete the current argument.
A uniqued constant string class.
Definition ConstString.h:40
static bool GetSummaryFormat(ConstString type, lldb::TypeSummaryImplSP &entry)
ScriptInterpreter * GetScriptInterpreter(bool can_create=true, std::optional< lldb::ScriptLanguage > language={})
std::function< bool(ConstString, ConstString, const DumpValueObjectOptions &, Stream &)> DeclPrintingHelper
DumpValueObjectOptions & SetDeclPrintingHelper(DeclPrintingHelper helper)
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
bool IsTopLevelFunction()
Get whether this function represents a 'top-level' function.
Definition Function.cpp:528
static const uint32_t OPTION_GROUP_GDB_FMT
static const uint32_t OPTION_GROUP_FORMAT
A command line option parsing protocol class.
Definition Options.h:58
std::vector< Option > m_getopt_table
Definition Options.h:198
A plug-in interface definition class for debugging a process.
Definition Process.h:356
bool IsValid() const
Test if this object contains a valid regular expression.
llvm::Error GetError() const
Return an error if the regular expression failed to compile.
virtual bool CheckObjectExists(const char *name)
Python implementation for frame recognizers.
void AddRecognizer(lldb::StackFrameRecognizerSP recognizer, ConstString module, llvm::ArrayRef< ConstString > symbols, Mangled::NamePreference symbol_mangling, bool first_instruction_only=true)
Add a new recognizer that triggers on a given symbol name.
void ForEach(std::function< void(uint32_t recognizer_id, bool enabled, std::string recognizer_name, std::string module, llvm::ArrayRef< ConstString > symbols, Mangled::NamePreference name_preference, bool regexp)> const &callback)
lldb::StackFrameRecognizerSP GetRecognizerForFrame(lldb::StackFrameSP frame)
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...
@ eExpressionPathOptionsInspectAnonymousUnions
Definition StackFrame.h:57
@ eExpressionPathOptionsAllowDirectIVarAccess
Definition StackFrame.h:56
virtual lldb::ValueObjectSP GetValueObjectForFrameVariable(const lldb::VariableSP &variable_sp, lldb::DynamicValueType use_dynamic)
Create a ValueObject for a given Variable in this StackFrame.
virtual VariableList * GetVariableList(bool get_file_globals, bool include_synthetic_vars, Status *error_ptr)
Retrieve the list of variables whose scope either:
virtual const SymbolContext & GetSymbolContext(lldb::SymbolContextItem resolve_scope)
Provide a SymbolContext for this StackFrame's current pc value.
virtual lldb::RecognizedStackFrameSP GetRecognizedFrame()
An error handling class.
Definition Status.h:118
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
Definition Status.cpp:106
static lldb::ValueObjectSP GetCrashingDereference(lldb::StopInfoSP &stop_info_sp, lldb::addr_t *crashing_address=nullptr)
llvm::StringRef GetString() const
A stream class that can stream formatted output to a file.
Definition Stream.h:28
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition Stream.cpp:134
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
Definition Stream.cpp:63
virtual void Flush()=0
Flush the stream.
size_t EOL()
Output and End of Line character to the stream.
Definition Stream.cpp:155
Function * function
The Function for a given query.
A class that represents statistics for a since lldb_private::Target.
Definition Statistics.h:309
StatsSuccessFail & GetFrameVariableStats()
Definition Statistics.h:324
TargetStats & GetStatistics()
Definition Target.h:2183
StackFrameRecognizerManager & GetFrameRecognizerManager()
Definition Target.h:1996
void Append(const lldb::ValueObjectSP &val_obj_sp)
bool AddVariableIfUnique(const lldb::VariableSP &var_sp)
lldb::VariableSP GetVariableAtIndex(size_t idx) const
llvm::ArrayRef< lldb::VariableSP > toArrayRef()
#define LLDB_OPT_SET_1
#define LLDB_OPT_SET_ALL
#define UINT32_MAX
@ SelectMostRelevantFrame
A class that represents a running process on the host machine.
constexpr bool IsSyntheticValueType(lldb::ValueType vt)
Return true if vt represents a synthetic value, false if not.
Definition ValueType.h:27
std::vector< OptionArgElement > OptionElementVector
Definition Options.h:43
constexpr lldb::ValueType GetBaseValueType(lldb::ValueType vt)
Get the base value type - for when we don't care if the value is synthetic or not,...
Definition ValueType.h:17
std::string toString(FormatterBytecode::OpCodes op)
std::shared_ptr< lldb_private::StackFrame > StackFrameSP
std::shared_ptr< lldb_private::TypeSummaryImpl > TypeSummaryImplSP
std::shared_ptr< lldb_private::CommandObject > CommandObjectSP
std::shared_ptr< lldb_private::ValueObject > ValueObjectSP
Format
Display format definitions.
std::shared_ptr< lldb_private::ValueObjectList > ValueObjectListSP
@ eReturnStatusFailed
@ eReturnStatusSuccessFinishResult
@ eReturnStatusSuccessFinishNoResult
@ eArgTypeRecognizerID
std::shared_ptr< lldb_private::Variable > VariableSP
@ eValueTypeVTableEntry
function pointer in virtual function table
@ eValueTypeVTable
virtual function table
@ eValueTypeVariableGlobal
globals variable
@ eValueTypeConstResult
constant result variables
@ eValueTypeVariableLocal
function local variables
@ eValueTypeVariableArgument
function argument variables
@ eValueTypeRegister
stack frame register value
@ eValueTypeVariableStatic
static variable
@ eValueTypeRegisterSet
A collection of stack frame register values.
@ eValueTypeVariableThreadLocal
thread local storage variable
std::shared_ptr< lldb_private::StackFrameRecognizer > StackFrameRecognizerSP
std::shared_ptr< lldb_private::StopInfo > StopInfoSP
static bool ToBoolean(llvm::StringRef s, bool fail_value, bool *success_ptr)