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