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