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