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