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