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