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