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