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