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