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