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