bool DoExecute(Args &command, CommandReturnObject &result) override { // No need to check "frame" for validity as eCommandRequiresFrame ensures it // is valid StackFrame *frame = m_exe_ctx.GetFramePtr(); Stream &s = result.GetOutputStream(); // Be careful about the stack frame, if any summary formatter runs code, it // might clear the StackFrameList // for the thread. So hold onto a shared pointer to the frame so it stays // alive. VariableList *variable_list = frame->GetVariableList(m_option_variable.show_globals); VariableSP var_sp; ValueObjectSP valobj_sp; const char *name_cstr = nullptr; size_t idx; TypeSummaryImplSP summary_format_sp; if (!m_option_variable.summary.IsCurrentValueEmpty()) DataVisualization::NamedSummaryFormats::GetSummaryFormat( ConstString(m_option_variable.summary.GetCurrentValue()), summary_format_sp); else if (!m_option_variable.summary_string.IsCurrentValueEmpty()) summary_format_sp.reset(new StringSummaryFormat( TypeSummaryImpl::Flags(), m_option_variable.summary_string.GetCurrentValue())); DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions( eLanguageRuntimeDescriptionDisplayVerbosityFull, eFormatDefault, summary_format_sp)); const SymbolContext &sym_ctx = frame->GetSymbolContext(eSymbolContextFunction); if (sym_ctx.function && sym_ctx.function->IsTopLevelFunction()) m_option_variable.show_globals = true; if (variable_list) { const Format format = m_option_format.GetFormat(); options.SetFormat(format); if (!command.empty()) { VariableList regex_var_list; // If we have any args to the variable command, we will make // variable objects from them... for (idx = 0; (name_cstr = command.GetArgumentAtIndex(idx)) != nullptr; ++idx) { if (m_option_variable.use_regex) { const size_t regex_start_index = regex_var_list.GetSize(); llvm::StringRef name_str(name_cstr); RegularExpression regex(name_str); if (regex.Compile(name_str)) { size_t num_matches = 0; const size_t num_new_regex_vars = variable_list->AppendVariablesIfUnique(regex, regex_var_list, num_matches); if (num_new_regex_vars > 0) { for (size_t regex_idx = regex_start_index, end_index = regex_var_list.GetSize(); regex_idx < end_index; ++regex_idx) { var_sp = regex_var_list.GetVariableAtIndex(regex_idx); if (var_sp) { valobj_sp = frame->GetValueObjectForFrameVariable( var_sp, m_varobj_options.use_dynamic); if (valobj_sp) { // if (format // != // eFormatDefault) // valobj_sp->SetFormat // (format); std::string scope_string; if (m_option_variable.show_scope) scope_string = GetScopeString(var_sp).str(); if (!scope_string.empty()) s.PutCString(scope_string); if (m_option_variable.show_decl && var_sp->GetDeclaration().GetFile()) { bool show_fullpaths = false; bool show_module = true; if (var_sp->DumpDeclaration(&s, show_fullpaths, show_module)) s.PutCString(": "); } valobj_sp->Dump(result.GetOutputStream(), options); } } } } else if (num_matches == 0) { result.GetErrorStream().Printf("error: no variables matched " "the regular expression '%s'.\n", name_cstr); } } else { char regex_error[1024]; if (regex.GetErrorAsCString(regex_error, sizeof(regex_error))) result.GetErrorStream().Printf("error: %s\n", regex_error); else result.GetErrorStream().Printf( "error: unknown regex error when compiling '%s'\n", name_cstr); } } else // No regex, either exact variable names or variable // expressions. { Error error; uint32_t expr_path_options = StackFrame::eExpressionPathOptionCheckPtrVsMember | StackFrame::eExpressionPathOptionsAllowDirectIVarAccess | StackFrame::eExpressionPathOptionsInspectAnonymousUnions; lldb::VariableSP var_sp; valobj_sp = frame->GetValueForVariableExpressionPath( name_cstr, m_varobj_options.use_dynamic, expr_path_options, var_sp, error); if (valobj_sp) { std::string scope_string; if (m_option_variable.show_scope) scope_string = GetScopeString(var_sp).str(); if (!scope_string.empty()) s.PutCString(scope_string); // if (format != eFormatDefault) // valobj_sp->SetFormat (format); if (m_option_variable.show_decl && var_sp && var_sp->GetDeclaration().GetFile()) { var_sp->GetDeclaration().DumpStopContext(&s, false); s.PutCString(": "); } options.SetFormat(format); options.SetVariableFormatDisplayLanguage( valobj_sp->GetPreferredDisplayLanguage()); Stream &output_stream = result.GetOutputStream(); options.SetRootValueObjectName(valobj_sp->GetParent() ? name_cstr : nullptr); valobj_sp->Dump(output_stream, options); } else { const char *error_cstr = error.AsCString(nullptr); if (error_cstr) result.GetErrorStream().Printf("error: %s\n", error_cstr); else result.GetErrorStream().Printf("error: unable to find any " "variable expression path that " "matches '%s'.\n", name_cstr); } } } } else // No command arg specified. Use variable_list, instead. { const size_t num_variables = variable_list->GetSize(); if (num_variables > 0) { for (size_t i = 0; i < num_variables; i++) { var_sp = variable_list->GetVariableAtIndex(i); bool dump_variable = true; std::string scope_string; if (dump_variable && m_option_variable.show_scope) scope_string = GetScopeString(var_sp).str(); if (dump_variable) { // Use the variable object code to make sure we are // using the same APIs as the public API will be // using... valobj_sp = frame->GetValueObjectForFrameVariable( var_sp, m_varobj_options.use_dynamic); if (valobj_sp) { // if (format != eFormatDefault) // valobj_sp->SetFormat // (format); // When dumping all variables, don't print any variables // that are not in scope to avoid extra unneeded output if (valobj_sp->IsInScope()) { if (!valobj_sp->GetTargetSP() ->GetDisplayRuntimeSupportValues() && valobj_sp->IsRuntimeSupportValue()) continue; if (!scope_string.empty()) s.PutCString(scope_string); if (m_option_variable.show_decl && var_sp->GetDeclaration().GetFile()) { var_sp->GetDeclaration().DumpStopContext(&s, false); s.PutCString(": "); } options.SetFormat(format); options.SetVariableFormatDisplayLanguage( valobj_sp->GetPreferredDisplayLanguage()); options.SetRootValueObjectName(name_cstr); valobj_sp->Dump(result.GetOutputStream(), options); } } } } } } result.SetStatus(eReturnStatusSuccessFinishResult); } if (m_interpreter.TruncationWarningNecessary()) { result.GetOutputStream().Printf(m_interpreter.TruncationWarningText(), m_cmd_name.c_str()); m_interpreter.TruncationWarningGiven(); } return result.Succeeded(); }
virtual bool DoExecute (Args& command, CommandReturnObject &result) { ExecutionContext exe_ctx(m_interpreter.GetExecutionContext()); StackFrame *frame = exe_ctx.GetFramePtr(); if (frame == NULL) { result.AppendError ("you must be stopped in a valid stack frame to view frame variables."); result.SetStatus (eReturnStatusFailed); return false; } Stream &s = result.GetOutputStream(); bool get_file_globals = true; // Be careful about the stack frame, if any summary formatter runs code, it might clear the StackFrameList // for the thread. So hold onto a shared pointer to the frame so it stays alive. VariableList *variable_list = frame->GetVariableList (get_file_globals); VariableSP var_sp; ValueObjectSP valobj_sp; const char *name_cstr = NULL; size_t idx; TypeSummaryImplSP summary_format_sp; if (!m_option_variable.summary.IsCurrentValueEmpty()) DataVisualization::NamedSummaryFormats::GetSummaryFormat(ConstString(m_option_variable.summary.GetCurrentValue()), summary_format_sp); else if (!m_option_variable.summary_string.IsCurrentValueEmpty()) summary_format_sp.reset(new StringSummaryFormat(TypeSummaryImpl::Flags(),m_option_variable.summary_string.GetCurrentValue())); ValueObject::DumpValueObjectOptions options; options.SetMaximumPointerDepth(m_varobj_options.ptr_depth) .SetMaximumDepth(m_varobj_options.max_depth) .SetShowTypes(m_varobj_options.show_types) .SetShowLocation(m_varobj_options.show_location) .SetUseObjectiveC(m_varobj_options.use_objc) .SetUseDynamicType(m_varobj_options.use_dynamic) .SetUseSyntheticValue(m_varobj_options.use_synth) .SetFlatOutput(m_varobj_options.flat_output) .SetOmitSummaryDepth(m_varobj_options.no_summary_depth) .SetIgnoreCap(m_varobj_options.ignore_cap) .SetSummary(summary_format_sp); if (m_varobj_options.be_raw) options.SetRawDisplay(true); if (variable_list) { const Format format = m_option_format.GetFormat(); options.SetFormat(format); if (command.GetArgumentCount() > 0) { VariableList regex_var_list; // If we have any args to the variable command, we will make // variable objects from them... for (idx = 0; (name_cstr = command.GetArgumentAtIndex(idx)) != NULL; ++idx) { if (m_option_variable.use_regex) { const uint32_t regex_start_index = regex_var_list.GetSize(); RegularExpression regex (name_cstr); if (regex.Compile(name_cstr)) { size_t num_matches = 0; const size_t num_new_regex_vars = variable_list->AppendVariablesIfUnique(regex, regex_var_list, num_matches); if (num_new_regex_vars > 0) { for (uint32_t regex_idx = regex_start_index, end_index = regex_var_list.GetSize(); regex_idx < end_index; ++regex_idx) { var_sp = regex_var_list.GetVariableAtIndex (regex_idx); if (var_sp) { valobj_sp = frame->GetValueObjectForFrameVariable (var_sp, m_varobj_options.use_dynamic); if (valobj_sp) { // if (format != eFormatDefault) // valobj_sp->SetFormat (format); if (m_option_variable.show_decl && var_sp->GetDeclaration ().GetFile()) { bool show_fullpaths = false; bool show_module = true; if (var_sp->DumpDeclaration(&s, show_fullpaths, show_module)) s.PutCString (": "); } ValueObject::DumpValueObject (result.GetOutputStream(), valobj_sp.get(), options); } } } } else if (num_matches == 0) { result.GetErrorStream().Printf ("error: no variables matched the regular expression '%s'.\n", name_cstr); } } else { char regex_error[1024]; if (regex.GetErrorAsCString(regex_error, sizeof(regex_error))) result.GetErrorStream().Printf ("error: %s\n", regex_error); else result.GetErrorStream().Printf ("error: unkown regex error when compiling '%s'\n", name_cstr); } } else // No regex, either exact variable names or variable expressions. { Error error; uint32_t expr_path_options = StackFrame::eExpressionPathOptionCheckPtrVsMember | StackFrame::eExpressionPathOptionsAllowDirectIVarAccess; lldb::VariableSP var_sp; valobj_sp = frame->GetValueForVariableExpressionPath (name_cstr, m_varobj_options.use_dynamic, expr_path_options, var_sp, error); if (valobj_sp) { // if (format != eFormatDefault) // valobj_sp->SetFormat (format); if (m_option_variable.show_decl && var_sp && var_sp->GetDeclaration ().GetFile()) { var_sp->GetDeclaration ().DumpStopContext (&s, false); s.PutCString (": "); } options.SetFormat(format); Stream &output_stream = result.GetOutputStream(); options.SetRootValueObjectName(valobj_sp->GetParent() ? name_cstr : NULL); ValueObject::DumpValueObject (output_stream, valobj_sp.get(), options); } else { const char *error_cstr = error.AsCString(NULL); if (error_cstr) result.GetErrorStream().Printf("error: %s\n", error_cstr); else result.GetErrorStream().Printf ("error: unable to find any variable expression path that matches '%s'\n", name_cstr); } } } } else // No command arg specified. Use variable_list, instead. { const uint32_t num_variables = variable_list->GetSize(); if (num_variables > 0) { for (uint32_t i=0; i<num_variables; i++) { var_sp = variable_list->GetVariableAtIndex(i); bool dump_variable = true; switch (var_sp->GetScope()) { case eValueTypeVariableGlobal: dump_variable = m_option_variable.show_globals; if (dump_variable && m_option_variable.show_scope) s.PutCString("GLOBAL: "); break; case eValueTypeVariableStatic: dump_variable = m_option_variable.show_globals; if (dump_variable && m_option_variable.show_scope) s.PutCString("STATIC: "); break; case eValueTypeVariableArgument: dump_variable = m_option_variable.show_args; if (dump_variable && m_option_variable.show_scope) s.PutCString(" ARG: "); break; case eValueTypeVariableLocal: dump_variable = m_option_variable.show_locals; if (dump_variable && m_option_variable.show_scope) s.PutCString(" LOCAL: "); break; default: break; } if (dump_variable) { // Use the variable object code to make sure we are // using the same APIs as the the public API will be // using... valobj_sp = frame->GetValueObjectForFrameVariable (var_sp, m_varobj_options.use_dynamic); if (valobj_sp) { // if (format != eFormatDefault) // valobj_sp->SetFormat (format); // When dumping all variables, don't print any variables // that are not in scope to avoid extra unneeded output if (valobj_sp->IsInScope ()) { if (m_option_variable.show_decl && var_sp->GetDeclaration ().GetFile()) { var_sp->GetDeclaration ().DumpStopContext (&s, false); s.PutCString (": "); } options.SetFormat(format); options.SetRootValueObjectName(name_cstr); ValueObject::DumpValueObject (result.GetOutputStream(), valobj_sp.get(), options); } } } } } } result.SetStatus (eReturnStatusSuccessFinishResult); } if (m_interpreter.TruncationWarningNecessary()) { result.GetOutputStream().Printf(m_interpreter.TruncationWarningText(), m_cmd_name.c_str()); m_interpreter.TruncationWarningGiven(); } return result.Succeeded(); }
SBValue SBFrame::FindVariable (const char *name, lldb::DynamicValueType use_dynamic) { LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); VariableSP var_sp; SBValue sb_value; if (name == NULL || name[0] == '\0') { if (log) log->Printf ("SBFrame::FindVariable called with empty name"); return sb_value; } ValueObjectSP value_sp; Mutex::Locker api_locker; ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); StackFrame *frame = NULL; Target *target = exe_ctx.GetTargetPtr(); Process *process = exe_ctx.GetProcessPtr(); if (target && process) { Process::StopLocker stop_locker; if (stop_locker.TryLock(&process->GetRunLock())) { frame = exe_ctx.GetFramePtr(); if (frame) { VariableList variable_list; SymbolContext sc (frame->GetSymbolContext (eSymbolContextBlock)); if (sc.block) { const bool can_create = true; const bool get_parent_variables = true; const bool stop_if_block_is_inlined_function = true; if (sc.block->AppendVariables (can_create, get_parent_variables, stop_if_block_is_inlined_function, &variable_list)) { var_sp = variable_list.FindVariable (ConstString(name)); } } if (var_sp) { value_sp = frame->GetValueObjectForFrameVariable(var_sp, eNoDynamicValues); sb_value.SetSP(value_sp, use_dynamic); } } else { if (log) log->Printf ("SBFrame::FindVariable () => error: could not reconstruct frame object for this SBFrame."); } } else { if (log) log->Printf ("SBFrame::FindVariable () => error: process is running"); } } if (log) log->Printf ("SBFrame(%p)::FindVariable (name=\"%s\") => SBValue(%p)", frame, name, value_sp.get()); return sb_value; }
SBValue SBFrame::FindValue (const char *name, ValueType value_type, lldb::DynamicValueType use_dynamic) { LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); SBValue sb_value; if (name == NULL || name[0] == '\0') { if (log) log->Printf ("SBFrame::FindValue called with empty name."); return sb_value; } ValueObjectSP value_sp; Mutex::Locker api_locker; ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); StackFrame *frame = NULL; Target *target = exe_ctx.GetTargetPtr(); Process *process = exe_ctx.GetProcessPtr(); if (target && process) { Process::StopLocker stop_locker; if (stop_locker.TryLock(&process->GetRunLock())) { frame = exe_ctx.GetFramePtr(); if (frame) { switch (value_type) { case eValueTypeVariableGlobal: // global variable case eValueTypeVariableStatic: // static variable case eValueTypeVariableArgument: // function argument variables case eValueTypeVariableLocal: // function local variables { VariableList *variable_list = frame->GetVariableList(true); SymbolContext sc (frame->GetSymbolContext (eSymbolContextBlock)); const bool can_create = true; const bool get_parent_variables = true; const bool stop_if_block_is_inlined_function = true; if (sc.block && sc.block->AppendVariables (can_create, get_parent_variables, stop_if_block_is_inlined_function, variable_list)) { ConstString const_name(name); const uint32_t num_variables = variable_list->GetSize(); for (uint32_t i = 0; i < num_variables; ++i) { VariableSP variable_sp (variable_list->GetVariableAtIndex(i)); if (variable_sp && variable_sp->GetScope() == value_type && variable_sp->GetName() == const_name) { value_sp = frame->GetValueObjectForFrameVariable (variable_sp, eNoDynamicValues); sb_value.SetSP (value_sp, use_dynamic); break; } } } } break; case eValueTypeRegister: // stack frame register value { RegisterContextSP reg_ctx (frame->GetRegisterContext()); if (reg_ctx) { const uint32_t num_regs = reg_ctx->GetRegisterCount(); for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) { const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_idx); if (reg_info && ((reg_info->name && strcasecmp (reg_info->name, name) == 0) || (reg_info->alt_name && strcasecmp (reg_info->alt_name, name) == 0))) { value_sp = ValueObjectRegister::Create (frame, reg_ctx, reg_idx); sb_value.SetSP (value_sp); break; } } } } break; case eValueTypeRegisterSet: // A collection of stack frame register values { RegisterContextSP reg_ctx (frame->GetRegisterContext()); if (reg_ctx) { const uint32_t num_sets = reg_ctx->GetRegisterSetCount(); for (uint32_t set_idx = 0; set_idx < num_sets; ++set_idx) { const RegisterSet *reg_set = reg_ctx->GetRegisterSet (set_idx); if (reg_set && ((reg_set->name && strcasecmp (reg_set->name, name) == 0) || (reg_set->short_name && strcasecmp (reg_set->short_name, name) == 0))) { value_sp = ValueObjectRegisterSet::Create (frame, reg_ctx, set_idx); sb_value.SetSP (value_sp); break; } } } } break; case eValueTypeConstResult: // constant result variables { ConstString const_name(name); ClangExpressionVariableSP expr_var_sp (target->GetPersistentVariables().GetVariable (const_name)); if (expr_var_sp) { value_sp = expr_var_sp->GetValueObject(); sb_value.SetSP (value_sp, use_dynamic); } } break; default: break; } } else { if (log) log->Printf ("SBFrame::FindValue () => error: could not reconstruct frame object for this SBFrame."); } } else { if (log) log->Printf ("SBFrame::FindValue () => error: process is running"); } } if (log) log->Printf ("SBFrame(%p)::FindVariableInScope (name=\"%s\", value_type=%i) => SBValue(%p)", frame, name, value_type, value_sp.get()); return sb_value; }
SBValueList SBFrame::GetVariables (bool arguments, bool locals, bool statics, bool in_scope_only, lldb::DynamicValueType use_dynamic) { LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); SBValueList value_list; Mutex::Locker api_locker; ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); StackFrame *frame = NULL; Target *target = exe_ctx.GetTargetPtr(); if (log) log->Printf ("SBFrame::GetVariables (arguments=%i, locals=%i, statics=%i, in_scope_only=%i)", arguments, locals, statics, in_scope_only); Process *process = exe_ctx.GetProcessPtr(); if (target && process) { Process::StopLocker stop_locker; if (stop_locker.TryLock(&process->GetRunLock())) { frame = exe_ctx.GetFramePtr(); if (frame) { size_t i; VariableList *variable_list = NULL; variable_list = frame->GetVariableList(true); if (variable_list) { const size_t num_variables = variable_list->GetSize(); if (num_variables) { for (i = 0; i < num_variables; ++i) { VariableSP variable_sp (variable_list->GetVariableAtIndex(i)); if (variable_sp) { bool add_variable = false; switch (variable_sp->GetScope()) { case eValueTypeVariableGlobal: case eValueTypeVariableStatic: add_variable = statics; break; case eValueTypeVariableArgument: add_variable = arguments; break; case eValueTypeVariableLocal: add_variable = locals; break; default: break; } if (add_variable) { if (in_scope_only && !variable_sp->IsInScope(frame)) continue; ValueObjectSP valobj_sp(frame->GetValueObjectForFrameVariable (variable_sp, eNoDynamicValues)); SBValue value_sb; value_sb.SetSP(valobj_sp,use_dynamic); value_list.Append(value_sb); } } } } } } else { if (log) log->Printf ("SBFrame::GetVariables () => error: could not reconstruct frame object for this SBFrame."); } } else { if (log) log->Printf ("SBFrame::GetVariables () => error: process is running"); } } if (log) { log->Printf ("SBFrame(%p)::GetVariables (...) => SBValueList(%p)", frame, value_list.get()); } return value_list; }