13#include "lldb/Host/Config.h"
41#pragma mark CommandObjectFrameDiagnose
47#define LLDB_OPTIONS_frame_diag
48#include "CommandOptions.inc"
62 switch (short_option) {
69 if (option_arg.getAsInteger(0, *
address)) {
71 error.SetErrorStringWithFormat(
"invalid address argument '%s'",
72 option_arg.str().c_str());
78 if (option_arg.getAsInteger(0, *
offset)) {
80 error.SetErrorStringWithFormat(
"invalid offset argument '%s'",
81 option_arg.str().c_str());
86 llvm_unreachable(
"Unimplemented option");
99 return llvm::ArrayRef(g_frame_diag_options);
104 std::optional<ConstString>
reg;
110 "Try to determine what path the current stop "
111 "location used to get to a register or address",
113 eCommandRequiresThread | eCommandTryTargetAPILock |
114 eCommandProcessMustBeLaunched |
115 eCommandProcessMustBePaused) {
125 arg.push_back(index_arg);
140 ValueObjectSP valobj_sp;
145 "`frame diagnose --address` is incompatible with other arguments.");
150 valobj_sp = frame_sp->GuessValueForRegisterAndOffset(
155 result.
AppendError(
"No arguments provided, and no stop info.");
172 GetExpressionPathFormat::eGetExpressionPathFormatHonorPointers;
173 valobj_sp->GetExpressionPath(stream, format);
174 stream.PutCString(
" =");
190#pragma mark CommandObjectFrameInfo
198 "List information about the current "
199 "stack frame in the current thread.",
201 eCommandRequiresFrame | eCommandTryTargetAPILock |
202 eCommandProcessMustBeLaunched |
203 eCommandProcessMustBePaused) {}
215#pragma mark CommandObjectFrameSelect
219#define LLDB_OPTIONS_frame_select
220#include "CommandOptions.inc"
234 switch (short_option) {
237 if (option_arg.getAsInteger(0, offset) || offset == INT32_MIN) {
238 error.SetErrorStringWithFormat(
"invalid frame offset argument '%s'",
239 option_arg.str().c_str());
246 llvm_unreachable(
"Unimplemented option");
257 return llvm::ArrayRef(g_frame_select_options);
265 "Select the current stack frame by "
266 "index from within the current thread "
267 "(see 'thread backtrace'.)",
269 eCommandRequiresThread | eCommandTryTargetAPILock |
270 eCommandProcessMustBeLaunched |
271 eCommandProcessMustBePaused) {
281 arg.push_back(index_arg);
316 if (
static_cast<int32_t
>(frame_idx) >=
320 if (frame_idx == 0) {
323 result.
AppendError(
"Already at the bottom of the stack.");
334 if (
static_cast<int32_t
>(num_frames - frame_idx) >
338 if (frame_idx == num_frames - 1) {
341 result.
AppendError(
"Already at the top of the stack.");
344 frame_idx = num_frames - 1;
350 "too many arguments; expected frame-index, saw '%s'.\n",
359 if (command[0].ref().getAsInteger(0, frame_idx)) {
388#pragma mark CommandObjectFrameVariable
394 interpreter,
"frame variable",
395 "Show variables for the current stack frame. Defaults to all "
396 "arguments and local variables in scope. Names of argument, "
397 "local, file static and file global variables can be specified.",
399 eCommandRequiresFrame | eCommandTryTargetAPILock |
400 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused |
401 eCommandRequiresProcess),
406Children of aggregate variables can be specified such as 'var->child.x'. In
407'frame variable', the operators -> and [] do not invoke operator overloads if
408they exist, but directly access the specified element. If you want to trigger
409operator overloads use the expression command to print the variable instead.
411It is worth noting that except for overloaded operators, when printing local
412variables 'expr local_var' and 'frame var local_var' produce the same results.
413However, 'frame variable' is more efficient, since it uses debug information and
414memory reads directly, rather than parsing and evaluating an expression, which
415may even involve JITing and running code in the target program.)");
426 arg.push_back(var_name_arg);
456 return llvm::StringRef();
458 switch (var_sp->GetScope()) {
473 return llvm::StringRef();
491 if (
error.Fail() && (!variable_list || variable_list->
GetSize() == 0)) {
496 ValueObjectSP valobj_sp;
498 TypeSummaryImplSP summary_format_sp;
504 summary_format_sp = std::make_shared<StringSummaryFormat>(
521 if (!command.
empty()) {
526 for (
auto &entry : command) {
528 const size_t regex_start_index = regex_var_list.
GetSize();
529 llvm::StringRef name_str = entry.ref();
532 size_t num_matches = 0;
533 const size_t num_new_regex_vars =
536 if (num_new_regex_vars > 0) {
537 for (
size_t regex_idx = regex_start_index,
538 end_index = regex_var_list.
GetSize();
539 regex_idx < end_index; ++regex_idx) {
545 std::string scope_string;
549 if (!scope_string.empty())
553 var_sp->GetDeclaration().GetFile()) {
554 bool show_fullpaths =
false;
555 bool show_module =
true;
556 if (var_sp->DumpDeclaration(&s, show_fullpaths,
564 }
else if (num_matches == 0) {
566 "no variables matched the regular expression '%s'.",
570 if (llvm::Error err = regex.
GetError())
571 result.
AppendError(llvm::toString(std::move(err)));
574 "unknown regex error when compiling '%s'", entry.c_str());
584 lldb::VariableSP var_sp;
589 std::string scope_string;
593 if (!scope_string.empty())
596 var_sp->GetDeclaration().GetFile()) {
597 var_sp->GetDeclaration().DumpStopContext(&s,
false);
603 valobj_sp->GetPreferredDisplayLanguage());
607 valobj_sp->GetParent() ? entry.c_str() :
nullptr);
608 valobj_sp->Dump(output_stream, options);
610 if (
auto error_cstr =
error.AsCString(
nullptr))
614 "unable to find any variable expression path that matches "
622 const size_t num_variables = variable_list->
GetSize();
623 if (num_variables > 0) {
624 for (
size_t i = 0; i < num_variables; i++) {
626 switch (var_sp->GetScope()) {
647 std::string scope_string;
658 if (valobj_sp->IsInScope()) {
659 if (!valobj_sp->GetTargetSP()
660 ->GetDisplayRuntimeSupportValues() &&
661 valobj_sp->IsRuntimeSupportValue())
664 if (!scope_string.empty())
668 var_sp->GetDeclaration().GetFile()) {
669 var_sp->GetDeclaration().DumpStopContext(&s,
false);
675 valobj_sp->GetPreferredDisplayLanguage());
677 var_sp ? var_sp->GetName().AsCString() :
nullptr);
690 if (recognized_frame) {
691 ValueObjectListSP recognized_arg_list =
692 recognized_frame->GetRecognizedArguments();
693 if (recognized_arg_list) {
694 for (
auto &rec_value_sp : recognized_arg_list->GetObjects()) {
697 rec_value_sp->GetPreferredDisplayLanguage());
724#pragma mark CommandObjectFrameRecognizer
726#define LLDB_OPTIONS_frame_recognizer_add
727#include "CommandOptions.inc"
741 switch (short_option) {
748 error.SetErrorStringWithFormat(
749 "invalid boolean value '%s' passed for -f option",
750 option_arg.str().c_str());
760 m_symbols.push_back(std::string(option_arg));
766 llvm_unreachable(
"Unimplemented option");
781 return llvm::ArrayRef(g_frame_recognizer_add_options);
802 "Add a new frame recognizer.", nullptr) {
804Frame recognizers allow for retrieving information about special frames based on
805ABI, arguments or other special properties of that frame, even without source
806code or debug info. Currently, one use case is to extract function arguments
807that would otherwise be unaccesible, or augment existing arguments.
809Adding a custom frame recognizer is possible by implementing a Python class
810and using the 'frame recognizer add' command. The Python class should have a
811'get_recognized_arguments' method and it will receive an argument of type
812lldb.SBFrame representing the current frame that we are trying to recognize.
813The method should return a (possibly empty) list of lldb.SBValue objects that
814represent the recognized arguments.
816An example of a recognizer that retrieves the file descriptor values from libc
817functions 'read', 'write' and 'close' follows:
819 class LibcFdRecognizer(object):
820 def get_recognized_arguments(self, frame):
821 if frame.name in ["read", "write", "close"]:
822 fd = frame.EvaluateExpression("$arg1").unsigned
823 target = frame.thread.process.target
824 value = target.CreateValueFromExpression("fd", "(int)%d" % fd)
828The file containing this implementation can be imported via 'command script
829import' and then we can register this recognizer with 'frame recognizer add'.
830It's important to restrict the recognizer to the libc library (which is
831libsystem_kernel.dylib on macOS) to avoid matching functions with the same name
834(lldb) command script import .../fd_recognizer.py
835(lldb) frame recognizer add -l fd_recognizer.LibcFdRecognizer -n read -s libsystem_kernel.dylib
837When the program is stopped at the beginning of the 'read' function in libc, we
838can view the recognizer arguments in 'frame variable':
843* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.3
844 frame #0: 0x00007fff06013ca0 libsystem_kernel.dylib`read
855#if LLDB_ENABLE_PYTHON
858 "%s needs a Python class name (-l argument).\n",
m_cmd_name.c_str());
870 "%s needs at least one symbol name (-n argument).\n",
877 "%s needs only one symbol regular expression (-n argument).\n",
886 result.
AppendWarning(
"The provided class does not exist - please define it "
887 "before attempting to use this frame recognizer");
890 StackFrameRecognizerSP recognizer_sp =
917 "Delete all frame recognizers.", nullptr) {}
935 "Delete an existing frame recognizer by id.",
950 [&request](
uint32_t rid, std::string rname, std::string module,
951 llvm::ArrayRef<lldb_private::ConstString> symbols,
955 rname =
"(internal)";
959 strm <<
", module " << module;
960 if (!symbols.empty())
961 for (
auto &symbol : symbols)
962 strm <<
", symbol " << symbol;
974 "About to delete all frame recognizers, do you want to do that?",
1001 .GetFrameRecognizerManager()
1002 .RemoveRecognizerWithID(recognizer_id)) {
1016 "Show a list of active frame recognizers.",
1023 bool any_printed =
false;
1025 [&result, &any_printed](
1026 uint32_t recognizer_id, std::string name, std::string module,
1027 llvm::ArrayRef<ConstString> symbols,
bool regexp) {
1031 name =
"(internal)";
1033 stream << std::to_string(recognizer_id) <<
": " << name;
1034 if (!module.empty())
1035 stream <<
", module " << module;
1036 if (!symbols.empty())
1037 for (
auto &symbol : symbols)
1038 stream <<
", symbol " << symbol;
1040 stream <<
" (regexp)";
1062 interpreter,
"frame recognizer info",
1063 "Show which frame recognizer is applied a stack frame (if any).",
1074 arg.push_back(index_arg);
1086 if (!llvm::to_integer(frame_index_str, frame_index)) {
1093 if (process ==
nullptr) {
1098 if (thread ==
nullptr) {
1104 "'%s' takes exactly one frame index argument.\n",
m_cmd_name.c_str());
1119 output_stream.
Printf(
"frame %d ", frame_index);
1121 output_stream <<
"is recognized by ";
1122 output_stream << recognizer->GetName();
1124 output_stream <<
"not recognized by any recognizer";
1126 output_stream.
EOL();
1136 interpreter,
"frame recognizer",
1137 "Commands for editing and viewing frame recognizers.",
1138 "frame recognizer [<sub-command-options>] ") {
1156#pragma mark CommandObjectMultiwordFrame
1163 "Commands for selecting and "
1164 "examing the current "
1165 "thread's stack frames.",
1166 "frame <subcommand> [<subcommand-options>]") {
1175#if LLDB_ENABLE_PYTHON
static llvm::raw_ostream & error(Stream &strm)
CommandObjectFrameInfo(CommandInterpreter &interpreter)
bool DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectFrameInfo() override=default
void OptionParsingStarting(ExecutionContext *execution_context) override
std::vector< std::string > m_symbols
bool m_first_instruction_only
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
~CommandOptions() override=default
CommandObjectFrameRecognizerAdd(CommandInterpreter &interpreter)
bool DoExecute(Args &command, CommandReturnObject &result) override
Options * GetOptions() override
~CommandObjectFrameRecognizerAdd() override=default
CommandObjectFrameRecognizerClear(CommandInterpreter &interpreter)
~CommandObjectFrameRecognizerClear() override=default
bool DoExecute(Args &command, CommandReturnObject &result) override
bool DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectFrameRecognizerDelete() override=default
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The input array contains a parsed version of the line.
CommandObjectFrameRecognizerDelete(CommandInterpreter &interpreter)
CommandObjectFrameRecognizerInfo(CommandInterpreter &interpreter)
~CommandObjectFrameRecognizerInfo() override=default
bool DoExecute(Args &command, CommandReturnObject &result) override
bool DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectFrameRecognizerList(CommandInterpreter &interpreter)
~CommandObjectFrameRecognizerList() override=default
~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.
std::optional< int32_t > relative_frame_offset
void OptionParsingStarting(ExecutionContext *execution_context) override
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
~CommandOptions() override=default
bool DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectFrameSelect() override=default
CommandObjectFrameSelect(CommandInterpreter &interpreter)
Options * GetOptions() override
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The input array contains a parsed version of the line.
OptionGroupOptions m_option_group
OptionGroupFormat m_option_format
Options * GetOptions() override
OptionGroupVariable m_option_variable
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The input array contains a parsed version of the line.
OptionGroupValueObjectDisplay m_varobj_options
bool DoExecute(Args &command, CommandReturnObject &result) override
llvm::StringRef GetScopeString(VariableSP var_sp)
~CommandObjectFrameVariable() override=default
CommandObjectFrameVariable(CommandInterpreter &interpreter)
A command line argument class.
size_t GetArgumentCount() const
Gets the number of arguments left in this command object.
const char * GetArgumentAtIndex(size_t idx) const
Gets the NULL terminated C string argument pointer for the argument at index idx.
static bool InvokeCommonCompletionCallbacks(CommandInterpreter &interpreter, uint32_t completion_mask, lldb_private::CompletionRequest &request, SearchFilter *searcher)
@ eVariablePathCompletion
bool Confirm(llvm::StringRef message, bool default_answer)
void PrintWarningsIfNecessary(Stream &s, const std::string &cmd_name)
CommandObjectMultiwordFrame(CommandInterpreter &interpreter)
~CommandObjectMultiwordFrame() override
bool LoadSubCommand(llvm::StringRef cmd_name, const lldb::CommandObjectSP &command_obj) override
std::vector< CommandArgumentData > CommandArgumentEntry
virtual void SetHelpLong(llvm::StringRef str)
ExecutionContext m_exe_ctx
std::vector< CommandArgumentEntry > m_arguments
CommandInterpreter & GetCommandInterpreter()
CommandInterpreter & m_interpreter
Target & GetSelectedOrDummyTarget(bool prefer_dummy=false)
void AppendMessage(llvm::StringRef in_string)
void void AppendError(llvm::StringRef in_string)
Stream & GetErrorStream()
void SetStatus(lldb::ReturnStatus status)
void AppendErrorWithFormat(const char *format,...) __attribute__((format(printf
lldb::ReturnStatus GetStatus() const
void void AppendWarning(llvm::StringRef in_string)
Stream & GetOutputStream()
"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.
size_t GetCursorIndex() const
A uniqued constant string class.
ScriptInterpreter * GetScriptInterpreter(bool can_create=true, std::optional< lldb::ScriptLanguage > language={})
DumpValueObjectOptions & SetVariableFormatDisplayLanguage(lldb::LanguageType lang=lldb::eLanguageTypeUnknown)
std::function< bool(ConstString, ConstString, const DumpValueObjectOptions &, Stream &)> DeclPrintingHelper
DumpValueObjectOptions & SetDeclPrintingHelper(DeclPrintingHelper helper)
DumpValueObjectOptions & SetRootValueObjectName(const char *name=nullptr)
DumpValueObjectOptions & SetFormat(lldb::Format format=lldb::eFormatDefault)
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
void SetFrameSP(const lldb::StackFrameSP &frame_sp)
Set accessor to set only the frame shared pointer.
StackFrame * GetFramePtr() const
Returns a pointer to the frame object.
StackFrame & GetFrameRef() const
Returns a reference to the thread object.
Process * GetProcessPtr() const
Returns a pointer to the process object.
Thread * GetThreadPtr() const
Returns a pointer to the thread object.
bool IsTopLevelFunction()
Get whether this function represents a 'top-level' function.
void Append(OptionGroup *group)
Append options from a OptionGroup class.
DumpValueObjectOptions GetAsDumpOptions(LanguageRuntimeDescriptionDisplayVerbosity lang_descr_verbosity=eLanguageRuntimeDescriptionDisplayVerbosityFull, lldb::Format format=lldb::eFormatDefault, lldb::TypeSummaryImplSP summary_sp=lldb::TypeSummaryImplSP())
lldb::DynamicValueType use_dynamic
OptionValueString summary_string
OptionValueString summary
bool show_recognized_args
bool IsCurrentValueEmpty() const
const char * GetCurrentValue() const
A command line option parsing protocol class.
void GenerateOptionUsage(Stream &strm, CommandObject &cmd, uint32_t screen_width)
std::vector< Option > m_getopt_table
A plug-in interface definition class for debugging a process.
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.
lldb::StackFrameRecognizerSP GetRecognizerForFrame(lldb::StackFrameSP frame)
void RemoveAllRecognizers()
void AddRecognizer(lldb::StackFrameRecognizerSP recognizer, ConstString module, llvm::ArrayRef< ConstString > symbols, bool first_instruction_only=true)
void ForEach(std::function< void(uint32_t recognizer_id, std::string recognizer_name, std::string module, llvm::ArrayRef< ConstString > symbols, bool regexp)> const &callback)
This base class provides an interface to stack frames.
@ eExpressionPathOptionCheckPtrVsMember
@ eExpressionPathOptionsInspectAnonymousUnions
@ eExpressionPathOptionsAllowDirectIVarAccess
VariableList * GetVariableList(bool get_file_globals, Status *error_ptr)
Retrieve the list of variables that are in scope at this StackFrame's pc.
void DumpUsingSettingsFormat(Stream *strm, bool show_unique=false, const char *frame_marker=nullptr)
Print a description for this frame using the frame-format formatter settings.
lldb::ValueObjectSP GetValueForVariableExpressionPath(llvm::StringRef var_expr, lldb::DynamicValueType use_dynamic, uint32_t options, lldb::VariableSP &var_sp, Status &error)
Create a ValueObject for a variable name / pathname, possibly including simple dereference/child sele...
lldb::ValueObjectSP GetValueObjectForFrameVariable(const lldb::VariableSP &variable_sp, lldb::DynamicValueType use_dynamic)
Create a ValueObject for a given Variable in this StackFrame.
const SymbolContext & GetSymbolContext(lldb::SymbolContextItem resolve_scope)
Provide a SymbolContext for this StackFrame's current pc value.
lldb::RecognizedStackFrameSP GetRecognizedFrame()
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.
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
virtual void Flush()=0
Flush the stream.
size_t EOL()
Output and End of Line character to the stream.
Defines a symbol context baton that can be handed other debug core functions.
Function * function
The Function for a given query.
A class that represents statistics for a since lldb_private::Target.
StatsSuccessFail & GetFrameVariableStats()
TargetStats & GetStatistics()
StackFrameRecognizerManager & GetFrameRecognizerManager()
virtual lldb::StackFrameSP GetStackFrameAtIndex(uint32_t idx)
uint32_t GetSelectedFrameIndex()
lldb::StackFrameSP GetSelectedFrame()
lldb::StopInfoSP GetStopInfo()
bool SetSelectedFrameByIndexNoisily(uint32_t frame_idx, Stream &output_stream)
virtual uint32_t GetStackFrameCount()
lldb::VariableSP GetVariableAtIndex(size_t idx) const
size_t AppendVariablesIfUnique(VariableList &var_list)
A class that represents a running process on the host machine.
std::vector< OptionArgElement > OptionElementVector
@ eLanguageRuntimeDescriptionDisplayVerbosityFull
Format
Display format definitions.
@ eReturnStatusSuccessFinishResult
@ eReturnStatusSuccessFinishNoResult
@ eValueTypeVariableGlobal
globals variable
@ eValueTypeVariableLocal
function local variables
@ eValueTypeVariableArgument
function argument variables
@ eValueTypeVariableStatic
static variable
@ eValueTypeVariableThreadLocal
thread local storage variable
Used to build individual command argument lists.
ArgumentRepetitionType arg_repetition
lldb::CommandArgumentType arg_type
static bool ToBoolean(llvm::StringRef s, bool fail_value, bool *success_ptr)