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