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