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