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