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