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