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