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