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