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 825 { LLDB_OPT_SET_9, false, "all-files", 'A', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, 826 "All files are searched for source pattern matches." }, 827 828 { LLDB_OPT_SET_10, true, "language-exception", 'E', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage, 829 "Set the breakpoint on exceptions thrown by the specified language (without options, on throw but not catch.)" }, 830 831 { LLDB_OPT_SET_10, false, "on-throw", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, 832 "Set the breakpoint on exception throW." }, 833 834 { LLDB_OPT_SET_10, false, "on-catch", 'h', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, 835 "Set the breakpoint on exception catcH." }, 836 837 // Don't add this option till it actually does something useful... 838 // { LLDB_OPT_SET_10, false, "exception-typename", 'O', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeTypeName, 839 // "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" }, 840 841 { LLDB_OPT_EXPR_LANGUAGE, false, "language", 'L', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage, 842 "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." }, 843 844 { LLDB_OPT_SKIP_PROLOGUE, false, "skip-prologue", 'K', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, 845 "sKip the prologue if the breakpoint is at the beginning of a function. If not set the target.skip-prologue setting is used." }, 846 847 { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, 848 "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."}, 849 850 { LLDB_OPT_SET_ALL, false, "breakpoint-name", 'N', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBreakpointName, 851 "Adds this to the list of names for this breakopint."}, 852 853 { LLDB_OPT_MOVE_TO_NEAREST_CODE, false, "move-to-nearest-code", 'm', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, 854 "Move breakpoints to nearest code. If not set the target.move-to-nearest-code setting is used." }, 855 856 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 857 }; 858 859 //------------------------------------------------------------------------- 860 // CommandObjectBreakpointModify 861 //------------------------------------------------------------------------- 862 #pragma mark Modify 863 864 class CommandObjectBreakpointModify : public CommandObjectParsed 865 { 866 public: 867 868 CommandObjectBreakpointModify (CommandInterpreter &interpreter) : 869 CommandObjectParsed (interpreter, 870 "breakpoint modify", 871 "Modify the options on a breakpoint or set of breakpoints in the executable. " 872 "If no breakpoint is specified, acts on the last created breakpoint. " 873 "With the exception of -e, -d and -i, passing an empty argument clears the modification.", 874 NULL), 875 m_options (interpreter) 876 { 877 CommandArgumentEntry arg; 878 CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange); 879 // Add the entry for the first argument for this command to the object's arguments vector. 880 m_arguments.push_back (arg); 881 } 882 883 884 ~CommandObjectBreakpointModify () override {} 885 886 Options * 887 GetOptions () override 888 { 889 return &m_options; 890 } 891 892 class CommandOptions : public Options 893 { 894 public: 895 896 CommandOptions (CommandInterpreter &interpreter) : 897 Options (interpreter), 898 m_ignore_count (0), 899 m_thread_id(LLDB_INVALID_THREAD_ID), 900 m_thread_id_passed(false), 901 m_thread_index (UINT32_MAX), 902 m_thread_index_passed(false), 903 m_thread_name(), 904 m_queue_name(), 905 m_condition (), 906 m_one_shot (false), 907 m_enable_passed (false), 908 m_enable_value (false), 909 m_name_passed (false), 910 m_queue_passed (false), 911 m_condition_passed (false), 912 m_one_shot_passed (false), 913 m_use_dummy (false) 914 { 915 } 916 917 ~CommandOptions () override {} 918 919 Error 920 SetOptionValue (uint32_t option_idx, const char *option_arg) override 921 { 922 Error error; 923 const int short_option = m_getopt_table[option_idx].val; 924 925 switch (short_option) 926 { 927 case 'c': 928 if (option_arg != NULL) 929 m_condition.assign (option_arg); 930 else 931 m_condition.clear(); 932 m_condition_passed = true; 933 break; 934 case 'd': 935 m_enable_passed = true; 936 m_enable_value = false; 937 break; 938 case 'D': 939 m_use_dummy = true; 940 break; 941 case 'e': 942 m_enable_passed = true; 943 m_enable_value = true; 944 break; 945 case 'i': 946 { 947 m_ignore_count = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0); 948 if (m_ignore_count == UINT32_MAX) 949 error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg); 950 } 951 break; 952 case 'o': 953 { 954 bool value, success; 955 value = Args::StringToBoolean(option_arg, false, &success); 956 if (success) 957 { 958 m_one_shot_passed = true; 959 m_one_shot = value; 960 } 961 else 962 error.SetErrorStringWithFormat("invalid boolean value '%s' passed for -o option", option_arg); 963 } 964 break; 965 case 't' : 966 { 967 if (option_arg[0] == '\0') 968 { 969 m_thread_id = LLDB_INVALID_THREAD_ID; 970 m_thread_id_passed = true; 971 } 972 else 973 { 974 m_thread_id = StringConvert::ToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0); 975 if (m_thread_id == LLDB_INVALID_THREAD_ID) 976 error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg); 977 else 978 m_thread_id_passed = true; 979 } 980 } 981 break; 982 case 'T': 983 if (option_arg != NULL) 984 m_thread_name.assign (option_arg); 985 else 986 m_thread_name.clear(); 987 m_name_passed = true; 988 break; 989 case 'q': 990 if (option_arg != NULL) 991 m_queue_name.assign (option_arg); 992 else 993 m_queue_name.clear(); 994 m_queue_passed = true; 995 break; 996 case 'x': 997 { 998 if (option_arg[0] == '\n') 999 { 1000 m_thread_index = UINT32_MAX; 1001 m_thread_index_passed = true; 1002 } 1003 else 1004 { 1005 m_thread_index = StringConvert::ToUInt32 (option_arg, UINT32_MAX, 0); 1006 if (m_thread_id == UINT32_MAX) 1007 error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg); 1008 else 1009 m_thread_index_passed = true; 1010 } 1011 } 1012 break; 1013 default: 1014 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 1015 break; 1016 } 1017 1018 return error; 1019 } 1020 void 1021 OptionParsingStarting () override 1022 { 1023 m_ignore_count = 0; 1024 m_thread_id = LLDB_INVALID_THREAD_ID; 1025 m_thread_id_passed = false; 1026 m_thread_index = UINT32_MAX; 1027 m_thread_index_passed = false; 1028 m_thread_name.clear(); 1029 m_queue_name.clear(); 1030 m_condition.clear(); 1031 m_one_shot = false; 1032 m_enable_passed = false; 1033 m_queue_passed = false; 1034 m_name_passed = false; 1035 m_condition_passed = false; 1036 m_one_shot_passed = false; 1037 m_use_dummy = false; 1038 } 1039 1040 const OptionDefinition* 1041 GetDefinitions () override 1042 { 1043 return g_option_table; 1044 } 1045 1046 1047 // Options table: Required for subclasses of Options. 1048 1049 static OptionDefinition g_option_table[]; 1050 1051 // Instance variables to hold the values for command options. 1052 1053 uint32_t m_ignore_count; 1054 lldb::tid_t m_thread_id; 1055 bool m_thread_id_passed; 1056 uint32_t m_thread_index; 1057 bool m_thread_index_passed; 1058 std::string m_thread_name; 1059 std::string m_queue_name; 1060 std::string m_condition; 1061 bool m_one_shot; 1062 bool m_enable_passed; 1063 bool m_enable_value; 1064 bool m_name_passed; 1065 bool m_queue_passed; 1066 bool m_condition_passed; 1067 bool m_one_shot_passed; 1068 bool m_use_dummy; 1069 1070 }; 1071 1072 protected: 1073 bool 1074 DoExecute (Args& command, CommandReturnObject &result) override 1075 { 1076 Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy); 1077 if (target == NULL) 1078 { 1079 result.AppendError ("Invalid target. No existing target or breakpoints."); 1080 result.SetStatus (eReturnStatusFailed); 1081 return false; 1082 } 1083 1084 Mutex::Locker locker; 1085 target->GetBreakpointList().GetListMutex(locker); 1086 1087 BreakpointIDList valid_bp_ids; 1088 1089 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids); 1090 1091 if (result.Succeeded()) 1092 { 1093 const size_t count = valid_bp_ids.GetSize(); 1094 for (size_t i = 0; i < count; ++i) 1095 { 1096 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i); 1097 1098 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) 1099 { 1100 Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 1101 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) 1102 { 1103 BreakpointLocation *location = bp->FindLocationByID (cur_bp_id.GetLocationID()).get(); 1104 if (location) 1105 { 1106 if (m_options.m_thread_id_passed) 1107 location->SetThreadID (m_options.m_thread_id); 1108 1109 if (m_options.m_thread_index_passed) 1110 location->SetThreadIndex(m_options.m_thread_index); 1111 1112 if (m_options.m_name_passed) 1113 location->SetThreadName(m_options.m_thread_name.c_str()); 1114 1115 if (m_options.m_queue_passed) 1116 location->SetQueueName(m_options.m_queue_name.c_str()); 1117 1118 if (m_options.m_ignore_count != 0) 1119 location->SetIgnoreCount(m_options.m_ignore_count); 1120 1121 if (m_options.m_enable_passed) 1122 location->SetEnabled (m_options.m_enable_value); 1123 1124 if (m_options.m_condition_passed) 1125 location->SetCondition (m_options.m_condition.c_str()); 1126 } 1127 } 1128 else 1129 { 1130 if (m_options.m_thread_id_passed) 1131 bp->SetThreadID (m_options.m_thread_id); 1132 1133 if (m_options.m_thread_index_passed) 1134 bp->SetThreadIndex(m_options.m_thread_index); 1135 1136 if (m_options.m_name_passed) 1137 bp->SetThreadName(m_options.m_thread_name.c_str()); 1138 1139 if (m_options.m_queue_passed) 1140 bp->SetQueueName(m_options.m_queue_name.c_str()); 1141 1142 if (m_options.m_ignore_count != 0) 1143 bp->SetIgnoreCount(m_options.m_ignore_count); 1144 1145 if (m_options.m_enable_passed) 1146 bp->SetEnabled (m_options.m_enable_value); 1147 1148 if (m_options.m_condition_passed) 1149 bp->SetCondition (m_options.m_condition.c_str()); 1150 } 1151 } 1152 } 1153 } 1154 1155 return result.Succeeded(); 1156 } 1157 1158 private: 1159 CommandOptions m_options; 1160 }; 1161 1162 #pragma mark Modify::CommandOptions 1163 OptionDefinition 1164 CommandObjectBreakpointModify::CommandOptions::g_option_table[] = 1165 { 1166 { 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." }, 1167 { 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." }, 1168 { 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."}, 1169 { 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."}, 1170 { 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."}, 1171 { 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."}, 1172 { LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeExpression, "The breakpoint stops only if this condition expression evaluates to true."}, 1173 { LLDB_OPT_SET_1, false, "enable", 'e', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Enable the breakpoint."}, 1174 { LLDB_OPT_SET_2, false, "disable", 'd', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Disable the breakpoint."}, 1175 { 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."}, 1176 1177 { 0, false, NULL, 0 , 0, NULL, NULL, 0, eArgTypeNone, NULL } 1178 }; 1179 1180 //------------------------------------------------------------------------- 1181 // CommandObjectBreakpointEnable 1182 //------------------------------------------------------------------------- 1183 #pragma mark Enable 1184 1185 class CommandObjectBreakpointEnable : public CommandObjectParsed 1186 { 1187 public: 1188 CommandObjectBreakpointEnable (CommandInterpreter &interpreter) : 1189 CommandObjectParsed (interpreter, 1190 "enable", 1191 "Enable the specified disabled breakpoint(s). If no breakpoints are specified, enable all of them.", 1192 NULL) 1193 { 1194 CommandArgumentEntry arg; 1195 CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange); 1196 // Add the entry for the first argument for this command to the object's arguments vector. 1197 m_arguments.push_back (arg); 1198 } 1199 1200 1201 ~CommandObjectBreakpointEnable () override {} 1202 1203 protected: 1204 bool 1205 DoExecute (Args& command, CommandReturnObject &result) override 1206 { 1207 Target *target = GetSelectedOrDummyTarget(); 1208 if (target == NULL) 1209 { 1210 result.AppendError ("Invalid target. No existing target or breakpoints."); 1211 result.SetStatus (eReturnStatusFailed); 1212 return false; 1213 } 1214 1215 Mutex::Locker locker; 1216 target->GetBreakpointList().GetListMutex(locker); 1217 1218 const BreakpointList &breakpoints = target->GetBreakpointList(); 1219 1220 size_t num_breakpoints = breakpoints.GetSize(); 1221 1222 if (num_breakpoints == 0) 1223 { 1224 result.AppendError ("No breakpoints exist to be enabled."); 1225 result.SetStatus (eReturnStatusFailed); 1226 return false; 1227 } 1228 1229 if (command.GetArgumentCount() == 0) 1230 { 1231 // No breakpoint selected; enable all currently set breakpoints. 1232 target->EnableAllBreakpoints (); 1233 result.AppendMessageWithFormat ("All breakpoints enabled. (%" PRIu64 " breakpoints)\n", (uint64_t)num_breakpoints); 1234 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1235 } 1236 else 1237 { 1238 // Particular breakpoint selected; enable that breakpoint. 1239 BreakpointIDList valid_bp_ids; 1240 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids); 1241 1242 if (result.Succeeded()) 1243 { 1244 int enable_count = 0; 1245 int loc_count = 0; 1246 const size_t count = valid_bp_ids.GetSize(); 1247 for (size_t i = 0; i < count; ++i) 1248 { 1249 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i); 1250 1251 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) 1252 { 1253 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 1254 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) 1255 { 1256 BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get(); 1257 if (location) 1258 { 1259 location->SetEnabled (true); 1260 ++loc_count; 1261 } 1262 } 1263 else 1264 { 1265 breakpoint->SetEnabled (true); 1266 ++enable_count; 1267 } 1268 } 1269 } 1270 result.AppendMessageWithFormat ("%d breakpoints enabled.\n", enable_count + loc_count); 1271 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1272 } 1273 } 1274 1275 return result.Succeeded(); 1276 } 1277 }; 1278 1279 //------------------------------------------------------------------------- 1280 // CommandObjectBreakpointDisable 1281 //------------------------------------------------------------------------- 1282 #pragma mark Disable 1283 1284 class CommandObjectBreakpointDisable : public CommandObjectParsed 1285 { 1286 public: 1287 CommandObjectBreakpointDisable (CommandInterpreter &interpreter) : 1288 CommandObjectParsed (interpreter, 1289 "breakpoint disable", 1290 "Disable the specified breakpoint(s) without removing them. If none are specified, disable all breakpoints.", 1291 NULL) 1292 { 1293 SetHelpLong( 1294 "Disable the specified breakpoint(s) without removing them. \ 1295 If none are specified, disable all breakpoints." R"( 1296 1297 )" "Note: disabling a breakpoint will cause none of its locations to be hit \ 1298 regardless of whether they are enabled or disabled. After the sequence:" R"( 1299 1300 (lldb) break disable 1 1301 (lldb) break enable 1.1 1302 1303 execution will NOT stop at location 1.1. To achieve that, type: 1304 1305 (lldb) break disable 1.* 1306 (lldb) break enable 1.1 1307 1308 )" "The first command disables all the locations of breakpoint 1, \ 1309 the second re-enables the first location." 1310 ); 1311 1312 CommandArgumentEntry arg; 1313 CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange); 1314 // Add the entry for the first argument for this command to the object's arguments vector. 1315 m_arguments.push_back (arg); 1316 1317 } 1318 1319 1320 ~CommandObjectBreakpointDisable () override {} 1321 1322 protected: 1323 bool 1324 DoExecute (Args& command, CommandReturnObject &result) override 1325 { 1326 Target *target = GetSelectedOrDummyTarget(); 1327 if (target == NULL) 1328 { 1329 result.AppendError ("Invalid target. No existing target or breakpoints."); 1330 result.SetStatus (eReturnStatusFailed); 1331 return false; 1332 } 1333 1334 Mutex::Locker locker; 1335 target->GetBreakpointList().GetListMutex(locker); 1336 1337 const BreakpointList &breakpoints = target->GetBreakpointList(); 1338 size_t num_breakpoints = breakpoints.GetSize(); 1339 1340 if (num_breakpoints == 0) 1341 { 1342 result.AppendError ("No breakpoints exist to be disabled."); 1343 result.SetStatus (eReturnStatusFailed); 1344 return false; 1345 } 1346 1347 if (command.GetArgumentCount() == 0) 1348 { 1349 // No breakpoint selected; disable all currently set breakpoints. 1350 target->DisableAllBreakpoints (); 1351 result.AppendMessageWithFormat ("All breakpoints disabled. (%" PRIu64 " breakpoints)\n", (uint64_t)num_breakpoints); 1352 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1353 } 1354 else 1355 { 1356 // Particular breakpoint selected; disable that breakpoint. 1357 BreakpointIDList valid_bp_ids; 1358 1359 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids); 1360 1361 if (result.Succeeded()) 1362 { 1363 int disable_count = 0; 1364 int loc_count = 0; 1365 const size_t count = valid_bp_ids.GetSize(); 1366 for (size_t i = 0; i < count; ++i) 1367 { 1368 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i); 1369 1370 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) 1371 { 1372 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 1373 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) 1374 { 1375 BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get(); 1376 if (location) 1377 { 1378 location->SetEnabled (false); 1379 ++loc_count; 1380 } 1381 } 1382 else 1383 { 1384 breakpoint->SetEnabled (false); 1385 ++disable_count; 1386 } 1387 } 1388 } 1389 result.AppendMessageWithFormat ("%d breakpoints disabled.\n", disable_count + loc_count); 1390 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1391 } 1392 } 1393 1394 return result.Succeeded(); 1395 } 1396 1397 }; 1398 1399 //------------------------------------------------------------------------- 1400 // CommandObjectBreakpointList 1401 //------------------------------------------------------------------------- 1402 #pragma mark List 1403 1404 class CommandObjectBreakpointList : public CommandObjectParsed 1405 { 1406 public: 1407 CommandObjectBreakpointList (CommandInterpreter &interpreter) : 1408 CommandObjectParsed (interpreter, 1409 "breakpoint list", 1410 "List some or all breakpoints at configurable levels of detail.", 1411 NULL), 1412 m_options (interpreter) 1413 { 1414 CommandArgumentEntry arg; 1415 CommandArgumentData bp_id_arg; 1416 1417 // Define the first (and only) variant of this arg. 1418 bp_id_arg.arg_type = eArgTypeBreakpointID; 1419 bp_id_arg.arg_repetition = eArgRepeatOptional; 1420 1421 // There is only one variant this argument could be; put it into the argument entry. 1422 arg.push_back (bp_id_arg); 1423 1424 // Push the data for the first argument into the m_arguments vector. 1425 m_arguments.push_back (arg); 1426 } 1427 1428 1429 ~CommandObjectBreakpointList () override {} 1430 1431 Options * 1432 GetOptions () override 1433 { 1434 return &m_options; 1435 } 1436 1437 class CommandOptions : public Options 1438 { 1439 public: 1440 1441 CommandOptions (CommandInterpreter &interpreter) : 1442 Options (interpreter), 1443 m_level (lldb::eDescriptionLevelBrief), 1444 m_use_dummy(false) 1445 { 1446 } 1447 1448 ~CommandOptions () override {} 1449 1450 Error 1451 SetOptionValue (uint32_t option_idx, const char *option_arg) override 1452 { 1453 Error error; 1454 const int short_option = m_getopt_table[option_idx].val; 1455 1456 switch (short_option) 1457 { 1458 case 'b': 1459 m_level = lldb::eDescriptionLevelBrief; 1460 break; 1461 case 'D': 1462 m_use_dummy = true; 1463 break; 1464 case 'f': 1465 m_level = lldb::eDescriptionLevelFull; 1466 break; 1467 case 'v': 1468 m_level = lldb::eDescriptionLevelVerbose; 1469 break; 1470 case 'i': 1471 m_internal = true; 1472 break; 1473 default: 1474 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 1475 break; 1476 } 1477 1478 return error; 1479 } 1480 1481 void 1482 OptionParsingStarting () override 1483 { 1484 m_level = lldb::eDescriptionLevelFull; 1485 m_internal = false; 1486 m_use_dummy = false; 1487 } 1488 1489 const OptionDefinition * 1490 GetDefinitions () override 1491 { 1492 return g_option_table; 1493 } 1494 1495 // Options table: Required for subclasses of Options. 1496 1497 static OptionDefinition g_option_table[]; 1498 1499 // Instance variables to hold the values for command options. 1500 1501 lldb::DescriptionLevel m_level; 1502 1503 bool m_internal; 1504 bool m_use_dummy; 1505 }; 1506 1507 protected: 1508 bool 1509 DoExecute (Args& command, CommandReturnObject &result) override 1510 { 1511 Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy); 1512 1513 if (target == NULL) 1514 { 1515 result.AppendError ("Invalid target. No current target or breakpoints."); 1516 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1517 return true; 1518 } 1519 1520 const BreakpointList &breakpoints = target->GetBreakpointList(m_options.m_internal); 1521 Mutex::Locker locker; 1522 target->GetBreakpointList(m_options.m_internal).GetListMutex(locker); 1523 1524 size_t num_breakpoints = breakpoints.GetSize(); 1525 1526 if (num_breakpoints == 0) 1527 { 1528 result.AppendMessage ("No breakpoints currently set."); 1529 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1530 return true; 1531 } 1532 1533 Stream &output_stream = result.GetOutputStream(); 1534 1535 if (command.GetArgumentCount() == 0) 1536 { 1537 // No breakpoint selected; show info about all currently set breakpoints. 1538 result.AppendMessage ("Current breakpoints:"); 1539 for (size_t i = 0; i < num_breakpoints; ++i) 1540 { 1541 Breakpoint *breakpoint = breakpoints.GetBreakpointAtIndex (i).get(); 1542 AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level); 1543 } 1544 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1545 } 1546 else 1547 { 1548 // Particular breakpoints selected; show info about that breakpoint. 1549 BreakpointIDList valid_bp_ids; 1550 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids); 1551 1552 if (result.Succeeded()) 1553 { 1554 for (size_t i = 0; i < valid_bp_ids.GetSize(); ++i) 1555 { 1556 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i); 1557 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 1558 AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level); 1559 } 1560 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1561 } 1562 else 1563 { 1564 result.AppendError ("Invalid breakpoint id."); 1565 result.SetStatus (eReturnStatusFailed); 1566 } 1567 } 1568 1569 return result.Succeeded(); 1570 } 1571 1572 private: 1573 CommandOptions m_options; 1574 }; 1575 1576 #pragma mark List::CommandOptions 1577 OptionDefinition 1578 CommandObjectBreakpointList::CommandOptions::g_option_table[] = 1579 { 1580 { LLDB_OPT_SET_ALL, false, "internal", 'i', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, 1581 "Show debugger internal breakpoints" }, 1582 1583 { LLDB_OPT_SET_1, false, "brief", 'b', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, 1584 "Give a brief description of the breakpoint (no location info)."}, 1585 1586 // FIXME: We need to add an "internal" command, and then add this sort of thing to it. 1587 // But I need to see it for now, and don't want to wait. 1588 { LLDB_OPT_SET_2, false, "full", 'f', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, 1589 "Give a full description of the breakpoint and its locations."}, 1590 1591 { LLDB_OPT_SET_3, false, "verbose", 'v', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, 1592 "Explain everything we know about the breakpoint (for debugging debugger bugs)." }, 1593 1594 { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, 1595 "List Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."}, 1596 1597 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 1598 }; 1599 1600 //------------------------------------------------------------------------- 1601 // CommandObjectBreakpointClear 1602 //------------------------------------------------------------------------- 1603 #pragma mark Clear 1604 1605 class CommandObjectBreakpointClear : public CommandObjectParsed 1606 { 1607 public: 1608 1609 typedef enum BreakpointClearType 1610 { 1611 eClearTypeInvalid, 1612 eClearTypeFileAndLine 1613 } BreakpointClearType; 1614 1615 CommandObjectBreakpointClear (CommandInterpreter &interpreter) : 1616 CommandObjectParsed (interpreter, 1617 "breakpoint clear", 1618 "Clears a breakpoint or set of breakpoints in the executable.", 1619 "breakpoint clear <cmd-options>"), 1620 m_options (interpreter) 1621 { 1622 } 1623 1624 ~CommandObjectBreakpointClear () override {} 1625 1626 Options * 1627 GetOptions () override 1628 { 1629 return &m_options; 1630 } 1631 1632 class CommandOptions : public Options 1633 { 1634 public: 1635 1636 CommandOptions (CommandInterpreter &interpreter) : 1637 Options (interpreter), 1638 m_filename (), 1639 m_line_num (0) 1640 { 1641 } 1642 1643 ~CommandOptions () override {} 1644 1645 Error 1646 SetOptionValue (uint32_t option_idx, const char *option_arg) override 1647 { 1648 Error error; 1649 const int short_option = m_getopt_table[option_idx].val; 1650 1651 switch (short_option) 1652 { 1653 case 'f': 1654 m_filename.assign (option_arg); 1655 break; 1656 1657 case 'l': 1658 m_line_num = StringConvert::ToUInt32 (option_arg, 0); 1659 break; 1660 1661 default: 1662 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 1663 break; 1664 } 1665 1666 return error; 1667 } 1668 1669 void 1670 OptionParsingStarting () override 1671 { 1672 m_filename.clear(); 1673 m_line_num = 0; 1674 } 1675 1676 const OptionDefinition* 1677 GetDefinitions () override 1678 { 1679 return g_option_table; 1680 } 1681 1682 // Options table: Required for subclasses of Options. 1683 1684 static OptionDefinition g_option_table[]; 1685 1686 // Instance variables to hold the values for command options. 1687 1688 std::string m_filename; 1689 uint32_t m_line_num; 1690 1691 }; 1692 1693 protected: 1694 bool 1695 DoExecute (Args& command, CommandReturnObject &result) override 1696 { 1697 Target *target = GetSelectedOrDummyTarget(); 1698 if (target == NULL) 1699 { 1700 result.AppendError ("Invalid target. No existing target or breakpoints."); 1701 result.SetStatus (eReturnStatusFailed); 1702 return false; 1703 } 1704 1705 // The following are the various types of breakpoints that could be cleared: 1706 // 1). -f -l (clearing breakpoint by source location) 1707 1708 BreakpointClearType break_type = eClearTypeInvalid; 1709 1710 if (m_options.m_line_num != 0) 1711 break_type = eClearTypeFileAndLine; 1712 1713 Mutex::Locker locker; 1714 target->GetBreakpointList().GetListMutex(locker); 1715 1716 BreakpointList &breakpoints = target->GetBreakpointList(); 1717 size_t num_breakpoints = breakpoints.GetSize(); 1718 1719 // Early return if there's no breakpoint at all. 1720 if (num_breakpoints == 0) 1721 { 1722 result.AppendError ("Breakpoint clear: No breakpoint cleared."); 1723 result.SetStatus (eReturnStatusFailed); 1724 return result.Succeeded(); 1725 } 1726 1727 // Find matching breakpoints and delete them. 1728 1729 // First create a copy of all the IDs. 1730 std::vector<break_id_t> BreakIDs; 1731 for (size_t i = 0; i < num_breakpoints; ++i) 1732 BreakIDs.push_back(breakpoints.GetBreakpointAtIndex(i).get()->GetID()); 1733 1734 int num_cleared = 0; 1735 StreamString ss; 1736 switch (break_type) 1737 { 1738 case eClearTypeFileAndLine: // Breakpoint by source position 1739 { 1740 const ConstString filename(m_options.m_filename.c_str()); 1741 BreakpointLocationCollection loc_coll; 1742 1743 for (size_t i = 0; i < num_breakpoints; ++i) 1744 { 1745 Breakpoint *bp = breakpoints.FindBreakpointByID(BreakIDs[i]).get(); 1746 1747 if (bp->GetMatchingFileLine(filename, m_options.m_line_num, loc_coll)) 1748 { 1749 // If the collection size is 0, it's a full match and we can just remove the breakpoint. 1750 if (loc_coll.GetSize() == 0) 1751 { 1752 bp->GetDescription(&ss, lldb::eDescriptionLevelBrief); 1753 ss.EOL(); 1754 target->RemoveBreakpointByID (bp->GetID()); 1755 ++num_cleared; 1756 } 1757 } 1758 } 1759 } 1760 break; 1761 1762 default: 1763 break; 1764 } 1765 1766 if (num_cleared > 0) 1767 { 1768 Stream &output_stream = result.GetOutputStream(); 1769 output_stream.Printf ("%d breakpoints cleared:\n", num_cleared); 1770 output_stream << ss.GetData(); 1771 output_stream.EOL(); 1772 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1773 } 1774 else 1775 { 1776 result.AppendError ("Breakpoint clear: No breakpoint cleared."); 1777 result.SetStatus (eReturnStatusFailed); 1778 } 1779 1780 return result.Succeeded(); 1781 } 1782 1783 private: 1784 CommandOptions m_options; 1785 }; 1786 1787 #pragma mark Clear::CommandOptions 1788 1789 OptionDefinition 1790 CommandObjectBreakpointClear::CommandOptions::g_option_table[] = 1791 { 1792 { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, 1793 "Specify the breakpoint by source location in this particular file."}, 1794 1795 { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum, 1796 "Specify the breakpoint by source location at this particular line."}, 1797 1798 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 1799 }; 1800 1801 //------------------------------------------------------------------------- 1802 // CommandObjectBreakpointDelete 1803 //------------------------------------------------------------------------- 1804 #pragma mark Delete 1805 1806 class CommandObjectBreakpointDelete : public CommandObjectParsed 1807 { 1808 public: 1809 CommandObjectBreakpointDelete (CommandInterpreter &interpreter) : 1810 CommandObjectParsed (interpreter, 1811 "breakpoint delete", 1812 "Delete the specified breakpoint(s). If no breakpoints are specified, delete them all.", 1813 NULL), 1814 m_options (interpreter) 1815 { 1816 CommandArgumentEntry arg; 1817 CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange); 1818 // Add the entry for the first argument for this command to the object's arguments vector. 1819 m_arguments.push_back (arg); 1820 } 1821 1822 ~CommandObjectBreakpointDelete () override {} 1823 1824 Options * 1825 GetOptions () override 1826 { 1827 return &m_options; 1828 } 1829 1830 class CommandOptions : public Options 1831 { 1832 public: 1833 1834 CommandOptions (CommandInterpreter &interpreter) : 1835 Options (interpreter), 1836 m_use_dummy (false), 1837 m_force (false) 1838 { 1839 } 1840 1841 ~CommandOptions () override {} 1842 1843 Error 1844 SetOptionValue (uint32_t option_idx, const char *option_arg) override 1845 { 1846 Error error; 1847 const int short_option = m_getopt_table[option_idx].val; 1848 1849 switch (short_option) 1850 { 1851 case 'f': 1852 m_force = true; 1853 break; 1854 1855 case 'D': 1856 m_use_dummy = true; 1857 break; 1858 1859 default: 1860 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 1861 break; 1862 } 1863 1864 return error; 1865 } 1866 1867 void 1868 OptionParsingStarting () override 1869 { 1870 m_use_dummy = false; 1871 m_force = false; 1872 } 1873 1874 const OptionDefinition* 1875 GetDefinitions () override 1876 { 1877 return g_option_table; 1878 } 1879 1880 // Options table: Required for subclasses of Options. 1881 1882 static OptionDefinition g_option_table[]; 1883 1884 // Instance variables to hold the values for command options. 1885 bool m_use_dummy; 1886 bool m_force; 1887 }; 1888 1889 protected: 1890 bool 1891 DoExecute (Args& command, CommandReturnObject &result) override 1892 { 1893 Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy); 1894 1895 if (target == NULL) 1896 { 1897 result.AppendError ("Invalid target. No existing target or breakpoints."); 1898 result.SetStatus (eReturnStatusFailed); 1899 return false; 1900 } 1901 1902 Mutex::Locker locker; 1903 target->GetBreakpointList().GetListMutex(locker); 1904 1905 const BreakpointList &breakpoints = target->GetBreakpointList(); 1906 1907 size_t num_breakpoints = breakpoints.GetSize(); 1908 1909 if (num_breakpoints == 0) 1910 { 1911 result.AppendError ("No breakpoints exist to be deleted."); 1912 result.SetStatus (eReturnStatusFailed); 1913 return false; 1914 } 1915 1916 if (command.GetArgumentCount() == 0) 1917 { 1918 if (!m_options.m_force && !m_interpreter.Confirm ("About to delete all breakpoints, do you want to do that?", true)) 1919 { 1920 result.AppendMessage("Operation cancelled..."); 1921 } 1922 else 1923 { 1924 target->RemoveAllBreakpoints (); 1925 result.AppendMessageWithFormat ("All breakpoints removed. (%" PRIu64 " breakpoint%s)\n", (uint64_t)num_breakpoints, num_breakpoints > 1 ? "s" : ""); 1926 } 1927 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1928 } 1929 else 1930 { 1931 // Particular breakpoint selected; disable that breakpoint. 1932 BreakpointIDList valid_bp_ids; 1933 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids); 1934 1935 if (result.Succeeded()) 1936 { 1937 int delete_count = 0; 1938 int disable_count = 0; 1939 const size_t count = valid_bp_ids.GetSize(); 1940 for (size_t i = 0; i < count; ++i) 1941 { 1942 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i); 1943 1944 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) 1945 { 1946 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) 1947 { 1948 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 1949 BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get(); 1950 // It makes no sense to try to delete individual locations, so we disable them instead. 1951 if (location) 1952 { 1953 location->SetEnabled (false); 1954 ++disable_count; 1955 } 1956 } 1957 else 1958 { 1959 target->RemoveBreakpointByID (cur_bp_id.GetBreakpointID()); 1960 ++delete_count; 1961 } 1962 } 1963 } 1964 result.AppendMessageWithFormat ("%d breakpoints deleted; %d breakpoint locations disabled.\n", 1965 delete_count, disable_count); 1966 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1967 } 1968 } 1969 return result.Succeeded(); 1970 } 1971 private: 1972 CommandOptions m_options; 1973 }; 1974 1975 OptionDefinition 1976 CommandObjectBreakpointDelete::CommandOptions::g_option_table[] = 1977 { 1978 { LLDB_OPT_SET_1, false, "force", 'f', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, 1979 "Delete all breakpoints without querying for confirmation."}, 1980 1981 { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, 1982 "Delete Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."}, 1983 1984 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 1985 }; 1986 1987 //------------------------------------------------------------------------- 1988 // CommandObjectBreakpointName 1989 //------------------------------------------------------------------------- 1990 1991 static OptionDefinition 1992 g_breakpoint_name_options[] = 1993 { 1994 { LLDB_OPT_SET_1, false, "name", 'N', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBreakpointName, "Specifies a breakpoint name to use."}, 1995 { LLDB_OPT_SET_2, false, "breakpoint-id", 'B', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBreakpointID, "Specify a breakpoint id to use."}, 1996 { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, 1997 "Operate on Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."}, 1998 }; 1999 class BreakpointNameOptionGroup : public OptionGroup 2000 { 2001 public: 2002 BreakpointNameOptionGroup() : 2003 OptionGroup(), 2004 m_breakpoint(LLDB_INVALID_BREAK_ID), 2005 m_use_dummy (false) 2006 { 2007 2008 } 2009 2010 ~BreakpointNameOptionGroup () override 2011 { 2012 } 2013 2014 uint32_t 2015 GetNumDefinitions () override 2016 { 2017 return sizeof (g_breakpoint_name_options) / sizeof (OptionDefinition); 2018 } 2019 2020 const OptionDefinition* 2021 GetDefinitions () override 2022 { 2023 return g_breakpoint_name_options; 2024 } 2025 2026 Error 2027 SetOptionValue (CommandInterpreter &interpreter, 2028 uint32_t option_idx, 2029 const char *option_value) override 2030 { 2031 Error error; 2032 const int short_option = g_breakpoint_name_options[option_idx].short_option; 2033 2034 switch (short_option) 2035 { 2036 case 'N': 2037 if (BreakpointID::StringIsBreakpointName(option_value, error) && error.Success()) 2038 m_name.SetValueFromString(option_value); 2039 break; 2040 2041 case 'B': 2042 if (m_breakpoint.SetValueFromString(option_value).Fail()) 2043 error.SetErrorStringWithFormat ("unrecognized value \"%s\" for breakpoint", option_value); 2044 break; 2045 case 'D': 2046 if (m_use_dummy.SetValueFromString(option_value).Fail()) 2047 error.SetErrorStringWithFormat ("unrecognized value \"%s\" for use-dummy", option_value); 2048 break; 2049 2050 default: 2051 error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option); 2052 break; 2053 } 2054 return error; 2055 } 2056 2057 void 2058 OptionParsingStarting (CommandInterpreter &interpreter) override 2059 { 2060 m_name.Clear(); 2061 m_breakpoint.Clear(); 2062 m_use_dummy.Clear(); 2063 m_use_dummy.SetDefaultValue(false); 2064 } 2065 2066 OptionValueString m_name; 2067 OptionValueUInt64 m_breakpoint; 2068 OptionValueBoolean m_use_dummy; 2069 }; 2070 2071 2072 class CommandObjectBreakpointNameAdd : public CommandObjectParsed 2073 { 2074 public: 2075 CommandObjectBreakpointNameAdd (CommandInterpreter &interpreter) : 2076 CommandObjectParsed (interpreter, 2077 "add", 2078 "Add a name to the breakpoints provided.", 2079 "breakpoint name add <command-options> <breakpoint-id-list>"), 2080 m_name_options(), 2081 m_option_group(interpreter) 2082 { 2083 // Create the first variant for the first (and only) argument for this command. 2084 CommandArgumentEntry arg1; 2085 CommandArgumentData id_arg; 2086 id_arg.arg_type = eArgTypeBreakpointID; 2087 id_arg.arg_repetition = eArgRepeatOptional; 2088 arg1.push_back(id_arg); 2089 m_arguments.push_back (arg1); 2090 2091 m_option_group.Append (&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL); 2092 m_option_group.Finalize(); 2093 } 2094 2095 ~CommandObjectBreakpointNameAdd () override {} 2096 2097 Options * 2098 GetOptions () override 2099 { 2100 return &m_option_group; 2101 } 2102 2103 protected: 2104 bool 2105 DoExecute (Args& command, CommandReturnObject &result) override 2106 { 2107 if (!m_name_options.m_name.OptionWasSet()) 2108 { 2109 result.SetError("No name option provided."); 2110 return false; 2111 } 2112 2113 Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue()); 2114 2115 if (target == NULL) 2116 { 2117 result.AppendError ("Invalid target. No existing target or breakpoints."); 2118 result.SetStatus (eReturnStatusFailed); 2119 return false; 2120 } 2121 2122 Mutex::Locker locker; 2123 target->GetBreakpointList().GetListMutex(locker); 2124 2125 const BreakpointList &breakpoints = target->GetBreakpointList(); 2126 2127 size_t num_breakpoints = breakpoints.GetSize(); 2128 if (num_breakpoints == 0) 2129 { 2130 result.SetError("No breakpoints, cannot add names."); 2131 result.SetStatus (eReturnStatusFailed); 2132 return false; 2133 } 2134 2135 // Particular breakpoint selected; disable that breakpoint. 2136 BreakpointIDList valid_bp_ids; 2137 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids); 2138 2139 if (result.Succeeded()) 2140 { 2141 if (valid_bp_ids.GetSize() == 0) 2142 { 2143 result.SetError("No breakpoints specified, cannot add names."); 2144 result.SetStatus (eReturnStatusFailed); 2145 return false; 2146 } 2147 size_t num_valid_ids = valid_bp_ids.GetSize(); 2148 for (size_t index = 0; index < num_valid_ids; index++) 2149 { 2150 lldb::break_id_t bp_id = valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID(); 2151 BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id); 2152 Error error; // We don't need to check the error here, since the option parser checked it... 2153 bp_sp->AddName(m_name_options.m_name.GetCurrentValue(), error); 2154 } 2155 } 2156 2157 return true; 2158 } 2159 2160 private: 2161 BreakpointNameOptionGroup m_name_options; 2162 OptionGroupOptions m_option_group; 2163 }; 2164 2165 2166 2167 class CommandObjectBreakpointNameDelete : public CommandObjectParsed 2168 { 2169 public: 2170 CommandObjectBreakpointNameDelete (CommandInterpreter &interpreter) : 2171 CommandObjectParsed (interpreter, 2172 "delete", 2173 "Delete a name from the breakpoints provided.", 2174 "breakpoint name delete <command-options> <breakpoint-id-list>"), 2175 m_name_options(), 2176 m_option_group(interpreter) 2177 { 2178 // Create the first variant for the first (and only) argument for this command. 2179 CommandArgumentEntry arg1; 2180 CommandArgumentData id_arg; 2181 id_arg.arg_type = eArgTypeBreakpointID; 2182 id_arg.arg_repetition = eArgRepeatOptional; 2183 arg1.push_back(id_arg); 2184 m_arguments.push_back (arg1); 2185 2186 m_option_group.Append (&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL); 2187 m_option_group.Finalize(); 2188 } 2189 2190 ~CommandObjectBreakpointNameDelete () override {} 2191 2192 Options * 2193 GetOptions () override 2194 { 2195 return &m_option_group; 2196 } 2197 2198 protected: 2199 bool 2200 DoExecute (Args& command, CommandReturnObject &result) override 2201 { 2202 if (!m_name_options.m_name.OptionWasSet()) 2203 { 2204 result.SetError("No name option provided."); 2205 return false; 2206 } 2207 2208 Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue()); 2209 2210 if (target == NULL) 2211 { 2212 result.AppendError ("Invalid target. No existing target or breakpoints."); 2213 result.SetStatus (eReturnStatusFailed); 2214 return false; 2215 } 2216 2217 Mutex::Locker locker; 2218 target->GetBreakpointList().GetListMutex(locker); 2219 2220 const BreakpointList &breakpoints = target->GetBreakpointList(); 2221 2222 size_t num_breakpoints = breakpoints.GetSize(); 2223 if (num_breakpoints == 0) 2224 { 2225 result.SetError("No breakpoints, cannot delete names."); 2226 result.SetStatus (eReturnStatusFailed); 2227 return false; 2228 } 2229 2230 // Particular breakpoint selected; disable that breakpoint. 2231 BreakpointIDList valid_bp_ids; 2232 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids); 2233 2234 if (result.Succeeded()) 2235 { 2236 if (valid_bp_ids.GetSize() == 0) 2237 { 2238 result.SetError("No breakpoints specified, cannot delete names."); 2239 result.SetStatus (eReturnStatusFailed); 2240 return false; 2241 } 2242 size_t num_valid_ids = valid_bp_ids.GetSize(); 2243 for (size_t index = 0; index < num_valid_ids; index++) 2244 { 2245 lldb::break_id_t bp_id = valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID(); 2246 BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id); 2247 bp_sp->RemoveName(m_name_options.m_name.GetCurrentValue()); 2248 } 2249 } 2250 2251 return true; 2252 } 2253 2254 private: 2255 BreakpointNameOptionGroup m_name_options; 2256 OptionGroupOptions m_option_group; 2257 }; 2258 2259 class CommandObjectBreakpointNameList : public CommandObjectParsed 2260 { 2261 public: 2262 CommandObjectBreakpointNameList (CommandInterpreter &interpreter) : 2263 CommandObjectParsed (interpreter, 2264 "list", 2265 "List either the names for a breakpoint or the breakpoints for a given name.", 2266 "breakpoint name list <command-options>"), 2267 m_name_options(), 2268 m_option_group(interpreter) 2269 { 2270 m_option_group.Append (&m_name_options); 2271 m_option_group.Finalize(); 2272 } 2273 2274 ~CommandObjectBreakpointNameList () override {} 2275 2276 Options * 2277 GetOptions () override 2278 { 2279 return &m_option_group; 2280 } 2281 2282 protected: 2283 bool 2284 DoExecute (Args& command, CommandReturnObject &result) override 2285 { 2286 Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue()); 2287 2288 if (target == NULL) 2289 { 2290 result.AppendError ("Invalid target. No existing target or breakpoints."); 2291 result.SetStatus (eReturnStatusFailed); 2292 return false; 2293 } 2294 2295 if (m_name_options.m_name.OptionWasSet()) 2296 { 2297 const char *name = m_name_options.m_name.GetCurrentValue(); 2298 Mutex::Locker locker; 2299 target->GetBreakpointList().GetListMutex(locker); 2300 2301 BreakpointList &breakpoints = target->GetBreakpointList(); 2302 for (BreakpointSP bp_sp : breakpoints.Breakpoints()) 2303 { 2304 if (bp_sp->MatchesName(name)) 2305 { 2306 StreamString s; 2307 bp_sp->GetDescription(&s, eDescriptionLevelBrief); 2308 s.EOL(); 2309 result.AppendMessage(s.GetData()); 2310 } 2311 } 2312 2313 } 2314 else if (m_name_options.m_breakpoint.OptionWasSet()) 2315 { 2316 BreakpointSP bp_sp = target->GetBreakpointList().FindBreakpointByID(m_name_options.m_breakpoint.GetCurrentValue()); 2317 if (bp_sp) 2318 { 2319 std::vector<std::string> names; 2320 bp_sp->GetNames (names); 2321 result.AppendMessage ("Names:"); 2322 for (auto name : names) 2323 result.AppendMessageWithFormat (" %s\n", name.c_str()); 2324 } 2325 else 2326 { 2327 result.AppendErrorWithFormat ("Could not find breakpoint %" PRId64 ".\n", 2328 m_name_options.m_breakpoint.GetCurrentValue()); 2329 result.SetStatus (eReturnStatusFailed); 2330 return false; 2331 } 2332 } 2333 else 2334 { 2335 result.SetError ("Must specify -N or -B option to list."); 2336 result.SetStatus (eReturnStatusFailed); 2337 return false; 2338 } 2339 return true; 2340 } 2341 2342 private: 2343 BreakpointNameOptionGroup m_name_options; 2344 OptionGroupOptions m_option_group; 2345 }; 2346 2347 //------------------------------------------------------------------------- 2348 // CommandObjectMultiwordBreakpoint 2349 //------------------------------------------------------------------------- 2350 class CommandObjectBreakpointName : public CommandObjectMultiword 2351 { 2352 public: 2353 CommandObjectBreakpointName (CommandInterpreter &interpreter) : 2354 CommandObjectMultiword(interpreter, 2355 "name", 2356 "A set of commands to manage name tags for breakpoints", 2357 "breakpoint name <command> [<command-options>]") 2358 { 2359 CommandObjectSP add_command_object (new CommandObjectBreakpointNameAdd (interpreter)); 2360 CommandObjectSP delete_command_object (new CommandObjectBreakpointNameDelete (interpreter)); 2361 CommandObjectSP list_command_object (new CommandObjectBreakpointNameList (interpreter)); 2362 2363 LoadSubCommand ("add", add_command_object); 2364 LoadSubCommand ("delete", delete_command_object); 2365 LoadSubCommand ("list", list_command_object); 2366 2367 } 2368 2369 ~CommandObjectBreakpointName () override 2370 { 2371 } 2372 2373 }; 2374 2375 2376 //------------------------------------------------------------------------- 2377 // CommandObjectMultiwordBreakpoint 2378 //------------------------------------------------------------------------- 2379 #pragma mark MultiwordBreakpoint 2380 2381 CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint (CommandInterpreter &interpreter) : 2382 CommandObjectMultiword (interpreter, 2383 "breakpoint", 2384 "A set of commands for operating on breakpoints. Also see _regexp-break.", 2385 "breakpoint <command> [<command-options>]") 2386 { 2387 CommandObjectSP list_command_object (new CommandObjectBreakpointList (interpreter)); 2388 CommandObjectSP enable_command_object (new CommandObjectBreakpointEnable (interpreter)); 2389 CommandObjectSP disable_command_object (new CommandObjectBreakpointDisable (interpreter)); 2390 CommandObjectSP clear_command_object (new CommandObjectBreakpointClear (interpreter)); 2391 CommandObjectSP delete_command_object (new CommandObjectBreakpointDelete (interpreter)); 2392 CommandObjectSP set_command_object (new CommandObjectBreakpointSet (interpreter)); 2393 CommandObjectSP command_command_object (new CommandObjectBreakpointCommand (interpreter)); 2394 CommandObjectSP modify_command_object (new CommandObjectBreakpointModify(interpreter)); 2395 CommandObjectSP name_command_object (new CommandObjectBreakpointName(interpreter)); 2396 2397 list_command_object->SetCommandName ("breakpoint list"); 2398 enable_command_object->SetCommandName("breakpoint enable"); 2399 disable_command_object->SetCommandName("breakpoint disable"); 2400 clear_command_object->SetCommandName("breakpoint clear"); 2401 delete_command_object->SetCommandName("breakpoint delete"); 2402 set_command_object->SetCommandName("breakpoint set"); 2403 command_command_object->SetCommandName ("breakpoint command"); 2404 modify_command_object->SetCommandName ("breakpoint modify"); 2405 name_command_object->SetCommandName ("breakpoint name"); 2406 2407 LoadSubCommand ("list", list_command_object); 2408 LoadSubCommand ("enable", enable_command_object); 2409 LoadSubCommand ("disable", disable_command_object); 2410 LoadSubCommand ("clear", clear_command_object); 2411 LoadSubCommand ("delete", delete_command_object); 2412 LoadSubCommand ("set", set_command_object); 2413 LoadSubCommand ("command", command_command_object); 2414 LoadSubCommand ("modify", modify_command_object); 2415 LoadSubCommand ("name", name_command_object); 2416 } 2417 2418 CommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint () 2419 { 2420 } 2421 2422 void 2423 CommandObjectMultiwordBreakpoint::VerifyIDs (Args &args, 2424 Target *target, 2425 bool allow_locations, 2426 CommandReturnObject &result, 2427 BreakpointIDList *valid_ids) 2428 { 2429 // args can be strings representing 1). integers (for breakpoint ids) 2430 // 2). the full breakpoint & location canonical representation 2431 // 3). the word "to" or a hyphen, representing a range (in which case there 2432 // had *better* be an entry both before & after of one of the first two types. 2433 // 4). A breakpoint name 2434 // If args is empty, we will use the last created breakpoint (if there is one.) 2435 2436 Args temp_args; 2437 2438 if (args.GetArgumentCount() == 0) 2439 { 2440 if (target->GetLastCreatedBreakpoint()) 2441 { 2442 valid_ids->AddBreakpointID (BreakpointID(target->GetLastCreatedBreakpoint()->GetID(), LLDB_INVALID_BREAK_ID)); 2443 result.SetStatus (eReturnStatusSuccessFinishNoResult); 2444 } 2445 else 2446 { 2447 result.AppendError("No breakpoint specified and no last created breakpoint."); 2448 result.SetStatus (eReturnStatusFailed); 2449 } 2450 return; 2451 } 2452 2453 // Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff directly from the old ARGS to 2454 // the new TEMP_ARGS. Do not copy breakpoint id range strings over; instead generate a list of strings for 2455 // all the breakpoint ids in the range, and shove all of those breakpoint id strings into TEMP_ARGS. 2456 2457 BreakpointIDList::FindAndReplaceIDRanges (args, target, allow_locations, result, temp_args); 2458 2459 // NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual BreakpointIDList: 2460 2461 valid_ids->InsertStringArray (temp_args.GetConstArgumentVector(), temp_args.GetArgumentCount(), result); 2462 2463 // At this point, all of the breakpoint ids that the user passed in have been converted to breakpoint IDs 2464 // and put into valid_ids. 2465 2466 if (result.Succeeded()) 2467 { 2468 // Now that we've converted everything from args into a list of breakpoint ids, go through our tentative list 2469 // of breakpoint id's and verify that they correspond to valid/currently set breakpoints. 2470 2471 const size_t count = valid_ids->GetSize(); 2472 for (size_t i = 0; i < count; ++i) 2473 { 2474 BreakpointID cur_bp_id = valid_ids->GetBreakpointIDAtIndex (i); 2475 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); 2476 if (breakpoint != NULL) 2477 { 2478 const size_t num_locations = breakpoint->GetNumLocations(); 2479 if (static_cast<size_t>(cur_bp_id.GetLocationID()) > num_locations) 2480 { 2481 StreamString id_str; 2482 BreakpointID::GetCanonicalReference (&id_str, 2483 cur_bp_id.GetBreakpointID(), 2484 cur_bp_id.GetLocationID()); 2485 i = valid_ids->GetSize() + 1; 2486 result.AppendErrorWithFormat ("'%s' is not a currently valid breakpoint/location id.\n", 2487 id_str.GetData()); 2488 result.SetStatus (eReturnStatusFailed); 2489 } 2490 } 2491 else 2492 { 2493 i = valid_ids->GetSize() + 1; 2494 result.AppendErrorWithFormat ("'%d' is not a currently valid breakpoint id.\n", cur_bp_id.GetBreakpointID()); 2495 result.SetStatus (eReturnStatusFailed); 2496 } 2497 } 2498 } 2499 } 2500