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