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