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