1*30fdc8d8SChris Lattner //===-- CommandObjectBreakpoint.cpp -----------------------------*- C++ -*-===// 2*30fdc8d8SChris Lattner // 3*30fdc8d8SChris Lattner // The LLVM Compiler Infrastructure 4*30fdc8d8SChris Lattner // 5*30fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source 6*30fdc8d8SChris Lattner // License. See LICENSE.TXT for details. 7*30fdc8d8SChris Lattner // 8*30fdc8d8SChris Lattner //===----------------------------------------------------------------------===// 9*30fdc8d8SChris Lattner 10*30fdc8d8SChris Lattner #include "CommandObjectBreakpoint.h" 11*30fdc8d8SChris Lattner #include "CommandObjectBreakpointCommand.h" 12*30fdc8d8SChris Lattner 13*30fdc8d8SChris Lattner // C Includes 14*30fdc8d8SChris Lattner // C++ Includes 15*30fdc8d8SChris Lattner // Other libraries and framework includes 16*30fdc8d8SChris Lattner // Project includes 17*30fdc8d8SChris Lattner #include "lldb/Breakpoint/Breakpoint.h" 18*30fdc8d8SChris Lattner #include "lldb/Breakpoint/BreakpointIDList.h" 19*30fdc8d8SChris Lattner #include "lldb/Breakpoint/BreakpointLocation.h" 20*30fdc8d8SChris Lattner #include "lldb/Core/RegularExpression.h" 21*30fdc8d8SChris Lattner #include "lldb/Core/StreamString.h" 22*30fdc8d8SChris Lattner #include "lldb/Interpreter/CommandInterpreter.h" 23*30fdc8d8SChris Lattner #include "lldb/Interpreter/CommandReturnObject.h" 24*30fdc8d8SChris Lattner #include "lldb/Target/Target.h" 25*30fdc8d8SChris Lattner #include "lldb/Interpreter/CommandCompletions.h" 26*30fdc8d8SChris Lattner #include "lldb/Target/StackFrame.h" 27*30fdc8d8SChris Lattner 28*30fdc8d8SChris Lattner using namespace lldb; 29*30fdc8d8SChris Lattner using namespace lldb_private; 30*30fdc8d8SChris Lattner 31*30fdc8d8SChris Lattner static void 32*30fdc8d8SChris Lattner AddBreakpointDescription (CommandContext *context, StreamString *s, Breakpoint *bp, lldb::DescriptionLevel level) 33*30fdc8d8SChris Lattner { 34*30fdc8d8SChris Lattner s->IndentMore(); 35*30fdc8d8SChris Lattner bp->GetDescription (s, level, true); 36*30fdc8d8SChris Lattner s->IndentLess(); 37*30fdc8d8SChris Lattner s->EOL(); 38*30fdc8d8SChris Lattner } 39*30fdc8d8SChris Lattner 40*30fdc8d8SChris Lattner //------------------------------------------------------------------------- 41*30fdc8d8SChris Lattner // CommandObjectBreakpointSet::CommandOptions 42*30fdc8d8SChris Lattner //------------------------------------------------------------------------- 43*30fdc8d8SChris Lattner 44*30fdc8d8SChris Lattner CommandObjectBreakpointSet::CommandOptions::CommandOptions() : 45*30fdc8d8SChris Lattner Options (), 46*30fdc8d8SChris Lattner m_filename (), 47*30fdc8d8SChris Lattner m_line_num (0), 48*30fdc8d8SChris Lattner m_column (0), 49*30fdc8d8SChris Lattner m_ignore_inlines (false), 50*30fdc8d8SChris Lattner m_func_name (), 51*30fdc8d8SChris Lattner m_func_regexp (), 52*30fdc8d8SChris Lattner m_modules (), 53*30fdc8d8SChris Lattner m_load_addr() 54*30fdc8d8SChris Lattner { 55*30fdc8d8SChris Lattner BuildValidOptionSets(); 56*30fdc8d8SChris Lattner } 57*30fdc8d8SChris Lattner 58*30fdc8d8SChris Lattner CommandObjectBreakpointSet::CommandOptions::~CommandOptions () 59*30fdc8d8SChris Lattner { 60*30fdc8d8SChris Lattner } 61*30fdc8d8SChris Lattner 62*30fdc8d8SChris Lattner lldb::OptionDefinition 63*30fdc8d8SChris Lattner CommandObjectBreakpointSet::CommandOptions::g_option_table[] = 64*30fdc8d8SChris Lattner { 65*30fdc8d8SChris Lattner { 0, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, "<filename>", 66*30fdc8d8SChris Lattner "Set the breakpoint by source location in this particular file."}, 67*30fdc8d8SChris Lattner 68*30fdc8d8SChris Lattner { 0, true, "line", 'l', required_argument, NULL, 0, "<linenum>", 69*30fdc8d8SChris Lattner "Set the breakpoint by source location at this particular line."}, 70*30fdc8d8SChris Lattner 71*30fdc8d8SChris Lattner { 0, false, "shlib", 's', required_argument, NULL, CommandCompletions::eModuleCompletion, "<shlib-name>", 72*30fdc8d8SChris Lattner "Set the breakpoint only in this shared library (can use this option multiple times for multiple shlibs)."}, 73*30fdc8d8SChris Lattner 74*30fdc8d8SChris Lattner // Comment out this option for the moment, as we don't actually use it, but will in the future. 75*30fdc8d8SChris Lattner // This way users won't see it, but the infrastructure is left in place. 76*30fdc8d8SChris Lattner // { 0, false, "column", 'c', required_argument, NULL, "<column>", 77*30fdc8d8SChris Lattner // "Set the breakpoint by source location at this particular column."}, 78*30fdc8d8SChris Lattner 79*30fdc8d8SChris Lattner { 0, false, "ignore_inlines", 'i', no_argument, NULL, 0, NULL, 80*30fdc8d8SChris Lattner "Ignore inlined subroutines when setting the breakppoint." }, 81*30fdc8d8SChris Lattner 82*30fdc8d8SChris Lattner { 1, true, "address", 'a', required_argument, NULL, 0, "<address>", 83*30fdc8d8SChris Lattner "Set the breakpoint by address, at the specified address."}, 84*30fdc8d8SChris Lattner 85*30fdc8d8SChris Lattner { 1, false, "ignore_inlines", 'i', no_argument, NULL, 0, NULL, 86*30fdc8d8SChris Lattner "Ignore inlined subroutines when setting the breakppoint." }, 87*30fdc8d8SChris Lattner 88*30fdc8d8SChris Lattner { 2, true, "name", 'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, "<function-name>", 89*30fdc8d8SChris Lattner "Set the breakpoint by function name." }, 90*30fdc8d8SChris Lattner 91*30fdc8d8SChris Lattner { 2, false, "shlib", 's', required_argument, NULL, CommandCompletions::eModuleCompletion, "<shlib-name>", 92*30fdc8d8SChris Lattner "Set the breakpoint only in this shared library (can use this option multiple times for multiple shlibs)."}, 93*30fdc8d8SChris Lattner 94*30fdc8d8SChris Lattner { 2, false, "ignore_inlines", 'i', no_argument, NULL, 0, NULL, 95*30fdc8d8SChris Lattner "Ignore inlined subroutines when setting the breakpoint." }, 96*30fdc8d8SChris Lattner 97*30fdc8d8SChris Lattner { 3, true, "func_regex", 'r', required_argument, NULL, 0, "<regular-expression>", 98*30fdc8d8SChris Lattner "Set the breakpoint by function name, evaluating a regular-expression to find the function name(s)." }, 99*30fdc8d8SChris Lattner 100*30fdc8d8SChris Lattner { 3, false, "shlib", 's', required_argument, NULL, CommandCompletions::eModuleCompletion, "<shlib-name>", 101*30fdc8d8SChris Lattner "Set the breakpoint only in this shared library (can use this option multiple times for multiple shlibs)."}, 102*30fdc8d8SChris Lattner 103*30fdc8d8SChris Lattner { 3, false, "ignore_inlines", 'i', no_argument, NULL, 0, NULL, 104*30fdc8d8SChris Lattner "Ignore inlined subroutines when setting the breakpoint." }, 105*30fdc8d8SChris Lattner 106*30fdc8d8SChris Lattner { 0, false, NULL, 0, 0, NULL, 0, NULL, NULL } 107*30fdc8d8SChris Lattner }; 108*30fdc8d8SChris Lattner 109*30fdc8d8SChris Lattner const lldb::OptionDefinition* 110*30fdc8d8SChris Lattner CommandObjectBreakpointSet::CommandOptions::GetDefinitions () 111*30fdc8d8SChris Lattner { 112*30fdc8d8SChris Lattner return g_option_table; 113*30fdc8d8SChris Lattner } 114*30fdc8d8SChris Lattner 115*30fdc8d8SChris Lattner Error 116*30fdc8d8SChris Lattner CommandObjectBreakpointSet::CommandOptions::SetOptionValue (int option_idx, const char *option_arg) 117*30fdc8d8SChris Lattner { 118*30fdc8d8SChris Lattner Error error; 119*30fdc8d8SChris Lattner char short_option = (char) m_getopt_table[option_idx].val; 120*30fdc8d8SChris Lattner 121*30fdc8d8SChris Lattner switch (short_option) 122*30fdc8d8SChris Lattner { 123*30fdc8d8SChris Lattner case 'a': 124*30fdc8d8SChris Lattner m_load_addr = Args::StringToUInt64(optarg, LLDB_INVALID_ADDRESS, 0); 125*30fdc8d8SChris Lattner if (m_load_addr == LLDB_INVALID_ADDRESS) 126*30fdc8d8SChris Lattner m_load_addr = Args::StringToUInt64(optarg, LLDB_INVALID_ADDRESS, 16); 127*30fdc8d8SChris Lattner 128*30fdc8d8SChris Lattner if (m_load_addr == LLDB_INVALID_ADDRESS) 129*30fdc8d8SChris Lattner error.SetErrorStringWithFormat ("Invalid address string '%s'.\n", optarg); 130*30fdc8d8SChris Lattner break; 131*30fdc8d8SChris Lattner 132*30fdc8d8SChris Lattner case 'c': 133*30fdc8d8SChris Lattner m_column = Args::StringToUInt32 (option_arg, 0); 134*30fdc8d8SChris Lattner break; 135*30fdc8d8SChris Lattner case 'f': 136*30fdc8d8SChris Lattner m_filename = option_arg; 137*30fdc8d8SChris Lattner break; 138*30fdc8d8SChris Lattner case 'i': 139*30fdc8d8SChris Lattner m_ignore_inlines = true; 140*30fdc8d8SChris Lattner break; 141*30fdc8d8SChris Lattner case 'l': 142*30fdc8d8SChris Lattner m_line_num = Args::StringToUInt32 (option_arg, 0); 143*30fdc8d8SChris Lattner break; 144*30fdc8d8SChris Lattner case 'n': 145*30fdc8d8SChris Lattner m_func_name = option_arg; 146*30fdc8d8SChris Lattner break; 147*30fdc8d8SChris Lattner case 'r': 148*30fdc8d8SChris Lattner m_func_regexp = option_arg; 149*30fdc8d8SChris Lattner break; 150*30fdc8d8SChris Lattner case 's': 151*30fdc8d8SChris Lattner { 152*30fdc8d8SChris Lattner m_modules.push_back (std::string (option_arg)); 153*30fdc8d8SChris Lattner break; 154*30fdc8d8SChris Lattner } 155*30fdc8d8SChris Lattner default: 156*30fdc8d8SChris Lattner error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option); 157*30fdc8d8SChris Lattner break; 158*30fdc8d8SChris Lattner } 159*30fdc8d8SChris Lattner 160*30fdc8d8SChris Lattner return error; 161*30fdc8d8SChris Lattner } 162*30fdc8d8SChris Lattner 163*30fdc8d8SChris Lattner void 164*30fdc8d8SChris Lattner CommandObjectBreakpointSet::CommandOptions::ResetOptionValues () 165*30fdc8d8SChris Lattner { 166*30fdc8d8SChris Lattner Options::ResetOptionValues(); 167*30fdc8d8SChris Lattner 168*30fdc8d8SChris Lattner m_filename.clear(); 169*30fdc8d8SChris Lattner m_line_num = 0; 170*30fdc8d8SChris Lattner m_column = 0; 171*30fdc8d8SChris Lattner m_ignore_inlines = false; 172*30fdc8d8SChris Lattner m_func_name.clear(); 173*30fdc8d8SChris Lattner m_func_regexp.clear(); 174*30fdc8d8SChris Lattner m_load_addr = LLDB_INVALID_ADDRESS; 175*30fdc8d8SChris Lattner m_modules.clear(); 176*30fdc8d8SChris Lattner } 177*30fdc8d8SChris Lattner 178*30fdc8d8SChris Lattner //------------------------------------------------------------------------- 179*30fdc8d8SChris Lattner // CommandObjectBreakpointSet 180*30fdc8d8SChris Lattner //------------------------------------------------------------------------- 181*30fdc8d8SChris Lattner 182*30fdc8d8SChris Lattner CommandObjectBreakpointSet::CommandObjectBreakpointSet () : 183*30fdc8d8SChris Lattner CommandObject ("breakpoint set", "Sets a breakpoint or set of breakpoints in the executable.", 184*30fdc8d8SChris Lattner "breakpoint set <cmd-options>") 185*30fdc8d8SChris Lattner { 186*30fdc8d8SChris Lattner } 187*30fdc8d8SChris Lattner 188*30fdc8d8SChris Lattner CommandObjectBreakpointSet::~CommandObjectBreakpointSet () 189*30fdc8d8SChris Lattner { 190*30fdc8d8SChris Lattner } 191*30fdc8d8SChris Lattner 192*30fdc8d8SChris Lattner Options * 193*30fdc8d8SChris Lattner CommandObjectBreakpointSet::GetOptions () 194*30fdc8d8SChris Lattner { 195*30fdc8d8SChris Lattner return &m_options; 196*30fdc8d8SChris Lattner } 197*30fdc8d8SChris Lattner 198*30fdc8d8SChris Lattner bool 199*30fdc8d8SChris Lattner CommandObjectBreakpointSet::Execute 200*30fdc8d8SChris Lattner ( 201*30fdc8d8SChris Lattner Args& command, 202*30fdc8d8SChris Lattner CommandContext *context, 203*30fdc8d8SChris Lattner CommandInterpreter *interpreter, 204*30fdc8d8SChris Lattner CommandReturnObject &result 205*30fdc8d8SChris Lattner ) 206*30fdc8d8SChris Lattner { 207*30fdc8d8SChris Lattner Target *target = context->GetTarget(); 208*30fdc8d8SChris Lattner if (target == NULL) 209*30fdc8d8SChris Lattner { 210*30fdc8d8SChris Lattner result.AppendError ("Invalid target, set executable file using 'file' command."); 211*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 212*30fdc8d8SChris Lattner return false; 213*30fdc8d8SChris Lattner } 214*30fdc8d8SChris Lattner 215*30fdc8d8SChris Lattner // The following are the various types of breakpoints that could be set: 216*30fdc8d8SChris Lattner // 1). -f -l -p [-s -g] (setting breakpoint by source location) 217*30fdc8d8SChris Lattner // 2). -a [-s -g] (setting breakpoint by address) 218*30fdc8d8SChris Lattner // 3). -n [-s -g] (setting breakpoint by function name) 219*30fdc8d8SChris Lattner // 4). -r [-s -g] (setting breakpoint by function name regular expression) 220*30fdc8d8SChris Lattner 221*30fdc8d8SChris Lattner BreakpointSetType break_type = eSetTypeInvalid; 222*30fdc8d8SChris Lattner 223*30fdc8d8SChris Lattner if (m_options.m_line_num != 0) 224*30fdc8d8SChris Lattner break_type = eSetTypeFileAndLine; 225*30fdc8d8SChris Lattner else if (m_options.m_load_addr != LLDB_INVALID_ADDRESS) 226*30fdc8d8SChris Lattner break_type = eSetTypeAddress; 227*30fdc8d8SChris Lattner else if (!m_options.m_func_name.empty()) 228*30fdc8d8SChris Lattner break_type = eSetTypeFunctionName; 229*30fdc8d8SChris Lattner else if (!m_options.m_func_regexp.empty()) 230*30fdc8d8SChris Lattner break_type = eSetTypeFunctionRegexp; 231*30fdc8d8SChris Lattner 232*30fdc8d8SChris Lattner ModuleSP module_sp = target->GetExecutableModule(); 233*30fdc8d8SChris Lattner Breakpoint *bp = NULL; 234*30fdc8d8SChris Lattner FileSpec module; 235*30fdc8d8SChris Lattner bool use_module = false; 236*30fdc8d8SChris Lattner int num_modules = m_options.m_modules.size(); 237*30fdc8d8SChris Lattner 238*30fdc8d8SChris Lattner if ((num_modules > 0) && (break_type != eSetTypeAddress)) 239*30fdc8d8SChris Lattner use_module = true; 240*30fdc8d8SChris Lattner 241*30fdc8d8SChris Lattner switch (break_type) 242*30fdc8d8SChris Lattner { 243*30fdc8d8SChris Lattner case eSetTypeFileAndLine: // Breakpoint by source position 244*30fdc8d8SChris Lattner { 245*30fdc8d8SChris Lattner FileSpec file; 246*30fdc8d8SChris Lattner if (m_options.m_filename.empty()) 247*30fdc8d8SChris Lattner { 248*30fdc8d8SChris Lattner StackFrame *cur_frame = context->GetExecutionContext().frame; 249*30fdc8d8SChris Lattner if (cur_frame == NULL) 250*30fdc8d8SChris Lattner { 251*30fdc8d8SChris Lattner result.AppendError ("Attempting to set breakpoint by line number alone with no selected frame."); 252*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 253*30fdc8d8SChris Lattner break; 254*30fdc8d8SChris Lattner } 255*30fdc8d8SChris Lattner else if (!cur_frame->HasDebugInformation()) 256*30fdc8d8SChris Lattner { 257*30fdc8d8SChris Lattner result.AppendError ("Attempting to set breakpoint by line number alone but selected frame has no debug info."); 258*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 259*30fdc8d8SChris Lattner break; 260*30fdc8d8SChris Lattner } 261*30fdc8d8SChris Lattner else 262*30fdc8d8SChris Lattner { 263*30fdc8d8SChris Lattner const SymbolContext &context = cur_frame->GetSymbolContext(true); 264*30fdc8d8SChris Lattner if (context.line_entry.file) 265*30fdc8d8SChris Lattner { 266*30fdc8d8SChris Lattner file = context.line_entry.file; 267*30fdc8d8SChris Lattner } 268*30fdc8d8SChris Lattner else if (context.comp_unit != NULL) 269*30fdc8d8SChris Lattner { file = context.comp_unit; 270*30fdc8d8SChris Lattner } 271*30fdc8d8SChris Lattner else 272*30fdc8d8SChris Lattner { 273*30fdc8d8SChris Lattner result.AppendError ("Attempting to set breakpoint by line number alone but can't find the file for the selected frame."); 274*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 275*30fdc8d8SChris Lattner break; 276*30fdc8d8SChris Lattner } 277*30fdc8d8SChris Lattner } 278*30fdc8d8SChris Lattner } 279*30fdc8d8SChris Lattner else 280*30fdc8d8SChris Lattner { 281*30fdc8d8SChris Lattner file.SetFile(m_options.m_filename.c_str()); 282*30fdc8d8SChris Lattner } 283*30fdc8d8SChris Lattner 284*30fdc8d8SChris Lattner if (use_module) 285*30fdc8d8SChris Lattner { 286*30fdc8d8SChris Lattner for (int i = 0; i < num_modules; ++i) 287*30fdc8d8SChris Lattner { 288*30fdc8d8SChris Lattner module.SetFile(m_options.m_modules[i].c_str()); 289*30fdc8d8SChris Lattner bp = target->CreateBreakpoint (&module, 290*30fdc8d8SChris Lattner file, 291*30fdc8d8SChris Lattner m_options.m_line_num, 292*30fdc8d8SChris Lattner m_options.m_ignore_inlines).get(); 293*30fdc8d8SChris Lattner if (bp) 294*30fdc8d8SChris Lattner { 295*30fdc8d8SChris Lattner StreamString &output_stream = result.GetOutputStream(); 296*30fdc8d8SChris Lattner output_stream.Printf ("Breakpoint created: "); 297*30fdc8d8SChris Lattner bp->GetDescription(&output_stream, lldb::eDescriptionLevelBrief); 298*30fdc8d8SChris Lattner output_stream.EOL(); 299*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishResult); 300*30fdc8d8SChris Lattner } 301*30fdc8d8SChris Lattner else 302*30fdc8d8SChris Lattner { 303*30fdc8d8SChris Lattner result.AppendErrorWithFormat("Breakpoint creation failed: No breakpoint created in module '%s'.\n", 304*30fdc8d8SChris Lattner m_options.m_modules[i].c_str()); 305*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 306*30fdc8d8SChris Lattner } 307*30fdc8d8SChris Lattner } 308*30fdc8d8SChris Lattner } 309*30fdc8d8SChris Lattner else 310*30fdc8d8SChris Lattner bp = target->CreateBreakpoint (NULL, 311*30fdc8d8SChris Lattner file, 312*30fdc8d8SChris Lattner m_options.m_line_num, 313*30fdc8d8SChris Lattner m_options.m_ignore_inlines).get(); 314*30fdc8d8SChris Lattner } 315*30fdc8d8SChris Lattner break; 316*30fdc8d8SChris Lattner case eSetTypeAddress: // Breakpoint by address 317*30fdc8d8SChris Lattner bp = target->CreateBreakpoint (m_options.m_load_addr, false).get(); 318*30fdc8d8SChris Lattner break; 319*30fdc8d8SChris Lattner case eSetTypeFunctionName: // Breakpoint by function name 320*30fdc8d8SChris Lattner if (use_module) 321*30fdc8d8SChris Lattner { 322*30fdc8d8SChris Lattner for (int i = 0; i < num_modules; ++i) 323*30fdc8d8SChris Lattner { 324*30fdc8d8SChris Lattner module.SetFile(m_options.m_modules[i].c_str()); 325*30fdc8d8SChris Lattner bp = target->CreateBreakpoint (&module, m_options.m_func_name.c_str()).get(); 326*30fdc8d8SChris Lattner if (bp) 327*30fdc8d8SChris Lattner { 328*30fdc8d8SChris Lattner StreamString &output_stream = result.GetOutputStream(); 329*30fdc8d8SChris Lattner output_stream.Printf ("Breakpoint created: "); 330*30fdc8d8SChris Lattner bp->GetDescription(&output_stream, lldb::eDescriptionLevelBrief); 331*30fdc8d8SChris Lattner output_stream.EOL(); 332*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishResult); 333*30fdc8d8SChris Lattner } 334*30fdc8d8SChris Lattner else 335*30fdc8d8SChris Lattner { 336*30fdc8d8SChris Lattner result.AppendErrorWithFormat("Breakpoint creation failed: No breakpoint created in module '%s'.\n", 337*30fdc8d8SChris Lattner m_options.m_modules[i].c_str()); 338*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 339*30fdc8d8SChris Lattner } 340*30fdc8d8SChris Lattner } 341*30fdc8d8SChris Lattner } 342*30fdc8d8SChris Lattner else 343*30fdc8d8SChris Lattner bp = target->CreateBreakpoint (NULL, m_options.m_func_name.c_str()).get(); 344*30fdc8d8SChris Lattner break; 345*30fdc8d8SChris Lattner case eSetTypeFunctionRegexp: // Breakpoint by regular expression function name 346*30fdc8d8SChris Lattner { 347*30fdc8d8SChris Lattner RegularExpression regexp(m_options.m_func_regexp.c_str()); 348*30fdc8d8SChris Lattner if (use_module) 349*30fdc8d8SChris Lattner { 350*30fdc8d8SChris Lattner for (int i = 0; i < num_modules; ++i) 351*30fdc8d8SChris Lattner { 352*30fdc8d8SChris Lattner module.SetFile(m_options.m_modules[i].c_str()); 353*30fdc8d8SChris Lattner bp = target->CreateBreakpoint (&module, regexp).get(); 354*30fdc8d8SChris Lattner if (bp) 355*30fdc8d8SChris Lattner { 356*30fdc8d8SChris Lattner StreamString &output_stream = result.GetOutputStream(); 357*30fdc8d8SChris Lattner output_stream.Printf ("Breakpoint created: "); 358*30fdc8d8SChris Lattner bp->GetDescription(&output_stream, lldb::eDescriptionLevelBrief); 359*30fdc8d8SChris Lattner output_stream.EOL(); 360*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishResult); 361*30fdc8d8SChris Lattner } 362*30fdc8d8SChris Lattner else 363*30fdc8d8SChris Lattner { 364*30fdc8d8SChris Lattner result.AppendErrorWithFormat("Breakpoint creation failed: No breakpoint created in module '%s'.\n", 365*30fdc8d8SChris Lattner m_options.m_modules[i].c_str()); 366*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 367*30fdc8d8SChris Lattner } 368*30fdc8d8SChris Lattner } 369*30fdc8d8SChris Lattner } 370*30fdc8d8SChris Lattner else 371*30fdc8d8SChris Lattner bp = target->CreateBreakpoint (NULL, regexp).get(); 372*30fdc8d8SChris Lattner } 373*30fdc8d8SChris Lattner break; 374*30fdc8d8SChris Lattner default: 375*30fdc8d8SChris Lattner break; 376*30fdc8d8SChris Lattner } 377*30fdc8d8SChris Lattner 378*30fdc8d8SChris Lattner if (bp && !use_module) 379*30fdc8d8SChris Lattner { 380*30fdc8d8SChris Lattner StreamString &output_stream = result.GetOutputStream(); 381*30fdc8d8SChris Lattner output_stream.Printf ("Breakpoint created: "); 382*30fdc8d8SChris Lattner bp->GetDescription(&output_stream, lldb::eDescriptionLevelBrief); 383*30fdc8d8SChris Lattner output_stream.EOL(); 384*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishResult); 385*30fdc8d8SChris Lattner } 386*30fdc8d8SChris Lattner else if (!bp) 387*30fdc8d8SChris Lattner { 388*30fdc8d8SChris Lattner result.AppendError ("Breakpoint creation failed: No breakpoint created."); 389*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 390*30fdc8d8SChris Lattner } 391*30fdc8d8SChris Lattner 392*30fdc8d8SChris Lattner return result.Succeeded(); 393*30fdc8d8SChris Lattner } 394*30fdc8d8SChris Lattner 395*30fdc8d8SChris Lattner 396*30fdc8d8SChris Lattner 397*30fdc8d8SChris Lattner //------------------------------------------------------------------------- 398*30fdc8d8SChris Lattner // CommandObjectMultiwordBreakpoint 399*30fdc8d8SChris Lattner //------------------------------------------------------------------------- 400*30fdc8d8SChris Lattner 401*30fdc8d8SChris Lattner CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint (CommandInterpreter *interpreter) : 402*30fdc8d8SChris Lattner CommandObjectMultiword ("breakpoint", 403*30fdc8d8SChris Lattner "A set of commands for operating on breakpoints.", 404*30fdc8d8SChris Lattner "breakpoint <command> [<command-options>]") 405*30fdc8d8SChris Lattner { 406*30fdc8d8SChris Lattner bool status; 407*30fdc8d8SChris Lattner 408*30fdc8d8SChris Lattner CommandObjectSP list_command_object (new CommandObjectBreakpointList ()); 409*30fdc8d8SChris Lattner CommandObjectSP delete_command_object (new CommandObjectBreakpointDelete ()); 410*30fdc8d8SChris Lattner CommandObjectSP enable_command_object (new CommandObjectBreakpointEnable ()); 411*30fdc8d8SChris Lattner CommandObjectSP disable_command_object (new CommandObjectBreakpointDisable ()); 412*30fdc8d8SChris Lattner CommandObjectSP set_command_object (new CommandObjectBreakpointSet ()); 413*30fdc8d8SChris Lattner CommandObjectSP command_command_object (new CommandObjectBreakpointCommand (interpreter)); 414*30fdc8d8SChris Lattner 415*30fdc8d8SChris Lattner enable_command_object->SetCommandName("breakpoint enable"); 416*30fdc8d8SChris Lattner disable_command_object->SetCommandName("breakpoint disable"); 417*30fdc8d8SChris Lattner set_command_object->SetCommandName("breakpoint set"); 418*30fdc8d8SChris Lattner command_command_object->SetCommandName ("breakpoint command"); 419*30fdc8d8SChris Lattner list_command_object->SetCommandName ("breakpoint list"); 420*30fdc8d8SChris Lattner 421*30fdc8d8SChris Lattner status = LoadSubCommand (list_command_object, "list", interpreter); 422*30fdc8d8SChris Lattner status = LoadSubCommand (enable_command_object, "enable", interpreter); 423*30fdc8d8SChris Lattner status = LoadSubCommand (disable_command_object, "disable", interpreter); 424*30fdc8d8SChris Lattner status = LoadSubCommand (delete_command_object, "delete", interpreter); 425*30fdc8d8SChris Lattner status = LoadSubCommand (set_command_object, "set", interpreter); 426*30fdc8d8SChris Lattner status = LoadSubCommand (command_command_object, "command", interpreter); 427*30fdc8d8SChris Lattner } 428*30fdc8d8SChris Lattner 429*30fdc8d8SChris Lattner CommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint () 430*30fdc8d8SChris Lattner { 431*30fdc8d8SChris Lattner } 432*30fdc8d8SChris Lattner 433*30fdc8d8SChris Lattner void 434*30fdc8d8SChris Lattner CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (Args &args, Target *target, CommandReturnObject &result, 435*30fdc8d8SChris Lattner BreakpointIDList *valid_ids) 436*30fdc8d8SChris Lattner { 437*30fdc8d8SChris Lattner // args can be strings representing 1). integers (for breakpoint ids) 438*30fdc8d8SChris Lattner // 2). the full breakpoint & location canonical representation 439*30fdc8d8SChris Lattner // 3). the word "to" or a hyphen, representing a range (in which case there 440*30fdc8d8SChris Lattner // had *better* be an entry both before & after of one of the first two types. 441*30fdc8d8SChris Lattner 442*30fdc8d8SChris Lattner Args temp_args; 443*30fdc8d8SChris Lattner 444*30fdc8d8SChris Lattner // Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff directly from the old ARGS to 445*30fdc8d8SChris Lattner // the new TEMP_ARGS. Do not copy breakpoint id range strings over; instead generate a list of strings for 446*30fdc8d8SChris Lattner // all the breakpoint ids in the range, and shove all of those breakpoint id strings into TEMP_ARGS. 447*30fdc8d8SChris Lattner 448*30fdc8d8SChris Lattner BreakpointIDList::FindAndReplaceIDRanges (args, target, result, temp_args); 449*30fdc8d8SChris Lattner 450*30fdc8d8SChris Lattner // NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual BreakpointIDList: 451*30fdc8d8SChris Lattner 452*30fdc8d8SChris Lattner valid_ids->InsertStringArray ((const char **) temp_args.GetArgumentVector(), temp_args.GetArgumentCount(), result); 453*30fdc8d8SChris Lattner 454*30fdc8d8SChris Lattner // At this point, all of the breakpoint ids that the user passed in have been converted to breakpoint IDs 455*30fdc8d8SChris Lattner // and put into valid_ids. 456*30fdc8d8SChris Lattner 457*30fdc8d8SChris Lattner if (result.Succeeded()) 458*30fdc8d8SChris Lattner { 459*30fdc8d8SChris Lattner // Now that we've converted everything from args into a list of breakpoint ids, go through our tentative list 460*30fdc8d8SChris Lattner // of breakpoint id's and verify that they correspond to valid/currently set breakpoints. 461*30fdc8d8SChris Lattner 462*30fdc8d8SChris Lattner for (int i = 0; i < valid_ids->Size(); ++i) 463*30fdc8d8SChris Lattner { 464*30fdc8d8SChris Lattner BreakpointID cur_bp_id = valid_ids->GetBreakpointIDAtIndex (i); 465*30fdc8d8SChris Lattner Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 466*30fdc8d8SChris Lattner if (breakpoint != NULL) 467*30fdc8d8SChris Lattner { 468*30fdc8d8SChris Lattner int num_locations = breakpoint->GetNumLocations(); 469*30fdc8d8SChris Lattner if (cur_bp_id.GetLocationID() > num_locations) 470*30fdc8d8SChris Lattner { 471*30fdc8d8SChris Lattner StreamString id_str; 472*30fdc8d8SChris Lattner BreakpointID::GetCanonicalReference (&id_str, cur_bp_id.GetBreakpointID(), 473*30fdc8d8SChris Lattner cur_bp_id.GetLocationID()); 474*30fdc8d8SChris Lattner i = valid_ids->Size() + 1; 475*30fdc8d8SChris Lattner result.AppendErrorWithFormat ("'%s' is not a currently valid breakpoint/location id.\n", 476*30fdc8d8SChris Lattner id_str.GetData()); 477*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 478*30fdc8d8SChris Lattner } 479*30fdc8d8SChris Lattner } 480*30fdc8d8SChris Lattner else 481*30fdc8d8SChris Lattner { 482*30fdc8d8SChris Lattner i = valid_ids->Size() + 1; 483*30fdc8d8SChris Lattner result.AppendErrorWithFormat ("'%d' is not a currently valid breakpoint id.\n", cur_bp_id.GetBreakpointID()); 484*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 485*30fdc8d8SChris Lattner } 486*30fdc8d8SChris Lattner } 487*30fdc8d8SChris Lattner } 488*30fdc8d8SChris Lattner } 489*30fdc8d8SChris Lattner 490*30fdc8d8SChris Lattner //------------------------------------------------------------------------- 491*30fdc8d8SChris Lattner // CommandObjectBreakpointList::Options 492*30fdc8d8SChris Lattner //------------------------------------------------------------------------- 493*30fdc8d8SChris Lattner 494*30fdc8d8SChris Lattner CommandObjectBreakpointList::CommandOptions::CommandOptions() : 495*30fdc8d8SChris Lattner Options (), 496*30fdc8d8SChris Lattner m_level (lldb::eDescriptionLevelFull) // Breakpoint List defaults to brief descriptions 497*30fdc8d8SChris Lattner { 498*30fdc8d8SChris Lattner BuildValidOptionSets(); 499*30fdc8d8SChris Lattner } 500*30fdc8d8SChris Lattner 501*30fdc8d8SChris Lattner CommandObjectBreakpointList::CommandOptions::~CommandOptions () 502*30fdc8d8SChris Lattner { 503*30fdc8d8SChris Lattner } 504*30fdc8d8SChris Lattner 505*30fdc8d8SChris Lattner lldb::OptionDefinition 506*30fdc8d8SChris Lattner CommandObjectBreakpointList::CommandOptions::g_option_table[] = 507*30fdc8d8SChris Lattner { 508*30fdc8d8SChris Lattner { 0, false, "brief", 'b', no_argument, NULL, 0, NULL, 509*30fdc8d8SChris Lattner "Give a brief description of the breakpoint (no location info)."}, 510*30fdc8d8SChris Lattner 511*30fdc8d8SChris Lattner // FIXME: We need to add an "internal" command, and then add this sort of thing to it. 512*30fdc8d8SChris Lattner // But I need to see it for now, and don't want to wait. 513*30fdc8d8SChris Lattner { 0, false, "internal", 'i', no_argument, NULL, 0, NULL, 514*30fdc8d8SChris Lattner "Show debugger internal breakpoints" }, 515*30fdc8d8SChris Lattner 516*30fdc8d8SChris Lattner { 1, false, "full", 'f', no_argument, NULL, 0, NULL, 517*30fdc8d8SChris Lattner "Give a full description of the breakpoint and its locations."}, 518*30fdc8d8SChris Lattner // DITTO FIXME 519*30fdc8d8SChris Lattner { 1, false, "internal", 'i', no_argument, NULL, 0, NULL, 520*30fdc8d8SChris Lattner "Show debugger internal breakpoints" }, 521*30fdc8d8SChris Lattner 522*30fdc8d8SChris Lattner { 2, false, "verbose", 'v', no_argument, NULL, 0, NULL, 523*30fdc8d8SChris Lattner "Explain everything we know about the breakpoint (for debugging debugger bugs)." }, 524*30fdc8d8SChris Lattner // DITTO FIXME 525*30fdc8d8SChris Lattner { 2, false, "internal", 'i', no_argument, NULL, 0, NULL, 526*30fdc8d8SChris Lattner "Show debugger internal breakpoints" }, 527*30fdc8d8SChris Lattner 528*30fdc8d8SChris Lattner { 0, false, NULL, 0, 0, NULL, 0, NULL, NULL } 529*30fdc8d8SChris Lattner }; 530*30fdc8d8SChris Lattner 531*30fdc8d8SChris Lattner const lldb::OptionDefinition* 532*30fdc8d8SChris Lattner CommandObjectBreakpointList::CommandOptions::GetDefinitions () 533*30fdc8d8SChris Lattner { 534*30fdc8d8SChris Lattner return g_option_table; 535*30fdc8d8SChris Lattner } 536*30fdc8d8SChris Lattner 537*30fdc8d8SChris Lattner Error 538*30fdc8d8SChris Lattner CommandObjectBreakpointList::CommandOptions::SetOptionValue (int option_idx, const char *option_arg) 539*30fdc8d8SChris Lattner { 540*30fdc8d8SChris Lattner Error error; 541*30fdc8d8SChris Lattner char short_option = (char) m_getopt_table[option_idx].val; 542*30fdc8d8SChris Lattner 543*30fdc8d8SChris Lattner switch (short_option) 544*30fdc8d8SChris Lattner { 545*30fdc8d8SChris Lattner case 'b': 546*30fdc8d8SChris Lattner m_level = lldb::eDescriptionLevelBrief; 547*30fdc8d8SChris Lattner break; 548*30fdc8d8SChris Lattner case 'f': 549*30fdc8d8SChris Lattner m_level = lldb::eDescriptionLevelFull; 550*30fdc8d8SChris Lattner break; 551*30fdc8d8SChris Lattner case 'v': 552*30fdc8d8SChris Lattner m_level = lldb::eDescriptionLevelVerbose; 553*30fdc8d8SChris Lattner break; 554*30fdc8d8SChris Lattner case 'i': 555*30fdc8d8SChris Lattner m_internal = true; 556*30fdc8d8SChris Lattner break; 557*30fdc8d8SChris Lattner default: 558*30fdc8d8SChris Lattner error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option); 559*30fdc8d8SChris Lattner break; 560*30fdc8d8SChris Lattner } 561*30fdc8d8SChris Lattner 562*30fdc8d8SChris Lattner return error; 563*30fdc8d8SChris Lattner } 564*30fdc8d8SChris Lattner 565*30fdc8d8SChris Lattner void 566*30fdc8d8SChris Lattner CommandObjectBreakpointList::CommandOptions::ResetOptionValues () 567*30fdc8d8SChris Lattner { 568*30fdc8d8SChris Lattner Options::ResetOptionValues(); 569*30fdc8d8SChris Lattner 570*30fdc8d8SChris Lattner m_level = lldb::eDescriptionLevelFull; 571*30fdc8d8SChris Lattner m_internal = false; 572*30fdc8d8SChris Lattner } 573*30fdc8d8SChris Lattner 574*30fdc8d8SChris Lattner //------------------------------------------------------------------------- 575*30fdc8d8SChris Lattner // CommandObjectBreakpointList 576*30fdc8d8SChris Lattner //------------------------------------------------------------------------- 577*30fdc8d8SChris Lattner 578*30fdc8d8SChris Lattner CommandObjectBreakpointList::CommandObjectBreakpointList () : 579*30fdc8d8SChris Lattner CommandObject ("breakpoint list", 580*30fdc8d8SChris Lattner "List some or all breakpoints at configurable levels of detail.", 581*30fdc8d8SChris Lattner "breakpoint list [<breakpoint-id>]") 582*30fdc8d8SChris Lattner { 583*30fdc8d8SChris Lattner } 584*30fdc8d8SChris Lattner 585*30fdc8d8SChris Lattner CommandObjectBreakpointList::~CommandObjectBreakpointList () 586*30fdc8d8SChris Lattner { 587*30fdc8d8SChris Lattner } 588*30fdc8d8SChris Lattner 589*30fdc8d8SChris Lattner Options * 590*30fdc8d8SChris Lattner CommandObjectBreakpointList::GetOptions () 591*30fdc8d8SChris Lattner { 592*30fdc8d8SChris Lattner return &m_options; 593*30fdc8d8SChris Lattner } 594*30fdc8d8SChris Lattner 595*30fdc8d8SChris Lattner bool 596*30fdc8d8SChris Lattner CommandObjectBreakpointList::Execute 597*30fdc8d8SChris Lattner ( 598*30fdc8d8SChris Lattner Args& args, 599*30fdc8d8SChris Lattner CommandContext *context, 600*30fdc8d8SChris Lattner CommandInterpreter *interpreter, 601*30fdc8d8SChris Lattner CommandReturnObject &result 602*30fdc8d8SChris Lattner ) 603*30fdc8d8SChris Lattner { 604*30fdc8d8SChris Lattner Target *target = context->GetTarget(); 605*30fdc8d8SChris Lattner if (target == NULL) 606*30fdc8d8SChris Lattner { 607*30fdc8d8SChris Lattner result.AppendError ("Invalid target, set executable file using 'file' command."); 608*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishNoResult); 609*30fdc8d8SChris Lattner return true; 610*30fdc8d8SChris Lattner } 611*30fdc8d8SChris Lattner 612*30fdc8d8SChris Lattner const BreakpointList &breakpoints = target->GetBreakpointList(m_options.m_internal); 613*30fdc8d8SChris Lattner size_t num_breakpoints = breakpoints.GetSize(); 614*30fdc8d8SChris Lattner 615*30fdc8d8SChris Lattner if (num_breakpoints == 0) 616*30fdc8d8SChris Lattner { 617*30fdc8d8SChris Lattner result.AppendMessage ("No breakpoints currently set."); 618*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishNoResult); 619*30fdc8d8SChris Lattner return true; 620*30fdc8d8SChris Lattner } 621*30fdc8d8SChris Lattner 622*30fdc8d8SChris Lattner StreamString &output_stream = result.GetOutputStream(); 623*30fdc8d8SChris Lattner 624*30fdc8d8SChris Lattner if (args.GetArgumentCount() == 0) 625*30fdc8d8SChris Lattner { 626*30fdc8d8SChris Lattner // No breakpoint selected; show info about all currently set breakpoints. 627*30fdc8d8SChris Lattner result.AppendMessage ("Current breakpoints:"); 628*30fdc8d8SChris Lattner for (int i = 0; i < num_breakpoints; ++i) 629*30fdc8d8SChris Lattner { 630*30fdc8d8SChris Lattner Breakpoint *breakpoint = breakpoints.GetBreakpointByIndex (i).get(); 631*30fdc8d8SChris Lattner AddBreakpointDescription (context, &output_stream, breakpoint, m_options.m_level); 632*30fdc8d8SChris Lattner } 633*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishNoResult); 634*30fdc8d8SChris Lattner } 635*30fdc8d8SChris Lattner else 636*30fdc8d8SChris Lattner { 637*30fdc8d8SChris Lattner // Particular breakpoints selected; show info about that breakpoint. 638*30fdc8d8SChris Lattner BreakpointIDList valid_bp_ids; 639*30fdc8d8SChris Lattner CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (args, target, result, &valid_bp_ids); 640*30fdc8d8SChris Lattner 641*30fdc8d8SChris Lattner if (result.Succeeded()) 642*30fdc8d8SChris Lattner { 643*30fdc8d8SChris Lattner for (int i = 0; i < valid_bp_ids.Size(); ++i) 644*30fdc8d8SChris Lattner { 645*30fdc8d8SChris Lattner BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i); 646*30fdc8d8SChris Lattner Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 647*30fdc8d8SChris Lattner AddBreakpointDescription (context, &output_stream, breakpoint, m_options.m_level); 648*30fdc8d8SChris Lattner } 649*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishNoResult); 650*30fdc8d8SChris Lattner } 651*30fdc8d8SChris Lattner else 652*30fdc8d8SChris Lattner { 653*30fdc8d8SChris Lattner result.AppendError ("Invalid breakpoint id."); 654*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 655*30fdc8d8SChris Lattner } 656*30fdc8d8SChris Lattner } 657*30fdc8d8SChris Lattner 658*30fdc8d8SChris Lattner return result.Succeeded(); 659*30fdc8d8SChris Lattner } 660*30fdc8d8SChris Lattner 661*30fdc8d8SChris Lattner //------------------------------------------------------------------------- 662*30fdc8d8SChris Lattner // CommandObjectBreakpointEnable 663*30fdc8d8SChris Lattner //------------------------------------------------------------------------- 664*30fdc8d8SChris Lattner 665*30fdc8d8SChris Lattner CommandObjectBreakpointEnable::CommandObjectBreakpointEnable () : 666*30fdc8d8SChris Lattner CommandObject ("enable", 667*30fdc8d8SChris Lattner "Enables the specified disabled breakpoint(s). If no breakpoints are specified, enables all of them.", 668*30fdc8d8SChris Lattner "breakpoint enable [<breakpoint-id> | <breakpoint-id-list>]") 669*30fdc8d8SChris Lattner { 670*30fdc8d8SChris Lattner // This command object can either be called via 'enable' or 'breakpoint enable'. Because it has two different 671*30fdc8d8SChris Lattner // potential invocation methods, we need to be a little tricky about generating the syntax string. 672*30fdc8d8SChris Lattner //StreamString tmp_string; 673*30fdc8d8SChris Lattner //tmp_string.Printf ("%s <breakpoint-id>", GetCommandName()); 674*30fdc8d8SChris Lattner //m_cmd_syntax.assign (tmp_string.GetData(), tmp_string.GetSize()); 675*30fdc8d8SChris Lattner } 676*30fdc8d8SChris Lattner 677*30fdc8d8SChris Lattner 678*30fdc8d8SChris Lattner CommandObjectBreakpointEnable::~CommandObjectBreakpointEnable () 679*30fdc8d8SChris Lattner { 680*30fdc8d8SChris Lattner } 681*30fdc8d8SChris Lattner 682*30fdc8d8SChris Lattner 683*30fdc8d8SChris Lattner bool 684*30fdc8d8SChris Lattner CommandObjectBreakpointEnable::Execute (Args& args, CommandContext *context, 685*30fdc8d8SChris Lattner CommandInterpreter *interpreter, CommandReturnObject &result) 686*30fdc8d8SChris Lattner { 687*30fdc8d8SChris Lattner Target *target = context->GetTarget(); 688*30fdc8d8SChris Lattner if (target == NULL) 689*30fdc8d8SChris Lattner { 690*30fdc8d8SChris Lattner result.AppendError ("Invalid target, set executable file using 'file' command."); 691*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 692*30fdc8d8SChris Lattner return false; 693*30fdc8d8SChris Lattner } 694*30fdc8d8SChris Lattner 695*30fdc8d8SChris Lattner const BreakpointList &breakpoints = target->GetBreakpointList(); 696*30fdc8d8SChris Lattner size_t num_breakpoints = breakpoints.GetSize(); 697*30fdc8d8SChris Lattner 698*30fdc8d8SChris Lattner if (num_breakpoints == 0) 699*30fdc8d8SChris Lattner { 700*30fdc8d8SChris Lattner result.AppendError ("No breakpoints exist to be enabled."); 701*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 702*30fdc8d8SChris Lattner return false; 703*30fdc8d8SChris Lattner } 704*30fdc8d8SChris Lattner 705*30fdc8d8SChris Lattner if (args.GetArgumentCount() == 0) 706*30fdc8d8SChris Lattner { 707*30fdc8d8SChris Lattner // No breakpoint selected; enable all currently set breakpoints. 708*30fdc8d8SChris Lattner target->EnableAllBreakpoints (); 709*30fdc8d8SChris Lattner result.AppendMessageWithFormat ("All breakpoints enabled. (%d breakpoints)\n", num_breakpoints); 710*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishNoResult); 711*30fdc8d8SChris Lattner } 712*30fdc8d8SChris Lattner else 713*30fdc8d8SChris Lattner { 714*30fdc8d8SChris Lattner // Particular breakpoint selected; enable that breakpoint. 715*30fdc8d8SChris Lattner BreakpointIDList valid_bp_ids; 716*30fdc8d8SChris Lattner CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (args, target, result, &valid_bp_ids); 717*30fdc8d8SChris Lattner 718*30fdc8d8SChris Lattner if (result.Succeeded()) 719*30fdc8d8SChris Lattner { 720*30fdc8d8SChris Lattner int enable_count = 0; 721*30fdc8d8SChris Lattner int loc_count = 0; 722*30fdc8d8SChris Lattner for (int i = 0; i < valid_bp_ids.Size(); ++i) 723*30fdc8d8SChris Lattner { 724*30fdc8d8SChris Lattner BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i); 725*30fdc8d8SChris Lattner 726*30fdc8d8SChris Lattner if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) 727*30fdc8d8SChris Lattner { 728*30fdc8d8SChris Lattner Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 729*30fdc8d8SChris Lattner if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) 730*30fdc8d8SChris Lattner { 731*30fdc8d8SChris Lattner BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get(); 732*30fdc8d8SChris Lattner if (location) 733*30fdc8d8SChris Lattner { 734*30fdc8d8SChris Lattner location->SetEnabled (true); 735*30fdc8d8SChris Lattner breakpoint->SetEnabled (true); 736*30fdc8d8SChris Lattner ++loc_count; 737*30fdc8d8SChris Lattner } 738*30fdc8d8SChris Lattner } 739*30fdc8d8SChris Lattner else 740*30fdc8d8SChris Lattner { 741*30fdc8d8SChris Lattner target->EnableBreakpointByID (cur_bp_id.GetBreakpointID()); 742*30fdc8d8SChris Lattner ++enable_count; 743*30fdc8d8SChris Lattner 744*30fdc8d8SChris Lattner int num_locations = breakpoint->GetNumLocations (); 745*30fdc8d8SChris Lattner for (int j = 0; j < num_locations; ++j) 746*30fdc8d8SChris Lattner { 747*30fdc8d8SChris Lattner BreakpointLocation *cur_loc = breakpoint->GetLocationAtIndex(j).get(); 748*30fdc8d8SChris Lattner if (cur_loc) 749*30fdc8d8SChris Lattner cur_loc->SetEnabled (true); 750*30fdc8d8SChris Lattner } 751*30fdc8d8SChris Lattner } 752*30fdc8d8SChris Lattner } 753*30fdc8d8SChris Lattner } 754*30fdc8d8SChris Lattner result.AppendMessageWithFormat ("%d breakpoints enabled.\n", enable_count + loc_count); 755*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishNoResult); 756*30fdc8d8SChris Lattner } 757*30fdc8d8SChris Lattner } 758*30fdc8d8SChris Lattner 759*30fdc8d8SChris Lattner return result.Succeeded(); 760*30fdc8d8SChris Lattner } 761*30fdc8d8SChris Lattner 762*30fdc8d8SChris Lattner //------------------------------------------------------------------------- 763*30fdc8d8SChris Lattner // CommandObjectBreakpointDisable 764*30fdc8d8SChris Lattner //------------------------------------------------------------------------- 765*30fdc8d8SChris Lattner 766*30fdc8d8SChris Lattner CommandObjectBreakpointDisable::CommandObjectBreakpointDisable () : 767*30fdc8d8SChris Lattner CommandObject ("disable", 768*30fdc8d8SChris Lattner "Disables the specified breakpoint(s) without removing it/them. If no breakpoints are specified, disables them all.", 769*30fdc8d8SChris Lattner "disable [<breakpoint-id> | <breakpoint-id-list>]") 770*30fdc8d8SChris Lattner { 771*30fdc8d8SChris Lattner // This command object can either be called via 'enable' or 'breakpoint enable'. Because it has two different 772*30fdc8d8SChris Lattner // potential invocation methods, we need to be a little tricky about generating the syntax string. 773*30fdc8d8SChris Lattner //StreamString tmp_string; 774*30fdc8d8SChris Lattner //tmp_string.Printf ("%s <breakpoint-id>", GetCommandName()); 775*30fdc8d8SChris Lattner //m_cmd_syntax.assign(tmp_string.GetData(), tmp_string.GetSize()); 776*30fdc8d8SChris Lattner } 777*30fdc8d8SChris Lattner 778*30fdc8d8SChris Lattner CommandObjectBreakpointDisable::~CommandObjectBreakpointDisable () 779*30fdc8d8SChris Lattner { 780*30fdc8d8SChris Lattner } 781*30fdc8d8SChris Lattner 782*30fdc8d8SChris Lattner bool 783*30fdc8d8SChris Lattner CommandObjectBreakpointDisable::Execute (Args& args, CommandContext *context, 784*30fdc8d8SChris Lattner CommandInterpreter *interpreter, CommandReturnObject &result) 785*30fdc8d8SChris Lattner { 786*30fdc8d8SChris Lattner Target *target = context->GetTarget(); 787*30fdc8d8SChris Lattner if (target == NULL) 788*30fdc8d8SChris Lattner { 789*30fdc8d8SChris Lattner result.AppendError ("Invalid target, set executable file using 'file' command."); 790*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 791*30fdc8d8SChris Lattner return false; 792*30fdc8d8SChris Lattner } 793*30fdc8d8SChris Lattner 794*30fdc8d8SChris Lattner const BreakpointList &breakpoints = target->GetBreakpointList(); 795*30fdc8d8SChris Lattner size_t num_breakpoints = breakpoints.GetSize(); 796*30fdc8d8SChris Lattner 797*30fdc8d8SChris Lattner if (num_breakpoints == 0) 798*30fdc8d8SChris Lattner { 799*30fdc8d8SChris Lattner result.AppendError ("No breakpoints exist to be disabled."); 800*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 801*30fdc8d8SChris Lattner return false; 802*30fdc8d8SChris Lattner } 803*30fdc8d8SChris Lattner 804*30fdc8d8SChris Lattner if (args.GetArgumentCount() == 0) 805*30fdc8d8SChris Lattner { 806*30fdc8d8SChris Lattner // No breakpoint selected; disable all currently set breakpoints. 807*30fdc8d8SChris Lattner target->DisableAllBreakpoints (); 808*30fdc8d8SChris Lattner result.AppendMessageWithFormat ("All breakpoints disabled. (%d breakpoints)\n", num_breakpoints); 809*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishNoResult); 810*30fdc8d8SChris Lattner } 811*30fdc8d8SChris Lattner else 812*30fdc8d8SChris Lattner { 813*30fdc8d8SChris Lattner // Particular breakpoint selected; disable that breakpoint. 814*30fdc8d8SChris Lattner BreakpointIDList valid_bp_ids; 815*30fdc8d8SChris Lattner 816*30fdc8d8SChris Lattner CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (args, target, result, &valid_bp_ids); 817*30fdc8d8SChris Lattner 818*30fdc8d8SChris Lattner if (result.Succeeded()) 819*30fdc8d8SChris Lattner { 820*30fdc8d8SChris Lattner int disable_count = 0; 821*30fdc8d8SChris Lattner int loc_count = 0; 822*30fdc8d8SChris Lattner for (int i = 0; i < valid_bp_ids.Size(); ++i) 823*30fdc8d8SChris Lattner { 824*30fdc8d8SChris Lattner BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i); 825*30fdc8d8SChris Lattner 826*30fdc8d8SChris Lattner if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) 827*30fdc8d8SChris Lattner { 828*30fdc8d8SChris Lattner Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 829*30fdc8d8SChris Lattner if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) 830*30fdc8d8SChris Lattner { 831*30fdc8d8SChris Lattner BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get(); 832*30fdc8d8SChris Lattner if (location) 833*30fdc8d8SChris Lattner { 834*30fdc8d8SChris Lattner location->SetEnabled (false); 835*30fdc8d8SChris Lattner ++loc_count; 836*30fdc8d8SChris Lattner } 837*30fdc8d8SChris Lattner } 838*30fdc8d8SChris Lattner else 839*30fdc8d8SChris Lattner { 840*30fdc8d8SChris Lattner target->DisableBreakpointByID (cur_bp_id.GetBreakpointID()); 841*30fdc8d8SChris Lattner ++disable_count; 842*30fdc8d8SChris Lattner 843*30fdc8d8SChris Lattner int num_locations = breakpoint->GetNumLocations(); 844*30fdc8d8SChris Lattner for (int j = 0; j < num_locations; ++j) 845*30fdc8d8SChris Lattner { 846*30fdc8d8SChris Lattner BreakpointLocation *cur_loc = breakpoint->GetLocationAtIndex(j).get(); 847*30fdc8d8SChris Lattner if (cur_loc) 848*30fdc8d8SChris Lattner cur_loc->SetEnabled (false); 849*30fdc8d8SChris Lattner } 850*30fdc8d8SChris Lattner } 851*30fdc8d8SChris Lattner } 852*30fdc8d8SChris Lattner } 853*30fdc8d8SChris Lattner result.AppendMessageWithFormat ("%d breakpoints disabled.\n", disable_count + loc_count); 854*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishNoResult); 855*30fdc8d8SChris Lattner } 856*30fdc8d8SChris Lattner } 857*30fdc8d8SChris Lattner 858*30fdc8d8SChris Lattner return result.Succeeded(); 859*30fdc8d8SChris Lattner } 860*30fdc8d8SChris Lattner 861*30fdc8d8SChris Lattner //------------------------------------------------------------------------- 862*30fdc8d8SChris Lattner // CommandObjectBreakpointDelete 863*30fdc8d8SChris Lattner //------------------------------------------------------------------------- 864*30fdc8d8SChris Lattner 865*30fdc8d8SChris Lattner CommandObjectBreakpointDelete::CommandObjectBreakpointDelete() : 866*30fdc8d8SChris Lattner CommandObject ("breakpoint delete", 867*30fdc8d8SChris Lattner "Delete the specified breakpoint(s). If no breakpoints are specified, deletes them all.", 868*30fdc8d8SChris Lattner "breakpoint delete [<breakpoint-id> | <breakpoint-id-list>]") 869*30fdc8d8SChris Lattner { 870*30fdc8d8SChris Lattner } 871*30fdc8d8SChris Lattner 872*30fdc8d8SChris Lattner 873*30fdc8d8SChris Lattner CommandObjectBreakpointDelete::~CommandObjectBreakpointDelete () 874*30fdc8d8SChris Lattner { 875*30fdc8d8SChris Lattner } 876*30fdc8d8SChris Lattner 877*30fdc8d8SChris Lattner bool 878*30fdc8d8SChris Lattner CommandObjectBreakpointDelete::Execute (Args& args, CommandContext *context, 879*30fdc8d8SChris Lattner CommandInterpreter *interpreter, CommandReturnObject &result) 880*30fdc8d8SChris Lattner { 881*30fdc8d8SChris Lattner Target *target = context->GetTarget(); 882*30fdc8d8SChris Lattner if (target == NULL) 883*30fdc8d8SChris Lattner { 884*30fdc8d8SChris Lattner result.AppendError ("Invalid target, set executable file using 'file' command."); 885*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 886*30fdc8d8SChris Lattner return false; 887*30fdc8d8SChris Lattner } 888*30fdc8d8SChris Lattner 889*30fdc8d8SChris Lattner const BreakpointList &breakpoints = target->GetBreakpointList(); 890*30fdc8d8SChris Lattner size_t num_breakpoints = breakpoints.GetSize(); 891*30fdc8d8SChris Lattner 892*30fdc8d8SChris Lattner if (num_breakpoints == 0) 893*30fdc8d8SChris Lattner { 894*30fdc8d8SChris Lattner result.AppendError ("No breakpoints exist to be deleted."); 895*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 896*30fdc8d8SChris Lattner return false; 897*30fdc8d8SChris Lattner } 898*30fdc8d8SChris Lattner 899*30fdc8d8SChris Lattner if (args.GetArgumentCount() == 0) 900*30fdc8d8SChris Lattner { 901*30fdc8d8SChris Lattner // No breakpoint selected; disable all currently set breakpoints. 902*30fdc8d8SChris Lattner if (args.GetArgumentCount() != 0) 903*30fdc8d8SChris Lattner { 904*30fdc8d8SChris Lattner result.AppendErrorWithFormat ("Specify breakpoints to delete with the -i option.\n"); 905*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 906*30fdc8d8SChris Lattner return false; 907*30fdc8d8SChris Lattner } 908*30fdc8d8SChris Lattner 909*30fdc8d8SChris Lattner target->RemoveAllBreakpoints (); 910*30fdc8d8SChris Lattner result.AppendMessageWithFormat ("All breakpoints removed. (%d breakpoints)\n", num_breakpoints); 911*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishNoResult); 912*30fdc8d8SChris Lattner } 913*30fdc8d8SChris Lattner else 914*30fdc8d8SChris Lattner { 915*30fdc8d8SChris Lattner // Particular breakpoint selected; disable that breakpoint. 916*30fdc8d8SChris Lattner BreakpointIDList valid_bp_ids; 917*30fdc8d8SChris Lattner CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (args, target, result, &valid_bp_ids); 918*30fdc8d8SChris Lattner 919*30fdc8d8SChris Lattner if (result.Succeeded()) 920*30fdc8d8SChris Lattner { 921*30fdc8d8SChris Lattner int delete_count = 0; 922*30fdc8d8SChris Lattner int disable_count = 0; 923*30fdc8d8SChris Lattner for (int i = 0; i < valid_bp_ids.Size(); ++i) 924*30fdc8d8SChris Lattner { 925*30fdc8d8SChris Lattner BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i); 926*30fdc8d8SChris Lattner 927*30fdc8d8SChris Lattner if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) 928*30fdc8d8SChris Lattner { 929*30fdc8d8SChris Lattner if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) 930*30fdc8d8SChris Lattner { 931*30fdc8d8SChris Lattner Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 932*30fdc8d8SChris Lattner BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get(); 933*30fdc8d8SChris Lattner // It makes no sense to try to delete individual locations, so we disable them instead. 934*30fdc8d8SChris Lattner if (location) 935*30fdc8d8SChris Lattner { 936*30fdc8d8SChris Lattner location->SetEnabled (false); 937*30fdc8d8SChris Lattner ++disable_count; 938*30fdc8d8SChris Lattner } 939*30fdc8d8SChris Lattner } 940*30fdc8d8SChris Lattner else 941*30fdc8d8SChris Lattner { 942*30fdc8d8SChris Lattner target->RemoveBreakpointByID (cur_bp_id.GetBreakpointID()); 943*30fdc8d8SChris Lattner ++delete_count; 944*30fdc8d8SChris Lattner } 945*30fdc8d8SChris Lattner } 946*30fdc8d8SChris Lattner } 947*30fdc8d8SChris Lattner result.AppendMessageWithFormat ("%d breakpoints deleted; %d breakpoint locations disabled.\n", 948*30fdc8d8SChris Lattner delete_count, disable_count); 949*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishNoResult); 950*30fdc8d8SChris Lattner } 951*30fdc8d8SChris Lattner } 952*30fdc8d8SChris Lattner return result.Succeeded(); 953*30fdc8d8SChris Lattner } 954