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/Host/StringConvert.h" 21 #include "lldb/Interpreter/Options.h" 22 #include "lldb/Interpreter/OptionValueBoolean.h" 23 #include "lldb/Interpreter/OptionValueString.h" 24 #include "lldb/Interpreter/OptionValueUInt64.h" 25 #include "lldb/Core/RegularExpression.h" 26 #include "lldb/Core/StreamString.h" 27 #include "lldb/Interpreter/CommandInterpreter.h" 28 #include "lldb/Interpreter/CommandReturnObject.h" 29 #include "lldb/Target/Language.h" 30 #include "lldb/Target/Target.h" 31 #include "lldb/Interpreter/CommandCompletions.h" 32 #include "lldb/Target/StackFrame.h" 33 #include "lldb/Target/Thread.h" 34 #include "lldb/Target/ThreadSpec.h" 35 36 #include <vector> 37 38 using namespace lldb; 39 using namespace lldb_private; 40 41 static void 42 AddBreakpointDescription (Stream *s, Breakpoint *bp, lldb::DescriptionLevel level) 43 { 44 s->IndentMore(); 45 bp->GetDescription (s, level, true); 46 s->IndentLess(); 47 s->EOL(); 48 } 49 50 //------------------------------------------------------------------------- 51 // CommandObjectBreakpointSet 52 //------------------------------------------------------------------------- 53 54 55 class CommandObjectBreakpointSet : public CommandObjectParsed 56 { 57 public: 58 59 typedef enum BreakpointSetType 60 { 61 eSetTypeInvalid, 62 eSetTypeFileAndLine, 63 eSetTypeAddress, 64 eSetTypeFunctionName, 65 eSetTypeFunctionRegexp, 66 eSetTypeSourceRegexp, 67 eSetTypeException 68 } BreakpointSetType; 69 70 CommandObjectBreakpointSet (CommandInterpreter &interpreter) : 71 CommandObjectParsed (interpreter, 72 "breakpoint set", 73 "Sets a breakpoint or set of breakpoints in the executable.", 74 "breakpoint set <cmd-options>"), 75 m_options (interpreter) 76 { 77 } 78 79 80 ~CommandObjectBreakpointSet () override {} 81 82 Options * 83 GetOptions () override 84 { 85 return &m_options; 86 } 87 88 class CommandOptions : public Options 89 { 90 public: 91 92 CommandOptions (CommandInterpreter &interpreter) : 93 Options (interpreter), 94 m_condition (), 95 m_filenames (), 96 m_line_num (0), 97 m_column (0), 98 m_func_names (), 99 m_func_name_type_mask (eFunctionNameTypeNone), 100 m_func_regexp (), 101 m_source_text_regexp(), 102 m_modules (), 103 m_load_addr(), 104 m_ignore_count (0), 105 m_thread_id(LLDB_INVALID_THREAD_ID), 106 m_thread_index (UINT32_MAX), 107 m_thread_name(), 108 m_queue_name(), 109 m_catch_bp (false), 110 m_throw_bp (true), 111 m_hardware (false), 112 m_exception_language (eLanguageTypeUnknown), 113 m_language (lldb::eLanguageTypeUnknown), 114 m_skip_prologue (eLazyBoolCalculate), 115 m_one_shot (false), 116 m_all_files (false), 117 m_move_to_nearest_code (eLazyBoolCalculate) 118 { 119 } 120 121 122 ~CommandOptions () override {} 123 124 Error 125 SetOptionValue (uint32_t option_idx, const char *option_arg) override 126 { 127 Error error; 128 const int short_option = m_getopt_table[option_idx].val; 129 130 switch (short_option) 131 { 132 case 'a': 133 { 134 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext()); 135 m_load_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error); 136 } 137 break; 138 139 case 'A': 140 m_all_files = true; 141 break; 142 143 case 'b': 144 m_func_names.push_back (option_arg); 145 m_func_name_type_mask |= eFunctionNameTypeBase; 146 break; 147 148 case 'C': 149 { 150 bool success; 151 m_column = StringConvert::ToUInt32 (option_arg, 0, 0, &success); 152 if (!success) 153 error.SetErrorStringWithFormat("invalid column number: %s", option_arg); 154 break; 155 } 156 case 'c': 157 m_condition.assign(option_arg); 158 break; 159 160 case 'D': 161 m_use_dummy = true; 162 break; 163 164 case 'E': 165 { 166 LanguageType language = Language::GetLanguageTypeFromString (option_arg); 167 168 switch (language) 169 { 170 case eLanguageTypeC89: 171 case eLanguageTypeC: 172 case eLanguageTypeC99: 173 case eLanguageTypeC11: 174 m_exception_language = eLanguageTypeC; 175 break; 176 case eLanguageTypeC_plus_plus: 177 case eLanguageTypeC_plus_plus_03: 178 case eLanguageTypeC_plus_plus_11: 179 case eLanguageTypeC_plus_plus_14: 180 m_exception_language = eLanguageTypeC_plus_plus; 181 break; 182 case eLanguageTypeObjC: 183 m_exception_language = eLanguageTypeObjC; 184 break; 185 case eLanguageTypeObjC_plus_plus: 186 error.SetErrorStringWithFormat ("Set exception breakpoints separately for c++ and objective-c"); 187 break; 188 case eLanguageTypeUnknown: 189 error.SetErrorStringWithFormat ("Unknown language type: '%s' for exception breakpoint", option_arg); 190 break; 191 default: 192 error.SetErrorStringWithFormat ("Unsupported language type: '%s' for exception breakpoint", option_arg); 193 } 194 } 195 break; 196 197 case 'f': 198 m_filenames.AppendIfUnique (FileSpec(option_arg, false)); 199 break; 200 201 case 'F': 202 m_func_names.push_back (option_arg); 203 m_func_name_type_mask |= eFunctionNameTypeFull; 204 break; 205 206 case 'h': 207 { 208 bool success; 209 m_catch_bp = Args::StringToBoolean (option_arg, true, &success); 210 if (!success) 211 error.SetErrorStringWithFormat ("Invalid boolean value for on-catch option: '%s'", option_arg); 212 } 213 break; 214 215 case 'H': 216 m_hardware = true; 217 break; 218 219 case 'i': 220 { 221 m_ignore_count = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0); 222 if (m_ignore_count == UINT32_MAX) 223 error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg); 224 break; 225 } 226 227 case 'K': 228 { 229 bool success; 230 bool value; 231 value = Args::StringToBoolean (option_arg, true, &success); 232 if (value) 233 m_skip_prologue = eLazyBoolYes; 234 else 235 m_skip_prologue = eLazyBoolNo; 236 237 if (!success) 238 error.SetErrorStringWithFormat ("Invalid boolean value for skip prologue option: '%s'", option_arg); 239 } 240 break; 241 242 case 'l': 243 { 244 bool success; 245 m_line_num = StringConvert::ToUInt32 (option_arg, 0, 0, &success); 246 if (!success) 247 error.SetErrorStringWithFormat ("invalid line number: %s.", option_arg); 248 break; 249 } 250 251 case 'L': 252 m_language = Language::GetLanguageTypeFromString (option_arg); 253 if (m_language == eLanguageTypeUnknown) 254 error.SetErrorStringWithFormat ("Unknown language type: '%s' for breakpoint", option_arg); 255 break; 256 257 case 'm': 258 { 259 bool success; 260 bool value; 261 value = Args::StringToBoolean (option_arg, true, &success); 262 if (value) 263 m_move_to_nearest_code = eLazyBoolYes; 264 else 265 m_move_to_nearest_code = eLazyBoolNo; 266 267 if (!success) 268 error.SetErrorStringWithFormat ("Invalid boolean value for move-to-nearest-code option: '%s'", option_arg); 269 break; 270 } 271 272 case 'M': 273 m_func_names.push_back (option_arg); 274 m_func_name_type_mask |= eFunctionNameTypeMethod; 275 break; 276 277 case 'n': 278 m_func_names.push_back (option_arg); 279 m_func_name_type_mask |= eFunctionNameTypeAuto; 280 break; 281 282 case 'N': 283 if (BreakpointID::StringIsBreakpointName(option_arg, error)) 284 m_breakpoint_names.push_back (option_arg); 285 break; 286 287 case 'o': 288 m_one_shot = true; 289 break; 290 291 case 'O': 292 m_exception_extra_args.AppendArgument ("-O"); 293 m_exception_extra_args.AppendArgument (option_arg); 294 break; 295 296 case 'p': 297 m_source_text_regexp.assign (option_arg); 298 break; 299 300 case 'q': 301 m_queue_name.assign (option_arg); 302 break; 303 304 case 'r': 305 m_func_regexp.assign (option_arg); 306 break; 307 308 case 's': 309 { 310 m_modules.AppendIfUnique (FileSpec (option_arg, false)); 311 break; 312 } 313 314 case 'S': 315 m_func_names.push_back (option_arg); 316 m_func_name_type_mask |= eFunctionNameTypeSelector; 317 break; 318 319 case 't' : 320 { 321 m_thread_id = StringConvert::ToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0); 322 if (m_thread_id == LLDB_INVALID_THREAD_ID) 323 error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg); 324 } 325 break; 326 327 case 'T': 328 m_thread_name.assign (option_arg); 329 break; 330 331 case 'w': 332 { 333 bool success; 334 m_throw_bp = Args::StringToBoolean (option_arg, true, &success); 335 if (!success) 336 error.SetErrorStringWithFormat ("Invalid boolean value for on-throw option: '%s'", option_arg); 337 } 338 break; 339 340 case 'x': 341 { 342 m_thread_index = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0); 343 if (m_thread_id == UINT32_MAX) 344 error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg); 345 346 } 347 break; 348 349 default: 350 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 351 break; 352 } 353 354 return error; 355 } 356 void 357 OptionParsingStarting () override 358 { 359 m_condition.clear(); 360 m_filenames.Clear(); 361 m_line_num = 0; 362 m_column = 0; 363 m_func_names.clear(); 364 m_func_name_type_mask = eFunctionNameTypeNone; 365 m_func_regexp.clear(); 366 m_source_text_regexp.clear(); 367 m_modules.Clear(); 368 m_load_addr = LLDB_INVALID_ADDRESS; 369 m_ignore_count = 0; 370 m_thread_id = LLDB_INVALID_THREAD_ID; 371 m_thread_index = UINT32_MAX; 372 m_thread_name.clear(); 373 m_queue_name.clear(); 374 m_catch_bp = false; 375 m_throw_bp = true; 376 m_hardware = false; 377 m_exception_language = eLanguageTypeUnknown; 378 m_language = lldb::eLanguageTypeUnknown; 379 m_skip_prologue = eLazyBoolCalculate; 380 m_one_shot = false; 381 m_use_dummy = false; 382 m_breakpoint_names.clear(); 383 m_all_files = false; 384 m_exception_extra_args.Clear(); 385 m_move_to_nearest_code = eLazyBoolCalculate; 386 } 387 388 const OptionDefinition* 389 GetDefinitions () override 390 { 391 return g_option_table; 392 } 393 394 // Options table: Required for subclasses of Options. 395 396 static OptionDefinition g_option_table[]; 397 398 // Instance variables to hold the values for command options. 399 400 std::string m_condition; 401 FileSpecList m_filenames; 402 uint32_t m_line_num; 403 uint32_t m_column; 404 std::vector<std::string> m_func_names; 405 std::vector<std::string> m_breakpoint_names; 406 uint32_t m_func_name_type_mask; 407 std::string m_func_regexp; 408 std::string m_source_text_regexp; 409 FileSpecList m_modules; 410 lldb::addr_t m_load_addr; 411 uint32_t m_ignore_count; 412 lldb::tid_t m_thread_id; 413 uint32_t m_thread_index; 414 std::string m_thread_name; 415 std::string m_queue_name; 416 bool m_catch_bp; 417 bool m_throw_bp; 418 bool m_hardware; // Request to use hardware breakpoints 419 lldb::LanguageType m_exception_language; 420 lldb::LanguageType m_language; 421 LazyBool m_skip_prologue; 422 bool m_one_shot; 423 bool m_use_dummy; 424 bool m_all_files; 425 Args m_exception_extra_args; 426 LazyBool m_move_to_nearest_code; 427 428 }; 429 430 protected: 431 bool 432 DoExecute (Args& command, 433 CommandReturnObject &result) override 434 { 435 Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy); 436 437 if (target == nullptr) 438 { 439 result.AppendError ("Invalid target. Must set target before setting breakpoints (see 'target create' command)."); 440 result.SetStatus (eReturnStatusFailed); 441 return false; 442 } 443 444 // The following are the various types of breakpoints that could be set: 445 // 1). -f -l -p [-s -g] (setting breakpoint by source location) 446 // 2). -a [-s -g] (setting breakpoint by address) 447 // 3). -n [-s -g] (setting breakpoint by function name) 448 // 4). -r [-s -g] (setting breakpoint by function name regular expression) 449 // 5). -p -f (setting a breakpoint by comparing a reg-exp to source text) 450 // 6). -E [-w -h] (setting a breakpoint for exceptions for a given language.) 451 452 BreakpointSetType break_type = eSetTypeInvalid; 453 454 if (m_options.m_line_num != 0) 455 break_type = eSetTypeFileAndLine; 456 else if (m_options.m_load_addr != LLDB_INVALID_ADDRESS) 457 break_type = eSetTypeAddress; 458 else if (!m_options.m_func_names.empty()) 459 break_type = eSetTypeFunctionName; 460 else if (!m_options.m_func_regexp.empty()) 461 break_type = eSetTypeFunctionRegexp; 462 else if (!m_options.m_source_text_regexp.empty()) 463 break_type = eSetTypeSourceRegexp; 464 else if (m_options.m_exception_language != eLanguageTypeUnknown) 465 break_type = eSetTypeException; 466 467 Breakpoint *bp = NULL; 468 FileSpec module_spec; 469 const bool internal = false; 470 471 switch (break_type) 472 { 473 case eSetTypeFileAndLine: // Breakpoint by source position 474 { 475 FileSpec file; 476 const size_t num_files = m_options.m_filenames.GetSize(); 477 if (num_files == 0) 478 { 479 if (!GetDefaultFile (target, file, result)) 480 { 481 result.AppendError("No file supplied and no default file available."); 482 result.SetStatus (eReturnStatusFailed); 483 return false; 484 } 485 } 486 else if (num_files > 1) 487 { 488 result.AppendError("Only one file at a time is allowed for file and line breakpoints."); 489 result.SetStatus (eReturnStatusFailed); 490 return false; 491 } 492 else 493 file = m_options.m_filenames.GetFileSpecAtIndex(0); 494 495 // Only check for inline functions if 496 LazyBool check_inlines = eLazyBoolCalculate; 497 498 bp = target->CreateBreakpoint (&(m_options.m_modules), 499 file, 500 m_options.m_line_num, 501 check_inlines, 502 m_options.m_skip_prologue, 503 internal, 504 m_options.m_hardware, 505 m_options.m_move_to_nearest_code).get(); 506 } 507 break; 508 509 case eSetTypeAddress: // Breakpoint by address 510 { 511 // If a shared library has been specified, make an lldb_private::Address with the library, and 512 // use that. That way the address breakpoint will track the load location of the library. 513 size_t num_modules_specified = m_options.m_modules.GetSize(); 514 if (num_modules_specified == 1) 515 { 516 const FileSpec *file_spec = m_options.m_modules.GetFileSpecPointerAtIndex(0); 517 bp = target->CreateAddressInModuleBreakpoint (m_options.m_load_addr, 518 internal, 519 file_spec, 520 m_options.m_hardware).get(); 521 } 522 else if (num_modules_specified == 0) 523 { 524 bp = target->CreateBreakpoint (m_options.m_load_addr, 525 internal, 526 m_options.m_hardware).get(); 527 } 528 else 529 { 530 result.AppendError("Only one shared library can be specified for address breakpoints."); 531 result.SetStatus(eReturnStatusFailed); 532 return false; 533 } 534 break; 535 } 536 case eSetTypeFunctionName: // Breakpoint by function name 537 { 538 uint32_t name_type_mask = m_options.m_func_name_type_mask; 539 540 if (name_type_mask == 0) 541 name_type_mask = eFunctionNameTypeAuto; 542 543 bp = target->CreateBreakpoint (&(m_options.m_modules), 544 &(m_options.m_filenames), 545 m_options.m_func_names, 546 name_type_mask, 547 m_options.m_language, 548 m_options.m_skip_prologue, 549 internal, 550 m_options.m_hardware).get(); 551 } 552 break; 553 554 case eSetTypeFunctionRegexp: // Breakpoint by regular expression function name 555 { 556 RegularExpression regexp(m_options.m_func_regexp.c_str()); 557 if (!regexp.IsValid()) 558 { 559 char err_str[1024]; 560 regexp.GetErrorAsCString(err_str, sizeof(err_str)); 561 result.AppendErrorWithFormat("Function name regular expression could not be compiled: \"%s\"", 562 err_str); 563 result.SetStatus (eReturnStatusFailed); 564 return false; 565 } 566 567 bp = target->CreateFuncRegexBreakpoint (&(m_options.m_modules), 568 &(m_options.m_filenames), 569 regexp, 570 m_options.m_language, 571 m_options.m_skip_prologue, 572 internal, 573 m_options.m_hardware).get(); 574 } 575 break; 576 case eSetTypeSourceRegexp: // Breakpoint by regexp on source text. 577 { 578 const size_t num_files = m_options.m_filenames.GetSize(); 579 580 if (num_files == 0 && !m_options.m_all_files) 581 { 582 FileSpec file; 583 if (!GetDefaultFile (target, file, result)) 584 { 585 result.AppendError ("No files provided and could not find default file."); 586 result.SetStatus (eReturnStatusFailed); 587 return false; 588 } 589 else 590 { 591 m_options.m_filenames.Append (file); 592 } 593 } 594 595 RegularExpression regexp(m_options.m_source_text_regexp.c_str()); 596 if (!regexp.IsValid()) 597 { 598 char err_str[1024]; 599 regexp.GetErrorAsCString(err_str, sizeof(err_str)); 600 result.AppendErrorWithFormat("Source text regular expression could not be compiled: \"%s\"", 601 err_str); 602 result.SetStatus (eReturnStatusFailed); 603 return false; 604 } 605 bp = target->CreateSourceRegexBreakpoint (&(m_options.m_modules), 606 &(m_options.m_filenames), 607 regexp, 608 internal, 609 m_options.m_hardware, 610 m_options.m_move_to_nearest_code).get(); 611 } 612 break; 613 case eSetTypeException: 614 { 615 Error precond_error; 616 bp = target->CreateExceptionBreakpoint (m_options.m_exception_language, 617 m_options.m_catch_bp, 618 m_options.m_throw_bp, 619 internal, 620 &m_options.m_exception_extra_args, 621 &precond_error).get(); 622 if (precond_error.Fail()) 623 { 624 result.AppendErrorWithFormat("Error setting extra exception arguments: %s", 625 precond_error.AsCString()); 626 target->RemoveBreakpointByID(bp->GetID()); 627 result.SetStatus(eReturnStatusFailed); 628 return false; 629 } 630 } 631 break; 632 default: 633 break; 634 } 635 636 // Now set the various options that were passed in: 637 if (bp) 638 { 639 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID) 640 bp->SetThreadID (m_options.m_thread_id); 641 642 if (m_options.m_thread_index != UINT32_MAX) 643 bp->GetOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index); 644 645 if (!m_options.m_thread_name.empty()) 646 bp->GetOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str()); 647 648 if (!m_options.m_queue_name.empty()) 649 bp->GetOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str()); 650 651 if (m_options.m_ignore_count != 0) 652 bp->GetOptions()->SetIgnoreCount(m_options.m_ignore_count); 653 654 if (!m_options.m_condition.empty()) 655 bp->GetOptions()->SetCondition(m_options.m_condition.c_str()); 656 657 if (!m_options.m_breakpoint_names.empty()) 658 { 659 Error error; // We don't need to check the error here, since the option parser checked it... 660 for (auto name : m_options.m_breakpoint_names) 661 bp->AddName(name.c_str(), error); 662 } 663 664 bp->SetOneShot (m_options.m_one_shot); 665 } 666 667 if (bp) 668 { 669 Stream &output_stream = result.GetOutputStream(); 670 const bool show_locations = false; 671 bp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial, show_locations); 672 if (target == m_interpreter.GetDebugger().GetDummyTarget()) 673 output_stream.Printf ("Breakpoint set in dummy target, will get copied into future targets.\n"); 674 else 675 { 676 // Don't print out this warning for exception breakpoints. They can get set before the target 677 // is set, but we won't know how to actually set the breakpoint till we run. 678 if (bp->GetNumLocations() == 0 && break_type != eSetTypeException) 679 { 680 output_stream.Printf ("WARNING: Unable to resolve breakpoint to any actual locations.\n"); 681 } 682 } 683 result.SetStatus (eReturnStatusSuccessFinishResult); 684 } 685 else if (!bp) 686 { 687 result.AppendError ("Breakpoint creation failed: No breakpoint created."); 688 result.SetStatus (eReturnStatusFailed); 689 } 690 691 return result.Succeeded(); 692 } 693 694 private: 695 bool 696 GetDefaultFile (Target *target, FileSpec &file, CommandReturnObject &result) 697 { 698 uint32_t default_line; 699 // First use the Source Manager's default file. 700 // Then use the current stack frame's file. 701 if (!target->GetSourceManager().GetDefaultFileAndLine(file, default_line)) 702 { 703 StackFrame *cur_frame = m_exe_ctx.GetFramePtr(); 704 if (cur_frame == NULL) 705 { 706 result.AppendError ("No selected frame to use to find the default file."); 707 result.SetStatus (eReturnStatusFailed); 708 return false; 709 } 710 else if (!cur_frame->HasDebugInformation()) 711 { 712 result.AppendError ("Cannot use the selected frame to find the default file, it has no debug info."); 713 result.SetStatus (eReturnStatusFailed); 714 return false; 715 } 716 else 717 { 718 const SymbolContext &sc = cur_frame->GetSymbolContext (eSymbolContextLineEntry); 719 if (sc.line_entry.file) 720 { 721 file = sc.line_entry.file; 722 } 723 else 724 { 725 result.AppendError ("Can't find the file for the selected frame to use as the default file."); 726 result.SetStatus (eReturnStatusFailed); 727 return false; 728 } 729 } 730 } 731 return true; 732 } 733 734 CommandOptions m_options; 735 }; 736 // If an additional option set beyond LLDB_OPTION_SET_10 is added, make sure to 737 // update the numbers passed to LLDB_OPT_SET_FROM_TO(...) appropriately. 738 #define LLDB_OPT_FILE ( LLDB_OPT_SET_FROM_TO(1, 9) & ~LLDB_OPT_SET_2 ) 739 #define LLDB_OPT_NOT_10 ( LLDB_OPT_SET_FROM_TO(1, 10) & ~LLDB_OPT_SET_10 ) 740 #define LLDB_OPT_SKIP_PROLOGUE ( LLDB_OPT_SET_1 | LLDB_OPT_SET_FROM_TO(3,8) ) 741 #define LLDB_OPT_MOVE_TO_NEAREST_CODE ( LLDB_OPT_SET_1 | LLDB_OPT_SET_9 ) 742 #define LLDB_OPT_EXPR_LANGUAGE ( LLDB_OPT_SET_FROM_TO(3, 8) ) 743 744 OptionDefinition 745 CommandObjectBreakpointSet::CommandOptions::g_option_table[] = 746 { 747 { LLDB_OPT_NOT_10, false, "shlib", 's', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName, 748 "Set the breakpoint only in this shared library. " 749 "Can repeat this option multiple times to specify multiple shared libraries."}, 750 751 { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeCount, 752 "Set the number of times this breakpoint is skipped before stopping." }, 753 754 { LLDB_OPT_SET_ALL, false, "one-shot", 'o', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, 755 "The breakpoint is deleted the first time it causes a stop." }, 756 757 { LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeExpression, 758 "The breakpoint stops only if this condition expression evaluates to true."}, 759 760 { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadIndex, 761 "The breakpoint stops only for the thread whose indeX matches this argument."}, 762 763 { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadID, 764 "The breakpoint stops only for the thread whose TID matches this argument."}, 765 766 { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadName, 767 "The breakpoint stops only for the thread whose thread name matches this argument."}, 768 769 { LLDB_OPT_SET_ALL, false, "hardware", 'H', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, 770 "Require the breakpoint to use hardware breakpoints."}, 771 772 { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeQueueName, 773 "The breakpoint stops only for threads in the queue whose name is given by this argument."}, 774 775 { LLDB_OPT_FILE, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, 776 "Specifies the source file in which to set this breakpoint. " 777 "Note, by default lldb only looks for files that are #included if they use the standard include file extensions. " 778 "To set breakpoints on .c/.cpp/.m/.mm files that are #included, set target.inline-breakpoint-strategy" 779 " to \"always\"."}, 780 781 { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum, 782 "Specifies the line number on which to set this breakpoint."}, 783 784 // Comment out this option for the moment, as we don't actually use it, but will in the future. 785 // This way users won't see it, but the infrastructure is left in place. 786 // { 0, false, "column", 'C', OptionParser::eRequiredArgument, NULL, "<column>", 787 // "Set the breakpoint by source location at this particular column."}, 788 789 { LLDB_OPT_SET_2, true, "address", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression, 790 "Set the breakpoint at the specified address. " 791 "If the address maps uniquely to a particular " 792 "binary, then the address will be converted to a \"file\" address, so that the breakpoint will track that binary+offset no matter where " 793 "the binary eventually loads. " 794 "Alternately, if you also specify the module - with the -s option - then the address will be treated as " 795 "a file address in that module, and resolved accordingly. Again, this will allow lldb to track that offset on " 796 "subsequent reloads. The module need not have been loaded at the time you specify this breakpoint, and will " 797 "get resolved when the module is loaded."}, 798 799 { LLDB_OPT_SET_3, true, "name", 'n', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, 800 "Set the breakpoint by function name. Can be repeated multiple times to make one breakpoint for multiple names" }, 801 802 { LLDB_OPT_SET_4, true, "fullname", 'F', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFullName, 803 "Set the breakpoint by fully qualified function names. For C++ this means namespaces and all arguments, and " 804 "for Objective C this means a full function prototype with class and selector. " 805 "Can be repeated multiple times to make one breakpoint for multiple names." }, 806 807 { LLDB_OPT_SET_5, true, "selector", 'S', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeSelector, 808 "Set the breakpoint by ObjC selector name. Can be repeated multiple times to make one breakpoint for multiple Selectors." }, 809 810 { LLDB_OPT_SET_6, true, "method", 'M', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeMethod, 811 "Set the breakpoint by C++ method names. Can be repeated multiple times to make one breakpoint for multiple methods." }, 812 813 { LLDB_OPT_SET_7, true, "func-regex", 'r', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeRegularExpression, 814 "Set the breakpoint by function name, evaluating a regular-expression to find the function name(s)." }, 815 816 { LLDB_OPT_SET_8, true, "basename", 'b', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, 817 "Set the breakpoint by function basename (C++ namespaces and arguments will be ignored). " 818 "Can be repeated multiple times to make one breakpoint for multiple symbols." }, 819 820 { LLDB_OPT_SET_9, true, "source-pattern-regexp", 'p', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeRegularExpression, 821 "Set the breakpoint by specifying a regular expression which is matched against the source text in a source file or files " 822 "specified with the -f option. The -f option can be specified more than once. " 823 "If no source files are specified, uses the current \"default source file\". " 824 "If you want to match against all source files, pass the \"--all-files\" option." }, 825 826 { LLDB_OPT_SET_9, false, "all-files", 'A', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, 827 "All files are searched for source pattern matches." }, 828 829 { LLDB_OPT_SET_10, true, "language-exception", 'E', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage, 830 "Set the breakpoint on exceptions thrown by the specified language (without options, on throw but not catch.)" }, 831 832 { LLDB_OPT_SET_10, false, "on-throw", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, 833 "Set the breakpoint on exception throW." }, 834 835 { LLDB_OPT_SET_10, false, "on-catch", 'h', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, 836 "Set the breakpoint on exception catcH." }, 837 838 // Don't add this option till it actually does something useful... 839 // { LLDB_OPT_SET_10, false, "exception-typename", 'O', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeTypeName, 840 // "The breakpoint will only stop if an exception Object of this type is thrown. Can be repeated multiple times to stop for multiple object types" }, 841 842 { LLDB_OPT_EXPR_LANGUAGE, false, "language", 'L', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage, 843 "Specifies the Language to use when interpreting the breakpoint's expression (note: currently only implemented for setting breakpoints on identifiers). If not set the target.language setting is used." }, 844 845 { LLDB_OPT_SKIP_PROLOGUE, false, "skip-prologue", 'K', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, 846 "sKip the prologue if the breakpoint is at the beginning of a function. If not set the target.skip-prologue setting is used." }, 847 848 { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, 849 "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."}, 850 851 { LLDB_OPT_SET_ALL, false, "breakpoint-name", 'N', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBreakpointName, 852 "Adds this to the list of names for this breakopint."}, 853 854 { LLDB_OPT_MOVE_TO_NEAREST_CODE, false, "move-to-nearest-code", 'm', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, 855 "Move breakpoints to nearest code. If not set the target.move-to-nearest-code setting is used." }, 856 857 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 858 }; 859 860 //------------------------------------------------------------------------- 861 // CommandObjectBreakpointModify 862 //------------------------------------------------------------------------- 863 #pragma mark Modify 864 865 class CommandObjectBreakpointModify : public CommandObjectParsed 866 { 867 public: 868 869 CommandObjectBreakpointModify (CommandInterpreter &interpreter) : 870 CommandObjectParsed (interpreter, 871 "breakpoint modify", 872 "Modify the options on a breakpoint or set of breakpoints in the executable. " 873 "If no breakpoint is specified, acts on the last created breakpoint. " 874 "With the exception of -e, -d and -i, passing an empty argument clears the modification.", 875 NULL), 876 m_options (interpreter) 877 { 878 CommandArgumentEntry arg; 879 CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange); 880 // Add the entry for the first argument for this command to the object's arguments vector. 881 m_arguments.push_back (arg); 882 } 883 884 885 ~CommandObjectBreakpointModify () override {} 886 887 Options * 888 GetOptions () override 889 { 890 return &m_options; 891 } 892 893 class CommandOptions : public Options 894 { 895 public: 896 897 CommandOptions (CommandInterpreter &interpreter) : 898 Options (interpreter), 899 m_ignore_count (0), 900 m_thread_id(LLDB_INVALID_THREAD_ID), 901 m_thread_id_passed(false), 902 m_thread_index (UINT32_MAX), 903 m_thread_index_passed(false), 904 m_thread_name(), 905 m_queue_name(), 906 m_condition (), 907 m_one_shot (false), 908 m_enable_passed (false), 909 m_enable_value (false), 910 m_name_passed (false), 911 m_queue_passed (false), 912 m_condition_passed (false), 913 m_one_shot_passed (false), 914 m_use_dummy (false) 915 { 916 } 917 918 ~CommandOptions () override {} 919 920 Error 921 SetOptionValue (uint32_t option_idx, const char *option_arg) override 922 { 923 Error error; 924 const int short_option = m_getopt_table[option_idx].val; 925 926 switch (short_option) 927 { 928 case 'c': 929 if (option_arg != NULL) 930 m_condition.assign (option_arg); 931 else 932 m_condition.clear(); 933 m_condition_passed = true; 934 break; 935 case 'd': 936 m_enable_passed = true; 937 m_enable_value = false; 938 break; 939 case 'D': 940 m_use_dummy = true; 941 break; 942 case 'e': 943 m_enable_passed = true; 944 m_enable_value = true; 945 break; 946 case 'i': 947 { 948 m_ignore_count = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0); 949 if (m_ignore_count == UINT32_MAX) 950 error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg); 951 } 952 break; 953 case 'o': 954 { 955 bool value, success; 956 value = Args::StringToBoolean(option_arg, false, &success); 957 if (success) 958 { 959 m_one_shot_passed = true; 960 m_one_shot = value; 961 } 962 else 963 error.SetErrorStringWithFormat("invalid boolean value '%s' passed for -o option", option_arg); 964 } 965 break; 966 case 't' : 967 { 968 if (option_arg[0] == '\0') 969 { 970 m_thread_id = LLDB_INVALID_THREAD_ID; 971 m_thread_id_passed = true; 972 } 973 else 974 { 975 m_thread_id = StringConvert::ToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0); 976 if (m_thread_id == LLDB_INVALID_THREAD_ID) 977 error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg); 978 else 979 m_thread_id_passed = true; 980 } 981 } 982 break; 983 case 'T': 984 if (option_arg != NULL) 985 m_thread_name.assign (option_arg); 986 else 987 m_thread_name.clear(); 988 m_name_passed = true; 989 break; 990 case 'q': 991 if (option_arg != NULL) 992 m_queue_name.assign (option_arg); 993 else 994 m_queue_name.clear(); 995 m_queue_passed = true; 996 break; 997 case 'x': 998 { 999 if (option_arg[0] == '\n') 1000 { 1001 m_thread_index = UINT32_MAX; 1002 m_thread_index_passed = true; 1003 } 1004 else 1005 { 1006 m_thread_index = StringConvert::ToUInt32 (option_arg, UINT32_MAX, 0); 1007 if (m_thread_id == UINT32_MAX) 1008 error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg); 1009 else 1010 m_thread_index_passed = true; 1011 } 1012 } 1013 break; 1014 default: 1015 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 1016 break; 1017 } 1018 1019 return error; 1020 } 1021 void 1022 OptionParsingStarting () override 1023 { 1024 m_ignore_count = 0; 1025 m_thread_id = LLDB_INVALID_THREAD_ID; 1026 m_thread_id_passed = false; 1027 m_thread_index = UINT32_MAX; 1028 m_thread_index_passed = false; 1029 m_thread_name.clear(); 1030 m_queue_name.clear(); 1031 m_condition.clear(); 1032 m_one_shot = false; 1033 m_enable_passed = false; 1034 m_queue_passed = false; 1035 m_name_passed = false; 1036 m_condition_passed = false; 1037 m_one_shot_passed = false; 1038 m_use_dummy = false; 1039 } 1040 1041 const OptionDefinition* 1042 GetDefinitions () override 1043 { 1044 return g_option_table; 1045 } 1046 1047 1048 // Options table: Required for subclasses of Options. 1049 1050 static OptionDefinition g_option_table[]; 1051 1052 // Instance variables to hold the values for command options. 1053 1054 uint32_t m_ignore_count; 1055 lldb::tid_t m_thread_id; 1056 bool m_thread_id_passed; 1057 uint32_t m_thread_index; 1058 bool m_thread_index_passed; 1059 std::string m_thread_name; 1060 std::string m_queue_name; 1061 std::string m_condition; 1062 bool m_one_shot; 1063 bool m_enable_passed; 1064 bool m_enable_value; 1065 bool m_name_passed; 1066 bool m_queue_passed; 1067 bool m_condition_passed; 1068 bool m_one_shot_passed; 1069 bool m_use_dummy; 1070 1071 }; 1072 1073 protected: 1074 bool 1075 DoExecute (Args& command, CommandReturnObject &result) override 1076 { 1077 Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy); 1078 if (target == NULL) 1079 { 1080 result.AppendError ("Invalid target. No existing target or breakpoints."); 1081 result.SetStatus (eReturnStatusFailed); 1082 return false; 1083 } 1084 1085 Mutex::Locker locker; 1086 target->GetBreakpointList().GetListMutex(locker); 1087 1088 BreakpointIDList valid_bp_ids; 1089 1090 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids); 1091 1092 if (result.Succeeded()) 1093 { 1094 const size_t count = valid_bp_ids.GetSize(); 1095 for (size_t i = 0; i < count; ++i) 1096 { 1097 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i); 1098 1099 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) 1100 { 1101 Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 1102 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) 1103 { 1104 BreakpointLocation *location = bp->FindLocationByID (cur_bp_id.GetLocationID()).get(); 1105 if (location) 1106 { 1107 if (m_options.m_thread_id_passed) 1108 location->SetThreadID (m_options.m_thread_id); 1109 1110 if (m_options.m_thread_index_passed) 1111 location->SetThreadIndex(m_options.m_thread_index); 1112 1113 if (m_options.m_name_passed) 1114 location->SetThreadName(m_options.m_thread_name.c_str()); 1115 1116 if (m_options.m_queue_passed) 1117 location->SetQueueName(m_options.m_queue_name.c_str()); 1118 1119 if (m_options.m_ignore_count != 0) 1120 location->SetIgnoreCount(m_options.m_ignore_count); 1121 1122 if (m_options.m_enable_passed) 1123 location->SetEnabled (m_options.m_enable_value); 1124 1125 if (m_options.m_condition_passed) 1126 location->SetCondition (m_options.m_condition.c_str()); 1127 } 1128 } 1129 else 1130 { 1131 if (m_options.m_thread_id_passed) 1132 bp->SetThreadID (m_options.m_thread_id); 1133 1134 if (m_options.m_thread_index_passed) 1135 bp->SetThreadIndex(m_options.m_thread_index); 1136 1137 if (m_options.m_name_passed) 1138 bp->SetThreadName(m_options.m_thread_name.c_str()); 1139 1140 if (m_options.m_queue_passed) 1141 bp->SetQueueName(m_options.m_queue_name.c_str()); 1142 1143 if (m_options.m_ignore_count != 0) 1144 bp->SetIgnoreCount(m_options.m_ignore_count); 1145 1146 if (m_options.m_enable_passed) 1147 bp->SetEnabled (m_options.m_enable_value); 1148 1149 if (m_options.m_condition_passed) 1150 bp->SetCondition (m_options.m_condition.c_str()); 1151 } 1152 } 1153 } 1154 } 1155 1156 return result.Succeeded(); 1157 } 1158 1159 private: 1160 CommandOptions m_options; 1161 }; 1162 1163 #pragma mark Modify::CommandOptions 1164 OptionDefinition 1165 CommandObjectBreakpointModify::CommandOptions::g_option_table[] = 1166 { 1167 { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeCount, "Set the number of times this breakpoint is skipped before stopping." }, 1168 { LLDB_OPT_SET_ALL, false, "one-shot", 'o', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "The breakpoint is deleted the first time it stop causes a stop." }, 1169 { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadIndex, "The breakpoint stops only for the thread whose index matches this argument."}, 1170 { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadID, "The breakpoint stops only for the thread whose TID matches this argument."}, 1171 { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadName, "The breakpoint stops only for the thread whose thread name matches this argument."}, 1172 { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeQueueName, "The breakpoint stops only for threads in the queue whose name is given by this argument."}, 1173 { LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeExpression, "The breakpoint stops only if this condition expression evaluates to true."}, 1174 { LLDB_OPT_SET_1, false, "enable", 'e', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Enable the breakpoint."}, 1175 { LLDB_OPT_SET_2, false, "disable", 'd', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Disable the breakpoint."}, 1176 { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."}, 1177 1178 { 0, false, NULL, 0 , 0, NULL, NULL, 0, eArgTypeNone, NULL } 1179 }; 1180 1181 //------------------------------------------------------------------------- 1182 // CommandObjectBreakpointEnable 1183 //------------------------------------------------------------------------- 1184 #pragma mark Enable 1185 1186 class CommandObjectBreakpointEnable : public CommandObjectParsed 1187 { 1188 public: 1189 CommandObjectBreakpointEnable (CommandInterpreter &interpreter) : 1190 CommandObjectParsed (interpreter, 1191 "enable", 1192 "Enable the specified disabled breakpoint(s). If no breakpoints are specified, enable all of them.", 1193 NULL) 1194 { 1195 CommandArgumentEntry arg; 1196 CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange); 1197 // Add the entry for the first argument for this command to the object's arguments vector. 1198 m_arguments.push_back (arg); 1199 } 1200 1201 1202 ~CommandObjectBreakpointEnable () override {} 1203 1204 protected: 1205 bool 1206 DoExecute (Args& command, CommandReturnObject &result) override 1207 { 1208 Target *target = GetSelectedOrDummyTarget(); 1209 if (target == NULL) 1210 { 1211 result.AppendError ("Invalid target. No existing target or breakpoints."); 1212 result.SetStatus (eReturnStatusFailed); 1213 return false; 1214 } 1215 1216 Mutex::Locker locker; 1217 target->GetBreakpointList().GetListMutex(locker); 1218 1219 const BreakpointList &breakpoints = target->GetBreakpointList(); 1220 1221 size_t num_breakpoints = breakpoints.GetSize(); 1222 1223 if (num_breakpoints == 0) 1224 { 1225 result.AppendError ("No breakpoints exist to be enabled."); 1226 result.SetStatus (eReturnStatusFailed); 1227 return false; 1228 } 1229 1230 if (command.GetArgumentCount() == 0) 1231 { 1232 // No breakpoint selected; enable all currently set breakpoints. 1233 target->EnableAllBreakpoints (); 1234 result.AppendMessageWithFormat ("All breakpoints enabled. (%" PRIu64 " breakpoints)\n", (uint64_t)num_breakpoints); 1235 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1236 } 1237 else 1238 { 1239 // Particular breakpoint selected; enable that breakpoint. 1240 BreakpointIDList valid_bp_ids; 1241 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids); 1242 1243 if (result.Succeeded()) 1244 { 1245 int enable_count = 0; 1246 int loc_count = 0; 1247 const size_t count = valid_bp_ids.GetSize(); 1248 for (size_t i = 0; i < count; ++i) 1249 { 1250 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i); 1251 1252 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) 1253 { 1254 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 1255 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) 1256 { 1257 BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get(); 1258 if (location) 1259 { 1260 location->SetEnabled (true); 1261 ++loc_count; 1262 } 1263 } 1264 else 1265 { 1266 breakpoint->SetEnabled (true); 1267 ++enable_count; 1268 } 1269 } 1270 } 1271 result.AppendMessageWithFormat ("%d breakpoints enabled.\n", enable_count + loc_count); 1272 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1273 } 1274 } 1275 1276 return result.Succeeded(); 1277 } 1278 }; 1279 1280 //------------------------------------------------------------------------- 1281 // CommandObjectBreakpointDisable 1282 //------------------------------------------------------------------------- 1283 #pragma mark Disable 1284 1285 class CommandObjectBreakpointDisable : public CommandObjectParsed 1286 { 1287 public: 1288 CommandObjectBreakpointDisable (CommandInterpreter &interpreter) : 1289 CommandObjectParsed (interpreter, 1290 "breakpoint disable", 1291 "Disable the specified breakpoint(s) without removing them. If none are specified, disable all breakpoints.", 1292 NULL) 1293 { 1294 SetHelpLong( 1295 "Disable the specified breakpoint(s) without removing them. \ 1296 If none are specified, disable all breakpoints." R"( 1297 1298 )" "Note: disabling a breakpoint will cause none of its locations to be hit \ 1299 regardless of whether they are enabled or disabled. After the sequence:" R"( 1300 1301 (lldb) break disable 1 1302 (lldb) break enable 1.1 1303 1304 execution will NOT stop at location 1.1. To achieve that, type: 1305 1306 (lldb) break disable 1.* 1307 (lldb) break enable 1.1 1308 1309 )" "The first command disables all the locations of breakpoint 1, \ 1310 the second re-enables the first location." 1311 ); 1312 1313 CommandArgumentEntry arg; 1314 CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange); 1315 // Add the entry for the first argument for this command to the object's arguments vector. 1316 m_arguments.push_back (arg); 1317 1318 } 1319 1320 1321 ~CommandObjectBreakpointDisable () override {} 1322 1323 protected: 1324 bool 1325 DoExecute (Args& command, CommandReturnObject &result) override 1326 { 1327 Target *target = GetSelectedOrDummyTarget(); 1328 if (target == NULL) 1329 { 1330 result.AppendError ("Invalid target. No existing target or breakpoints."); 1331 result.SetStatus (eReturnStatusFailed); 1332 return false; 1333 } 1334 1335 Mutex::Locker locker; 1336 target->GetBreakpointList().GetListMutex(locker); 1337 1338 const BreakpointList &breakpoints = target->GetBreakpointList(); 1339 size_t num_breakpoints = breakpoints.GetSize(); 1340 1341 if (num_breakpoints == 0) 1342 { 1343 result.AppendError ("No breakpoints exist to be disabled."); 1344 result.SetStatus (eReturnStatusFailed); 1345 return false; 1346 } 1347 1348 if (command.GetArgumentCount() == 0) 1349 { 1350 // No breakpoint selected; disable all currently set breakpoints. 1351 target->DisableAllBreakpoints (); 1352 result.AppendMessageWithFormat ("All breakpoints disabled. (%" PRIu64 " breakpoints)\n", (uint64_t)num_breakpoints); 1353 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1354 } 1355 else 1356 { 1357 // Particular breakpoint selected; disable that breakpoint. 1358 BreakpointIDList valid_bp_ids; 1359 1360 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids); 1361 1362 if (result.Succeeded()) 1363 { 1364 int disable_count = 0; 1365 int loc_count = 0; 1366 const size_t count = valid_bp_ids.GetSize(); 1367 for (size_t i = 0; i < count; ++i) 1368 { 1369 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i); 1370 1371 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) 1372 { 1373 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 1374 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) 1375 { 1376 BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get(); 1377 if (location) 1378 { 1379 location->SetEnabled (false); 1380 ++loc_count; 1381 } 1382 } 1383 else 1384 { 1385 breakpoint->SetEnabled (false); 1386 ++disable_count; 1387 } 1388 } 1389 } 1390 result.AppendMessageWithFormat ("%d breakpoints disabled.\n", disable_count + loc_count); 1391 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1392 } 1393 } 1394 1395 return result.Succeeded(); 1396 } 1397 1398 }; 1399 1400 //------------------------------------------------------------------------- 1401 // CommandObjectBreakpointList 1402 //------------------------------------------------------------------------- 1403 #pragma mark List 1404 1405 class CommandObjectBreakpointList : public CommandObjectParsed 1406 { 1407 public: 1408 CommandObjectBreakpointList (CommandInterpreter &interpreter) : 1409 CommandObjectParsed (interpreter, 1410 "breakpoint list", 1411 "List some or all breakpoints at configurable levels of detail.", 1412 NULL), 1413 m_options (interpreter) 1414 { 1415 CommandArgumentEntry arg; 1416 CommandArgumentData bp_id_arg; 1417 1418 // Define the first (and only) variant of this arg. 1419 bp_id_arg.arg_type = eArgTypeBreakpointID; 1420 bp_id_arg.arg_repetition = eArgRepeatOptional; 1421 1422 // There is only one variant this argument could be; put it into the argument entry. 1423 arg.push_back (bp_id_arg); 1424 1425 // Push the data for the first argument into the m_arguments vector. 1426 m_arguments.push_back (arg); 1427 } 1428 1429 1430 ~CommandObjectBreakpointList () override {} 1431 1432 Options * 1433 GetOptions () override 1434 { 1435 return &m_options; 1436 } 1437 1438 class CommandOptions : public Options 1439 { 1440 public: 1441 1442 CommandOptions (CommandInterpreter &interpreter) : 1443 Options (interpreter), 1444 m_level (lldb::eDescriptionLevelBrief), 1445 m_use_dummy(false) 1446 { 1447 } 1448 1449 ~CommandOptions () override {} 1450 1451 Error 1452 SetOptionValue (uint32_t option_idx, const char *option_arg) override 1453 { 1454 Error error; 1455 const int short_option = m_getopt_table[option_idx].val; 1456 1457 switch (short_option) 1458 { 1459 case 'b': 1460 m_level = lldb::eDescriptionLevelBrief; 1461 break; 1462 case 'D': 1463 m_use_dummy = true; 1464 break; 1465 case 'f': 1466 m_level = lldb::eDescriptionLevelFull; 1467 break; 1468 case 'v': 1469 m_level = lldb::eDescriptionLevelVerbose; 1470 break; 1471 case 'i': 1472 m_internal = true; 1473 break; 1474 default: 1475 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 1476 break; 1477 } 1478 1479 return error; 1480 } 1481 1482 void 1483 OptionParsingStarting () override 1484 { 1485 m_level = lldb::eDescriptionLevelFull; 1486 m_internal = false; 1487 m_use_dummy = false; 1488 } 1489 1490 const OptionDefinition * 1491 GetDefinitions () override 1492 { 1493 return g_option_table; 1494 } 1495 1496 // Options table: Required for subclasses of Options. 1497 1498 static OptionDefinition g_option_table[]; 1499 1500 // Instance variables to hold the values for command options. 1501 1502 lldb::DescriptionLevel m_level; 1503 1504 bool m_internal; 1505 bool m_use_dummy; 1506 }; 1507 1508 protected: 1509 bool 1510 DoExecute (Args& command, CommandReturnObject &result) override 1511 { 1512 Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy); 1513 1514 if (target == NULL) 1515 { 1516 result.AppendError ("Invalid target. No current target or breakpoints."); 1517 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1518 return true; 1519 } 1520 1521 const BreakpointList &breakpoints = target->GetBreakpointList(m_options.m_internal); 1522 Mutex::Locker locker; 1523 target->GetBreakpointList(m_options.m_internal).GetListMutex(locker); 1524 1525 size_t num_breakpoints = breakpoints.GetSize(); 1526 1527 if (num_breakpoints == 0) 1528 { 1529 result.AppendMessage ("No breakpoints currently set."); 1530 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1531 return true; 1532 } 1533 1534 Stream &output_stream = result.GetOutputStream(); 1535 1536 if (command.GetArgumentCount() == 0) 1537 { 1538 // No breakpoint selected; show info about all currently set breakpoints. 1539 result.AppendMessage ("Current breakpoints:"); 1540 for (size_t i = 0; i < num_breakpoints; ++i) 1541 { 1542 Breakpoint *breakpoint = breakpoints.GetBreakpointAtIndex (i).get(); 1543 AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level); 1544 } 1545 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1546 } 1547 else 1548 { 1549 // Particular breakpoints selected; show info about that breakpoint. 1550 BreakpointIDList valid_bp_ids; 1551 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids); 1552 1553 if (result.Succeeded()) 1554 { 1555 for (size_t i = 0; i < valid_bp_ids.GetSize(); ++i) 1556 { 1557 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i); 1558 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 1559 AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level); 1560 } 1561 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1562 } 1563 else 1564 { 1565 result.AppendError ("Invalid breakpoint id."); 1566 result.SetStatus (eReturnStatusFailed); 1567 } 1568 } 1569 1570 return result.Succeeded(); 1571 } 1572 1573 private: 1574 CommandOptions m_options; 1575 }; 1576 1577 #pragma mark List::CommandOptions 1578 OptionDefinition 1579 CommandObjectBreakpointList::CommandOptions::g_option_table[] = 1580 { 1581 { LLDB_OPT_SET_ALL, false, "internal", 'i', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, 1582 "Show debugger internal breakpoints" }, 1583 1584 { LLDB_OPT_SET_1, false, "brief", 'b', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, 1585 "Give a brief description of the breakpoint (no location info)."}, 1586 1587 // FIXME: We need to add an "internal" command, and then add this sort of thing to it. 1588 // But I need to see it for now, and don't want to wait. 1589 { LLDB_OPT_SET_2, false, "full", 'f', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, 1590 "Give a full description of the breakpoint and its locations."}, 1591 1592 { LLDB_OPT_SET_3, false, "verbose", 'v', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, 1593 "Explain everything we know about the breakpoint (for debugging debugger bugs)." }, 1594 1595 { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, 1596 "List Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."}, 1597 1598 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 1599 }; 1600 1601 //------------------------------------------------------------------------- 1602 // CommandObjectBreakpointClear 1603 //------------------------------------------------------------------------- 1604 #pragma mark Clear 1605 1606 class CommandObjectBreakpointClear : public CommandObjectParsed 1607 { 1608 public: 1609 1610 typedef enum BreakpointClearType 1611 { 1612 eClearTypeInvalid, 1613 eClearTypeFileAndLine 1614 } BreakpointClearType; 1615 1616 CommandObjectBreakpointClear (CommandInterpreter &interpreter) : 1617 CommandObjectParsed (interpreter, 1618 "breakpoint clear", 1619 "Clears a breakpoint or set of breakpoints in the executable.", 1620 "breakpoint clear <cmd-options>"), 1621 m_options (interpreter) 1622 { 1623 } 1624 1625 ~CommandObjectBreakpointClear () override {} 1626 1627 Options * 1628 GetOptions () override 1629 { 1630 return &m_options; 1631 } 1632 1633 class CommandOptions : public Options 1634 { 1635 public: 1636 1637 CommandOptions (CommandInterpreter &interpreter) : 1638 Options (interpreter), 1639 m_filename (), 1640 m_line_num (0) 1641 { 1642 } 1643 1644 ~CommandOptions () override {} 1645 1646 Error 1647 SetOptionValue (uint32_t option_idx, const char *option_arg) override 1648 { 1649 Error error; 1650 const int short_option = m_getopt_table[option_idx].val; 1651 1652 switch (short_option) 1653 { 1654 case 'f': 1655 m_filename.assign (option_arg); 1656 break; 1657 1658 case 'l': 1659 m_line_num = StringConvert::ToUInt32 (option_arg, 0); 1660 break; 1661 1662 default: 1663 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 1664 break; 1665 } 1666 1667 return error; 1668 } 1669 1670 void 1671 OptionParsingStarting () override 1672 { 1673 m_filename.clear(); 1674 m_line_num = 0; 1675 } 1676 1677 const OptionDefinition* 1678 GetDefinitions () override 1679 { 1680 return g_option_table; 1681 } 1682 1683 // Options table: Required for subclasses of Options. 1684 1685 static OptionDefinition g_option_table[]; 1686 1687 // Instance variables to hold the values for command options. 1688 1689 std::string m_filename; 1690 uint32_t m_line_num; 1691 1692 }; 1693 1694 protected: 1695 bool 1696 DoExecute (Args& command, CommandReturnObject &result) override 1697 { 1698 Target *target = GetSelectedOrDummyTarget(); 1699 if (target == NULL) 1700 { 1701 result.AppendError ("Invalid target. No existing target or breakpoints."); 1702 result.SetStatus (eReturnStatusFailed); 1703 return false; 1704 } 1705 1706 // The following are the various types of breakpoints that could be cleared: 1707 // 1). -f -l (clearing breakpoint by source location) 1708 1709 BreakpointClearType break_type = eClearTypeInvalid; 1710 1711 if (m_options.m_line_num != 0) 1712 break_type = eClearTypeFileAndLine; 1713 1714 Mutex::Locker locker; 1715 target->GetBreakpointList().GetListMutex(locker); 1716 1717 BreakpointList &breakpoints = target->GetBreakpointList(); 1718 size_t num_breakpoints = breakpoints.GetSize(); 1719 1720 // Early return if there's no breakpoint at all. 1721 if (num_breakpoints == 0) 1722 { 1723 result.AppendError ("Breakpoint clear: No breakpoint cleared."); 1724 result.SetStatus (eReturnStatusFailed); 1725 return result.Succeeded(); 1726 } 1727 1728 // Find matching breakpoints and delete them. 1729 1730 // First create a copy of all the IDs. 1731 std::vector<break_id_t> BreakIDs; 1732 for (size_t i = 0; i < num_breakpoints; ++i) 1733 BreakIDs.push_back(breakpoints.GetBreakpointAtIndex(i).get()->GetID()); 1734 1735 int num_cleared = 0; 1736 StreamString ss; 1737 switch (break_type) 1738 { 1739 case eClearTypeFileAndLine: // Breakpoint by source position 1740 { 1741 const ConstString filename(m_options.m_filename.c_str()); 1742 BreakpointLocationCollection loc_coll; 1743 1744 for (size_t i = 0; i < num_breakpoints; ++i) 1745 { 1746 Breakpoint *bp = breakpoints.FindBreakpointByID(BreakIDs[i]).get(); 1747 1748 if (bp->GetMatchingFileLine(filename, m_options.m_line_num, loc_coll)) 1749 { 1750 // If the collection size is 0, it's a full match and we can just remove the breakpoint. 1751 if (loc_coll.GetSize() == 0) 1752 { 1753 bp->GetDescription(&ss, lldb::eDescriptionLevelBrief); 1754 ss.EOL(); 1755 target->RemoveBreakpointByID (bp->GetID()); 1756 ++num_cleared; 1757 } 1758 } 1759 } 1760 } 1761 break; 1762 1763 default: 1764 break; 1765 } 1766 1767 if (num_cleared > 0) 1768 { 1769 Stream &output_stream = result.GetOutputStream(); 1770 output_stream.Printf ("%d breakpoints cleared:\n", num_cleared); 1771 output_stream << ss.GetData(); 1772 output_stream.EOL(); 1773 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1774 } 1775 else 1776 { 1777 result.AppendError ("Breakpoint clear: No breakpoint cleared."); 1778 result.SetStatus (eReturnStatusFailed); 1779 } 1780 1781 return result.Succeeded(); 1782 } 1783 1784 private: 1785 CommandOptions m_options; 1786 }; 1787 1788 #pragma mark Clear::CommandOptions 1789 1790 OptionDefinition 1791 CommandObjectBreakpointClear::CommandOptions::g_option_table[] = 1792 { 1793 { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, 1794 "Specify the breakpoint by source location in this particular file."}, 1795 1796 { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum, 1797 "Specify the breakpoint by source location at this particular line."}, 1798 1799 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 1800 }; 1801 1802 //------------------------------------------------------------------------- 1803 // CommandObjectBreakpointDelete 1804 //------------------------------------------------------------------------- 1805 #pragma mark Delete 1806 1807 class CommandObjectBreakpointDelete : public CommandObjectParsed 1808 { 1809 public: 1810 CommandObjectBreakpointDelete (CommandInterpreter &interpreter) : 1811 CommandObjectParsed (interpreter, 1812 "breakpoint delete", 1813 "Delete the specified breakpoint(s). If no breakpoints are specified, delete them all.", 1814 NULL), 1815 m_options (interpreter) 1816 { 1817 CommandArgumentEntry arg; 1818 CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange); 1819 // Add the entry for the first argument for this command to the object's arguments vector. 1820 m_arguments.push_back (arg); 1821 } 1822 1823 ~CommandObjectBreakpointDelete () override {} 1824 1825 Options * 1826 GetOptions () override 1827 { 1828 return &m_options; 1829 } 1830 1831 class CommandOptions : public Options 1832 { 1833 public: 1834 1835 CommandOptions (CommandInterpreter &interpreter) : 1836 Options (interpreter), 1837 m_use_dummy (false), 1838 m_force (false) 1839 { 1840 } 1841 1842 ~CommandOptions () override {} 1843 1844 Error 1845 SetOptionValue (uint32_t option_idx, const char *option_arg) override 1846 { 1847 Error error; 1848 const int short_option = m_getopt_table[option_idx].val; 1849 1850 switch (short_option) 1851 { 1852 case 'f': 1853 m_force = true; 1854 break; 1855 1856 case 'D': 1857 m_use_dummy = true; 1858 break; 1859 1860 default: 1861 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 1862 break; 1863 } 1864 1865 return error; 1866 } 1867 1868 void 1869 OptionParsingStarting () override 1870 { 1871 m_use_dummy = false; 1872 m_force = false; 1873 } 1874 1875 const OptionDefinition* 1876 GetDefinitions () override 1877 { 1878 return g_option_table; 1879 } 1880 1881 // Options table: Required for subclasses of Options. 1882 1883 static OptionDefinition g_option_table[]; 1884 1885 // Instance variables to hold the values for command options. 1886 bool m_use_dummy; 1887 bool m_force; 1888 }; 1889 1890 protected: 1891 bool 1892 DoExecute (Args& command, CommandReturnObject &result) override 1893 { 1894 Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy); 1895 1896 if (target == NULL) 1897 { 1898 result.AppendError ("Invalid target. No existing target or breakpoints."); 1899 result.SetStatus (eReturnStatusFailed); 1900 return false; 1901 } 1902 1903 Mutex::Locker locker; 1904 target->GetBreakpointList().GetListMutex(locker); 1905 1906 const BreakpointList &breakpoints = target->GetBreakpointList(); 1907 1908 size_t num_breakpoints = breakpoints.GetSize(); 1909 1910 if (num_breakpoints == 0) 1911 { 1912 result.AppendError ("No breakpoints exist to be deleted."); 1913 result.SetStatus (eReturnStatusFailed); 1914 return false; 1915 } 1916 1917 if (command.GetArgumentCount() == 0) 1918 { 1919 if (!m_options.m_force && !m_interpreter.Confirm ("About to delete all breakpoints, do you want to do that?", true)) 1920 { 1921 result.AppendMessage("Operation cancelled..."); 1922 } 1923 else 1924 { 1925 target->RemoveAllBreakpoints (); 1926 result.AppendMessageWithFormat ("All breakpoints removed. (%" PRIu64 " breakpoint%s)\n", (uint64_t)num_breakpoints, num_breakpoints > 1 ? "s" : ""); 1927 } 1928 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1929 } 1930 else 1931 { 1932 // Particular breakpoint selected; disable that breakpoint. 1933 BreakpointIDList valid_bp_ids; 1934 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids); 1935 1936 if (result.Succeeded()) 1937 { 1938 int delete_count = 0; 1939 int disable_count = 0; 1940 const size_t count = valid_bp_ids.GetSize(); 1941 for (size_t i = 0; i < count; ++i) 1942 { 1943 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i); 1944 1945 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) 1946 { 1947 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) 1948 { 1949 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 1950 BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get(); 1951 // It makes no sense to try to delete individual locations, so we disable them instead. 1952 if (location) 1953 { 1954 location->SetEnabled (false); 1955 ++disable_count; 1956 } 1957 } 1958 else 1959 { 1960 target->RemoveBreakpointByID (cur_bp_id.GetBreakpointID()); 1961 ++delete_count; 1962 } 1963 } 1964 } 1965 result.AppendMessageWithFormat ("%d breakpoints deleted; %d breakpoint locations disabled.\n", 1966 delete_count, disable_count); 1967 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1968 } 1969 } 1970 return result.Succeeded(); 1971 } 1972 private: 1973 CommandOptions m_options; 1974 }; 1975 1976 OptionDefinition 1977 CommandObjectBreakpointDelete::CommandOptions::g_option_table[] = 1978 { 1979 { LLDB_OPT_SET_1, false, "force", 'f', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, 1980 "Delete all breakpoints without querying for confirmation."}, 1981 1982 { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, 1983 "Delete Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."}, 1984 1985 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 1986 }; 1987 1988 //------------------------------------------------------------------------- 1989 // CommandObjectBreakpointName 1990 //------------------------------------------------------------------------- 1991 1992 static OptionDefinition 1993 g_breakpoint_name_options[] = 1994 { 1995 { LLDB_OPT_SET_1, false, "name", 'N', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBreakpointName, "Specifies a breakpoint name to use."}, 1996 { LLDB_OPT_SET_2, false, "breakpoint-id", 'B', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBreakpointID, "Specify a breakpoint id to use."}, 1997 { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, 1998 "Operate on Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."}, 1999 }; 2000 class BreakpointNameOptionGroup : public OptionGroup 2001 { 2002 public: 2003 BreakpointNameOptionGroup() : 2004 OptionGroup(), 2005 m_breakpoint(LLDB_INVALID_BREAK_ID), 2006 m_use_dummy (false) 2007 { 2008 2009 } 2010 2011 ~BreakpointNameOptionGroup () override 2012 { 2013 } 2014 2015 uint32_t 2016 GetNumDefinitions () override 2017 { 2018 return sizeof (g_breakpoint_name_options) / sizeof (OptionDefinition); 2019 } 2020 2021 const OptionDefinition* 2022 GetDefinitions () override 2023 { 2024 return g_breakpoint_name_options; 2025 } 2026 2027 Error 2028 SetOptionValue (CommandInterpreter &interpreter, 2029 uint32_t option_idx, 2030 const char *option_value) override 2031 { 2032 Error error; 2033 const int short_option = g_breakpoint_name_options[option_idx].short_option; 2034 2035 switch (short_option) 2036 { 2037 case 'N': 2038 if (BreakpointID::StringIsBreakpointName(option_value, error) && error.Success()) 2039 m_name.SetValueFromString(option_value); 2040 break; 2041 2042 case 'B': 2043 if (m_breakpoint.SetValueFromString(option_value).Fail()) 2044 error.SetErrorStringWithFormat ("unrecognized value \"%s\" for breakpoint", option_value); 2045 break; 2046 case 'D': 2047 if (m_use_dummy.SetValueFromString(option_value).Fail()) 2048 error.SetErrorStringWithFormat ("unrecognized value \"%s\" for use-dummy", option_value); 2049 break; 2050 2051 default: 2052 error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option); 2053 break; 2054 } 2055 return error; 2056 } 2057 2058 void 2059 OptionParsingStarting (CommandInterpreter &interpreter) override 2060 { 2061 m_name.Clear(); 2062 m_breakpoint.Clear(); 2063 m_use_dummy.Clear(); 2064 m_use_dummy.SetDefaultValue(false); 2065 } 2066 2067 OptionValueString m_name; 2068 OptionValueUInt64 m_breakpoint; 2069 OptionValueBoolean m_use_dummy; 2070 }; 2071 2072 2073 class CommandObjectBreakpointNameAdd : public CommandObjectParsed 2074 { 2075 public: 2076 CommandObjectBreakpointNameAdd (CommandInterpreter &interpreter) : 2077 CommandObjectParsed (interpreter, 2078 "add", 2079 "Add a name to the breakpoints provided.", 2080 "breakpoint name add <command-options> <breakpoint-id-list>"), 2081 m_name_options(), 2082 m_option_group(interpreter) 2083 { 2084 // Create the first variant for the first (and only) argument for this command. 2085 CommandArgumentEntry arg1; 2086 CommandArgumentData id_arg; 2087 id_arg.arg_type = eArgTypeBreakpointID; 2088 id_arg.arg_repetition = eArgRepeatOptional; 2089 arg1.push_back(id_arg); 2090 m_arguments.push_back (arg1); 2091 2092 m_option_group.Append (&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL); 2093 m_option_group.Finalize(); 2094 } 2095 2096 ~CommandObjectBreakpointNameAdd () override {} 2097 2098 Options * 2099 GetOptions () override 2100 { 2101 return &m_option_group; 2102 } 2103 2104 protected: 2105 bool 2106 DoExecute (Args& command, CommandReturnObject &result) override 2107 { 2108 if (!m_name_options.m_name.OptionWasSet()) 2109 { 2110 result.SetError("No name option provided."); 2111 return false; 2112 } 2113 2114 Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue()); 2115 2116 if (target == NULL) 2117 { 2118 result.AppendError ("Invalid target. No existing target or breakpoints."); 2119 result.SetStatus (eReturnStatusFailed); 2120 return false; 2121 } 2122 2123 Mutex::Locker locker; 2124 target->GetBreakpointList().GetListMutex(locker); 2125 2126 const BreakpointList &breakpoints = target->GetBreakpointList(); 2127 2128 size_t num_breakpoints = breakpoints.GetSize(); 2129 if (num_breakpoints == 0) 2130 { 2131 result.SetError("No breakpoints, cannot add names."); 2132 result.SetStatus (eReturnStatusFailed); 2133 return false; 2134 } 2135 2136 // Particular breakpoint selected; disable that breakpoint. 2137 BreakpointIDList valid_bp_ids; 2138 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids); 2139 2140 if (result.Succeeded()) 2141 { 2142 if (valid_bp_ids.GetSize() == 0) 2143 { 2144 result.SetError("No breakpoints specified, cannot add names."); 2145 result.SetStatus (eReturnStatusFailed); 2146 return false; 2147 } 2148 size_t num_valid_ids = valid_bp_ids.GetSize(); 2149 for (size_t index = 0; index < num_valid_ids; index++) 2150 { 2151 lldb::break_id_t bp_id = valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID(); 2152 BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id); 2153 Error error; // We don't need to check the error here, since the option parser checked it... 2154 bp_sp->AddName(m_name_options.m_name.GetCurrentValue(), error); 2155 } 2156 } 2157 2158 return true; 2159 } 2160 2161 private: 2162 BreakpointNameOptionGroup m_name_options; 2163 OptionGroupOptions m_option_group; 2164 }; 2165 2166 2167 2168 class CommandObjectBreakpointNameDelete : public CommandObjectParsed 2169 { 2170 public: 2171 CommandObjectBreakpointNameDelete (CommandInterpreter &interpreter) : 2172 CommandObjectParsed (interpreter, 2173 "delete", 2174 "Delete a name from the breakpoints provided.", 2175 "breakpoint name delete <command-options> <breakpoint-id-list>"), 2176 m_name_options(), 2177 m_option_group(interpreter) 2178 { 2179 // Create the first variant for the first (and only) argument for this command. 2180 CommandArgumentEntry arg1; 2181 CommandArgumentData id_arg; 2182 id_arg.arg_type = eArgTypeBreakpointID; 2183 id_arg.arg_repetition = eArgRepeatOptional; 2184 arg1.push_back(id_arg); 2185 m_arguments.push_back (arg1); 2186 2187 m_option_group.Append (&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL); 2188 m_option_group.Finalize(); 2189 } 2190 2191 ~CommandObjectBreakpointNameDelete () override {} 2192 2193 Options * 2194 GetOptions () override 2195 { 2196 return &m_option_group; 2197 } 2198 2199 protected: 2200 bool 2201 DoExecute (Args& command, CommandReturnObject &result) override 2202 { 2203 if (!m_name_options.m_name.OptionWasSet()) 2204 { 2205 result.SetError("No name option provided."); 2206 return false; 2207 } 2208 2209 Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue()); 2210 2211 if (target == NULL) 2212 { 2213 result.AppendError ("Invalid target. No existing target or breakpoints."); 2214 result.SetStatus (eReturnStatusFailed); 2215 return false; 2216 } 2217 2218 Mutex::Locker locker; 2219 target->GetBreakpointList().GetListMutex(locker); 2220 2221 const BreakpointList &breakpoints = target->GetBreakpointList(); 2222 2223 size_t num_breakpoints = breakpoints.GetSize(); 2224 if (num_breakpoints == 0) 2225 { 2226 result.SetError("No breakpoints, cannot delete names."); 2227 result.SetStatus (eReturnStatusFailed); 2228 return false; 2229 } 2230 2231 // Particular breakpoint selected; disable that breakpoint. 2232 BreakpointIDList valid_bp_ids; 2233 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids); 2234 2235 if (result.Succeeded()) 2236 { 2237 if (valid_bp_ids.GetSize() == 0) 2238 { 2239 result.SetError("No breakpoints specified, cannot delete names."); 2240 result.SetStatus (eReturnStatusFailed); 2241 return false; 2242 } 2243 size_t num_valid_ids = valid_bp_ids.GetSize(); 2244 for (size_t index = 0; index < num_valid_ids; index++) 2245 { 2246 lldb::break_id_t bp_id = valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID(); 2247 BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id); 2248 bp_sp->RemoveName(m_name_options.m_name.GetCurrentValue()); 2249 } 2250 } 2251 2252 return true; 2253 } 2254 2255 private: 2256 BreakpointNameOptionGroup m_name_options; 2257 OptionGroupOptions m_option_group; 2258 }; 2259 2260 class CommandObjectBreakpointNameList : public CommandObjectParsed 2261 { 2262 public: 2263 CommandObjectBreakpointNameList (CommandInterpreter &interpreter) : 2264 CommandObjectParsed (interpreter, 2265 "list", 2266 "List either the names for a breakpoint or the breakpoints for a given name.", 2267 "breakpoint name list <command-options>"), 2268 m_name_options(), 2269 m_option_group(interpreter) 2270 { 2271 m_option_group.Append (&m_name_options); 2272 m_option_group.Finalize(); 2273 } 2274 2275 ~CommandObjectBreakpointNameList () override {} 2276 2277 Options * 2278 GetOptions () override 2279 { 2280 return &m_option_group; 2281 } 2282 2283 protected: 2284 bool 2285 DoExecute (Args& command, CommandReturnObject &result) override 2286 { 2287 Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue()); 2288 2289 if (target == NULL) 2290 { 2291 result.AppendError ("Invalid target. No existing target or breakpoints."); 2292 result.SetStatus (eReturnStatusFailed); 2293 return false; 2294 } 2295 2296 if (m_name_options.m_name.OptionWasSet()) 2297 { 2298 const char *name = m_name_options.m_name.GetCurrentValue(); 2299 Mutex::Locker locker; 2300 target->GetBreakpointList().GetListMutex(locker); 2301 2302 BreakpointList &breakpoints = target->GetBreakpointList(); 2303 for (BreakpointSP bp_sp : breakpoints.Breakpoints()) 2304 { 2305 if (bp_sp->MatchesName(name)) 2306 { 2307 StreamString s; 2308 bp_sp->GetDescription(&s, eDescriptionLevelBrief); 2309 s.EOL(); 2310 result.AppendMessage(s.GetData()); 2311 } 2312 } 2313 2314 } 2315 else if (m_name_options.m_breakpoint.OptionWasSet()) 2316 { 2317 BreakpointSP bp_sp = target->GetBreakpointList().FindBreakpointByID(m_name_options.m_breakpoint.GetCurrentValue()); 2318 if (bp_sp) 2319 { 2320 std::vector<std::string> names; 2321 bp_sp->GetNames (names); 2322 result.AppendMessage ("Names:"); 2323 for (auto name : names) 2324 result.AppendMessageWithFormat (" %s\n", name.c_str()); 2325 } 2326 else 2327 { 2328 result.AppendErrorWithFormat ("Could not find breakpoint %" PRId64 ".\n", 2329 m_name_options.m_breakpoint.GetCurrentValue()); 2330 result.SetStatus (eReturnStatusFailed); 2331 return false; 2332 } 2333 } 2334 else 2335 { 2336 result.SetError ("Must specify -N or -B option to list."); 2337 result.SetStatus (eReturnStatusFailed); 2338 return false; 2339 } 2340 return true; 2341 } 2342 2343 private: 2344 BreakpointNameOptionGroup m_name_options; 2345 OptionGroupOptions m_option_group; 2346 }; 2347 2348 //------------------------------------------------------------------------- 2349 // CommandObjectMultiwordBreakpoint 2350 //------------------------------------------------------------------------- 2351 class CommandObjectBreakpointName : public CommandObjectMultiword 2352 { 2353 public: 2354 CommandObjectBreakpointName (CommandInterpreter &interpreter) : 2355 CommandObjectMultiword(interpreter, 2356 "name", 2357 "A set of commands to manage name tags for breakpoints", 2358 "breakpoint name <command> [<command-options>]") 2359 { 2360 CommandObjectSP add_command_object (new CommandObjectBreakpointNameAdd (interpreter)); 2361 CommandObjectSP delete_command_object (new CommandObjectBreakpointNameDelete (interpreter)); 2362 CommandObjectSP list_command_object (new CommandObjectBreakpointNameList (interpreter)); 2363 2364 LoadSubCommand ("add", add_command_object); 2365 LoadSubCommand ("delete", delete_command_object); 2366 LoadSubCommand ("list", list_command_object); 2367 2368 } 2369 2370 ~CommandObjectBreakpointName () override 2371 { 2372 } 2373 2374 }; 2375 2376 2377 //------------------------------------------------------------------------- 2378 // CommandObjectMultiwordBreakpoint 2379 //------------------------------------------------------------------------- 2380 #pragma mark MultiwordBreakpoint 2381 2382 CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint (CommandInterpreter &interpreter) : 2383 CommandObjectMultiword (interpreter, 2384 "breakpoint", 2385 "A set of commands for operating on breakpoints. Also see _regexp-break.", 2386 "breakpoint <command> [<command-options>]") 2387 { 2388 CommandObjectSP list_command_object (new CommandObjectBreakpointList (interpreter)); 2389 CommandObjectSP enable_command_object (new CommandObjectBreakpointEnable (interpreter)); 2390 CommandObjectSP disable_command_object (new CommandObjectBreakpointDisable (interpreter)); 2391 CommandObjectSP clear_command_object (new CommandObjectBreakpointClear (interpreter)); 2392 CommandObjectSP delete_command_object (new CommandObjectBreakpointDelete (interpreter)); 2393 CommandObjectSP set_command_object (new CommandObjectBreakpointSet (interpreter)); 2394 CommandObjectSP command_command_object (new CommandObjectBreakpointCommand (interpreter)); 2395 CommandObjectSP modify_command_object (new CommandObjectBreakpointModify(interpreter)); 2396 CommandObjectSP name_command_object (new CommandObjectBreakpointName(interpreter)); 2397 2398 list_command_object->SetCommandName ("breakpoint list"); 2399 enable_command_object->SetCommandName("breakpoint enable"); 2400 disable_command_object->SetCommandName("breakpoint disable"); 2401 clear_command_object->SetCommandName("breakpoint clear"); 2402 delete_command_object->SetCommandName("breakpoint delete"); 2403 set_command_object->SetCommandName("breakpoint set"); 2404 command_command_object->SetCommandName ("breakpoint command"); 2405 modify_command_object->SetCommandName ("breakpoint modify"); 2406 name_command_object->SetCommandName ("breakpoint name"); 2407 2408 LoadSubCommand ("list", list_command_object); 2409 LoadSubCommand ("enable", enable_command_object); 2410 LoadSubCommand ("disable", disable_command_object); 2411 LoadSubCommand ("clear", clear_command_object); 2412 LoadSubCommand ("delete", delete_command_object); 2413 LoadSubCommand ("set", set_command_object); 2414 LoadSubCommand ("command", command_command_object); 2415 LoadSubCommand ("modify", modify_command_object); 2416 LoadSubCommand ("name", name_command_object); 2417 } 2418 2419 CommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint () 2420 { 2421 } 2422 2423 void 2424 CommandObjectMultiwordBreakpoint::VerifyIDs (Args &args, 2425 Target *target, 2426 bool allow_locations, 2427 CommandReturnObject &result, 2428 BreakpointIDList *valid_ids) 2429 { 2430 // args can be strings representing 1). integers (for breakpoint ids) 2431 // 2). the full breakpoint & location canonical representation 2432 // 3). the word "to" or a hyphen, representing a range (in which case there 2433 // had *better* be an entry both before & after of one of the first two types. 2434 // 4). A breakpoint name 2435 // If args is empty, we will use the last created breakpoint (if there is one.) 2436 2437 Args temp_args; 2438 2439 if (args.GetArgumentCount() == 0) 2440 { 2441 if (target->GetLastCreatedBreakpoint()) 2442 { 2443 valid_ids->AddBreakpointID (BreakpointID(target->GetLastCreatedBreakpoint()->GetID(), LLDB_INVALID_BREAK_ID)); 2444 result.SetStatus (eReturnStatusSuccessFinishNoResult); 2445 } 2446 else 2447 { 2448 result.AppendError("No breakpoint specified and no last created breakpoint."); 2449 result.SetStatus (eReturnStatusFailed); 2450 } 2451 return; 2452 } 2453 2454 // Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff directly from the old ARGS to 2455 // the new TEMP_ARGS. Do not copy breakpoint id range strings over; instead generate a list of strings for 2456 // all the breakpoint ids in the range, and shove all of those breakpoint id strings into TEMP_ARGS. 2457 2458 BreakpointIDList::FindAndReplaceIDRanges (args, target, allow_locations, result, temp_args); 2459 2460 // NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual BreakpointIDList: 2461 2462 valid_ids->InsertStringArray (temp_args.GetConstArgumentVector(), temp_args.GetArgumentCount(), result); 2463 2464 // At this point, all of the breakpoint ids that the user passed in have been converted to breakpoint IDs 2465 // and put into valid_ids. 2466 2467 if (result.Succeeded()) 2468 { 2469 // Now that we've converted everything from args into a list of breakpoint ids, go through our tentative list 2470 // of breakpoint id's and verify that they correspond to valid/currently set breakpoints. 2471 2472 const size_t count = valid_ids->GetSize(); 2473 for (size_t i = 0; i < count; ++i) 2474 { 2475 BreakpointID cur_bp_id = valid_ids->GetBreakpointIDAtIndex (i); 2476 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 2477 if (breakpoint != NULL) 2478 { 2479 const size_t num_locations = breakpoint->GetNumLocations(); 2480 if (static_cast<size_t>(cur_bp_id.GetLocationID()) > num_locations) 2481 { 2482 StreamString id_str; 2483 BreakpointID::GetCanonicalReference (&id_str, 2484 cur_bp_id.GetBreakpointID(), 2485 cur_bp_id.GetLocationID()); 2486 i = valid_ids->GetSize() + 1; 2487 result.AppendErrorWithFormat ("'%s' is not a currently valid breakpoint/location id.\n", 2488 id_str.GetData()); 2489 result.SetStatus (eReturnStatusFailed); 2490 } 2491 } 2492 else 2493 { 2494 i = valid_ids->GetSize() + 1; 2495 result.AppendErrorWithFormat ("'%d' is not a currently valid breakpoint id.\n", cur_bp_id.GetBreakpointID()); 2496 result.SetStatus (eReturnStatusFailed); 2497 } 2498 } 2499 } 2500 } 2501