1 //===-- CommandObjectBreakpoint.cpp -----------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "CommandObjectBreakpoint.h" 11 #include "CommandObjectBreakpointCommand.h" 12 13 // C Includes 14 // C++ Includes 15 // Other libraries and framework includes 16 // Project includes 17 #include "lldb/Breakpoint/Breakpoint.h" 18 #include "lldb/Breakpoint/BreakpointIDList.h" 19 #include "lldb/Breakpoint/BreakpointLocation.h" 20 #include "lldb/Interpreter/Options.h" 21 #include "lldb/Core/RegularExpression.h" 22 #include "lldb/Core/StreamString.h" 23 #include "lldb/Interpreter/CommandInterpreter.h" 24 #include "lldb/Interpreter/CommandReturnObject.h" 25 #include "lldb/Target/Target.h" 26 #include "lldb/Interpreter/CommandCompletions.h" 27 #include "lldb/Target/StackFrame.h" 28 #include "lldb/Target/Thread.h" 29 #include "lldb/Target/ThreadSpec.h" 30 31 #include <vector> 32 33 using namespace lldb; 34 using namespace lldb_private; 35 36 static void 37 AddBreakpointDescription (Stream *s, Breakpoint *bp, lldb::DescriptionLevel level) 38 { 39 s->IndentMore(); 40 bp->GetDescription (s, level, true); 41 s->IndentLess(); 42 s->EOL(); 43 } 44 45 //------------------------------------------------------------------------- 46 // CommandObjectBreakpointSet::CommandOptions 47 //------------------------------------------------------------------------- 48 #pragma mark Set::CommandOptions 49 50 CommandObjectBreakpointSet::CommandOptions::CommandOptions(CommandInterpreter &interpreter) : 51 Options (interpreter), 52 m_filename (), 53 m_line_num (0), 54 m_column (0), 55 m_check_inlines (true), 56 m_func_name (), 57 m_func_name_type_mask (0), 58 m_func_regexp (), 59 m_modules (), 60 m_load_addr(), 61 m_ignore_count (0), 62 m_thread_id(LLDB_INVALID_THREAD_ID), 63 m_thread_index (UINT32_MAX), 64 m_thread_name(), 65 m_queue_name() 66 { 67 } 68 69 CommandObjectBreakpointSet::CommandOptions::~CommandOptions () 70 { 71 } 72 73 OptionDefinition 74 CommandObjectBreakpointSet::CommandOptions::g_option_table[] = 75 { 76 { LLDB_OPT_SET_ALL, false, "shlib", 's', required_argument, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName, 77 "Set the breakpoint only in this shared library (can use this option multiple times for multiple shlibs)."}, 78 79 { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', required_argument, NULL, 0, eArgTypeCount, 80 "Set the number of times this breakpoint is skipped before stopping." }, 81 82 { LLDB_OPT_SET_ALL, false, "thread-index", 'x', required_argument, NULL, NULL, eArgTypeThreadIndex, 83 "The breakpoint stops only for the thread whose index matches this argument."}, 84 85 { LLDB_OPT_SET_ALL, false, "thread-id", 't', required_argument, NULL, NULL, eArgTypeThreadID, 86 "The breakpoint stops only for the thread whose TID matches this argument."}, 87 88 { LLDB_OPT_SET_ALL, false, "thread-name", 'T', required_argument, NULL, NULL, eArgTypeThreadName, 89 "The breakpoint stops only for the thread whose thread name matches this argument."}, 90 91 { LLDB_OPT_SET_ALL, false, "queue-name", 'q', required_argument, NULL, NULL, eArgTypeQueueName, 92 "The breakpoint stops only for threads in the queue whose name is given by this argument."}, 93 94 { LLDB_OPT_SET_1, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, 95 "Set the breakpoint by source location in this particular file."}, 96 97 { LLDB_OPT_SET_1, true, "line", 'l', required_argument, NULL, 0, eArgTypeLineNum, 98 "Set the breakpoint by source location at this particular line."}, 99 100 // Comment out this option for the moment, as we don't actually use it, but will in the future. 101 // This way users won't see it, but the infrastructure is left in place. 102 // { 0, false, "column", 'c', required_argument, NULL, "<column>", 103 // "Set the breakpoint by source location at this particular column."}, 104 105 { LLDB_OPT_SET_2, true, "address", 'a', required_argument, NULL, 0, eArgTypeAddress, 106 "Set the breakpoint by address, at the specified address."}, 107 108 { LLDB_OPT_SET_3, true, "name", 'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, 109 "Set the breakpoint by function name." }, 110 111 { LLDB_OPT_SET_4, true, "fullname", 'F', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFullName, 112 "Set the breakpoint by fully qualified function names. For C++ this means namespaces and all arguemnts, and " 113 "for Objective C this means a full function prototype with class and selector." }, 114 115 { LLDB_OPT_SET_5, true, "selector", 'S', required_argument, NULL, 0, eArgTypeSelector, 116 "Set the breakpoint by ObjC selector name." }, 117 118 { LLDB_OPT_SET_6, true, "method", 'M', required_argument, NULL, 0, eArgTypeMethod, 119 "Set the breakpoint by C++ method names." }, 120 121 { LLDB_OPT_SET_7, true, "func-regex", 'r', required_argument, NULL, 0, eArgTypeRegularExpression, 122 "Set the breakpoint by function name, evaluating a regular-expression to find the function name(s)." }, 123 124 { LLDB_OPT_SET_8, true, "basename", 'b', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, 125 "Set the breakpoint by function basename (C++ namespaces and arguments will be ignored)." }, 126 127 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 128 }; 129 130 const OptionDefinition* 131 CommandObjectBreakpointSet::CommandOptions::GetDefinitions () 132 { 133 return g_option_table; 134 } 135 136 Error 137 CommandObjectBreakpointSet::CommandOptions::SetOptionValue (uint32_t option_idx, const char *option_arg) 138 { 139 Error error; 140 char short_option = (char) m_getopt_table[option_idx].val; 141 142 switch (short_option) 143 { 144 case 'a': 145 m_load_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS, 0); 146 if (m_load_addr == LLDB_INVALID_ADDRESS) 147 m_load_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS, 16); 148 149 if (m_load_addr == LLDB_INVALID_ADDRESS) 150 error.SetErrorStringWithFormat ("Invalid address string '%s'.\n", option_arg); 151 break; 152 153 case 'c': 154 m_column = Args::StringToUInt32 (option_arg, 0); 155 break; 156 157 case 'f': 158 m_filename.assign (option_arg); 159 break; 160 161 case 'l': 162 m_line_num = Args::StringToUInt32 (option_arg, 0); 163 break; 164 165 case 'b': 166 m_func_name.assign (option_arg); 167 m_func_name_type_mask |= eFunctionNameTypeBase; 168 break; 169 170 case 'n': 171 m_func_name.assign (option_arg); 172 m_func_name_type_mask |= eFunctionNameTypeAuto; 173 break; 174 175 case 'F': 176 m_func_name.assign (option_arg); 177 m_func_name_type_mask |= eFunctionNameTypeFull; 178 break; 179 180 case 'S': 181 m_func_name.assign (option_arg); 182 m_func_name_type_mask |= eFunctionNameTypeSelector; 183 break; 184 185 case 'M': 186 m_func_name.assign (option_arg); 187 m_func_name_type_mask |= eFunctionNameTypeMethod; 188 break; 189 190 case 'r': 191 m_func_regexp.assign (option_arg); 192 break; 193 194 case 's': 195 { 196 m_modules.push_back (std::string (option_arg)); 197 break; 198 } 199 case 'i': 200 { 201 m_ignore_count = Args::StringToUInt32(option_arg, UINT32_MAX, 0); 202 if (m_ignore_count == UINT32_MAX) 203 error.SetErrorStringWithFormat ("Invalid ignore count '%s'.\n", option_arg); 204 } 205 break; 206 case 't' : 207 { 208 m_thread_id = Args::StringToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0); 209 if (m_thread_id == LLDB_INVALID_THREAD_ID) 210 error.SetErrorStringWithFormat ("Invalid thread id string '%s'.\n", option_arg); 211 } 212 break; 213 case 'T': 214 m_thread_name.assign (option_arg); 215 break; 216 case 'q': 217 m_queue_name.assign (option_arg); 218 break; 219 case 'x': 220 { 221 m_thread_index = Args::StringToUInt32(option_arg, UINT32_MAX, 0); 222 if (m_thread_id == UINT32_MAX) 223 error.SetErrorStringWithFormat ("Invalid thread index string '%s'.\n", option_arg); 224 225 } 226 break; 227 default: 228 error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option); 229 break; 230 } 231 232 return error; 233 } 234 235 void 236 CommandObjectBreakpointSet::CommandOptions::OptionParsingStarting () 237 { 238 m_filename.clear(); 239 m_line_num = 0; 240 m_column = 0; 241 m_func_name.clear(); 242 m_func_name_type_mask = 0; 243 m_func_regexp.clear(); 244 m_load_addr = LLDB_INVALID_ADDRESS; 245 m_modules.clear(); 246 m_ignore_count = 0; 247 m_thread_id = LLDB_INVALID_THREAD_ID; 248 m_thread_index = UINT32_MAX; 249 m_thread_name.clear(); 250 m_queue_name.clear(); 251 } 252 253 //------------------------------------------------------------------------- 254 // CommandObjectBreakpointSet 255 //------------------------------------------------------------------------- 256 #pragma mark Set 257 258 CommandObjectBreakpointSet::CommandObjectBreakpointSet (CommandInterpreter &interpreter) : 259 CommandObject (interpreter, 260 "breakpoint set", 261 "Sets a breakpoint or set of breakpoints in the executable.", 262 "breakpoint set <cmd-options>"), 263 m_options (interpreter) 264 { 265 } 266 267 CommandObjectBreakpointSet::~CommandObjectBreakpointSet () 268 { 269 } 270 271 Options * 272 CommandObjectBreakpointSet::GetOptions () 273 { 274 return &m_options; 275 } 276 277 bool 278 CommandObjectBreakpointSet::Execute 279 ( 280 Args& command, 281 CommandReturnObject &result 282 ) 283 { 284 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 285 if (target == NULL) 286 { 287 result.AppendError ("Invalid target. Must set target before setting breakpoints (see 'file' command)."); 288 result.SetStatus (eReturnStatusFailed); 289 return false; 290 } 291 292 // The following are the various types of breakpoints that could be set: 293 // 1). -f -l -p [-s -g] (setting breakpoint by source location) 294 // 2). -a [-s -g] (setting breakpoint by address) 295 // 3). -n [-s -g] (setting breakpoint by function name) 296 // 4). -r [-s -g] (setting breakpoint by function name regular expression) 297 298 BreakpointSetType break_type = eSetTypeInvalid; 299 300 if (m_options.m_line_num != 0) 301 break_type = eSetTypeFileAndLine; 302 else if (m_options.m_load_addr != LLDB_INVALID_ADDRESS) 303 break_type = eSetTypeAddress; 304 else if (!m_options.m_func_name.empty()) 305 break_type = eSetTypeFunctionName; 306 else if (!m_options.m_func_regexp.empty()) 307 break_type = eSetTypeFunctionRegexp; 308 309 ModuleSP module_sp = target->GetExecutableModule(); 310 Breakpoint *bp = NULL; 311 FileSpec module_spec; 312 bool use_module = false; 313 int num_modules = m_options.m_modules.size(); 314 315 if ((num_modules > 0) && (break_type != eSetTypeAddress)) 316 use_module = true; 317 318 switch (break_type) 319 { 320 case eSetTypeFileAndLine: // Breakpoint by source position 321 { 322 FileSpec file; 323 if (m_options.m_filename.empty()) 324 { 325 StackFrame *cur_frame = m_interpreter.GetExecutionContext().frame; 326 if (cur_frame == NULL) 327 { 328 result.AppendError ("Attempting to set breakpoint by line number alone with no selected frame."); 329 result.SetStatus (eReturnStatusFailed); 330 break; 331 } 332 else if (!cur_frame->HasDebugInformation()) 333 { 334 result.AppendError ("Attempting to set breakpoint by line number alone but selected frame has no debug info."); 335 result.SetStatus (eReturnStatusFailed); 336 break; 337 } 338 else 339 { 340 const SymbolContext &context = cur_frame->GetSymbolContext(true); 341 if (context.line_entry.file) 342 { 343 file = context.line_entry.file; 344 } 345 else if (context.comp_unit != NULL) 346 { file = context.comp_unit; 347 } 348 else 349 { 350 result.AppendError ("Attempting to set breakpoint by line number alone but can't find the file for the selected frame."); 351 result.SetStatus (eReturnStatusFailed); 352 break; 353 } 354 } 355 } 356 else 357 { 358 file.SetFile(m_options.m_filename.c_str(), false); 359 } 360 361 if (use_module) 362 { 363 for (int i = 0; i < num_modules; ++i) 364 { 365 module_spec.SetFile(m_options.m_modules[i].c_str(), false); 366 bp = target->CreateBreakpoint (&module_spec, 367 file, 368 m_options.m_line_num, 369 m_options.m_check_inlines).get(); 370 if (bp) 371 { 372 Stream &output_stream = result.GetOutputStream(); 373 result.AppendMessage ("Breakpoint created: "); 374 bp->GetDescription(&output_stream, lldb::eDescriptionLevelBrief); 375 output_stream.EOL(); 376 if (bp->GetNumLocations() == 0) 377 output_stream.Printf ("WARNING: Unable to resolve breakpoint to any actual" 378 " locations.\n"); 379 result.SetStatus (eReturnStatusSuccessFinishResult); 380 } 381 else 382 { 383 result.AppendErrorWithFormat("Breakpoint creation failed: No breakpoint created in module '%s'.\n", 384 m_options.m_modules[i].c_str()); 385 result.SetStatus (eReturnStatusFailed); 386 } 387 } 388 } 389 else 390 bp = target->CreateBreakpoint (NULL, 391 file, 392 m_options.m_line_num, 393 m_options.m_check_inlines).get(); 394 } 395 break; 396 397 case eSetTypeAddress: // Breakpoint by address 398 bp = target->CreateBreakpoint (m_options.m_load_addr, false).get(); 399 break; 400 401 case eSetTypeFunctionName: // Breakpoint by function name 402 { 403 uint32_t name_type_mask = m_options.m_func_name_type_mask; 404 405 if (name_type_mask == 0) 406 name_type_mask = eFunctionNameTypeAuto; 407 408 if (use_module) 409 { 410 for (int i = 0; i < num_modules; ++i) 411 { 412 module_spec.SetFile(m_options.m_modules[i].c_str(), false); 413 bp = target->CreateBreakpoint (&module_spec, 414 m_options.m_func_name.c_str(), 415 name_type_mask, 416 Breakpoint::Exact).get(); 417 if (bp) 418 { 419 Stream &output_stream = result.GetOutputStream(); 420 output_stream.Printf ("Breakpoint created: "); 421 bp->GetDescription(&output_stream, lldb::eDescriptionLevelBrief); 422 output_stream.EOL(); 423 if (bp->GetNumLocations() == 0) 424 output_stream.Printf ("WARNING: Unable to resolve breakpoint to any actual" 425 " locations.\n"); 426 result.SetStatus (eReturnStatusSuccessFinishResult); 427 } 428 else 429 { 430 result.AppendErrorWithFormat("Breakpoint creation failed: No breakpoint created in module '%s'.\n", 431 m_options.m_modules[i].c_str()); 432 result.SetStatus (eReturnStatusFailed); 433 } 434 } 435 } 436 else 437 bp = target->CreateBreakpoint (NULL, m_options.m_func_name.c_str(), name_type_mask, Breakpoint::Exact).get(); 438 } 439 break; 440 441 case eSetTypeFunctionRegexp: // Breakpoint by regular expression function name 442 { 443 RegularExpression regexp(m_options.m_func_regexp.c_str()); 444 if (use_module) 445 { 446 for (int i = 0; i < num_modules; ++i) 447 { 448 module_spec.SetFile(m_options.m_modules[i].c_str(), false); 449 bp = target->CreateBreakpoint (&module_spec, regexp).get(); 450 if (bp) 451 { 452 Stream &output_stream = result.GetOutputStream(); 453 output_stream.Printf ("Breakpoint created: "); 454 bp->GetDescription(&output_stream, lldb::eDescriptionLevelBrief); 455 output_stream.EOL(); 456 if (bp->GetNumLocations() == 0) 457 output_stream.Printf ("WARNING: Unable to resolve breakpoint to any actual" 458 " locations.\n"); 459 result.SetStatus (eReturnStatusSuccessFinishResult); 460 } 461 else 462 { 463 result.AppendErrorWithFormat("Breakpoint creation failed: No breakpoint created in module '%s'.\n", 464 m_options.m_modules[i].c_str()); 465 result.SetStatus (eReturnStatusFailed); 466 } 467 } 468 } 469 else 470 bp = target->CreateBreakpoint (NULL, regexp).get(); 471 } 472 break; 473 474 default: 475 break; 476 } 477 478 // Now set the various options that were passed in: 479 if (bp) 480 { 481 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID) 482 bp->SetThreadID (m_options.m_thread_id); 483 484 if (m_options.m_thread_index != UINT32_MAX) 485 bp->GetOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index); 486 487 if (!m_options.m_thread_name.empty()) 488 bp->GetOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str()); 489 490 if (!m_options.m_queue_name.empty()) 491 bp->GetOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str()); 492 493 if (m_options.m_ignore_count != 0) 494 bp->GetOptions()->SetIgnoreCount(m_options.m_ignore_count); 495 } 496 497 if (bp && !use_module) 498 { 499 Stream &output_stream = result.GetOutputStream(); 500 output_stream.Printf ("Breakpoint created: "); 501 bp->GetDescription(&output_stream, lldb::eDescriptionLevelBrief); 502 output_stream.EOL(); 503 if (bp->GetNumLocations() == 0) 504 output_stream.Printf ("WARNING: Unable to resolve breakpoint to any actual locations.\n"); 505 result.SetStatus (eReturnStatusSuccessFinishResult); 506 } 507 else if (!bp) 508 { 509 result.AppendError ("Breakpoint creation failed: No breakpoint created."); 510 result.SetStatus (eReturnStatusFailed); 511 } 512 513 return result.Succeeded(); 514 } 515 516 //------------------------------------------------------------------------- 517 // CommandObjectMultiwordBreakpoint 518 //------------------------------------------------------------------------- 519 #pragma mark MultiwordBreakpoint 520 521 CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint (CommandInterpreter &interpreter) : 522 CommandObjectMultiword (interpreter, 523 "breakpoint", 524 "A set of commands for operating on breakpoints. Also see regexp-break.", 525 "breakpoint <command> [<command-options>]") 526 { 527 bool status; 528 529 CommandObjectSP list_command_object (new CommandObjectBreakpointList (interpreter)); 530 CommandObjectSP enable_command_object (new CommandObjectBreakpointEnable (interpreter)); 531 CommandObjectSP disable_command_object (new CommandObjectBreakpointDisable (interpreter)); 532 CommandObjectSP clear_command_object (new CommandObjectBreakpointClear (interpreter)); 533 CommandObjectSP delete_command_object (new CommandObjectBreakpointDelete (interpreter)); 534 CommandObjectSP set_command_object (new CommandObjectBreakpointSet (interpreter)); 535 CommandObjectSP command_command_object (new CommandObjectBreakpointCommand (interpreter)); 536 CommandObjectSP modify_command_object (new CommandObjectBreakpointModify(interpreter)); 537 538 list_command_object->SetCommandName ("breakpoint list"); 539 enable_command_object->SetCommandName("breakpoint enable"); 540 disable_command_object->SetCommandName("breakpoint disable"); 541 clear_command_object->SetCommandName("breakpoint clear"); 542 delete_command_object->SetCommandName("breakpoint delete"); 543 set_command_object->SetCommandName("breakpoint set"); 544 command_command_object->SetCommandName ("breakpoint command"); 545 modify_command_object->SetCommandName ("breakpoint modify"); 546 547 status = LoadSubCommand ("list", list_command_object); 548 status = LoadSubCommand ("enable", enable_command_object); 549 status = LoadSubCommand ("disable", disable_command_object); 550 status = LoadSubCommand ("clear", clear_command_object); 551 status = LoadSubCommand ("delete", delete_command_object); 552 status = LoadSubCommand ("set", set_command_object); 553 status = LoadSubCommand ("command", command_command_object); 554 status = LoadSubCommand ("modify", modify_command_object); 555 } 556 557 CommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint () 558 { 559 } 560 561 void 562 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (Args &args, Target *target, CommandReturnObject &result, 563 BreakpointIDList *valid_ids) 564 { 565 // args can be strings representing 1). integers (for breakpoint ids) 566 // 2). the full breakpoint & location canonical representation 567 // 3). the word "to" or a hyphen, representing a range (in which case there 568 // had *better* be an entry both before & after of one of the first two types. 569 // If args is empty, we will use the last created breakpoint (if there is one.) 570 571 Args temp_args; 572 573 if (args.GetArgumentCount() == 0) 574 { 575 if (target->GetLastCreatedBreakpoint() != NULL) 576 { 577 valid_ids->AddBreakpointID (BreakpointID(target->GetLastCreatedBreakpoint()->GetID(), LLDB_INVALID_BREAK_ID)); 578 result.SetStatus (eReturnStatusSuccessFinishNoResult); 579 } 580 else 581 { 582 result.AppendError("No breakpoint specified and no last created breakpoint."); 583 result.SetStatus (eReturnStatusFailed); 584 } 585 return; 586 } 587 588 // Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff directly from the old ARGS to 589 // the new TEMP_ARGS. Do not copy breakpoint id range strings over; instead generate a list of strings for 590 // all the breakpoint ids in the range, and shove all of those breakpoint id strings into TEMP_ARGS. 591 592 BreakpointIDList::FindAndReplaceIDRanges (args, target, result, temp_args); 593 594 // NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual BreakpointIDList: 595 596 valid_ids->InsertStringArray (temp_args.GetConstArgumentVector(), temp_args.GetArgumentCount(), result); 597 598 // At this point, all of the breakpoint ids that the user passed in have been converted to breakpoint IDs 599 // and put into valid_ids. 600 601 if (result.Succeeded()) 602 { 603 // Now that we've converted everything from args into a list of breakpoint ids, go through our tentative list 604 // of breakpoint id's and verify that they correspond to valid/currently set breakpoints. 605 606 const size_t count = valid_ids->GetSize(); 607 for (size_t i = 0; i < count; ++i) 608 { 609 BreakpointID cur_bp_id = valid_ids->GetBreakpointIDAtIndex (i); 610 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 611 if (breakpoint != NULL) 612 { 613 int num_locations = breakpoint->GetNumLocations(); 614 if (cur_bp_id.GetLocationID() > num_locations) 615 { 616 StreamString id_str; 617 BreakpointID::GetCanonicalReference (&id_str, 618 cur_bp_id.GetBreakpointID(), 619 cur_bp_id.GetLocationID()); 620 i = valid_ids->GetSize() + 1; 621 result.AppendErrorWithFormat ("'%s' is not a currently valid breakpoint/location id.\n", 622 id_str.GetData()); 623 result.SetStatus (eReturnStatusFailed); 624 } 625 } 626 else 627 { 628 i = valid_ids->GetSize() + 1; 629 result.AppendErrorWithFormat ("'%d' is not a currently valid breakpoint id.\n", cur_bp_id.GetBreakpointID()); 630 result.SetStatus (eReturnStatusFailed); 631 } 632 } 633 } 634 } 635 636 //------------------------------------------------------------------------- 637 // CommandObjectBreakpointList::Options 638 //------------------------------------------------------------------------- 639 #pragma mark List::CommandOptions 640 641 CommandObjectBreakpointList::CommandOptions::CommandOptions(CommandInterpreter &interpreter) : 642 Options (interpreter), 643 m_level (lldb::eDescriptionLevelBrief) // Breakpoint List defaults to brief descriptions 644 { 645 } 646 647 CommandObjectBreakpointList::CommandOptions::~CommandOptions () 648 { 649 } 650 651 OptionDefinition 652 CommandObjectBreakpointList::CommandOptions::g_option_table[] = 653 { 654 { LLDB_OPT_SET_ALL, false, "internal", 'i', no_argument, NULL, 0, eArgTypeNone, 655 "Show debugger internal breakpoints" }, 656 657 { LLDB_OPT_SET_1, false, "brief", 'b', no_argument, NULL, 0, eArgTypeNone, 658 "Give a brief description of the breakpoint (no location info)."}, 659 660 // FIXME: We need to add an "internal" command, and then add this sort of thing to it. 661 // But I need to see it for now, and don't want to wait. 662 { LLDB_OPT_SET_2, false, "full", 'f', no_argument, NULL, 0, eArgTypeNone, 663 "Give a full description of the breakpoint and its locations."}, 664 665 { LLDB_OPT_SET_3, false, "verbose", 'v', no_argument, NULL, 0, eArgTypeNone, 666 "Explain everything we know about the breakpoint (for debugging debugger bugs)." }, 667 668 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 669 }; 670 671 const OptionDefinition* 672 CommandObjectBreakpointList::CommandOptions::GetDefinitions () 673 { 674 return g_option_table; 675 } 676 677 Error 678 CommandObjectBreakpointList::CommandOptions::SetOptionValue (uint32_t option_idx, const char *option_arg) 679 { 680 Error error; 681 char short_option = (char) m_getopt_table[option_idx].val; 682 683 switch (short_option) 684 { 685 case 'b': 686 m_level = lldb::eDescriptionLevelBrief; 687 break; 688 case 'f': 689 m_level = lldb::eDescriptionLevelFull; 690 break; 691 case 'v': 692 m_level = lldb::eDescriptionLevelVerbose; 693 break; 694 case 'i': 695 m_internal = true; 696 break; 697 default: 698 error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option); 699 break; 700 } 701 702 return error; 703 } 704 705 void 706 CommandObjectBreakpointList::CommandOptions::OptionParsingStarting () 707 { 708 m_level = lldb::eDescriptionLevelBrief; 709 m_internal = false; 710 } 711 712 //------------------------------------------------------------------------- 713 // CommandObjectBreakpointList 714 //------------------------------------------------------------------------- 715 #pragma mark List 716 717 CommandObjectBreakpointList::CommandObjectBreakpointList (CommandInterpreter &interpreter) : 718 CommandObject (interpreter, 719 "breakpoint list", 720 "List some or all breakpoints at configurable levels of detail.", 721 NULL), 722 m_options (interpreter) 723 { 724 CommandArgumentEntry arg; 725 CommandArgumentData bp_id_arg; 726 727 // Define the first (and only) variant of this arg. 728 bp_id_arg.arg_type = eArgTypeBreakpointID; 729 bp_id_arg.arg_repetition = eArgRepeatOptional; 730 731 // There is only one variant this argument could be; put it into the argument entry. 732 arg.push_back (bp_id_arg); 733 734 // Push the data for the first argument into the m_arguments vector. 735 m_arguments.push_back (arg); 736 } 737 738 CommandObjectBreakpointList::~CommandObjectBreakpointList () 739 { 740 } 741 742 Options * 743 CommandObjectBreakpointList::GetOptions () 744 { 745 return &m_options; 746 } 747 748 bool 749 CommandObjectBreakpointList::Execute 750 ( 751 Args& args, 752 CommandReturnObject &result 753 ) 754 { 755 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 756 if (target == NULL) 757 { 758 result.AppendError ("Invalid target. No current target or breakpoints."); 759 result.SetStatus (eReturnStatusSuccessFinishNoResult); 760 return true; 761 } 762 763 const BreakpointList &breakpoints = target->GetBreakpointList(m_options.m_internal); 764 Mutex::Locker locker; 765 target->GetBreakpointList(m_options.m_internal).GetListMutex(locker); 766 767 size_t num_breakpoints = breakpoints.GetSize(); 768 769 if (num_breakpoints == 0) 770 { 771 result.AppendMessage ("No breakpoints currently set."); 772 result.SetStatus (eReturnStatusSuccessFinishNoResult); 773 return true; 774 } 775 776 Stream &output_stream = result.GetOutputStream(); 777 778 if (args.GetArgumentCount() == 0) 779 { 780 // No breakpoint selected; show info about all currently set breakpoints. 781 result.AppendMessage ("Current breakpoints:"); 782 for (size_t i = 0; i < num_breakpoints; ++i) 783 { 784 Breakpoint *breakpoint = breakpoints.GetBreakpointAtIndex (i).get(); 785 AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level); 786 } 787 result.SetStatus (eReturnStatusSuccessFinishNoResult); 788 } 789 else 790 { 791 // Particular breakpoints selected; show info about that breakpoint. 792 BreakpointIDList valid_bp_ids; 793 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (args, target, result, &valid_bp_ids); 794 795 if (result.Succeeded()) 796 { 797 for (size_t i = 0; i < valid_bp_ids.GetSize(); ++i) 798 { 799 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i); 800 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 801 AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level); 802 } 803 result.SetStatus (eReturnStatusSuccessFinishNoResult); 804 } 805 else 806 { 807 result.AppendError ("Invalid breakpoint id."); 808 result.SetStatus (eReturnStatusFailed); 809 } 810 } 811 812 return result.Succeeded(); 813 } 814 815 //------------------------------------------------------------------------- 816 // CommandObjectBreakpointEnable 817 //------------------------------------------------------------------------- 818 #pragma mark Enable 819 820 CommandObjectBreakpointEnable::CommandObjectBreakpointEnable (CommandInterpreter &interpreter) : 821 CommandObject (interpreter, 822 "enable", 823 "Enable the specified disabled breakpoint(s). If no breakpoints are specified, enable all of them.", 824 NULL) 825 { 826 CommandArgumentEntry arg; 827 CommandArgumentData bp_id_arg; 828 CommandArgumentData bp_id_range_arg; 829 830 // Create the first variant for the first (and only) argument for this command. 831 bp_id_arg.arg_type = eArgTypeBreakpointID; 832 bp_id_arg.arg_repetition = eArgRepeatOptional; 833 834 // Create the second variant for the first (and only) argument for this command. 835 bp_id_range_arg.arg_type = eArgTypeBreakpointIDRange; 836 bp_id_range_arg.arg_repetition = eArgRepeatOptional; 837 838 // The first (and only) argument for this command could be either a bp_id or a bp_id_range. 839 // Push both variants into the entry for the first argument for this command. 840 arg.push_back (bp_id_arg); 841 arg.push_back (bp_id_range_arg); 842 843 // Add the entry for the first argument for this command to the object's arguments vector. 844 m_arguments.push_back (arg); 845 } 846 847 848 CommandObjectBreakpointEnable::~CommandObjectBreakpointEnable () 849 { 850 } 851 852 853 bool 854 CommandObjectBreakpointEnable::Execute 855 ( 856 Args& args, 857 CommandReturnObject &result 858 ) 859 { 860 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 861 if (target == NULL) 862 { 863 result.AppendError ("Invalid target. No existing target or breakpoints."); 864 result.SetStatus (eReturnStatusFailed); 865 return false; 866 } 867 868 Mutex::Locker locker; 869 target->GetBreakpointList().GetListMutex(locker); 870 871 const BreakpointList &breakpoints = target->GetBreakpointList(); 872 873 size_t num_breakpoints = breakpoints.GetSize(); 874 875 if (num_breakpoints == 0) 876 { 877 result.AppendError ("No breakpoints exist to be enabled."); 878 result.SetStatus (eReturnStatusFailed); 879 return false; 880 } 881 882 if (args.GetArgumentCount() == 0) 883 { 884 // No breakpoint selected; enable all currently set breakpoints. 885 target->EnableAllBreakpoints (); 886 result.AppendMessageWithFormat ("All breakpoints enabled. (%d breakpoints)\n", num_breakpoints); 887 result.SetStatus (eReturnStatusSuccessFinishNoResult); 888 } 889 else 890 { 891 // Particular breakpoint selected; enable that breakpoint. 892 BreakpointIDList valid_bp_ids; 893 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (args, target, result, &valid_bp_ids); 894 895 if (result.Succeeded()) 896 { 897 int enable_count = 0; 898 int loc_count = 0; 899 const size_t count = valid_bp_ids.GetSize(); 900 for (size_t i = 0; i < count; ++i) 901 { 902 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i); 903 904 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) 905 { 906 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 907 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) 908 { 909 BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get(); 910 if (location) 911 { 912 location->SetEnabled (true); 913 ++loc_count; 914 } 915 } 916 else 917 { 918 breakpoint->SetEnabled (true); 919 ++enable_count; 920 } 921 } 922 } 923 result.AppendMessageWithFormat ("%d breakpoints enabled.\n", enable_count + loc_count); 924 result.SetStatus (eReturnStatusSuccessFinishNoResult); 925 } 926 } 927 928 return result.Succeeded(); 929 } 930 931 //------------------------------------------------------------------------- 932 // CommandObjectBreakpointDisable 933 //------------------------------------------------------------------------- 934 #pragma mark Disable 935 936 CommandObjectBreakpointDisable::CommandObjectBreakpointDisable (CommandInterpreter &interpreter) : 937 CommandObject (interpreter, 938 "breakpoint disable", 939 "Disable the specified breakpoint(s) without removing it/them. If no breakpoints are specified, disable them all.", 940 NULL) 941 { 942 CommandArgumentEntry arg; 943 CommandArgumentData bp_id_arg; 944 CommandArgumentData bp_id_range_arg; 945 946 // Create the first variant for the first (and only) argument for this command. 947 bp_id_arg.arg_type = eArgTypeBreakpointID; 948 bp_id_arg.arg_repetition = eArgRepeatOptional; 949 950 // Create the second variant for the first (and only) argument for this command. 951 bp_id_range_arg.arg_type = eArgTypeBreakpointIDRange; 952 bp_id_range_arg.arg_repetition = eArgRepeatOptional; 953 954 // The first (and only) argument for this command could be either a bp_id or a bp_id_range. 955 // Push both variants into the entry for the first argument for this command. 956 arg.push_back (bp_id_arg); 957 arg.push_back (bp_id_range_arg); 958 959 // Add the entry for the first argument for this command to the object's arguments vector. 960 m_arguments.push_back (arg); 961 } 962 963 CommandObjectBreakpointDisable::~CommandObjectBreakpointDisable () 964 { 965 } 966 967 bool 968 CommandObjectBreakpointDisable::Execute 969 ( 970 Args& args, 971 CommandReturnObject &result 972 ) 973 { 974 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 975 if (target == NULL) 976 { 977 result.AppendError ("Invalid target. No existing target or breakpoints."); 978 result.SetStatus (eReturnStatusFailed); 979 return false; 980 } 981 982 Mutex::Locker locker; 983 target->GetBreakpointList().GetListMutex(locker); 984 985 const BreakpointList &breakpoints = target->GetBreakpointList(); 986 size_t num_breakpoints = breakpoints.GetSize(); 987 988 if (num_breakpoints == 0) 989 { 990 result.AppendError ("No breakpoints exist to be disabled."); 991 result.SetStatus (eReturnStatusFailed); 992 return false; 993 } 994 995 if (args.GetArgumentCount() == 0) 996 { 997 // No breakpoint selected; disable all currently set breakpoints. 998 target->DisableAllBreakpoints (); 999 result.AppendMessageWithFormat ("All breakpoints disabled. (%d breakpoints)\n", num_breakpoints); 1000 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1001 } 1002 else 1003 { 1004 // Particular breakpoint selected; disable that breakpoint. 1005 BreakpointIDList valid_bp_ids; 1006 1007 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (args, target, result, &valid_bp_ids); 1008 1009 if (result.Succeeded()) 1010 { 1011 int disable_count = 0; 1012 int loc_count = 0; 1013 const size_t count = valid_bp_ids.GetSize(); 1014 for (size_t i = 0; i < count; ++i) 1015 { 1016 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i); 1017 1018 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) 1019 { 1020 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 1021 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) 1022 { 1023 BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get(); 1024 if (location) 1025 { 1026 location->SetEnabled (false); 1027 ++loc_count; 1028 } 1029 } 1030 else 1031 { 1032 breakpoint->SetEnabled (false); 1033 ++disable_count; 1034 } 1035 } 1036 } 1037 result.AppendMessageWithFormat ("%d breakpoints disabled.\n", disable_count + loc_count); 1038 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1039 } 1040 } 1041 1042 return result.Succeeded(); 1043 } 1044 1045 //------------------------------------------------------------------------- 1046 // CommandObjectBreakpointClear::CommandOptions 1047 //------------------------------------------------------------------------- 1048 #pragma mark Clear::CommandOptions 1049 1050 CommandObjectBreakpointClear::CommandOptions::CommandOptions(CommandInterpreter &interpreter) : 1051 Options (interpreter), 1052 m_filename (), 1053 m_line_num (0) 1054 { 1055 } 1056 1057 CommandObjectBreakpointClear::CommandOptions::~CommandOptions () 1058 { 1059 } 1060 1061 OptionDefinition 1062 CommandObjectBreakpointClear::CommandOptions::g_option_table[] = 1063 { 1064 { LLDB_OPT_SET_1, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, 1065 "Specify the breakpoint by source location in this particular file."}, 1066 1067 { LLDB_OPT_SET_1, true, "line", 'l', required_argument, NULL, 0, eArgTypeLineNum, 1068 "Specify the breakpoint by source location at this particular line."}, 1069 1070 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 1071 }; 1072 1073 const OptionDefinition* 1074 CommandObjectBreakpointClear::CommandOptions::GetDefinitions () 1075 { 1076 return g_option_table; 1077 } 1078 1079 Error 1080 CommandObjectBreakpointClear::CommandOptions::SetOptionValue (uint32_t option_idx, const char *option_arg) 1081 { 1082 Error error; 1083 char short_option = (char) m_getopt_table[option_idx].val; 1084 1085 switch (short_option) 1086 { 1087 case 'f': 1088 m_filename.assign (option_arg); 1089 break; 1090 1091 case 'l': 1092 m_line_num = Args::StringToUInt32 (option_arg, 0); 1093 break; 1094 1095 default: 1096 error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option); 1097 break; 1098 } 1099 1100 return error; 1101 } 1102 1103 void 1104 CommandObjectBreakpointClear::CommandOptions::OptionParsingStarting () 1105 { 1106 m_filename.clear(); 1107 m_line_num = 0; 1108 } 1109 1110 //------------------------------------------------------------------------- 1111 // CommandObjectBreakpointClear 1112 //------------------------------------------------------------------------- 1113 #pragma mark Clear 1114 1115 CommandObjectBreakpointClear::CommandObjectBreakpointClear (CommandInterpreter &interpreter) : 1116 CommandObject (interpreter, 1117 "breakpoint clear", 1118 "Clears a breakpoint or set of breakpoints in the executable.", 1119 "breakpoint clear <cmd-options>"), 1120 m_options (interpreter) 1121 { 1122 } 1123 1124 CommandObjectBreakpointClear::~CommandObjectBreakpointClear () 1125 { 1126 } 1127 1128 Options * 1129 CommandObjectBreakpointClear::GetOptions () 1130 { 1131 return &m_options; 1132 } 1133 1134 bool 1135 CommandObjectBreakpointClear::Execute 1136 ( 1137 Args& command, 1138 CommandReturnObject &result 1139 ) 1140 { 1141 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 1142 if (target == NULL) 1143 { 1144 result.AppendError ("Invalid target. No existing target or breakpoints."); 1145 result.SetStatus (eReturnStatusFailed); 1146 return false; 1147 } 1148 1149 // The following are the various types of breakpoints that could be cleared: 1150 // 1). -f -l (clearing breakpoint by source location) 1151 1152 BreakpointClearType break_type = eClearTypeInvalid; 1153 1154 if (m_options.m_line_num != 0) 1155 break_type = eClearTypeFileAndLine; 1156 1157 Mutex::Locker locker; 1158 target->GetBreakpointList().GetListMutex(locker); 1159 1160 BreakpointList &breakpoints = target->GetBreakpointList(); 1161 size_t num_breakpoints = breakpoints.GetSize(); 1162 1163 // Early return if there's no breakpoint at all. 1164 if (num_breakpoints == 0) 1165 { 1166 result.AppendError ("Breakpoint clear: No breakpoint cleared."); 1167 result.SetStatus (eReturnStatusFailed); 1168 return result.Succeeded(); 1169 } 1170 1171 // Find matching breakpoints and delete them. 1172 1173 // First create a copy of all the IDs. 1174 std::vector<break_id_t> BreakIDs; 1175 for (size_t i = 0; i < num_breakpoints; ++i) 1176 BreakIDs.push_back(breakpoints.GetBreakpointAtIndex(i).get()->GetID()); 1177 1178 int num_cleared = 0; 1179 StreamString ss; 1180 switch (break_type) 1181 { 1182 case eClearTypeFileAndLine: // Breakpoint by source position 1183 { 1184 const ConstString filename(m_options.m_filename.c_str()); 1185 BreakpointLocationCollection loc_coll; 1186 1187 for (size_t i = 0; i < num_breakpoints; ++i) 1188 { 1189 Breakpoint *bp = breakpoints.FindBreakpointByID(BreakIDs[i]).get(); 1190 1191 if (bp->GetMatchingFileLine(filename, m_options.m_line_num, loc_coll)) 1192 { 1193 // If the collection size is 0, it's a full match and we can just remove the breakpoint. 1194 if (loc_coll.GetSize() == 0) 1195 { 1196 bp->GetDescription(&ss, lldb::eDescriptionLevelBrief); 1197 ss.EOL(); 1198 target->RemoveBreakpointByID (bp->GetID()); 1199 ++num_cleared; 1200 } 1201 } 1202 } 1203 } 1204 break; 1205 1206 default: 1207 break; 1208 } 1209 1210 if (num_cleared > 0) 1211 { 1212 Stream &output_stream = result.GetOutputStream(); 1213 output_stream.Printf ("%d breakpoints cleared:\n", num_cleared); 1214 output_stream << ss.GetData(); 1215 output_stream.EOL(); 1216 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1217 } 1218 else 1219 { 1220 result.AppendError ("Breakpoint clear: No breakpoint cleared."); 1221 result.SetStatus (eReturnStatusFailed); 1222 } 1223 1224 return result.Succeeded(); 1225 } 1226 1227 //------------------------------------------------------------------------- 1228 // CommandObjectBreakpointDelete 1229 //------------------------------------------------------------------------- 1230 #pragma mark Delete 1231 1232 CommandObjectBreakpointDelete::CommandObjectBreakpointDelete(CommandInterpreter &interpreter) : 1233 CommandObject (interpreter, 1234 "breakpoint delete", 1235 "Delete the specified breakpoint(s). If no breakpoints are specified, delete them all.", 1236 NULL) 1237 { 1238 CommandArgumentEntry arg; 1239 CommandArgumentData bp_id_arg; 1240 CommandArgumentData bp_id_range_arg; 1241 1242 // Create the first variant for the first (and only) argument for this command. 1243 bp_id_arg.arg_type = eArgTypeBreakpointID; 1244 bp_id_arg.arg_repetition = eArgRepeatOptional; 1245 1246 // Create the second variant for the first (and only) argument for this command. 1247 bp_id_range_arg.arg_type = eArgTypeBreakpointIDRange; 1248 bp_id_range_arg.arg_repetition = eArgRepeatOptional; 1249 1250 // The first (and only) argument for this command could be either a bp_id or a bp_id_range. 1251 // Push both variants into the entry for the first argument for this command. 1252 arg.push_back (bp_id_arg); 1253 arg.push_back (bp_id_range_arg); 1254 1255 // Add the entry for the first argument for this command to the object's arguments vector. 1256 m_arguments.push_back (arg); 1257 } 1258 1259 1260 CommandObjectBreakpointDelete::~CommandObjectBreakpointDelete () 1261 { 1262 } 1263 1264 bool 1265 CommandObjectBreakpointDelete::Execute 1266 ( 1267 Args& args, 1268 CommandReturnObject &result 1269 ) 1270 { 1271 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 1272 if (target == NULL) 1273 { 1274 result.AppendError ("Invalid target. No existing target or breakpoints."); 1275 result.SetStatus (eReturnStatusFailed); 1276 return false; 1277 } 1278 1279 Mutex::Locker locker; 1280 target->GetBreakpointList().GetListMutex(locker); 1281 1282 const BreakpointList &breakpoints = target->GetBreakpointList(); 1283 1284 size_t num_breakpoints = breakpoints.GetSize(); 1285 1286 if (num_breakpoints == 0) 1287 { 1288 result.AppendError ("No breakpoints exist to be deleted."); 1289 result.SetStatus (eReturnStatusFailed); 1290 return false; 1291 } 1292 1293 if (args.GetArgumentCount() == 0) 1294 { 1295 if (!m_interpreter.Confirm ("About to delete all breakpoints, do you want to do that?", true)) 1296 { 1297 result.AppendMessage("Operation cancelled..."); 1298 } 1299 else 1300 { 1301 target->RemoveAllBreakpoints (); 1302 result.AppendMessageWithFormat ("All breakpoints removed. (%d breakpoints)\n", num_breakpoints); 1303 } 1304 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1305 } 1306 else 1307 { 1308 // Particular breakpoint selected; disable that breakpoint. 1309 BreakpointIDList valid_bp_ids; 1310 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (args, target, result, &valid_bp_ids); 1311 1312 if (result.Succeeded()) 1313 { 1314 int delete_count = 0; 1315 int disable_count = 0; 1316 const size_t count = valid_bp_ids.GetSize(); 1317 for (size_t i = 0; i < count; ++i) 1318 { 1319 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i); 1320 1321 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) 1322 { 1323 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) 1324 { 1325 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 1326 BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get(); 1327 // It makes no sense to try to delete individual locations, so we disable them instead. 1328 if (location) 1329 { 1330 location->SetEnabled (false); 1331 ++disable_count; 1332 } 1333 } 1334 else 1335 { 1336 target->RemoveBreakpointByID (cur_bp_id.GetBreakpointID()); 1337 ++delete_count; 1338 } 1339 } 1340 } 1341 result.AppendMessageWithFormat ("%d breakpoints deleted; %d breakpoint locations disabled.\n", 1342 delete_count, disable_count); 1343 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1344 } 1345 } 1346 return result.Succeeded(); 1347 } 1348 1349 //------------------------------------------------------------------------- 1350 // CommandObjectBreakpointModify::CommandOptions 1351 //------------------------------------------------------------------------- 1352 #pragma mark Modify::CommandOptions 1353 1354 CommandObjectBreakpointModify::CommandOptions::CommandOptions(CommandInterpreter &interpreter) : 1355 Options (interpreter), 1356 m_ignore_count (0), 1357 m_thread_id(LLDB_INVALID_THREAD_ID), 1358 m_thread_id_passed(false), 1359 m_thread_index (UINT32_MAX), 1360 m_thread_index_passed(false), 1361 m_thread_name(), 1362 m_queue_name(), 1363 m_condition (), 1364 m_enable_passed (false), 1365 m_enable_value (false), 1366 m_name_passed (false), 1367 m_queue_passed (false), 1368 m_condition_passed (false) 1369 { 1370 } 1371 1372 CommandObjectBreakpointModify::CommandOptions::~CommandOptions () 1373 { 1374 } 1375 1376 OptionDefinition 1377 CommandObjectBreakpointModify::CommandOptions::g_option_table[] = 1378 { 1379 { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', required_argument, NULL, NULL, eArgTypeCount, "Set the number of times this breakpoint is skipped before stopping." }, 1380 { LLDB_OPT_SET_ALL, false, "thread-index", 'x', required_argument, NULL, NULL, eArgTypeThreadIndex, "The breakpoint stops only for the thread whose indeX matches this argument."}, 1381 { LLDB_OPT_SET_ALL, false, "thread-id", 't', required_argument, NULL, NULL, eArgTypeThreadID, "The breakpoint stops only for the thread whose TID matches this argument."}, 1382 { LLDB_OPT_SET_ALL, false, "thread-name", 'T', required_argument, NULL, NULL, eArgTypeThreadName, "The breakpoint stops only for the thread whose thread name matches this argument."}, 1383 { LLDB_OPT_SET_ALL, false, "queue-name", 'q', required_argument, NULL, NULL, eArgTypeQueueName, "The breakpoint stops only for threads in the queue whose name is given by this argument."}, 1384 { LLDB_OPT_SET_ALL, false, "condition", 'c', required_argument, NULL, NULL, eArgTypeExpression, "The breakpoint stops only if this condition expression evaluates to true."}, 1385 { LLDB_OPT_SET_1, false, "enable", 'e', no_argument, NULL, NULL, eArgTypeNone, "Enable the breakpoint."}, 1386 { LLDB_OPT_SET_2, false, "disable", 'd', no_argument, NULL, NULL, eArgTypeNone, "Disable the breakpoint."}, 1387 { 0, false, NULL, 0 , 0, NULL, 0, eArgTypeNone, NULL } 1388 }; 1389 1390 const OptionDefinition* 1391 CommandObjectBreakpointModify::CommandOptions::GetDefinitions () 1392 { 1393 return g_option_table; 1394 } 1395 1396 Error 1397 CommandObjectBreakpointModify::CommandOptions::SetOptionValue (uint32_t option_idx, const char *option_arg) 1398 { 1399 Error error; 1400 char short_option = (char) m_getopt_table[option_idx].val; 1401 1402 switch (short_option) 1403 { 1404 case 'c': 1405 if (option_arg != NULL) 1406 m_condition.assign (option_arg); 1407 else 1408 m_condition.clear(); 1409 m_condition_passed = true; 1410 break; 1411 case 'd': 1412 m_enable_passed = true; 1413 m_enable_value = false; 1414 break; 1415 case 'e': 1416 m_enable_passed = true; 1417 m_enable_value = true; 1418 break; 1419 case 'i': 1420 { 1421 m_ignore_count = Args::StringToUInt32(option_arg, UINT32_MAX, 0); 1422 if (m_ignore_count == UINT32_MAX) 1423 error.SetErrorStringWithFormat ("Invalid ignore count '%s'.\n", option_arg); 1424 } 1425 break; 1426 case 't' : 1427 { 1428 if (option_arg[0] == '\0') 1429 { 1430 m_thread_id = LLDB_INVALID_THREAD_ID; 1431 m_thread_id_passed = true; 1432 } 1433 else 1434 { 1435 m_thread_id = Args::StringToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0); 1436 if (m_thread_id == LLDB_INVALID_THREAD_ID) 1437 error.SetErrorStringWithFormat ("Invalid thread id string '%s'.\n", option_arg); 1438 else 1439 m_thread_id_passed = true; 1440 } 1441 } 1442 break; 1443 case 'T': 1444 if (option_arg != NULL) 1445 m_thread_name.assign (option_arg); 1446 else 1447 m_thread_name.clear(); 1448 m_name_passed = true; 1449 break; 1450 case 'q': 1451 if (option_arg != NULL) 1452 m_queue_name.assign (option_arg); 1453 else 1454 m_queue_name.clear(); 1455 m_queue_passed = true; 1456 break; 1457 case 'x': 1458 { 1459 if (option_arg[0] == '\n') 1460 { 1461 m_thread_index = UINT32_MAX; 1462 m_thread_index_passed = true; 1463 } 1464 else 1465 { 1466 m_thread_index = Args::StringToUInt32 (option_arg, UINT32_MAX, 0); 1467 if (m_thread_id == UINT32_MAX) 1468 error.SetErrorStringWithFormat ("Invalid thread index string '%s'.\n", option_arg); 1469 else 1470 m_thread_index_passed = true; 1471 } 1472 } 1473 break; 1474 default: 1475 error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option); 1476 break; 1477 } 1478 1479 return error; 1480 } 1481 1482 void 1483 CommandObjectBreakpointModify::CommandOptions::OptionParsingStarting () 1484 { 1485 m_ignore_count = 0; 1486 m_thread_id = LLDB_INVALID_THREAD_ID; 1487 m_thread_id_passed = false; 1488 m_thread_index = UINT32_MAX; 1489 m_thread_index_passed = false; 1490 m_thread_name.clear(); 1491 m_queue_name.clear(); 1492 m_condition.clear(); 1493 m_enable_passed = false; 1494 m_queue_passed = false; 1495 m_name_passed = false; 1496 m_condition_passed = false; 1497 } 1498 1499 //------------------------------------------------------------------------- 1500 // CommandObjectBreakpointModify 1501 //------------------------------------------------------------------------- 1502 #pragma mark Modify 1503 1504 CommandObjectBreakpointModify::CommandObjectBreakpointModify (CommandInterpreter &interpreter) : 1505 CommandObject (interpreter, 1506 "breakpoint modify", 1507 "Modify the options on a breakpoint or set of breakpoints in the executable. " 1508 "If no breakpoint is specified, acts on the last created breakpoint. " 1509 "With the exception of -e, -d and -i, passing an empty argument clears the modification.", 1510 NULL), 1511 m_options (interpreter) 1512 { 1513 CommandArgumentEntry arg; 1514 CommandArgumentData bp_id_arg; 1515 CommandArgumentData bp_id_range_arg; 1516 1517 // Create the first variant for the first (and only) argument for this command. 1518 bp_id_arg.arg_type = eArgTypeBreakpointID; 1519 bp_id_arg.arg_repetition = eArgRepeatPlain; 1520 1521 // Create the second variant for the first (and only) argument for this command. 1522 bp_id_range_arg.arg_type = eArgTypeBreakpointIDRange; 1523 bp_id_range_arg.arg_repetition = eArgRepeatPlain; 1524 1525 // The first (and only) argument for this command could be either a bp_id or a bp_id_range. 1526 // Push both variants into the entry for the first argument for this command. 1527 arg.push_back (bp_id_arg); 1528 arg.push_back (bp_id_range_arg); 1529 1530 // Add the entry for the first argument for this command to the object's arguments vector. 1531 m_arguments.push_back (arg); 1532 } 1533 1534 CommandObjectBreakpointModify::~CommandObjectBreakpointModify () 1535 { 1536 } 1537 1538 Options * 1539 CommandObjectBreakpointModify::GetOptions () 1540 { 1541 return &m_options; 1542 } 1543 1544 bool 1545 CommandObjectBreakpointModify::Execute 1546 ( 1547 Args& command, 1548 CommandReturnObject &result 1549 ) 1550 { 1551 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 1552 if (target == NULL) 1553 { 1554 result.AppendError ("Invalid target. No existing target or breakpoints."); 1555 result.SetStatus (eReturnStatusFailed); 1556 return false; 1557 } 1558 1559 Mutex::Locker locker; 1560 target->GetBreakpointList().GetListMutex(locker); 1561 1562 BreakpointIDList valid_bp_ids; 1563 1564 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids); 1565 1566 if (result.Succeeded()) 1567 { 1568 const size_t count = valid_bp_ids.GetSize(); 1569 for (size_t i = 0; i < count; ++i) 1570 { 1571 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i); 1572 1573 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) 1574 { 1575 Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 1576 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) 1577 { 1578 BreakpointLocation *location = bp->FindLocationByID (cur_bp_id.GetLocationID()).get(); 1579 if (location) 1580 { 1581 if (m_options.m_thread_id_passed) 1582 location->SetThreadID (m_options.m_thread_id); 1583 1584 if (m_options.m_thread_index_passed) 1585 location->GetLocationOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index); 1586 1587 if (m_options.m_name_passed) 1588 location->GetLocationOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str()); 1589 1590 if (m_options.m_queue_passed) 1591 location->GetLocationOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str()); 1592 1593 if (m_options.m_ignore_count != 0) 1594 location->GetLocationOptions()->SetIgnoreCount(m_options.m_ignore_count); 1595 1596 if (m_options.m_enable_passed) 1597 location->SetEnabled (m_options.m_enable_value); 1598 1599 if (m_options.m_condition_passed) 1600 location->SetCondition (m_options.m_condition.c_str()); 1601 } 1602 } 1603 else 1604 { 1605 if (m_options.m_thread_id_passed) 1606 bp->SetThreadID (m_options.m_thread_id); 1607 1608 if (m_options.m_thread_index_passed) 1609 bp->GetOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index); 1610 1611 if (m_options.m_name_passed) 1612 bp->GetOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str()); 1613 1614 if (m_options.m_queue_passed) 1615 bp->GetOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str()); 1616 1617 if (m_options.m_ignore_count != 0) 1618 bp->GetOptions()->SetIgnoreCount(m_options.m_ignore_count); 1619 1620 if (m_options.m_enable_passed) 1621 bp->SetEnabled (m_options.m_enable_value); 1622 1623 if (m_options.m_condition_passed) 1624 bp->SetCondition (m_options.m_condition.c_str()); 1625 } 1626 } 1627 } 1628 } 1629 1630 return result.Succeeded(); 1631 } 1632 1633 1634