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