130fdc8d8SChris Lattner //===-- CommandObjectFrame.cpp ----------------------------------*- C++ -*-===// 230fdc8d8SChris Lattner // 330fdc8d8SChris Lattner // The LLVM Compiler Infrastructure 430fdc8d8SChris Lattner // 530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source 630fdc8d8SChris Lattner // License. See LICENSE.TXT for details. 730fdc8d8SChris Lattner // 830fdc8d8SChris Lattner //===----------------------------------------------------------------------===// 930fdc8d8SChris Lattner 1030fdc8d8SChris Lattner #include "CommandObjectFrame.h" 1130fdc8d8SChris Lattner 1230fdc8d8SChris Lattner // C Includes 1330fdc8d8SChris Lattner // C++ Includes 1430fdc8d8SChris Lattner // Other libraries and framework includes 1530fdc8d8SChris Lattner // Project includes 1630fdc8d8SChris Lattner #include "lldb/Core/Debugger.h" 17*6d56d2ceSJim Ingham #include "lldb/Core/Module.h" 18*6d56d2ceSJim Ingham #include "lldb/Core/StreamFile.h" 1930fdc8d8SChris Lattner #include "lldb/Core/Timer.h" 20*6d56d2ceSJim Ingham #include "lldb/Core/Value.h" 21*6d56d2ceSJim Ingham #include "lldb/Core/ValueObject.h" 22*6d56d2ceSJim Ingham #include "lldb/Core/ValueObjectVariable.h" 23*6d56d2ceSJim Ingham #include "lldb/Interpreter/Args.h" 2430fdc8d8SChris Lattner #include "lldb/Interpreter/CommandInterpreter.h" 2530fdc8d8SChris Lattner #include "lldb/Interpreter/CommandReturnObject.h" 26*6d56d2ceSJim Ingham #include "lldb/Interpreter/Options.h" 27*6d56d2ceSJim Ingham #include "lldb/Symbol/ClangASTType.h" 28*6d56d2ceSJim Ingham #include "lldb/Symbol/ClangASTContext.h" 29*6d56d2ceSJim Ingham #include "lldb/Symbol/ObjectFile.h" 30*6d56d2ceSJim Ingham #include "lldb/Symbol/SymbolContext.h" 31*6d56d2ceSJim Ingham #include "lldb/Symbol/Type.h" 32*6d56d2ceSJim Ingham #include "lldb/Symbol/Variable.h" 33*6d56d2ceSJim Ingham #include "lldb/Symbol/VariableList.h" 3430fdc8d8SChris Lattner #include "lldb/Target/Process.h" 3530fdc8d8SChris Lattner #include "lldb/Target/StackFrame.h" 3630fdc8d8SChris Lattner #include "lldb/Target/Thread.h" 37*6d56d2ceSJim Ingham #include "lldb/Target/Target.h" 3830fdc8d8SChris Lattner 3930fdc8d8SChris Lattner #include "CommandObjectThread.h" 4030fdc8d8SChris Lattner 4130fdc8d8SChris Lattner using namespace lldb; 4230fdc8d8SChris Lattner using namespace lldb_private; 4330fdc8d8SChris Lattner 4430fdc8d8SChris Lattner #pragma mark CommandObjectFrameInfo 4530fdc8d8SChris Lattner 4630fdc8d8SChris Lattner //------------------------------------------------------------------------- 4730fdc8d8SChris Lattner // CommandObjectFrameInfo 4830fdc8d8SChris Lattner //------------------------------------------------------------------------- 4930fdc8d8SChris Lattner 5030fdc8d8SChris Lattner class CommandObjectFrameInfo : public CommandObject 5130fdc8d8SChris Lattner { 5230fdc8d8SChris Lattner public: 5330fdc8d8SChris Lattner 5430fdc8d8SChris Lattner CommandObjectFrameInfo () : 5530fdc8d8SChris Lattner CommandObject ("frame info", 5630fdc8d8SChris Lattner "Lists information about the currently selected frame in the current thread.", 5730fdc8d8SChris Lattner "frame info", 5830fdc8d8SChris Lattner eFlagProcessMustBeLaunched | eFlagProcessMustBePaused) 5930fdc8d8SChris Lattner { 6030fdc8d8SChris Lattner } 6130fdc8d8SChris Lattner 6230fdc8d8SChris Lattner ~CommandObjectFrameInfo () 6330fdc8d8SChris Lattner { 6430fdc8d8SChris Lattner } 6530fdc8d8SChris Lattner 6630fdc8d8SChris Lattner bool 676611103cSGreg Clayton Execute (CommandInterpreter &interpreter, 686611103cSGreg Clayton Args& command, 6930fdc8d8SChris Lattner CommandReturnObject &result) 7030fdc8d8SChris Lattner { 716611103cSGreg Clayton ExecutionContext exe_ctx(interpreter.GetDebugger().GetExecutionContext()); 7230fdc8d8SChris Lattner if (exe_ctx.frame) 7330fdc8d8SChris Lattner { 7430fdc8d8SChris Lattner exe_ctx.frame->Dump (&result.GetOutputStream(), true); 7530fdc8d8SChris Lattner result.GetOutputStream().EOL(); 7630fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishResult); 7730fdc8d8SChris Lattner } 7830fdc8d8SChris Lattner else 7930fdc8d8SChris Lattner { 8030fdc8d8SChris Lattner result.AppendError ("no current frame"); 8130fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 8230fdc8d8SChris Lattner } 8330fdc8d8SChris Lattner return result.Succeeded(); 8430fdc8d8SChris Lattner } 8530fdc8d8SChris Lattner }; 8630fdc8d8SChris Lattner 8730fdc8d8SChris Lattner #pragma mark CommandObjectFrameSelect 8830fdc8d8SChris Lattner 8930fdc8d8SChris Lattner //------------------------------------------------------------------------- 9030fdc8d8SChris Lattner // CommandObjectFrameSelect 9130fdc8d8SChris Lattner //------------------------------------------------------------------------- 9230fdc8d8SChris Lattner 9330fdc8d8SChris Lattner class CommandObjectFrameSelect : public CommandObject 9430fdc8d8SChris Lattner { 9530fdc8d8SChris Lattner public: 9630fdc8d8SChris Lattner 9730fdc8d8SChris Lattner CommandObjectFrameSelect () : 9830fdc8d8SChris Lattner CommandObject ("frame select", 9930fdc8d8SChris Lattner "Select the current frame by index in the current thread.", 10030fdc8d8SChris Lattner "frame select <frame-index>", 10130fdc8d8SChris Lattner eFlagProcessMustBeLaunched | eFlagProcessMustBePaused) 10230fdc8d8SChris Lattner { 10330fdc8d8SChris Lattner } 10430fdc8d8SChris Lattner 10530fdc8d8SChris Lattner ~CommandObjectFrameSelect () 10630fdc8d8SChris Lattner { 10730fdc8d8SChris Lattner } 10830fdc8d8SChris Lattner 10930fdc8d8SChris Lattner bool 1106611103cSGreg Clayton Execute (CommandInterpreter &interpreter, 1116611103cSGreg Clayton Args& command, 11230fdc8d8SChris Lattner CommandReturnObject &result) 11330fdc8d8SChris Lattner { 1146611103cSGreg Clayton ExecutionContext exe_ctx (interpreter.GetDebugger().GetExecutionContext()); 11530fdc8d8SChris Lattner if (exe_ctx.thread) 11630fdc8d8SChris Lattner { 11730fdc8d8SChris Lattner if (command.GetArgumentCount() == 1) 11830fdc8d8SChris Lattner { 11930fdc8d8SChris Lattner const char *frame_idx_cstr = command.GetArgumentAtIndex(0); 12030fdc8d8SChris Lattner 12130fdc8d8SChris Lattner const uint32_t num_frames = exe_ctx.thread->GetStackFrameCount(); 12230fdc8d8SChris Lattner const uint32_t frame_idx = Args::StringToUInt32 (frame_idx_cstr, UINT32_MAX, 0); 12330fdc8d8SChris Lattner if (frame_idx < num_frames) 12430fdc8d8SChris Lattner { 1252976d00aSJim Ingham exe_ctx.thread->SetSelectedFrameByIndex (frame_idx); 1262976d00aSJim Ingham exe_ctx.frame = exe_ctx.thread->GetSelectedFrame ().get(); 12730fdc8d8SChris Lattner 12830fdc8d8SChris Lattner if (exe_ctx.frame) 12930fdc8d8SChris Lattner { 130e40e4218SJim Ingham bool already_shown = false; 131e40e4218SJim Ingham SymbolContext frame_sc(exe_ctx.frame->GetSymbolContext(eSymbolContextLineEntry)); 132e40e4218SJim Ingham if (interpreter.GetDebugger().UseExternalEditor() && frame_sc.line_entry.file && frame_sc.line_entry.line != 0) 133e40e4218SJim Ingham { 134e40e4218SJim Ingham already_shown = Host::OpenFileInExternalEditor (frame_sc.line_entry.file, frame_sc.line_entry.line); 135e40e4218SJim Ingham } 136e40e4218SJim Ingham 13730fdc8d8SChris Lattner if (DisplayFrameForExecutionContext (exe_ctx.thread, 13830fdc8d8SChris Lattner exe_ctx.frame, 13930fdc8d8SChris Lattner interpreter, 14030fdc8d8SChris Lattner result.GetOutputStream(), 14130fdc8d8SChris Lattner true, 142e40e4218SJim Ingham !already_shown, 14330fdc8d8SChris Lattner 3, 14430fdc8d8SChris Lattner 3)) 14530fdc8d8SChris Lattner { 14630fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishResult); 14730fdc8d8SChris Lattner return result.Succeeded(); 14830fdc8d8SChris Lattner } 14930fdc8d8SChris Lattner } 15030fdc8d8SChris Lattner } 15130fdc8d8SChris Lattner if (frame_idx == UINT32_MAX) 15230fdc8d8SChris Lattner result.AppendErrorWithFormat ("Invalid frame index: %s.\n", frame_idx_cstr); 15330fdc8d8SChris Lattner else 15430fdc8d8SChris Lattner result.AppendErrorWithFormat ("Frame index (%u) out of range.\n", frame_idx); 15530fdc8d8SChris Lattner } 15630fdc8d8SChris Lattner else 15730fdc8d8SChris Lattner { 15830fdc8d8SChris Lattner result.AppendError ("invalid arguments"); 15930fdc8d8SChris Lattner result.AppendErrorWithFormat ("Usage: %s\n", m_cmd_syntax.c_str()); 16030fdc8d8SChris Lattner } 16130fdc8d8SChris Lattner } 16230fdc8d8SChris Lattner else 16330fdc8d8SChris Lattner { 16430fdc8d8SChris Lattner result.AppendError ("no current thread"); 16530fdc8d8SChris Lattner } 16630fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 16730fdc8d8SChris Lattner return false; 16830fdc8d8SChris Lattner } 16930fdc8d8SChris Lattner }; 17030fdc8d8SChris Lattner 171*6d56d2ceSJim Ingham #pragma mark CommandObjectFrameVariable 172*6d56d2ceSJim Ingham //---------------------------------------------------------------------- 173*6d56d2ceSJim Ingham // List images with associated information 174*6d56d2ceSJim Ingham //---------------------------------------------------------------------- 175*6d56d2ceSJim Ingham class CommandObjectFrameVariable : public CommandObject 176*6d56d2ceSJim Ingham { 177*6d56d2ceSJim Ingham public: 178*6d56d2ceSJim Ingham 179*6d56d2ceSJim Ingham class CommandOptions : public Options 180*6d56d2ceSJim Ingham { 181*6d56d2ceSJim Ingham public: 182*6d56d2ceSJim Ingham 183*6d56d2ceSJim Ingham CommandOptions () : 184*6d56d2ceSJim Ingham Options() 185*6d56d2ceSJim Ingham { 186*6d56d2ceSJim Ingham ResetOptionValues (); 187*6d56d2ceSJim Ingham } 188*6d56d2ceSJim Ingham 189*6d56d2ceSJim Ingham virtual 190*6d56d2ceSJim Ingham ~CommandOptions () 191*6d56d2ceSJim Ingham { 192*6d56d2ceSJim Ingham } 193*6d56d2ceSJim Ingham 194*6d56d2ceSJim Ingham virtual Error 195*6d56d2ceSJim Ingham SetOptionValue (int option_idx, const char *option_arg) 196*6d56d2ceSJim Ingham { 197*6d56d2ceSJim Ingham Error error; 198*6d56d2ceSJim Ingham bool success; 199*6d56d2ceSJim Ingham char short_option = (char) m_getopt_table[option_idx].val; 200*6d56d2ceSJim Ingham switch (short_option) 201*6d56d2ceSJim Ingham { 202*6d56d2ceSJim Ingham case 'o': use_objc = true; break; 203*6d56d2ceSJim Ingham case 'n': name = option_arg; break; 204*6d56d2ceSJim Ingham case 'r': use_regex = true; break; 205*6d56d2ceSJim Ingham case 'a': show_args = false; break; 206*6d56d2ceSJim Ingham case 'l': show_locals = false; break; 207*6d56d2ceSJim Ingham case 'g': show_globals = false; break; 208*6d56d2ceSJim Ingham case 't': show_types = false; break; 209*6d56d2ceSJim Ingham case 'y': show_summary = false; break; 210*6d56d2ceSJim Ingham case 'L': show_location= true; break; 211*6d56d2ceSJim Ingham case 'D': debug = true; break; 212*6d56d2ceSJim Ingham case 'd': 213*6d56d2ceSJim Ingham max_depth = Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success); 214*6d56d2ceSJim Ingham if (!success) 215*6d56d2ceSJim Ingham error.SetErrorStringWithFormat("Invalid max depth '%s'.\n", option_arg); 216*6d56d2ceSJim Ingham break; 217*6d56d2ceSJim Ingham 218*6d56d2ceSJim Ingham case 'p': 219*6d56d2ceSJim Ingham ptr_depth = Args::StringToUInt32 (option_arg, 0, 0, &success); 220*6d56d2ceSJim Ingham if (!success) 221*6d56d2ceSJim Ingham error.SetErrorStringWithFormat("Invalid pointer depth '%s'.\n", option_arg); 222*6d56d2ceSJim Ingham break; 223*6d56d2ceSJim Ingham 224*6d56d2ceSJim Ingham case 'G': 225*6d56d2ceSJim Ingham { 226*6d56d2ceSJim Ingham ConstString const_string (option_arg); 227*6d56d2ceSJim Ingham globals.push_back(const_string); 228*6d56d2ceSJim Ingham } 229*6d56d2ceSJim Ingham break; 230*6d56d2ceSJim Ingham 231*6d56d2ceSJim Ingham case 's': 232*6d56d2ceSJim Ingham show_scope = true; 233*6d56d2ceSJim Ingham break; 234*6d56d2ceSJim Ingham 235*6d56d2ceSJim Ingham default: 236*6d56d2ceSJim Ingham error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option); 237*6d56d2ceSJim Ingham break; 238*6d56d2ceSJim Ingham } 239*6d56d2ceSJim Ingham 240*6d56d2ceSJim Ingham return error; 241*6d56d2ceSJim Ingham } 242*6d56d2ceSJim Ingham 243*6d56d2ceSJim Ingham void 244*6d56d2ceSJim Ingham ResetOptionValues () 245*6d56d2ceSJim Ingham { 246*6d56d2ceSJim Ingham Options::ResetOptionValues(); 247*6d56d2ceSJim Ingham 248*6d56d2ceSJim Ingham name.clear(); 249*6d56d2ceSJim Ingham use_objc = false; 250*6d56d2ceSJim Ingham use_regex = false; 251*6d56d2ceSJim Ingham show_args = true; 252*6d56d2ceSJim Ingham show_locals = true; 253*6d56d2ceSJim Ingham show_globals = true; 254*6d56d2ceSJim Ingham show_types = true; 255*6d56d2ceSJim Ingham show_scope = false; 256*6d56d2ceSJim Ingham show_summary = true; 257*6d56d2ceSJim Ingham show_location = false; 258*6d56d2ceSJim Ingham debug = false; 259*6d56d2ceSJim Ingham max_depth = UINT32_MAX; 260*6d56d2ceSJim Ingham ptr_depth = 0; 261*6d56d2ceSJim Ingham globals.clear(); 262*6d56d2ceSJim Ingham } 263*6d56d2ceSJim Ingham 264*6d56d2ceSJim Ingham const lldb::OptionDefinition* 265*6d56d2ceSJim Ingham GetDefinitions () 266*6d56d2ceSJim Ingham { 267*6d56d2ceSJim Ingham return g_option_table; 268*6d56d2ceSJim Ingham } 269*6d56d2ceSJim Ingham 270*6d56d2ceSJim Ingham // Options table: Required for subclasses of Options. 271*6d56d2ceSJim Ingham 272*6d56d2ceSJim Ingham static lldb::OptionDefinition g_option_table[]; 273*6d56d2ceSJim Ingham std::string name; 274*6d56d2ceSJim Ingham bool use_objc; 275*6d56d2ceSJim Ingham bool use_regex; 276*6d56d2ceSJim Ingham bool show_args; 277*6d56d2ceSJim Ingham bool show_locals; 278*6d56d2ceSJim Ingham bool show_globals; 279*6d56d2ceSJim Ingham bool show_types; 280*6d56d2ceSJim Ingham bool show_scope; // local/arg/global/static 281*6d56d2ceSJim Ingham bool show_summary; 282*6d56d2ceSJim Ingham bool show_location; 283*6d56d2ceSJim Ingham bool debug; 284*6d56d2ceSJim Ingham uint32_t max_depth; // The depth to print when dumping concrete (not pointers) aggreate values 285*6d56d2ceSJim Ingham uint32_t ptr_depth; // The default depth that is dumped when we find pointers 286*6d56d2ceSJim Ingham std::vector<ConstString> globals; 287*6d56d2ceSJim Ingham // Instance variables to hold the values for command options. 288*6d56d2ceSJim Ingham }; 289*6d56d2ceSJim Ingham 290*6d56d2ceSJim Ingham CommandObjectFrameVariable () : 291*6d56d2ceSJim Ingham CommandObject ( 292*6d56d2ceSJim Ingham "frame variable", 293*6d56d2ceSJim Ingham "Show specified argument, local variable, static variable or global variable for the current frame. If none specified, list them all.", 294*6d56d2ceSJim Ingham "frame variable [<cmd-options>] [<var-name1> [<var-name2>...]]") 295*6d56d2ceSJim Ingham { 296*6d56d2ceSJim Ingham } 297*6d56d2ceSJim Ingham 298*6d56d2ceSJim Ingham virtual 299*6d56d2ceSJim Ingham ~CommandObjectFrameVariable () 300*6d56d2ceSJim Ingham { 301*6d56d2ceSJim Ingham } 302*6d56d2ceSJim Ingham 303*6d56d2ceSJim Ingham virtual 304*6d56d2ceSJim Ingham Options * 305*6d56d2ceSJim Ingham GetOptions () 306*6d56d2ceSJim Ingham { 307*6d56d2ceSJim Ingham return &m_options; 308*6d56d2ceSJim Ingham } 309*6d56d2ceSJim Ingham 310*6d56d2ceSJim Ingham void 311*6d56d2ceSJim Ingham DumpVariable (CommandReturnObject &result, ExecutionContext *exe_ctx, Variable *variable) 312*6d56d2ceSJim Ingham { 313*6d56d2ceSJim Ingham if (variable) 314*6d56d2ceSJim Ingham { 315*6d56d2ceSJim Ingham Stream &s = result.GetOutputStream(); 316*6d56d2ceSJim Ingham DWARFExpression &expr = variable->LocationExpression(); 317*6d56d2ceSJim Ingham Value expr_result; 318*6d56d2ceSJim Ingham Error expr_error; 319*6d56d2ceSJim Ingham Type *variable_type = variable->GetType(); 320*6d56d2ceSJim Ingham bool expr_success = expr.Evaluate(exe_ctx, NULL, NULL, expr_result, &expr_error); 321*6d56d2ceSJim Ingham 322*6d56d2ceSJim Ingham if (m_options.debug) 323*6d56d2ceSJim Ingham s.Printf ("Variable{0x%8.8x}: ", variable->GetID()); 324*6d56d2ceSJim Ingham 325*6d56d2ceSJim Ingham if (!expr_success) 326*6d56d2ceSJim Ingham s.Printf ("%s = ERROR: %s\n", variable->GetName().AsCString(NULL), expr_error.AsCString()); 327*6d56d2ceSJim Ingham else 328*6d56d2ceSJim Ingham { 329*6d56d2ceSJim Ingham Value::ValueType expr_value_type = expr_result.GetValueType(); 330*6d56d2ceSJim Ingham switch (expr_value_type) 331*6d56d2ceSJim Ingham { 332*6d56d2ceSJim Ingham case Value::eValueTypeScalar: 333*6d56d2ceSJim Ingham s.Printf ("%s = ", variable->GetName().AsCString(NULL)); 334*6d56d2ceSJim Ingham if (variable_type) 335*6d56d2ceSJim Ingham { 336*6d56d2ceSJim Ingham DataExtractor data; 337*6d56d2ceSJim Ingham if (expr_result.ResolveValue (exe_ctx, NULL).GetData (data)) 338*6d56d2ceSJim Ingham variable_type->DumpValue (exe_ctx, &s, data, 0, m_options.show_types, m_options.show_summary, m_options.debug); 339*6d56d2ceSJim Ingham } 340*6d56d2ceSJim Ingham break; 341*6d56d2ceSJim Ingham 342*6d56d2ceSJim Ingham case Value::eValueTypeFileAddress: 343*6d56d2ceSJim Ingham case Value::eValueTypeLoadAddress: 344*6d56d2ceSJim Ingham case Value::eValueTypeHostAddress: 345*6d56d2ceSJim Ingham { 346*6d56d2ceSJim Ingham s.Printf ("%s = ", variable->GetName().AsCString(NULL)); 347*6d56d2ceSJim Ingham lldb::addr_t addr = LLDB_INVALID_ADDRESS; 348*6d56d2ceSJim Ingham lldb::AddressType addr_type = eAddressTypeLoad; 349*6d56d2ceSJim Ingham 350*6d56d2ceSJim Ingham if (expr_value_type == Value::eValueTypeFileAddress) 351*6d56d2ceSJim Ingham { 352*6d56d2ceSJim Ingham lldb::addr_t file_addr = expr_result.ResolveValue (exe_ctx, NULL).ULongLong(LLDB_INVALID_ADDRESS); 353*6d56d2ceSJim Ingham SymbolContext var_sc; 354*6d56d2ceSJim Ingham variable->CalculateSymbolContext(&var_sc); 355*6d56d2ceSJim Ingham if (var_sc.module_sp) 356*6d56d2ceSJim Ingham { 357*6d56d2ceSJim Ingham ObjectFile *objfile = var_sc.module_sp->GetObjectFile(); 358*6d56d2ceSJim Ingham if (objfile) 359*6d56d2ceSJim Ingham { 360*6d56d2ceSJim Ingham Address so_addr(file_addr, objfile->GetSectionList()); 361*6d56d2ceSJim Ingham addr = so_addr.GetLoadAddress(exe_ctx->process); 362*6d56d2ceSJim Ingham } 363*6d56d2ceSJim Ingham if (addr == LLDB_INVALID_ADDRESS) 364*6d56d2ceSJim Ingham { 365*6d56d2ceSJim Ingham result.GetErrorStream().Printf ("error: %s is not loaded", var_sc.module_sp->GetFileSpec().GetFilename().AsCString()); 366*6d56d2ceSJim Ingham } 367*6d56d2ceSJim Ingham } 368*6d56d2ceSJim Ingham else 369*6d56d2ceSJim Ingham { 370*6d56d2ceSJim Ingham result.GetErrorStream().Printf ("error: unable to resolve the variable address 0x%llx", file_addr); 371*6d56d2ceSJim Ingham } 372*6d56d2ceSJim Ingham } 373*6d56d2ceSJim Ingham else 374*6d56d2ceSJim Ingham { 375*6d56d2ceSJim Ingham if (expr_value_type == Value::eValueTypeHostAddress) 376*6d56d2ceSJim Ingham addr_type = eAddressTypeHost; 377*6d56d2ceSJim Ingham addr = expr_result.ResolveValue (exe_ctx, NULL).ULongLong(LLDB_INVALID_ADDRESS); 378*6d56d2ceSJim Ingham } 379*6d56d2ceSJim Ingham 380*6d56d2ceSJim Ingham if (addr != LLDB_INVALID_ADDRESS) 381*6d56d2ceSJim Ingham { 382*6d56d2ceSJim Ingham if (m_options.debug) 383*6d56d2ceSJim Ingham s.Printf("@ 0x%8.8llx, value = ", addr); 384*6d56d2ceSJim Ingham variable_type->DumpValueInMemory (exe_ctx, &s, addr, addr_type, m_options.show_types, m_options.show_summary, m_options.debug); 385*6d56d2ceSJim Ingham } 386*6d56d2ceSJim Ingham } 387*6d56d2ceSJim Ingham break; 388*6d56d2ceSJim Ingham } 389*6d56d2ceSJim Ingham s.EOL(); 390*6d56d2ceSJim Ingham } 391*6d56d2ceSJim Ingham } 392*6d56d2ceSJim Ingham } 393*6d56d2ceSJim Ingham 394*6d56d2ceSJim Ingham void 395*6d56d2ceSJim Ingham DumpValueObject (CommandReturnObject &result, 396*6d56d2ceSJim Ingham ExecutionContextScope *exe_scope, 397*6d56d2ceSJim Ingham ValueObject *valobj, 398*6d56d2ceSJim Ingham const char *root_valobj_name, 399*6d56d2ceSJim Ingham uint32_t ptr_depth, 400*6d56d2ceSJim Ingham uint32_t curr_depth, 401*6d56d2ceSJim Ingham uint32_t max_depth, 402*6d56d2ceSJim Ingham bool use_objc) 403*6d56d2ceSJim Ingham { 404*6d56d2ceSJim Ingham if (valobj) 405*6d56d2ceSJim Ingham { 406*6d56d2ceSJim Ingham Stream &s = result.GetOutputStream(); 407*6d56d2ceSJim Ingham 408*6d56d2ceSJim Ingham //const char *loc_cstr = valobj->GetLocationAsCString(); 409*6d56d2ceSJim Ingham if (m_options.show_location) 410*6d56d2ceSJim Ingham { 411*6d56d2ceSJim Ingham s.Printf("@ %s: ", valobj->GetLocationAsCString(exe_scope)); 412*6d56d2ceSJim Ingham } 413*6d56d2ceSJim Ingham if (m_options.debug) 414*6d56d2ceSJim Ingham s.Printf ("%p ValueObject{%u} ", valobj, valobj->GetID()); 415*6d56d2ceSJim Ingham 416*6d56d2ceSJim Ingham s.Indent(); 417*6d56d2ceSJim Ingham 418*6d56d2ceSJim Ingham if (m_options.show_types) 419*6d56d2ceSJim Ingham s.Printf("(%s) ", valobj->GetTypeName().AsCString()); 420*6d56d2ceSJim Ingham 421*6d56d2ceSJim Ingham const char *name_cstr = root_valobj_name ? root_valobj_name : valobj->GetName().AsCString(""); 422*6d56d2ceSJim Ingham s.Printf ("%s = ", name_cstr); 423*6d56d2ceSJim Ingham 424*6d56d2ceSJim Ingham const char *val_cstr = valobj->GetValueAsCString(exe_scope); 425*6d56d2ceSJim Ingham const char *err_cstr = valobj->GetError().AsCString(); 426*6d56d2ceSJim Ingham 427*6d56d2ceSJim Ingham if (err_cstr) 428*6d56d2ceSJim Ingham { 429*6d56d2ceSJim Ingham s.Printf ("error: %s\n", err_cstr); 430*6d56d2ceSJim Ingham } 431*6d56d2ceSJim Ingham else 432*6d56d2ceSJim Ingham { 433*6d56d2ceSJim Ingham const char *sum_cstr = valobj->GetSummaryAsCString(exe_scope); 434*6d56d2ceSJim Ingham 435*6d56d2ceSJim Ingham const bool is_aggregate = ClangASTContext::IsAggregateType (valobj->GetOpaqueClangQualType()); 436*6d56d2ceSJim Ingham 437*6d56d2ceSJim Ingham if (val_cstr) 438*6d56d2ceSJim Ingham s.PutCString(val_cstr); 439*6d56d2ceSJim Ingham 440*6d56d2ceSJim Ingham if (sum_cstr) 441*6d56d2ceSJim Ingham s.Printf(" %s", sum_cstr); 442*6d56d2ceSJim Ingham 443*6d56d2ceSJim Ingham if (use_objc) 444*6d56d2ceSJim Ingham { 445*6d56d2ceSJim Ingham if (!ClangASTContext::IsPointerType (valobj->GetOpaqueClangQualType())) 446*6d56d2ceSJim Ingham return; 447*6d56d2ceSJim Ingham 448*6d56d2ceSJim Ingham if (!valobj->GetValueIsValid()) 449*6d56d2ceSJim Ingham return; 450*6d56d2ceSJim Ingham 451*6d56d2ceSJim Ingham Process *process = exe_scope->CalculateProcess(); 452*6d56d2ceSJim Ingham 453*6d56d2ceSJim Ingham if (!process) 454*6d56d2ceSJim Ingham return; 455*6d56d2ceSJim Ingham 456*6d56d2ceSJim Ingham Scalar scalar; 457*6d56d2ceSJim Ingham 458*6d56d2ceSJim Ingham if (!ClangASTType::GetValueAsScalar (valobj->GetClangAST(), 459*6d56d2ceSJim Ingham valobj->GetOpaqueClangQualType(), 460*6d56d2ceSJim Ingham valobj->GetDataExtractor(), 461*6d56d2ceSJim Ingham 0, 462*6d56d2ceSJim Ingham valobj->GetByteSize(), 463*6d56d2ceSJim Ingham scalar)) 464*6d56d2ceSJim Ingham return; 465*6d56d2ceSJim Ingham 466*6d56d2ceSJim Ingham ConstString po_output; 467*6d56d2ceSJim Ingham 468*6d56d2ceSJim Ingham ExecutionContext exe_ctx; 469*6d56d2ceSJim Ingham exe_scope->Calculate(exe_ctx); 470*6d56d2ceSJim Ingham 471*6d56d2ceSJim Ingham Value val(scalar); 472*6d56d2ceSJim Ingham val.SetContext(Value::eContextTypeOpaqueClangQualType, 473*6d56d2ceSJim Ingham ClangASTContext::GetVoidPtrType(valobj->GetClangAST(), false)); 474*6d56d2ceSJim Ingham 475*6d56d2ceSJim Ingham if (!process->GetObjCObjectPrinter().PrintObject(po_output, val, exe_ctx)) 476*6d56d2ceSJim Ingham return; 477*6d56d2ceSJim Ingham 478*6d56d2ceSJim Ingham s.Printf("\n%s\n", po_output.GetCString()); 479*6d56d2ceSJim Ingham 480*6d56d2ceSJim Ingham return; 481*6d56d2ceSJim Ingham } 482*6d56d2ceSJim Ingham 483*6d56d2ceSJim Ingham 484*6d56d2ceSJim Ingham if (curr_depth < max_depth) 485*6d56d2ceSJim Ingham { 486*6d56d2ceSJim Ingham if (is_aggregate) 487*6d56d2ceSJim Ingham s.PutChar('{'); 488*6d56d2ceSJim Ingham 489*6d56d2ceSJim Ingham bool is_ptr_or_ref = ClangASTContext::IsPointerOrReferenceType (valobj->GetOpaqueClangQualType()); 490*6d56d2ceSJim Ingham 491*6d56d2ceSJim Ingham if (is_ptr_or_ref && ptr_depth == 0) 492*6d56d2ceSJim Ingham return; 493*6d56d2ceSJim Ingham 494*6d56d2ceSJim Ingham const uint32_t num_children = valobj->GetNumChildren(); 495*6d56d2ceSJim Ingham if (num_children) 496*6d56d2ceSJim Ingham { 497*6d56d2ceSJim Ingham s.IndentMore(); 498*6d56d2ceSJim Ingham for (uint32_t idx=0; idx<num_children; ++idx) 499*6d56d2ceSJim Ingham { 500*6d56d2ceSJim Ingham ValueObjectSP child_sp(valobj->GetChildAtIndex(idx, true)); 501*6d56d2ceSJim Ingham if (child_sp.get()) 502*6d56d2ceSJim Ingham { 503*6d56d2ceSJim Ingham s.EOL(); 504*6d56d2ceSJim Ingham DumpValueObject (result, 505*6d56d2ceSJim Ingham exe_scope, 506*6d56d2ceSJim Ingham child_sp.get(), 507*6d56d2ceSJim Ingham NULL, 508*6d56d2ceSJim Ingham is_ptr_or_ref ? ptr_depth - 1 : ptr_depth, 509*6d56d2ceSJim Ingham curr_depth + 1, 510*6d56d2ceSJim Ingham max_depth, 511*6d56d2ceSJim Ingham false); 512*6d56d2ceSJim Ingham if (idx + 1 < num_children) 513*6d56d2ceSJim Ingham s.PutChar(','); 514*6d56d2ceSJim Ingham } 515*6d56d2ceSJim Ingham } 516*6d56d2ceSJim Ingham s.IndentLess(); 517*6d56d2ceSJim Ingham } 518*6d56d2ceSJim Ingham if (is_aggregate) 519*6d56d2ceSJim Ingham { 520*6d56d2ceSJim Ingham s.EOL(); 521*6d56d2ceSJim Ingham s.Indent("}"); 522*6d56d2ceSJim Ingham } 523*6d56d2ceSJim Ingham } 524*6d56d2ceSJim Ingham else 525*6d56d2ceSJim Ingham { 526*6d56d2ceSJim Ingham if (is_aggregate) 527*6d56d2ceSJim Ingham { 528*6d56d2ceSJim Ingham s.PutCString("{...}"); 529*6d56d2ceSJim Ingham } 530*6d56d2ceSJim Ingham } 531*6d56d2ceSJim Ingham 532*6d56d2ceSJim Ingham } 533*6d56d2ceSJim Ingham } 534*6d56d2ceSJim Ingham } 535*6d56d2ceSJim Ingham 536*6d56d2ceSJim Ingham virtual bool 537*6d56d2ceSJim Ingham Execute 538*6d56d2ceSJim Ingham ( 539*6d56d2ceSJim Ingham CommandInterpreter &interpreter, 540*6d56d2ceSJim Ingham Args& command, 541*6d56d2ceSJim Ingham CommandReturnObject &result 542*6d56d2ceSJim Ingham ) 543*6d56d2ceSJim Ingham { 544*6d56d2ceSJim Ingham ExecutionContext exe_ctx(interpreter.GetDebugger().GetExecutionContext()); 545*6d56d2ceSJim Ingham if (exe_ctx.frame == NULL) 546*6d56d2ceSJim Ingham { 547*6d56d2ceSJim Ingham result.AppendError ("invalid frame"); 548*6d56d2ceSJim Ingham result.SetStatus (eReturnStatusFailed); 549*6d56d2ceSJim Ingham return false; 550*6d56d2ceSJim Ingham } 551*6d56d2ceSJim Ingham else 552*6d56d2ceSJim Ingham { 553*6d56d2ceSJim Ingham VariableList variable_list; 554*6d56d2ceSJim Ingham 555*6d56d2ceSJim Ingham bool show_inlined = true; // TODO: Get this from the process 556*6d56d2ceSJim Ingham SymbolContext frame_sc = exe_ctx.frame->GetSymbolContext (eSymbolContextEverything); 557*6d56d2ceSJim Ingham if (exe_ctx.frame && frame_sc.block) 558*6d56d2ceSJim Ingham frame_sc.block->AppendVariables(true, true, show_inlined, &variable_list); 559*6d56d2ceSJim Ingham VariableSP var_sp; 560*6d56d2ceSJim Ingham ValueObjectSP valobj_sp; 561*6d56d2ceSJim Ingham //ValueObjectList &valobj_list = exe_ctx.frame->GetValueObjectList(); 562*6d56d2ceSJim Ingham const char *name_cstr = NULL; 563*6d56d2ceSJim Ingham size_t idx; 564*6d56d2ceSJim Ingham if (!m_options.globals.empty()) 565*6d56d2ceSJim Ingham { 566*6d56d2ceSJim Ingham uint32_t fail_count = 0; 567*6d56d2ceSJim Ingham if (exe_ctx.target) 568*6d56d2ceSJim Ingham { 569*6d56d2ceSJim Ingham const size_t num_globals = m_options.globals.size(); 570*6d56d2ceSJim Ingham for (idx = 0; idx < num_globals; ++idx) 571*6d56d2ceSJim Ingham { 572*6d56d2ceSJim Ingham VariableList global_var_list; 573*6d56d2ceSJim Ingham const uint32_t num_matching_globals = exe_ctx.target->GetImages().FindGlobalVariables (m_options.globals[idx], true, UINT32_MAX, global_var_list); 574*6d56d2ceSJim Ingham 575*6d56d2ceSJim Ingham if (num_matching_globals == 0) 576*6d56d2ceSJim Ingham { 577*6d56d2ceSJim Ingham ++fail_count; 578*6d56d2ceSJim Ingham result.GetErrorStream().Printf ("error: can't find global variable '%s'\n", m_options.globals[idx].AsCString()); 579*6d56d2ceSJim Ingham } 580*6d56d2ceSJim Ingham else 581*6d56d2ceSJim Ingham { 582*6d56d2ceSJim Ingham for (uint32_t global_idx=0; global_idx<num_matching_globals; ++global_idx) 583*6d56d2ceSJim Ingham { 584*6d56d2ceSJim Ingham var_sp = global_var_list.GetVariableAtIndex(global_idx); 585*6d56d2ceSJim Ingham if (var_sp) 586*6d56d2ceSJim Ingham { 587*6d56d2ceSJim Ingham valobj_sp = exe_ctx.frame->GetValueObjectList().FindValueObjectByValueName (m_options.globals[idx].AsCString()); 588*6d56d2ceSJim Ingham if (!valobj_sp) 589*6d56d2ceSJim Ingham valobj_sp.reset (new ValueObjectVariable (var_sp)); 590*6d56d2ceSJim Ingham 591*6d56d2ceSJim Ingham if (valobj_sp) 592*6d56d2ceSJim Ingham { 593*6d56d2ceSJim Ingham exe_ctx.frame->GetValueObjectList().Append (valobj_sp); 594*6d56d2ceSJim Ingham DumpValueObject (result, exe_ctx.frame, valobj_sp.get(), name_cstr, m_options.ptr_depth, 0, m_options.max_depth, false); 595*6d56d2ceSJim Ingham result.GetOutputStream().EOL(); 596*6d56d2ceSJim Ingham } 597*6d56d2ceSJim Ingham } 598*6d56d2ceSJim Ingham } 599*6d56d2ceSJim Ingham } 600*6d56d2ceSJim Ingham } 601*6d56d2ceSJim Ingham } 602*6d56d2ceSJim Ingham if (fail_count) 603*6d56d2ceSJim Ingham { 604*6d56d2ceSJim Ingham result.SetStatus (eReturnStatusFailed); 605*6d56d2ceSJim Ingham } 606*6d56d2ceSJim Ingham } 607*6d56d2ceSJim Ingham 608*6d56d2ceSJim Ingham if (command.GetArgumentCount() > 0) 609*6d56d2ceSJim Ingham { 610*6d56d2ceSJim Ingham // If we have any args to the variable command, we will make 611*6d56d2ceSJim Ingham // variable objects from them... 612*6d56d2ceSJim Ingham for (idx = 0; (name_cstr = command.GetArgumentAtIndex(idx)) != NULL; ++idx) 613*6d56d2ceSJim Ingham { 614*6d56d2ceSJim Ingham uint32_t ptr_depth = m_options.ptr_depth; 615*6d56d2ceSJim Ingham // If first character is a '*', then show pointer contents 616*6d56d2ceSJim Ingham if (name_cstr[0] == '*') 617*6d56d2ceSJim Ingham { 618*6d56d2ceSJim Ingham ++ptr_depth; 619*6d56d2ceSJim Ingham name_cstr++; // Skip the '*' 620*6d56d2ceSJim Ingham } 621*6d56d2ceSJim Ingham 622*6d56d2ceSJim Ingham std::string var_path (name_cstr); 623*6d56d2ceSJim Ingham size_t separator_idx = var_path.find_first_of(".-["); 624*6d56d2ceSJim Ingham 625*6d56d2ceSJim Ingham ConstString name_const_string; 626*6d56d2ceSJim Ingham if (separator_idx == std::string::npos) 627*6d56d2ceSJim Ingham name_const_string.SetCString (var_path.c_str()); 628*6d56d2ceSJim Ingham else 629*6d56d2ceSJim Ingham name_const_string.SetCStringWithLength (var_path.c_str(), separator_idx); 630*6d56d2ceSJim Ingham 631*6d56d2ceSJim Ingham var_sp = variable_list.FindVariable(name_const_string); 632*6d56d2ceSJim Ingham if (var_sp) 633*6d56d2ceSJim Ingham { 634*6d56d2ceSJim Ingham //DumpVariable (result, &exe_ctx, var_sp.get()); 635*6d56d2ceSJim Ingham // TODO: redo history variables using a different map 636*6d56d2ceSJim Ingham // if (var_path[0] == '$') 637*6d56d2ceSJim Ingham // valobj_sp = valobj_list.FindValueObjectByValueObjectName (name_const_string.GetCString()); 638*6d56d2ceSJim Ingham // else 639*6d56d2ceSJim Ingham valobj_sp = exe_ctx.frame->GetValueObjectList().FindValueObjectByValueName (name_const_string.GetCString()); 640*6d56d2ceSJim Ingham 641*6d56d2ceSJim Ingham if (!valobj_sp) 642*6d56d2ceSJim Ingham { 643*6d56d2ceSJim Ingham valobj_sp.reset (new ValueObjectVariable (var_sp)); 644*6d56d2ceSJim Ingham exe_ctx.frame->GetValueObjectList().Append (valobj_sp); 645*6d56d2ceSJim Ingham } 646*6d56d2ceSJim Ingham 647*6d56d2ceSJim Ingham var_path.erase (0, name_const_string.GetLength ()); 648*6d56d2ceSJim Ingham // We are dumping at least one child 649*6d56d2ceSJim Ingham while (separator_idx != std::string::npos) 650*6d56d2ceSJim Ingham { 651*6d56d2ceSJim Ingham // Calculate the next separator index ahead of time 652*6d56d2ceSJim Ingham ValueObjectSP child_valobj_sp; 653*6d56d2ceSJim Ingham const char separator_type = var_path[0]; 654*6d56d2ceSJim Ingham switch (separator_type) 655*6d56d2ceSJim Ingham { 656*6d56d2ceSJim Ingham 657*6d56d2ceSJim Ingham case '-': 658*6d56d2ceSJim Ingham if (var_path.size() >= 2 && var_path[1] != '>') 659*6d56d2ceSJim Ingham { 660*6d56d2ceSJim Ingham result.GetErrorStream().Printf ("error: invalid character in variable path starting at '%s'\n", 661*6d56d2ceSJim Ingham var_path.c_str()); 662*6d56d2ceSJim Ingham var_path.clear(); 663*6d56d2ceSJim Ingham valobj_sp.reset(); 664*6d56d2ceSJim Ingham break; 665*6d56d2ceSJim Ingham } 666*6d56d2ceSJim Ingham var_path.erase (0, 1); // Remove the '-' 667*6d56d2ceSJim Ingham // Fall through 668*6d56d2ceSJim Ingham case '.': 669*6d56d2ceSJim Ingham { 670*6d56d2ceSJim Ingham var_path.erase (0, 1); // Remove the '.' or '>' 671*6d56d2ceSJim Ingham separator_idx = var_path.find_first_of(".-["); 672*6d56d2ceSJim Ingham ConstString child_name; 673*6d56d2ceSJim Ingham if (separator_idx == std::string::npos) 674*6d56d2ceSJim Ingham child_name.SetCString (var_path.c_str()); 675*6d56d2ceSJim Ingham else 676*6d56d2ceSJim Ingham child_name.SetCStringWithLength(var_path.c_str(), separator_idx); 677*6d56d2ceSJim Ingham 678*6d56d2ceSJim Ingham child_valobj_sp = valobj_sp->GetChildMemberWithName (child_name, true); 679*6d56d2ceSJim Ingham if (!child_valobj_sp) 680*6d56d2ceSJim Ingham { 681*6d56d2ceSJim Ingham result.GetErrorStream().Printf ("error: can't find child of '%s' named '%s'\n", 682*6d56d2ceSJim Ingham valobj_sp->GetName().AsCString(), 683*6d56d2ceSJim Ingham child_name.GetCString()); 684*6d56d2ceSJim Ingham var_path.clear(); 685*6d56d2ceSJim Ingham valobj_sp.reset(); 686*6d56d2ceSJim Ingham break; 687*6d56d2ceSJim Ingham } 688*6d56d2ceSJim Ingham // Remove the child name from the path 689*6d56d2ceSJim Ingham var_path.erase(0, child_name.GetLength()); 690*6d56d2ceSJim Ingham } 691*6d56d2ceSJim Ingham break; 692*6d56d2ceSJim Ingham 693*6d56d2ceSJim Ingham case '[': 694*6d56d2ceSJim Ingham // Array member access, or treating pointer as an array 695*6d56d2ceSJim Ingham if (var_path.size() > 2) // Need at least two brackets and a number 696*6d56d2ceSJim Ingham { 697*6d56d2ceSJim Ingham char *end = NULL; 698*6d56d2ceSJim Ingham int32_t child_index = ::strtol (&var_path[1], &end, 0); 699*6d56d2ceSJim Ingham if (end && *end == ']') 700*6d56d2ceSJim Ingham { 701*6d56d2ceSJim Ingham 702*6d56d2ceSJim Ingham if (valobj_sp->IsPointerType ()) 703*6d56d2ceSJim Ingham { 704*6d56d2ceSJim Ingham child_valobj_sp = valobj_sp->GetSyntheticArrayMemberFromPointer (child_index, true); 705*6d56d2ceSJim Ingham } 706*6d56d2ceSJim Ingham else 707*6d56d2ceSJim Ingham { 708*6d56d2ceSJim Ingham child_valobj_sp = valobj_sp->GetChildAtIndex (child_index, true); 709*6d56d2ceSJim Ingham } 710*6d56d2ceSJim Ingham 711*6d56d2ceSJim Ingham if (!child_valobj_sp) 712*6d56d2ceSJim Ingham { 713*6d56d2ceSJim Ingham result.GetErrorStream().Printf ("error: invalid array index %u in '%s'\n", 714*6d56d2ceSJim Ingham child_index, 715*6d56d2ceSJim Ingham valobj_sp->GetName().AsCString()); 716*6d56d2ceSJim Ingham var_path.clear(); 717*6d56d2ceSJim Ingham valobj_sp.reset(); 718*6d56d2ceSJim Ingham break; 719*6d56d2ceSJim Ingham } 720*6d56d2ceSJim Ingham 721*6d56d2ceSJim Ingham // Erase the array member specification '[%i]' where %i is the array index 722*6d56d2ceSJim Ingham var_path.erase(0, (end - var_path.c_str()) + 1); 723*6d56d2ceSJim Ingham separator_idx = var_path.find_first_of(".-["); 724*6d56d2ceSJim Ingham 725*6d56d2ceSJim Ingham // Break out early from the switch since we were able to find the child member 726*6d56d2ceSJim Ingham break; 727*6d56d2ceSJim Ingham } 728*6d56d2ceSJim Ingham } 729*6d56d2ceSJim Ingham result.GetErrorStream().Printf ("error: invalid array member specification for '%s' starting at '%s'\n", 730*6d56d2ceSJim Ingham valobj_sp->GetName().AsCString(), 731*6d56d2ceSJim Ingham var_path.c_str()); 732*6d56d2ceSJim Ingham var_path.clear(); 733*6d56d2ceSJim Ingham valobj_sp.reset(); 734*6d56d2ceSJim Ingham break; 735*6d56d2ceSJim Ingham 736*6d56d2ceSJim Ingham break; 737*6d56d2ceSJim Ingham 738*6d56d2ceSJim Ingham default: 739*6d56d2ceSJim Ingham result.GetErrorStream().Printf ("error: invalid character in variable path starting at '%s'\n", 740*6d56d2ceSJim Ingham var_path.c_str()); 741*6d56d2ceSJim Ingham var_path.clear(); 742*6d56d2ceSJim Ingham valobj_sp.reset(); 743*6d56d2ceSJim Ingham separator_idx = std::string::npos; 744*6d56d2ceSJim Ingham break; 745*6d56d2ceSJim Ingham } 746*6d56d2ceSJim Ingham 747*6d56d2ceSJim Ingham if (child_valobj_sp) 748*6d56d2ceSJim Ingham valobj_sp = child_valobj_sp; 749*6d56d2ceSJim Ingham 750*6d56d2ceSJim Ingham if (var_path.empty()) 751*6d56d2ceSJim Ingham break; 752*6d56d2ceSJim Ingham 753*6d56d2ceSJim Ingham } 754*6d56d2ceSJim Ingham 755*6d56d2ceSJim Ingham if (valobj_sp) 756*6d56d2ceSJim Ingham { 757*6d56d2ceSJim Ingham DumpValueObject (result, exe_ctx.frame, valobj_sp.get(), name_cstr, ptr_depth, 0, m_options.max_depth, m_options.use_objc); 758*6d56d2ceSJim Ingham result.GetOutputStream().EOL(); 759*6d56d2ceSJim Ingham } 760*6d56d2ceSJim Ingham } 761*6d56d2ceSJim Ingham else 762*6d56d2ceSJim Ingham { 763*6d56d2ceSJim Ingham result.GetErrorStream().Printf ("error: unable to find any variables named '%s'\n", name_cstr); 764*6d56d2ceSJim Ingham var_path.clear(); 765*6d56d2ceSJim Ingham } 766*6d56d2ceSJim Ingham } 767*6d56d2ceSJim Ingham } 768*6d56d2ceSJim Ingham else 769*6d56d2ceSJim Ingham { 770*6d56d2ceSJim Ingham 771*6d56d2ceSJim Ingham if (m_options.show_globals) 772*6d56d2ceSJim Ingham { 773*6d56d2ceSJim Ingham if (frame_sc.comp_unit) 774*6d56d2ceSJim Ingham { 775*6d56d2ceSJim Ingham variable_list.AddVariables (frame_sc.comp_unit->GetVariableList(true).get()); 776*6d56d2ceSJim Ingham } 777*6d56d2ceSJim Ingham } 778*6d56d2ceSJim Ingham 779*6d56d2ceSJim Ingham const uint32_t num_variables = variable_list.GetSize(); 780*6d56d2ceSJim Ingham 781*6d56d2ceSJim Ingham if (num_variables > 0) 782*6d56d2ceSJim Ingham { 783*6d56d2ceSJim Ingham for (uint32_t i=0; i<num_variables; i++) 784*6d56d2ceSJim Ingham { 785*6d56d2ceSJim Ingham Variable *variable = variable_list.GetVariableAtIndex(i).get(); 786*6d56d2ceSJim Ingham bool dump_variable = true; 787*6d56d2ceSJim Ingham 788*6d56d2ceSJim Ingham switch (variable->GetScope()) 789*6d56d2ceSJim Ingham { 790*6d56d2ceSJim Ingham case eValueTypeVariableGlobal: 791*6d56d2ceSJim Ingham dump_variable = m_options.show_globals; 792*6d56d2ceSJim Ingham if (dump_variable && m_options.show_scope) 793*6d56d2ceSJim Ingham result.GetOutputStream().PutCString("GLOBAL: "); 794*6d56d2ceSJim Ingham break; 795*6d56d2ceSJim Ingham 796*6d56d2ceSJim Ingham case eValueTypeVariableStatic: 797*6d56d2ceSJim Ingham dump_variable = m_options.show_globals; 798*6d56d2ceSJim Ingham if (dump_variable && m_options.show_scope) 799*6d56d2ceSJim Ingham result.GetOutputStream().PutCString("STATIC: "); 800*6d56d2ceSJim Ingham break; 801*6d56d2ceSJim Ingham 802*6d56d2ceSJim Ingham case eValueTypeVariableArgument: 803*6d56d2ceSJim Ingham dump_variable = m_options.show_args; 804*6d56d2ceSJim Ingham if (dump_variable && m_options.show_scope) 805*6d56d2ceSJim Ingham result.GetOutputStream().PutCString(" ARG: "); 806*6d56d2ceSJim Ingham break; 807*6d56d2ceSJim Ingham 808*6d56d2ceSJim Ingham case eValueTypeVariableLocal: 809*6d56d2ceSJim Ingham dump_variable = m_options.show_locals; 810*6d56d2ceSJim Ingham if (dump_variable && m_options.show_scope) 811*6d56d2ceSJim Ingham result.GetOutputStream().PutCString(" LOCAL: "); 812*6d56d2ceSJim Ingham break; 813*6d56d2ceSJim Ingham 814*6d56d2ceSJim Ingham default: 815*6d56d2ceSJim Ingham break; 816*6d56d2ceSJim Ingham } 817*6d56d2ceSJim Ingham 818*6d56d2ceSJim Ingham if (dump_variable) 819*6d56d2ceSJim Ingham DumpVariable (result, &exe_ctx, variable); 820*6d56d2ceSJim Ingham } 821*6d56d2ceSJim Ingham } 822*6d56d2ceSJim Ingham } 823*6d56d2ceSJim Ingham result.SetStatus (eReturnStatusSuccessFinishResult); 824*6d56d2ceSJim Ingham } 825*6d56d2ceSJim Ingham return result.Succeeded(); 826*6d56d2ceSJim Ingham } 827*6d56d2ceSJim Ingham protected: 828*6d56d2ceSJim Ingham 829*6d56d2ceSJim Ingham CommandOptions m_options; 830*6d56d2ceSJim Ingham }; 831*6d56d2ceSJim Ingham 832*6d56d2ceSJim Ingham lldb::OptionDefinition 833*6d56d2ceSJim Ingham CommandObjectFrameVariable::CommandOptions::g_option_table[] = 834*6d56d2ceSJim Ingham { 835*6d56d2ceSJim Ingham { LLDB_OPT_SET_1, false, "debug", 'D', no_argument, NULL, 0, NULL, "Show verbose debug information."}, 836*6d56d2ceSJim Ingham { LLDB_OPT_SET_1, false, "depth", 'd', required_argument, NULL, 0, "<count>", "Set the max recurse depth when dumping aggregate types (default is infinity)."}, 837*6d56d2ceSJim Ingham { LLDB_OPT_SET_1, false, "globals", 'g', no_argument, NULL, 0, NULL, "List global and static variables for the current stack frame source file."}, 838*6d56d2ceSJim Ingham { LLDB_OPT_SET_1, false, "global", 'G', required_argument, NULL, 0, NULL, "Find a global variable by name (which might not be in the current stack frame source file)."}, 839*6d56d2ceSJim Ingham { LLDB_OPT_SET_1, false, "location", 'L', no_argument, NULL, 0, NULL, "Show variable location information."}, 840*6d56d2ceSJim Ingham { LLDB_OPT_SET_1, false, "name", 'n', required_argument, NULL, 0, "<name>", "Lookup a variable by name or regex (--regex) for the current execution context."}, 841*6d56d2ceSJim Ingham { LLDB_OPT_SET_1, false, "no-args", 'a', no_argument, NULL, 0, NULL, "Omit function arguments."}, 842*6d56d2ceSJim Ingham { LLDB_OPT_SET_1, false, "no-locals", 'l', no_argument, NULL, 0, NULL, "Omit local variables."}, 843*6d56d2ceSJim Ingham { LLDB_OPT_SET_1, false, "no-types", 't', no_argument, NULL, 0, NULL, "Omit variable type names."}, 844*6d56d2ceSJim Ingham { LLDB_OPT_SET_1, false, "no-summary", 'y', no_argument, NULL, 0, NULL, "Omit summary information."}, 845*6d56d2ceSJim Ingham { LLDB_OPT_SET_1, false, "scope", 's', no_argument, NULL, 0, NULL, "Show variable scope (argument, local, global, static)."}, 846*6d56d2ceSJim Ingham { LLDB_OPT_SET_1, false, "objc", 'o', no_argument, NULL, 0, NULL, "When looking up a variable by name (--name), print as an Objective-C object."}, 847*6d56d2ceSJim Ingham { LLDB_OPT_SET_1, false, "ptr-depth", 'p', required_argument, NULL, 0, "<count>", "The number of pointers to be traversed when dumping values (default is zero)."}, 848*6d56d2ceSJim Ingham { LLDB_OPT_SET_1, false, "regex", 'r', no_argument, NULL, 0, NULL, "The <name> argument for name lookups are regular expressions."}, 849*6d56d2ceSJim Ingham { 0, false, NULL, 0, 0, NULL, NULL, NULL, NULL } 850*6d56d2ceSJim Ingham }; 85130fdc8d8SChris Lattner #pragma mark CommandObjectMultiwordFrame 85230fdc8d8SChris Lattner 85330fdc8d8SChris Lattner //------------------------------------------------------------------------- 85430fdc8d8SChris Lattner // CommandObjectMultiwordFrame 85530fdc8d8SChris Lattner //------------------------------------------------------------------------- 85630fdc8d8SChris Lattner 8576611103cSGreg Clayton CommandObjectMultiwordFrame::CommandObjectMultiwordFrame (CommandInterpreter &interpreter) : 85830fdc8d8SChris Lattner CommandObjectMultiword ("frame", 85930fdc8d8SChris Lattner "A set of commands for operating on the current thread's frames.", 86030fdc8d8SChris Lattner "frame <subcommand> [<subcommand-options>]") 86130fdc8d8SChris Lattner { 8626611103cSGreg Clayton LoadSubCommand (interpreter, "info", CommandObjectSP (new CommandObjectFrameInfo ())); 8636611103cSGreg Clayton LoadSubCommand (interpreter, "select", CommandObjectSP (new CommandObjectFrameSelect ())); 864*6d56d2ceSJim Ingham LoadSubCommand (interpreter, "variable", CommandObjectSP (new CommandObjectFrameVariable ())); 86530fdc8d8SChris Lattner } 86630fdc8d8SChris Lattner 86730fdc8d8SChris Lattner CommandObjectMultiwordFrame::~CommandObjectMultiwordFrame () 86830fdc8d8SChris Lattner { 86930fdc8d8SChris Lattner } 87030fdc8d8SChris Lattner 871