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