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