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 = GetCommandInterpreter().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 ValueObjectListSP recognized_arg_list;
646 if (m_option_variable.show_recognized_args)
647 if (auto recognized_frame = frame->GetRecognizedFrame())
648 recognized_arg_list = recognized_frame->GetRecognizedArguments();
649
650 const Format format = m_option_format.GetFormat();
651 options.SetFormat(format);
652
653 auto print_value = [&result, options](ValueObjectSP valobj_sp) {
654 result.GetValueObjectList().Append(valobj_sp);
655 if (auto error = valobj_sp->Dump(result.GetOutputStream(), options))
656 result.AppendError(toString(std::move(error)));
657 };
658
659 if (variable_list) {
660 if (!command.empty()) {
661 VariableList regex_var_list;
662
663 // If we have any args to the variable command, we will make variable
664 // objects from them...
665 for (auto &entry : command) {
666 if (m_option_variable.use_regex) {
667 llvm::StringRef name_str = entry.ref();
668 RegularExpression regex(name_str);
669 if (regex.IsValid()) {
670 std::optional<llvm::ArrayRef<VariableSP>> results =
671 findUniqueRegexMatches(regex, regex_var_list, *variable_list);
672 if (!results) {
673 // No variables matched. Try recognized args as fallback.
674 bool found_recognized = false;
675 if (recognized_arg_list)
676 for (auto &rec_value_sp : recognized_arg_list->GetObjects())
677 if (regex.Execute(rec_value_sp->GetName())) {
678 found_recognized = true;
679 print_value(rec_value_sp);
680 }
681 if (!found_recognized) {
683 "no variables matched the regular expression '%s'",
684 entry.c_str());
685 }
686 continue;
687 }
688 for (const VariableSP &var_sp : *results) {
689 valobj_sp = frame->GetValueObjectForFrameVariable(
690 var_sp, m_varobj_options.use_dynamic);
691 if (valobj_sp) {
692 result.GetValueObjectList().Append(valobj_sp);
693
694 std::string scope_string;
695 if (m_option_variable.show_scope)
696 scope_string = GetScopeString(var_sp).str();
697
698 if (!scope_string.empty())
699 s.PutCString(scope_string);
700
701 if (m_option_variable.show_decl &&
702 var_sp->GetDeclaration().GetFile()) {
703 bool show_fullpaths = false;
704 bool show_module = true;
705 if (var_sp->DumpDeclaration(&s, show_fullpaths,
706 show_module))
707 s.PutCString(": ");
708 }
709 auto &strm = result.GetOutputStream();
710 if (llvm::Error error = valobj_sp->Dump(strm, options))
711 result.AppendError(toString(std::move(error)));
712 }
713 }
714 } else {
715 if (llvm::Error err = regex.GetError())
716 result.AppendError(llvm::toString(std::move(err)));
717 else
719 "unknown regex error when compiling '%s'", entry.c_str());
720 }
721 } else // No regex, either exact variable names or variable
722 // expressions.
723 {
725 uint32_t expr_path_options =
730 lldb::VariableSP var_sp;
731 valobj_sp = frame->GetValueForVariableExpressionPath(
732 entry.ref(), m_varobj_options.use_dynamic, expr_path_options,
733 var_sp, error);
734 // Check only the `error` argument, because doing
735 // `valobj_sp->GetError()` will update the value and potentially
736 // return a new error that happens during the update, even if
737 // `GetValueForVariableExpressionPath` reported no errors.
738 if (valobj_sp && error.Success()) {
739 result.GetValueObjectList().Append(valobj_sp);
740
741 std::string scope_string;
742 if (m_option_variable.show_scope)
743 scope_string = GetScopeString(var_sp).str();
744
745 if (!scope_string.empty())
746 s.PutCString(scope_string);
747 if (m_option_variable.show_decl && var_sp &&
748 var_sp->GetDeclaration().GetFile()) {
749 var_sp->GetDeclaration().DumpStopContext(&s, false);
750 s.PutCString(": ");
751 }
752
753 options.SetFormat(format);
754 options.SetVariableFormatDisplayLanguage(
755 valobj_sp->GetPreferredDisplayLanguage());
756
757 Stream &output_stream = result.GetOutputStream();
758 options.SetRootValueObjectName(
759 valobj_sp->GetParent() ? entry.c_str() : nullptr);
760
761 // If there is an error while updating the value, it will be
762 // printed here as the contents of the value, e.g.
763 // `(int) *((int*)0) = <parent is NULL>`
764 if (llvm::Error error = valobj_sp->Dump(output_stream, options))
765 result.AppendError(toString(std::move(error)));
766 } else {
767 // Variable lookup failed. Check recognized args as a fallback.
768 bool found_recognized = false;
769 if (recognized_arg_list)
770 for (auto &obj_sp : recognized_arg_list->GetObjects())
771 if (obj_sp->GetName() == entry.ref()) {
772 found_recognized = true;
773 print_value(obj_sp);
774 break;
775 }
776 if (!found_recognized) {
777 if (error.Fail())
778 result.SetError(error.takeError());
779 else
781 "unable to find any variable expression path that "
782 "matches '%s'",
783 entry.c_str());
784 }
785 }
786 }
787 }
788 } else // No command arg specified. Use variable_list, instead.
789 {
790 const size_t num_variables = variable_list->GetSize();
791 if (num_variables > 0) {
792 for (size_t i = 0; i < num_variables; i++) {
793 VariableSP var_sp = variable_list->GetVariableAtIndex(i);
794 if (!ScopeRequested(var_sp->GetScope()))
795 continue;
796 std::string scope_string;
797 if (m_option_variable.show_scope)
798 scope_string = GetScopeString(var_sp).str();
799
800 // Use the variable object code to make sure we are using the same
801 // APIs as the public API will be using...
802 valobj_sp = frame->GetValueObjectForFrameVariable(
803 var_sp, m_varobj_options.use_dynamic);
804 if (valobj_sp) {
805 result.GetValueObjectList().Append(valobj_sp);
806
807 // When dumping all variables, don't print any variables that are
808 // not in scope to avoid extra unneeded output
809 if (valobj_sp->IsInScope()) {
810 if (!valobj_sp->GetTargetSP()
811 ->GetDisplayRuntimeSupportValues() &&
812 valobj_sp->IsRuntimeSupportValue())
813 continue;
814
815 if (!scope_string.empty())
816 s.PutCString(scope_string);
817
818 if (m_option_variable.show_decl &&
819 var_sp->GetDeclaration().GetFile()) {
820 var_sp->GetDeclaration().DumpStopContext(&s, false);
821 s.PutCString(": ");
822 }
823
824 options.SetFormat(format);
825 options.SetVariableFormatDisplayLanguage(
826 valobj_sp->GetPreferredDisplayLanguage());
827 options.SetRootValueObjectName(
828 var_sp ? var_sp->GetName().AsCString(nullptr) : nullptr);
829 if (llvm::Error error =
830 valobj_sp->Dump(result.GetOutputStream(), options))
831 result.AppendError(toString(std::move(error)));
832 }
833 }
834 }
835 }
836 }
837 if (result.GetStatus() != eReturnStatusFailed)
839 }
840
841 if (recognized_arg_list && (command.empty() || !variable_list))
842 for (auto &rec_value_sp : recognized_arg_list->GetObjects())
843 print_value(rec_value_sp);
844
845 m_interpreter.PrintWarningsIfNecessary(result.GetOutputStream(),
848 // Increment statistics.
849 TargetStats &target_stats = GetTarget()->GetStatistics();
850 if (result.Succeeded())
851 target_stats.GetFrameVariableStats().NotifySuccess();
852 else
853 target_stats.GetFrameVariableStats().NotifyFailure();
854 }
855
860};
861
862#pragma mark CommandObjectFrameRecognizer
863
864#define LLDB_OPTIONS_frame_recognizer_add
865#include "CommandOptions.inc"
866
868private:
869 class CommandOptions : public Options {
870 public:
871 CommandOptions() = default;
872 ~CommandOptions() override = default;
873
874 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
875 ExecutionContext *execution_context) override {
877 const int short_option = m_getopt_table[option_idx].val;
878
879 switch (short_option) {
880 case 'f': {
881 bool value, success;
882 value = OptionArgParser::ToBoolean(option_arg, true, &success);
883 if (success) {
885 } else {
887 "invalid boolean value '%s' passed for -f option",
888 option_arg.str().c_str());
889 }
890 } break;
891 case 'l':
892 m_class_name = std::string(option_arg);
893 break;
894 case 's':
895 m_module = std::string(option_arg);
896 break;
897 case 'n':
898 m_symbols.push_back(std::string(option_arg));
899 break;
900 case 'x':
901 m_regex = true;
902 break;
903 default:
904 llvm_unreachable("Unimplemented option");
905 }
906
907 return error;
908 }
909
910 void OptionParsingStarting(ExecutionContext *execution_context) override {
911 m_module = "";
912 m_symbols.clear();
913 m_class_name = "";
914 m_regex = false;
916 }
917
918 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
919 return llvm::ArrayRef(g_frame_recognizer_add_options);
920 }
921
922 // Instance variables to hold the values for command options.
923 std::string m_class_name;
924 std::string m_module;
925 std::vector<std::string> m_symbols;
928 };
929
931
932 Options *GetOptions() override { return &m_options; }
933
934protected:
935 void DoExecute(Args &command, CommandReturnObject &result) override;
936
937public:
939 : CommandObjectParsed(interpreter, "frame recognizer add",
940 "Add a new frame recognizer.", nullptr,
941 eCommandAllowsDummyTarget) {
942 SetHelpLong(R"(
943Frame recognizers allow for retrieving information about special frames based on
944ABI, arguments or other special properties of that frame, even without source
945code or debug info. Currently, one use case is to extract function arguments
946that would otherwise be unaccesible, or augment existing arguments.
947
948Adding a custom frame recognizer is possible by implementing a Python class
949and using the 'frame recognizer add' command. The Python class should have a
950'get_recognized_arguments' method and it will receive an argument of type
951lldb.SBFrame representing the current frame that we are trying to recognize.
952The method should return a (possibly empty) list of lldb.SBValue objects that
953represent the recognized arguments.
954
955An example of a recognizer that retrieves the file descriptor values from libc
956functions 'read', 'write' and 'close' follows:
957
958 class LibcFdRecognizer(object):
959 def get_recognized_arguments(self, frame):
960 if frame.name in ["read", "write", "close"]:
961 fd = frame.EvaluateExpression("$arg1").unsigned
962 target = frame.thread.process.target
963 value = target.CreateValueFromExpression("fd", "(int)%d" % fd)
964 return [value]
965 return []
966
967The file containing this implementation can be imported via 'command script
968import' and then we can register this recognizer with 'frame recognizer add'.
969It's important to restrict the recognizer to the libc library (which is
970libsystem_kernel.dylib on macOS) to avoid matching functions with the same name
971in other modules:
972
973(lldb) command script import .../fd_recognizer.py
974(lldb) frame recognizer add -l fd_recognizer.LibcFdRecognizer -n read -s libsystem_kernel.dylib
975
976When the program is stopped at the beginning of the 'read' function in libc, we
977can view the recognizer arguments in 'frame variable':
978
979(lldb) b read
980(lldb) r
981Process 1234 stopped
982* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.3
983 frame #0: 0x00007fff06013ca0 libsystem_kernel.dylib`read
984(lldb) frame variable
985(int) fd = 3
986
987 )");
988 }
989 ~CommandObjectFrameRecognizerAdd() override = default;
990};
991
993 CommandReturnObject &result) {
994#if LLDB_ENABLE_PYTHON
995 if (m_options.m_class_name.empty()) {
996 result.AppendErrorWithFormat("%s needs a Python class name (-l argument)",
997 m_cmd_name.c_str());
998 return;
999 }
1000
1001 if (m_options.m_module.empty()) {
1002 result.AppendErrorWithFormat("%s needs a module name (-s argument)",
1003 m_cmd_name.c_str());
1004 return;
1005 }
1006
1007 if (m_options.m_symbols.empty()) {
1008 result.AppendErrorWithFormat(
1009 "%s needs at least one symbol name (-n argument)", m_cmd_name.c_str());
1010 return;
1011 }
1012
1013 if (m_options.m_regex && m_options.m_symbols.size() > 1) {
1014 result.AppendErrorWithFormat(
1015 "%s needs only one symbol regular expression (-n argument)",
1016 m_cmd_name.c_str());
1017 return;
1018 }
1019
1021
1022 if (interpreter &&
1023 !interpreter->CheckObjectExists(m_options.m_class_name.c_str())) {
1024 result.AppendWarning("the provided class does not exist - please define it "
1025 "before attempting to use this frame recognizer");
1026 }
1027
1028 StackFrameRecognizerSP recognizer_sp =
1030 interpreter, m_options.m_class_name.c_str()));
1031 if (m_options.m_regex) {
1032 auto module = std::make_shared<RegularExpression>(m_options.m_module);
1033 auto func =
1034 std::make_shared<RegularExpression>(m_options.m_symbols.front());
1036 recognizer_sp, module, func, Mangled::NamePreference::ePreferDemangled,
1037 m_options.m_first_instruction_only);
1038 } else {
1039 auto module = ConstString(m_options.m_module);
1040 std::vector<ConstString> symbols(m_options.m_symbols.begin(),
1041 m_options.m_symbols.end());
1043 recognizer_sp, module, symbols,
1045 m_options.m_first_instruction_only);
1046 }
1047#endif
1048
1050}
1051
1053public:
1055 : CommandObjectParsed(interpreter, "frame recognizer clear",
1056 "Delete all frame recognizers.", nullptr,
1057 eCommandAllowsDummyTarget) {}
1058
1060
1061protected:
1066};
1067
1068static void
1069PrintRecognizerDetails(Stream &strm, const std::string &name, bool enabled,
1070 const std::string &module,
1071 llvm::ArrayRef<lldb_private::ConstString> symbols,
1072 Mangled::NamePreference symbol_mangling, bool regexp) {
1073 if (!enabled)
1074 strm << "[disabled] ";
1075
1076 strm << name << ", ";
1077
1078 if (!module.empty())
1079 strm << "module " << module << ", ";
1080
1081 switch (symbol_mangling) {
1082 case Mangled::NamePreference ::ePreferMangled:
1083 strm << "mangled symbol ";
1084 break;
1085 case Mangled::NamePreference ::ePreferDemangled:
1086 strm << "demangled symbol ";
1087 break;
1088 case Mangled::NamePreference ::ePreferDemangledWithoutArguments:
1089 strm << "demangled (no args) symbol ";
1090 break;
1091 }
1092
1093 if (regexp)
1094 strm << "regex ";
1095
1096 llvm::interleaveComma(symbols, strm);
1097}
1098
1099// Base class for commands which accept a single frame recognizer as an argument
1101public:
1103 const char *name,
1104 const char *help = nullptr,
1105 const char *syntax = nullptr,
1106 uint32_t flags = 0)
1107 : CommandObjectParsed(interpreter, name, help, syntax, flags) {
1109 }
1110
1111 void
1113 OptionElementVector &opt_element_vector) override {
1114 if (request.GetCursorIndex() != 0)
1115 return;
1116
1118 [&request](uint32_t rid, bool enabled, std::string rname,
1119 std::string module,
1120 llvm::ArrayRef<lldb_private::ConstString> symbols,
1121 Mangled::NamePreference symbol_mangling, bool regexp) {
1122 StreamString strm;
1123 if (rname.empty())
1124 rname = "(internal)";
1125
1126 PrintRecognizerDetails(strm, rname, enabled, module, symbols,
1127 symbol_mangling, regexp);
1128
1129 request.TryCompleteCurrentArg(std::to_string(rid), strm.GetString());
1130 });
1131 }
1132
1134 uint32_t recognizer_id) = 0;
1135
1136 void DoExecute(Args &command, CommandReturnObject &result) override {
1137 uint32_t recognizer_id;
1138 if (!llvm::to_integer(command.GetArgumentAtIndex(0), recognizer_id)) {
1139 result.AppendErrorWithFormat("'%s' is not a valid recognizer id",
1140 command.GetArgumentAtIndex(0));
1141 return;
1142 }
1143
1144 DoExecuteWithId(result, recognizer_id);
1145 }
1146};
1147
1150public:
1153 interpreter, "frame recognizer enable",
1154 "Enable a frame recognizer by id.", nullptr,
1155 eCommandAllowsDummyTarget) {
1157 }
1158
1160
1161protected:
1163 uint32_t recognizer_id) override {
1164 auto &recognizer_mgr = GetTarget()->GetFrameRecognizerManager();
1165 if (!recognizer_mgr.SetEnabledForID(recognizer_id, true)) {
1166 result.AppendErrorWithFormat("'%u' is not a valid recognizer id",
1167 recognizer_id);
1168 return;
1169 }
1171 }
1172};
1173
1176public:
1179 interpreter, "frame recognizer disable",
1180 "Disable a frame recognizer by id.", nullptr,
1181 eCommandAllowsDummyTarget) {
1183 }
1184
1186
1187protected:
1189 uint32_t recognizer_id) override {
1190 auto &recognizer_mgr = GetTarget()->GetFrameRecognizerManager();
1191 if (!recognizer_mgr.SetEnabledForID(recognizer_id, false)) {
1192 result.AppendErrorWithFormat("'%u' is not a valid recognizer id",
1193 recognizer_id);
1194 return;
1195 }
1197 }
1198};
1199
1202public:
1205 interpreter, "frame recognizer delete",
1206 "Delete an existing frame recognizer by id.", nullptr,
1207 eCommandAllowsDummyTarget) {
1209 }
1210
1212
1213protected:
1215 uint32_t recognizer_id) override {
1216 auto &recognizer_mgr = GetTarget()->GetFrameRecognizerManager();
1217 if (!recognizer_mgr.RemoveRecognizerWithID(recognizer_id)) {
1218 result.AppendErrorWithFormat("'%u' is not a valid recognizer id",
1219 recognizer_id);
1220 return;
1221 }
1223 }
1224};
1225
1227public:
1229 : CommandObjectParsed(interpreter, "frame recognizer list",
1230 "Show a list of active frame recognizers.", nullptr,
1231 eCommandAllowsDummyTarget) {}
1232
1234
1235protected:
1236 void DoExecute(Args &command, CommandReturnObject &result) override {
1237 bool any_printed = false;
1239 [&result,
1240 &any_printed](uint32_t recognizer_id, bool enabled, std::string name,
1241 std::string module, llvm::ArrayRef<ConstString> symbols,
1242 Mangled::NamePreference symbol_mangling, bool regexp) {
1243 Stream &stream = result.GetOutputStream();
1244
1245 if (name.empty())
1246 name = "(internal)";
1247
1248 stream << std::to_string(recognizer_id) << ": ";
1249 PrintRecognizerDetails(stream, name, enabled, module, symbols,
1250 symbol_mangling, regexp);
1251
1252 stream.EOL();
1253 stream.Flush();
1254
1255 any_printed = true;
1256 });
1257
1258 if (any_printed)
1260 else {
1261 result.GetOutputStream().PutCString("no matching results found.\n");
1263 }
1264 }
1265};
1266
1268public:
1271 interpreter, "frame recognizer info",
1272 "Show which frame recognizer is applied a stack frame (if any).",
1273 nullptr, eCommandAllowsDummyTarget) {
1275 }
1276
1278
1279protected:
1280 void DoExecute(Args &command, CommandReturnObject &result) override {
1281 const char *frame_index_str = command.GetArgumentAtIndex(0);
1282 uint32_t frame_index;
1283 if (!llvm::to_integer(frame_index_str, frame_index)) {
1284 result.AppendErrorWithFormat("'%s' is not a valid frame index",
1285 frame_index_str);
1286 return;
1287 }
1288
1289 Process *process = m_exe_ctx.GetProcessPtr();
1290 if (process == nullptr) {
1291 result.AppendError("no process");
1292 return;
1293 }
1294 Thread *thread = m_exe_ctx.GetThreadPtr();
1295 if (thread == nullptr) {
1296 result.AppendError("no thread");
1297 return;
1298 }
1299 if (command.GetArgumentCount() != 1) {
1300 result.AppendErrorWithFormat(
1301 "'%s' takes exactly one frame index argument", m_cmd_name.c_str());
1302 return;
1303 }
1304
1305 StackFrameSP frame_sp = thread->GetStackFrameAtIndex(frame_index);
1306 if (!frame_sp) {
1307 result.AppendErrorWithFormat("no frame with index %u", frame_index);
1308 return;
1309 }
1310
1311 auto recognizer =
1313 frame_sp);
1314
1315 Stream &output_stream = result.GetOutputStream();
1316 output_stream.Printf("frame %d ", frame_index);
1317 if (recognizer) {
1318 output_stream << "is recognized by ";
1319 output_stream << recognizer->GetName();
1320 } else {
1321 output_stream << "not recognized by any recognizer";
1322 }
1323 output_stream.EOL();
1325 }
1326};
1327
1329public:
1332 interpreter, "frame recognizer",
1333 "Commands for editing and viewing frame recognizers.",
1334 "frame recognizer [<sub-command-options>] ") {
1336 interpreter)));
1338 interpreter)));
1340 interpreter)));
1342 "enable",
1345 "disable",
1348 "delete",
1351 "clear",
1353 }
1354
1355 ~CommandObjectFrameRecognizer() override = default;
1356};
1357
1358#pragma mark CommandObjectMultiwordFrame
1359
1360// CommandObjectMultiwordFrame
1361
1363 CommandInterpreter &interpreter)
1364 : CommandObjectMultiword(interpreter, "frame",
1365 "Commands for selecting and "
1366 "examining the current "
1367 "thread's stack frames.",
1368 "frame <subcommand> [<subcommand-options>]") {
1369 LoadSubCommand("diagnose",
1371 LoadSubCommand("info",
1372 CommandObjectSP(new CommandObjectFrameInfo(interpreter)));
1373 LoadSubCommand("select",
1374 CommandObjectSP(new CommandObjectFrameSelect(interpreter)));
1375 LoadSubCommand("variable",
1377#if LLDB_ENABLE_PYTHON
1379 interpreter)));
1380#endif
1381}
1382
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
Target * GetTarget()
Get the target this command should operate on.
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:357
bool IsValid() const
Test if this object contains a valid regular expression.
bool Execute(llvm::StringRef string, llvm::SmallVectorImpl< llvm::StringRef > *matches=nullptr) const
Execute a regular expression match using the compiled regular expression that is already in this obje...
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:2180
StackFrameRecognizerManager & GetFrameRecognizerManager()
Definition Target.h:1993
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)