]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Commands/CommandObjectBreakpoint.cpp
Update LLDB snapshot to upstream r225923 (git 2b588ecd)
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Commands / CommandObjectBreakpoint.cpp
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/Interpreter/OptionValueString.h"
24 #include "lldb/Interpreter/OptionValueUInt64.h"
25 #include "lldb/Core/RegularExpression.h"
26 #include "lldb/Core/StreamString.h"
27 #include "lldb/Interpreter/CommandInterpreter.h"
28 #include "lldb/Interpreter/CommandReturnObject.h"
29 #include "lldb/Target/Target.h"
30 #include "lldb/Interpreter/CommandCompletions.h"
31 #include "lldb/Target/StackFrame.h"
32 #include "lldb/Target/Thread.h"
33 #include "lldb/Target/ThreadSpec.h"
34
35 #include <vector>
36
37 using namespace lldb;
38 using namespace lldb_private;
39
40 static void
41 AddBreakpointDescription (Stream *s, Breakpoint *bp, lldb::DescriptionLevel level)
42 {
43     s->IndentMore();
44     bp->GetDescription (s, level, true);
45     s->IndentLess();
46     s->EOL();
47 }
48
49 //-------------------------------------------------------------------------
50 // CommandObjectBreakpointSet
51 //-------------------------------------------------------------------------
52
53
54 class CommandObjectBreakpointSet : public CommandObjectParsed
55 {
56 public:
57
58     typedef enum BreakpointSetType
59     {
60         eSetTypeInvalid,
61         eSetTypeFileAndLine,
62         eSetTypeAddress,
63         eSetTypeFunctionName,
64         eSetTypeFunctionRegexp,
65         eSetTypeSourceRegexp,
66         eSetTypeException
67     } BreakpointSetType;
68
69     CommandObjectBreakpointSet (CommandInterpreter &interpreter) :
70         CommandObjectParsed (interpreter,
71                              "breakpoint set", 
72                              "Sets a breakpoint or set of breakpoints in the executable.", 
73                              "breakpoint set <cmd-options>"),
74         m_options (interpreter)
75     {
76     }
77
78
79     virtual
80     ~CommandObjectBreakpointSet () {}
81
82     virtual Options *
83     GetOptions ()
84     {
85         return &m_options;
86     }
87
88     class CommandOptions : public Options
89     {
90     public:
91
92         CommandOptions (CommandInterpreter &interpreter) :
93             Options (interpreter),
94             m_condition (),
95             m_filenames (),
96             m_line_num (0),
97             m_column (0),
98             m_func_names (),
99             m_func_name_type_mask (eFunctionNameTypeNone),
100             m_func_regexp (),
101             m_source_text_regexp(),
102             m_modules (),
103             m_load_addr(),
104             m_ignore_count (0),
105             m_thread_id(LLDB_INVALID_THREAD_ID),
106             m_thread_index (UINT32_MAX),
107             m_thread_name(),
108             m_queue_name(),
109             m_catch_bp (false),
110             m_throw_bp (true),
111             m_hardware (false),
112             m_language (eLanguageTypeUnknown),
113             m_skip_prologue (eLazyBoolCalculate),
114             m_one_shot (false)
115         {
116         }
117
118
119         virtual
120         ~CommandOptions () {}
121
122         virtual Error
123         SetOptionValue (uint32_t option_idx, const char *option_arg)
124         {
125             Error error;
126             const int short_option = m_getopt_table[option_idx].val;
127
128             switch (short_option)
129             {
130                 case 'a':
131                     {
132                         ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
133                         m_load_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
134                     }
135                     break;
136
137                 case 'b':
138                     m_func_names.push_back (option_arg);
139                     m_func_name_type_mask |= eFunctionNameTypeBase;
140                     break;
141
142                 case 'C':
143                     m_column = Args::StringToUInt32 (option_arg, 0);
144                     break;
145
146                 case 'c':
147                     m_condition.assign(option_arg);
148                     break;
149
150                 case 'D':
151                     m_use_dummy = true;
152                     break;
153
154                 case 'E':
155                 {
156                     LanguageType language = LanguageRuntime::GetLanguageTypeFromString (option_arg);
157
158                     switch (language)
159                     {
160                         case eLanguageTypeC89:
161                         case eLanguageTypeC:
162                         case eLanguageTypeC99:
163                         case eLanguageTypeC11:
164                             m_language = eLanguageTypeC;
165                             break;
166                         case eLanguageTypeC_plus_plus:
167                         case eLanguageTypeC_plus_plus_03:
168                         case eLanguageTypeC_plus_plus_11:
169                             m_language = eLanguageTypeC_plus_plus;
170                             break;
171                         case eLanguageTypeObjC:
172                             m_language = eLanguageTypeObjC;
173                             break;
174                         case eLanguageTypeObjC_plus_plus:
175                             error.SetErrorStringWithFormat ("Set exception breakpoints separately for c++ and objective-c");
176                             break;
177                         case eLanguageTypeUnknown:
178                             error.SetErrorStringWithFormat ("Unknown language type: '%s' for exception breakpoint", option_arg);
179                             break;
180                         default:
181                             error.SetErrorStringWithFormat ("Unsupported language type: '%s' for exception breakpoint", option_arg);
182                     }
183                 }
184                 break;
185
186                 case 'f':
187                     m_filenames.AppendIfUnique (FileSpec(option_arg, false));
188                     break;
189
190                 case 'F':
191                     m_func_names.push_back (option_arg);
192                     m_func_name_type_mask |= eFunctionNameTypeFull;
193                     break;
194
195                 case 'h':
196                     {
197                         bool success;
198                         m_catch_bp = Args::StringToBoolean (option_arg, true, &success);
199                         if (!success)
200                             error.SetErrorStringWithFormat ("Invalid boolean value for on-catch option: '%s'", option_arg);
201                     }
202                     break;
203
204                 case 'H':
205                     m_hardware = true;
206                     break;
207
208                 case 'i':
209                 {
210                     m_ignore_count = Args::StringToUInt32(option_arg, UINT32_MAX, 0);
211                     if (m_ignore_count == UINT32_MAX)
212                        error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
213                     break;
214                 }
215
216                 case 'K':
217                 {
218                     bool success;
219                     bool value;
220                     value = Args::StringToBoolean (option_arg, true, &success);
221                     if (value)
222                         m_skip_prologue = eLazyBoolYes;
223                     else
224                         m_skip_prologue = eLazyBoolNo;
225                         
226                     if (!success)
227                         error.SetErrorStringWithFormat ("Invalid boolean value for skip prologue option: '%s'", option_arg);
228                 }
229                 break;
230
231                 case 'l':
232                     m_line_num = Args::StringToUInt32 (option_arg, 0);
233                     break;
234
235                 case 'M':
236                     m_func_names.push_back (option_arg);
237                     m_func_name_type_mask |= eFunctionNameTypeMethod;
238                     break;
239
240                 case 'n':
241                     m_func_names.push_back (option_arg);
242                     m_func_name_type_mask |= eFunctionNameTypeAuto;
243                     break;
244
245                 case 'N':
246                     if (BreakpointID::StringIsBreakpointName(option_arg, error))
247                         m_breakpoint_names.push_back (option_arg);
248                     break;
249
250                 case 'o':
251                     m_one_shot = true;
252                     break;
253
254                 case 'p':
255                     m_source_text_regexp.assign (option_arg);
256                     break;
257                     
258                 case 'q':
259                     m_queue_name.assign (option_arg);
260                     break;
261
262                 case 'r':
263                     m_func_regexp.assign (option_arg);
264                     break;
265
266                 case 's':
267                 {
268                     m_modules.AppendIfUnique (FileSpec (option_arg, false));
269                     break;
270                 }
271                     
272                 case 'S':
273                     m_func_names.push_back (option_arg);
274                     m_func_name_type_mask |= eFunctionNameTypeSelector;
275                     break;
276
277                 case 't' :
278                 {
279                     m_thread_id = Args::StringToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
280                     if (m_thread_id == LLDB_INVALID_THREAD_ID)
281                        error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
282                 }
283                 break;
284
285                 case 'T':
286                     m_thread_name.assign (option_arg);
287                     break;
288
289                 case 'w':
290                 {
291                     bool success;
292                     m_throw_bp = Args::StringToBoolean (option_arg, true, &success);
293                     if (!success)
294                         error.SetErrorStringWithFormat ("Invalid boolean value for on-throw option: '%s'", option_arg);
295                 }
296                 break;
297
298                 case 'x':
299                 {
300                     m_thread_index = Args::StringToUInt32(option_arg, UINT32_MAX, 0);
301                     if (m_thread_id == UINT32_MAX)
302                        error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
303                     
304                 }
305                 break;
306
307                 default:
308                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
309                     break;
310             }
311
312             return error;
313         }
314         void
315         OptionParsingStarting ()
316         {
317             m_condition.clear();
318             m_filenames.Clear();
319             m_line_num = 0;
320             m_column = 0;
321             m_func_names.clear();
322             m_func_name_type_mask = eFunctionNameTypeNone;
323             m_func_regexp.clear();
324             m_source_text_regexp.clear();
325             m_modules.Clear();
326             m_load_addr = LLDB_INVALID_ADDRESS;
327             m_ignore_count = 0;
328             m_thread_id = LLDB_INVALID_THREAD_ID;
329             m_thread_index = UINT32_MAX;
330             m_thread_name.clear();
331             m_queue_name.clear();
332             m_catch_bp = false;
333             m_throw_bp = true;
334             m_hardware = false;
335             m_language = eLanguageTypeUnknown;
336             m_skip_prologue = eLazyBoolCalculate;
337             m_one_shot = false;
338             m_use_dummy = false;
339             m_breakpoint_names.clear();
340         }
341     
342         const OptionDefinition*
343         GetDefinitions ()
344         {
345             return g_option_table;
346         }
347
348         // Options table: Required for subclasses of Options.
349
350         static OptionDefinition g_option_table[];
351
352         // Instance variables to hold the values for command options.
353
354         std::string m_condition;
355         FileSpecList m_filenames;
356         uint32_t m_line_num;
357         uint32_t m_column;
358         std::vector<std::string> m_func_names;
359         std::vector<std::string> m_breakpoint_names;
360         uint32_t m_func_name_type_mask;
361         std::string m_func_regexp;
362         std::string m_source_text_regexp;
363         FileSpecList m_modules;
364         lldb::addr_t m_load_addr;
365         uint32_t m_ignore_count;
366         lldb::tid_t m_thread_id;
367         uint32_t m_thread_index;
368         std::string m_thread_name;
369         std::string m_queue_name;
370         bool m_catch_bp;
371         bool m_throw_bp;
372         bool m_hardware; // Request to use hardware breakpoints
373         lldb::LanguageType m_language;
374         LazyBool m_skip_prologue;
375         bool m_one_shot;
376         bool m_use_dummy;
377
378     };
379
380 protected:
381     virtual bool
382     DoExecute (Args& command,
383               CommandReturnObject &result)
384     {
385         Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
386
387         if (target == nullptr)
388         {
389             result.AppendError ("Invalid target.  Must set target before setting breakpoints (see 'target create' command).");
390             result.SetStatus (eReturnStatusFailed);
391             return false;
392         }
393
394         // The following are the various types of breakpoints that could be set:
395         //   1).  -f -l -p  [-s -g]   (setting breakpoint by source location)
396         //   2).  -a  [-s -g]         (setting breakpoint by address)
397         //   3).  -n  [-s -g]         (setting breakpoint by function name)
398         //   4).  -r  [-s -g]         (setting breakpoint by function name regular expression)
399         //   5).  -p -f               (setting a breakpoint by comparing a reg-exp to source text)
400         //   6).  -E [-w -h]          (setting a breakpoint for exceptions for a given language.)
401
402         BreakpointSetType break_type = eSetTypeInvalid;
403
404         if (m_options.m_line_num != 0)
405             break_type = eSetTypeFileAndLine;
406         else if (m_options.m_load_addr != LLDB_INVALID_ADDRESS)
407             break_type = eSetTypeAddress;
408         else if (!m_options.m_func_names.empty())
409             break_type = eSetTypeFunctionName;
410         else if  (!m_options.m_func_regexp.empty())
411             break_type = eSetTypeFunctionRegexp;
412         else if (!m_options.m_source_text_regexp.empty())
413             break_type = eSetTypeSourceRegexp;
414         else if (m_options.m_language != eLanguageTypeUnknown)
415             break_type = eSetTypeException;
416
417         Breakpoint *bp = NULL;
418         FileSpec module_spec;
419         const bool internal = false;
420
421         switch (break_type)
422         {
423             case eSetTypeFileAndLine: // Breakpoint by source position
424                 {
425                     FileSpec file;
426                     const size_t num_files = m_options.m_filenames.GetSize();
427                     if (num_files == 0)
428                     {
429                         if (!GetDefaultFile (target, file, result))
430                         {
431                             result.AppendError("No file supplied and no default file available.");
432                             result.SetStatus (eReturnStatusFailed);
433                             return false;
434                         }
435                     }
436                     else if (num_files > 1)
437                     {
438                         result.AppendError("Only one file at a time is allowed for file and line breakpoints.");
439                         result.SetStatus (eReturnStatusFailed);
440                         return false;
441                     }
442                     else
443                         file = m_options.m_filenames.GetFileSpecAtIndex(0);
444                     
445                     // Only check for inline functions if 
446                     LazyBool check_inlines = eLazyBoolCalculate;
447                     
448                     bp = target->CreateBreakpoint (&(m_options.m_modules),
449                                                    file,
450                                                    m_options.m_line_num,
451                                                    check_inlines,
452                                                    m_options.m_skip_prologue,
453                                                    internal,
454                                                    m_options.m_hardware).get();
455                 }
456                 break;
457
458             case eSetTypeAddress: // Breakpoint by address
459                 bp = target->CreateBreakpoint (m_options.m_load_addr,
460                                                internal,
461                                                m_options.m_hardware).get();
462                 break;
463
464             case eSetTypeFunctionName: // Breakpoint by function name
465                 {
466                     uint32_t name_type_mask = m_options.m_func_name_type_mask;
467                     
468                     if (name_type_mask == 0)
469                         name_type_mask = eFunctionNameTypeAuto;
470                     
471                     bp = target->CreateBreakpoint (&(m_options.m_modules),
472                                                    &(m_options.m_filenames),
473                                                    m_options.m_func_names,
474                                                    name_type_mask,
475                                                    m_options.m_skip_prologue,
476                                                    internal,
477                                                    m_options.m_hardware).get();
478                 }
479                 break;
480
481             case eSetTypeFunctionRegexp: // Breakpoint by regular expression function name
482                 {
483                     RegularExpression regexp(m_options.m_func_regexp.c_str());
484                     if (!regexp.IsValid())
485                     {
486                         char err_str[1024];
487                         regexp.GetErrorAsCString(err_str, sizeof(err_str));
488                         result.AppendErrorWithFormat("Function name regular expression could not be compiled: \"%s\"",
489                                                      err_str);
490                         result.SetStatus (eReturnStatusFailed);
491                         return false;
492                     }
493                     
494                     bp = target->CreateFuncRegexBreakpoint (&(m_options.m_modules),
495                                                             &(m_options.m_filenames),
496                                                             regexp,
497                                                             m_options.m_skip_prologue,
498                                                             internal,
499                                                             m_options.m_hardware).get();
500                 }
501                 break;
502             case eSetTypeSourceRegexp: // Breakpoint by regexp on source text.
503                 {
504                     const size_t num_files = m_options.m_filenames.GetSize();
505                     
506                     if (num_files == 0)
507                     {
508                         FileSpec file;
509                         if (!GetDefaultFile (target, file, result))
510                         {
511                             result.AppendError ("No files provided and could not find default file.");
512                             result.SetStatus (eReturnStatusFailed);
513                             return false;
514                         }
515                         else
516                         {
517                             m_options.m_filenames.Append (file);
518                         }
519                     }
520                     
521                     RegularExpression regexp(m_options.m_source_text_regexp.c_str());
522                     if (!regexp.IsValid())
523                     {
524                         char err_str[1024];
525                         regexp.GetErrorAsCString(err_str, sizeof(err_str));
526                         result.AppendErrorWithFormat("Source text regular expression could not be compiled: \"%s\"",
527                                                      err_str);
528                         result.SetStatus (eReturnStatusFailed);
529                         return false;
530                     }
531                     bp = target->CreateSourceRegexBreakpoint (&(m_options.m_modules),
532                                                               &(m_options.m_filenames),
533                                                               regexp,
534                                                               internal,
535                                                               m_options.m_hardware).get();
536                 }
537                 break;
538             case eSetTypeException:
539                 {
540                     bp = target->CreateExceptionBreakpoint (m_options.m_language,
541                                                             m_options.m_catch_bp,
542                                                             m_options.m_throw_bp,
543                                                             m_options.m_hardware).get();
544                 }
545                 break;
546             default:
547                 break;
548         }
549
550         // Now set the various options that were passed in:
551         if (bp)
552         {
553             if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
554                 bp->SetThreadID (m_options.m_thread_id);
555                 
556             if (m_options.m_thread_index != UINT32_MAX)
557                 bp->GetOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index);
558             
559             if (!m_options.m_thread_name.empty())
560                 bp->GetOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str());
561             
562             if (!m_options.m_queue_name.empty())
563                 bp->GetOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str());
564                 
565             if (m_options.m_ignore_count != 0)
566                 bp->GetOptions()->SetIgnoreCount(m_options.m_ignore_count);
567
568             if (!m_options.m_condition.empty())
569                 bp->GetOptions()->SetCondition(m_options.m_condition.c_str());
570
571             if (!m_options.m_breakpoint_names.empty())
572             {
573                 Error error;  // We don't need to check the error here, since the option parser checked it...
574                 for (auto name : m_options.m_breakpoint_names)
575                     bp->AddName(name.c_str(), error);
576             }
577             
578             bp->SetOneShot (m_options.m_one_shot);
579         }
580         
581         if (bp)
582         {
583             Stream &output_stream = result.GetOutputStream();
584             const bool show_locations = false;
585             bp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial, show_locations);
586             if (target == m_interpreter.GetDebugger().GetDummyTarget())
587                     output_stream.Printf ("Breakpoint set in dummy target, will get copied into future targets.\n");
588             else
589             {
590                 // Don't print out this warning for exception breakpoints.  They can get set before the target
591                 // is set, but we won't know how to actually set the breakpoint till we run.
592                 if (bp->GetNumLocations() == 0 && break_type != eSetTypeException)
593                 {
594                     output_stream.Printf ("WARNING:  Unable to resolve breakpoint to any actual locations.\n");
595                 }
596             }
597             result.SetStatus (eReturnStatusSuccessFinishResult);
598         }
599         else if (!bp)
600         {
601             result.AppendError ("Breakpoint creation failed: No breakpoint created.");
602             result.SetStatus (eReturnStatusFailed);
603         }
604
605         return result.Succeeded();
606     }
607
608 private:
609     bool
610     GetDefaultFile (Target *target, FileSpec &file, CommandReturnObject &result)
611     {
612         uint32_t default_line;
613         // First use the Source Manager's default file. 
614         // Then use the current stack frame's file.
615         if (!target->GetSourceManager().GetDefaultFileAndLine(file, default_line))
616         {
617             StackFrame *cur_frame = m_exe_ctx.GetFramePtr();
618             if (cur_frame == NULL)
619             {
620                 result.AppendError ("No selected frame to use to find the default file.");
621                 result.SetStatus (eReturnStatusFailed);
622                 return false;
623             }
624             else if (!cur_frame->HasDebugInformation())
625             {
626                 result.AppendError ("Cannot use the selected frame to find the default file, it has no debug info.");
627                 result.SetStatus (eReturnStatusFailed);
628                 return false;
629             }
630             else
631             {
632                 const SymbolContext &sc = cur_frame->GetSymbolContext (eSymbolContextLineEntry);
633                 if (sc.line_entry.file)
634                 {
635                     file = sc.line_entry.file;
636                 }
637                 else
638                 {
639                     result.AppendError ("Can't find the file for the selected frame to use as the default file.");
640                     result.SetStatus (eReturnStatusFailed);
641                     return false;
642                 }
643             }
644         }
645         return true;
646     }
647     
648     CommandOptions m_options;
649 };
650 // If an additional option set beyond LLDB_OPTION_SET_10 is added, make sure to
651 // update the numbers passed to LLDB_OPT_SET_FROM_TO(...) appropriately.
652 #define LLDB_OPT_FILE ( LLDB_OPT_SET_FROM_TO(1, 9) & ~LLDB_OPT_SET_2 )
653 #define LLDB_OPT_NOT_10 ( LLDB_OPT_SET_FROM_TO(1, 10) & ~LLDB_OPT_SET_10 )
654 #define LLDB_OPT_SKIP_PROLOGUE ( LLDB_OPT_SET_1 | LLDB_OPT_SET_FROM_TO(3,8) )
655
656 OptionDefinition
657 CommandObjectBreakpointSet::CommandOptions::g_option_table[] =
658 {
659     { LLDB_OPT_NOT_10, false, "shlib", 's', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName,
660         "Set the breakpoint only in this shared library.  "
661         "Can repeat this option multiple times to specify multiple shared libraries."},
662
663     { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', OptionParser::eRequiredArgument,   NULL, NULL, 0, eArgTypeCount,
664         "Set the number of times this breakpoint is skipped before stopping." },
665
666     { LLDB_OPT_SET_ALL, false, "one-shot", 'o', OptionParser::eNoArgument,   NULL, NULL, 0, eArgTypeNone,
667         "The breakpoint is deleted the first time it causes a stop." },
668
669     { LLDB_OPT_SET_ALL, false, "condition",    'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeExpression,
670         "The breakpoint stops only if this condition expression evaluates to true."},
671
672     { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadIndex,
673         "The breakpoint stops only for the thread whose indeX matches this argument."},
674
675     { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadID,
676         "The breakpoint stops only for the thread whose TID matches this argument."},
677
678     { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadName,
679         "The breakpoint stops only for the thread whose thread name matches this argument."},
680
681     { LLDB_OPT_SET_ALL, false, "hardware", 'H', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
682         "Require the breakpoint to use hardware breakpoints."},
683
684     { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeQueueName,
685         "The breakpoint stops only for threads in the queue whose name is given by this argument."},
686
687     { LLDB_OPT_FILE, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
688         "Specifies the source file in which to set this breakpoint.  "
689         "Note, by default lldb only looks for files that are #included if they use the standard include file extensions.  "
690         "To set breakpoints on .c/.cpp/.m/.mm files that are #included, set target.inline-breakpoint-strategy"
691         " to \"always\"."},
692
693     { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum,
694         "Specifies the line number on which to set this breakpoint."},
695
696     // Comment out this option for the moment, as we don't actually use it, but will in the future.
697     // This way users won't see it, but the infrastructure is left in place.
698     //    { 0, false, "column",     'C', OptionParser::eRequiredArgument, NULL, "<column>",
699     //    "Set the breakpoint by source location at this particular column."},
700
701     { LLDB_OPT_SET_2, true, "address", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression,
702         "Set the breakpoint by address, at the specified address."},
703
704     { LLDB_OPT_SET_3, true, "name", 'n', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
705         "Set the breakpoint by function name.  Can be repeated multiple times to make one breakpoint for multiple names" },
706
707     { LLDB_OPT_SET_4, true, "fullname", 'F', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFullName,
708         "Set the breakpoint by fully qualified function names. For C++ this means namespaces and all arguments, and "
709         "for Objective C this means a full function prototype with class and selector.   "
710         "Can be repeated multiple times to make one breakpoint for multiple names." },
711
712     { LLDB_OPT_SET_5, true, "selector", 'S', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeSelector,
713         "Set the breakpoint by ObjC selector name. Can be repeated multiple times to make one breakpoint for multiple Selectors." },
714
715     { LLDB_OPT_SET_6, true, "method", 'M', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeMethod,
716         "Set the breakpoint by C++ method names.  Can be repeated multiple times to make one breakpoint for multiple methods." },
717
718     { LLDB_OPT_SET_7, true, "func-regex", 'r', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeRegularExpression,
719         "Set the breakpoint by function name, evaluating a regular-expression to find the function name(s)." },
720
721     { LLDB_OPT_SET_8, true, "basename", 'b', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
722         "Set the breakpoint by function basename (C++ namespaces and arguments will be ignored). "
723         "Can be repeated multiple times to make one breakpoint for multiple symbols." },
724
725     { LLDB_OPT_SET_9, true, "source-pattern-regexp", 'p', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeRegularExpression,
726         "Set the breakpoint by specifying a regular expression which is matched against the source text in a source file or files "
727         "specified with the -f option.  The -f option can be specified more than once.  "
728         "If no source files are specified, uses the current \"default source file\"" },
729
730     { LLDB_OPT_SET_10, true, "language-exception", 'E', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage,
731         "Set the breakpoint on exceptions thrown by the specified language (without options, on throw but not catch.)" },
732
733     { LLDB_OPT_SET_10, false, "on-throw", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,
734         "Set the breakpoint on exception throW." },
735
736     { LLDB_OPT_SET_10, false, "on-catch", 'h', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,
737         "Set the breakpoint on exception catcH." },
738
739     { LLDB_OPT_SKIP_PROLOGUE, false, "skip-prologue", 'K', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,
740         "sKip the prologue if the breakpoint is at the beginning of a function.  If not set the target.skip-prologue setting is used." },
741
742     { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
743         "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
744
745     { LLDB_OPT_SET_ALL, false, "breakpoint-name", 'N', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBreakpointName,
746         "Adds this to the list of names for this breakopint."},
747
748     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
749 };
750
751 //-------------------------------------------------------------------------
752 // CommandObjectBreakpointModify
753 //-------------------------------------------------------------------------
754 #pragma mark Modify
755
756 class CommandObjectBreakpointModify : public CommandObjectParsed
757 {
758 public:
759
760     CommandObjectBreakpointModify (CommandInterpreter &interpreter) :
761         CommandObjectParsed (interpreter,
762                              "breakpoint modify", 
763                              "Modify the options on a breakpoint or set of breakpoints in the executable.  "
764                              "If no breakpoint is specified, acts on the last created breakpoint.  "
765                              "With the exception of -e, -d and -i, passing an empty argument clears the modification.", 
766                              NULL),
767         m_options (interpreter)
768     {
769         CommandArgumentEntry arg;
770         CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
771         // Add the entry for the first argument for this command to the object's arguments vector.
772         m_arguments.push_back (arg);   
773     }
774
775
776     virtual
777     ~CommandObjectBreakpointModify () {}
778
779     virtual Options *
780     GetOptions ()
781     {
782         return &m_options;
783     }
784
785     class CommandOptions : public Options
786     {
787     public:
788
789         CommandOptions (CommandInterpreter &interpreter) :
790             Options (interpreter),
791             m_ignore_count (0),
792             m_thread_id(LLDB_INVALID_THREAD_ID),
793             m_thread_id_passed(false),
794             m_thread_index (UINT32_MAX),
795             m_thread_index_passed(false),
796             m_thread_name(),
797             m_queue_name(),
798             m_condition (),
799             m_one_shot (false),
800             m_enable_passed (false),
801             m_enable_value (false),
802             m_name_passed (false),
803             m_queue_passed (false),
804             m_condition_passed (false),
805             m_one_shot_passed (false),
806             m_use_dummy (false)
807         {
808         }
809
810         virtual
811         ~CommandOptions () {}
812
813         virtual Error
814         SetOptionValue (uint32_t option_idx, const char *option_arg)
815         {
816             Error error;
817             const int short_option = m_getopt_table[option_idx].val;
818
819             switch (short_option)
820             {
821                 case 'c':
822                     if (option_arg != NULL)
823                         m_condition.assign (option_arg);
824                     else
825                         m_condition.clear();
826                     m_condition_passed = true;
827                     break;
828                 case 'd':
829                     m_enable_passed = true;
830                     m_enable_value = false;
831                     break;
832                 case 'D':
833                     m_use_dummy = true;
834                     break;
835                 case 'e':
836                     m_enable_passed = true;
837                     m_enable_value = true;
838                     break;
839                 case 'i':
840                 {
841                     m_ignore_count = Args::StringToUInt32(option_arg, UINT32_MAX, 0);
842                     if (m_ignore_count == UINT32_MAX)
843                        error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
844                 }
845                 break;
846                 case 'o':
847                 {
848                     bool value, success;
849                     value = Args::StringToBoolean(option_arg, false, &success);
850                     if (success)
851                     {
852                         m_one_shot_passed = true;
853                         m_one_shot = value;
854                     }
855                     else
856                         error.SetErrorStringWithFormat("invalid boolean value '%s' passed for -o option", option_arg);
857                 }
858                 break;
859                 case 't' :
860                 {
861                     if (option_arg[0] == '\0')
862                     {
863                         m_thread_id = LLDB_INVALID_THREAD_ID;
864                         m_thread_id_passed = true;
865                     }
866                     else
867                     {
868                         m_thread_id = Args::StringToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
869                         if (m_thread_id == LLDB_INVALID_THREAD_ID)
870                            error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
871                         else
872                             m_thread_id_passed = true;
873                     }
874                 }
875                 break;
876                 case 'T':
877                     if (option_arg != NULL)
878                         m_thread_name.assign (option_arg);
879                     else
880                         m_thread_name.clear();
881                     m_name_passed = true;
882                     break;
883                 case 'q':
884                     if (option_arg != NULL)
885                         m_queue_name.assign (option_arg);
886                     else
887                         m_queue_name.clear();
888                     m_queue_passed = true;
889                     break;
890                 case 'x':
891                 {
892                     if (option_arg[0] == '\n')
893                     {
894                         m_thread_index = UINT32_MAX;
895                         m_thread_index_passed = true;
896                     }
897                     else
898                     {
899                         m_thread_index = Args::StringToUInt32 (option_arg, UINT32_MAX, 0);
900                         if (m_thread_id == UINT32_MAX)
901                            error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
902                         else
903                             m_thread_index_passed = true;
904                     }
905                 }
906                 break;
907                 default:
908                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
909                     break;
910             }
911
912             return error;
913         }
914         void
915         OptionParsingStarting ()
916         {
917             m_ignore_count = 0;
918             m_thread_id = LLDB_INVALID_THREAD_ID;
919             m_thread_id_passed = false;
920             m_thread_index = UINT32_MAX;
921             m_thread_index_passed = false;
922             m_thread_name.clear();
923             m_queue_name.clear();
924             m_condition.clear();
925             m_one_shot = false;
926             m_enable_passed = false;
927             m_queue_passed = false;
928             m_name_passed = false;
929             m_condition_passed = false;
930             m_one_shot_passed = false;
931             m_use_dummy = false;
932         }
933         
934         const OptionDefinition*
935         GetDefinitions ()
936         {
937             return g_option_table;
938         }
939         
940
941         // Options table: Required for subclasses of Options.
942
943         static OptionDefinition g_option_table[];
944
945         // Instance variables to hold the values for command options.
946
947         uint32_t m_ignore_count;
948         lldb::tid_t m_thread_id;
949         bool m_thread_id_passed;
950         uint32_t m_thread_index;
951         bool m_thread_index_passed;
952         std::string m_thread_name;
953         std::string m_queue_name;
954         std::string m_condition;
955         bool m_one_shot;
956         bool m_enable_passed;
957         bool m_enable_value;
958         bool m_name_passed;
959         bool m_queue_passed;
960         bool m_condition_passed;
961         bool m_one_shot_passed;
962         bool m_use_dummy;
963
964     };
965
966 protected:
967     virtual bool
968     DoExecute (Args& command, CommandReturnObject &result)
969     {
970         Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
971         if (target == NULL)
972         {
973             result.AppendError ("Invalid target.  No existing target or breakpoints.");
974             result.SetStatus (eReturnStatusFailed);
975             return false;
976         }
977
978         Mutex::Locker locker;
979         target->GetBreakpointList().GetListMutex(locker);
980         
981         BreakpointIDList valid_bp_ids;
982
983         CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
984
985         if (result.Succeeded())
986         {
987             const size_t count = valid_bp_ids.GetSize(); 
988             for (size_t i = 0; i < count; ++i)
989             {
990                 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
991
992                 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
993                 {
994                     Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
995                     if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
996                     {
997                         BreakpointLocation *location = bp->FindLocationByID (cur_bp_id.GetLocationID()).get();
998                         if (location)
999                         {
1000                             if (m_options.m_thread_id_passed)
1001                                 location->SetThreadID (m_options.m_thread_id);
1002                                 
1003                             if (m_options.m_thread_index_passed)
1004                                 location->SetThreadIndex(m_options.m_thread_index);
1005                             
1006                             if (m_options.m_name_passed)
1007                                 location->SetThreadName(m_options.m_thread_name.c_str());
1008                             
1009                             if (m_options.m_queue_passed)
1010                                 location->SetQueueName(m_options.m_queue_name.c_str());
1011                                 
1012                             if (m_options.m_ignore_count != 0)
1013                                 location->SetIgnoreCount(m_options.m_ignore_count);
1014                                 
1015                             if (m_options.m_enable_passed)
1016                                 location->SetEnabled (m_options.m_enable_value);
1017                                 
1018                             if (m_options.m_condition_passed)
1019                                 location->SetCondition (m_options.m_condition.c_str());
1020                         }
1021                     }
1022                     else
1023                     {
1024                         if (m_options.m_thread_id_passed)
1025                             bp->SetThreadID (m_options.m_thread_id);
1026                             
1027                         if (m_options.m_thread_index_passed)
1028                             bp->SetThreadIndex(m_options.m_thread_index);
1029                         
1030                         if (m_options.m_name_passed)
1031                             bp->SetThreadName(m_options.m_thread_name.c_str());
1032                         
1033                         if (m_options.m_queue_passed)
1034                             bp->SetQueueName(m_options.m_queue_name.c_str());
1035                             
1036                         if (m_options.m_ignore_count != 0)
1037                             bp->SetIgnoreCount(m_options.m_ignore_count);
1038                             
1039                         if (m_options.m_enable_passed)
1040                             bp->SetEnabled (m_options.m_enable_value);
1041                             
1042                         if (m_options.m_condition_passed)
1043                             bp->SetCondition (m_options.m_condition.c_str());
1044                     }
1045                 }
1046             }
1047         }
1048         
1049         return result.Succeeded();
1050     }
1051
1052 private:
1053     CommandOptions m_options;
1054 };
1055
1056 #pragma mark Modify::CommandOptions
1057 OptionDefinition
1058 CommandObjectBreakpointModify::CommandOptions::g_option_table[] =
1059 {
1060 { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeCount, "Set the number of times this breakpoint is skipped before stopping." },
1061 { LLDB_OPT_SET_ALL, false, "one-shot",     'o', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "The breakpoint is deleted the first time it stop causes a stop." },
1062 { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadIndex, "The breakpoint stops only for the thread whose index matches this argument."},
1063 { LLDB_OPT_SET_ALL, false, "thread-id",    't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadID, "The breakpoint stops only for the thread whose TID matches this argument."},
1064 { LLDB_OPT_SET_ALL, false, "thread-name",  'T', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadName, "The breakpoint stops only for the thread whose thread name matches this argument."},
1065 { LLDB_OPT_SET_ALL, false, "queue-name",   'q', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeQueueName, "The breakpoint stops only for threads in the queue whose name is given by this argument."},
1066 { LLDB_OPT_SET_ALL, false, "condition",    'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeExpression, "The breakpoint stops only if this condition expression evaluates to true."},
1067 { LLDB_OPT_SET_1,   false, "enable",       'e', OptionParser::eNoArgument,       NULL, NULL, 0, eArgTypeNone, "Enable the breakpoint."},
1068 { LLDB_OPT_SET_2,   false, "disable",      'd', OptionParser::eNoArgument,       NULL, NULL, 0, eArgTypeNone, "Disable the breakpoint."},
1069 { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
1070
1071 { 0,                false, NULL,            0 , 0,                 NULL, NULL, 0, eArgTypeNone, NULL }
1072 };
1073
1074 //-------------------------------------------------------------------------
1075 // CommandObjectBreakpointEnable
1076 //-------------------------------------------------------------------------
1077 #pragma mark Enable
1078
1079 class CommandObjectBreakpointEnable : public CommandObjectParsed
1080 {
1081 public:
1082     CommandObjectBreakpointEnable (CommandInterpreter &interpreter) :
1083         CommandObjectParsed (interpreter,
1084                              "enable",
1085                              "Enable the specified disabled breakpoint(s). If no breakpoints are specified, enable all of them.",
1086                              NULL)
1087     {
1088         CommandArgumentEntry arg;
1089         CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
1090         // Add the entry for the first argument for this command to the object's arguments vector.
1091         m_arguments.push_back (arg);   
1092     }
1093
1094
1095     virtual
1096     ~CommandObjectBreakpointEnable () {}
1097
1098 protected:
1099     virtual bool
1100     DoExecute (Args& command, CommandReturnObject &result)
1101     {
1102         Target *target = GetSelectedOrDummyTarget();
1103         if (target == NULL)
1104         {
1105             result.AppendError ("Invalid target.  No existing target or breakpoints.");
1106             result.SetStatus (eReturnStatusFailed);
1107             return false;
1108         }
1109
1110         Mutex::Locker locker;
1111         target->GetBreakpointList().GetListMutex(locker);
1112
1113         const BreakpointList &breakpoints = target->GetBreakpointList();
1114
1115         size_t num_breakpoints = breakpoints.GetSize();
1116
1117         if (num_breakpoints == 0)
1118         {
1119             result.AppendError ("No breakpoints exist to be enabled.");
1120             result.SetStatus (eReturnStatusFailed);
1121             return false;
1122         }
1123
1124         if (command.GetArgumentCount() == 0)
1125         {
1126             // No breakpoint selected; enable all currently set breakpoints.
1127             target->EnableAllBreakpoints ();
1128             result.AppendMessageWithFormat ("All breakpoints enabled. (%" PRIu64 " breakpoints)\n", (uint64_t)num_breakpoints);
1129             result.SetStatus (eReturnStatusSuccessFinishNoResult);
1130         }
1131         else
1132         {
1133             // Particular breakpoint selected; enable that breakpoint.
1134             BreakpointIDList valid_bp_ids;
1135             CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
1136
1137             if (result.Succeeded())
1138             {
1139                 int enable_count = 0;
1140                 int loc_count = 0;
1141                 const size_t count = valid_bp_ids.GetSize();
1142                 for (size_t i = 0; i < count; ++i)
1143                 {
1144                     BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1145
1146                     if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
1147                     {
1148                         Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1149                         if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
1150                         {
1151                             BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
1152                             if (location)
1153                             {
1154                                 location->SetEnabled (true);
1155                                 ++loc_count;
1156                             }
1157                         }
1158                         else
1159                         {
1160                             breakpoint->SetEnabled (true);
1161                             ++enable_count;
1162                         }
1163                     }
1164                 }
1165                 result.AppendMessageWithFormat ("%d breakpoints enabled.\n", enable_count + loc_count);
1166                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1167             }
1168         }
1169
1170         return result.Succeeded();
1171     }
1172 };
1173
1174 //-------------------------------------------------------------------------
1175 // CommandObjectBreakpointDisable
1176 //-------------------------------------------------------------------------
1177 #pragma mark Disable
1178
1179 class CommandObjectBreakpointDisable : public CommandObjectParsed
1180 {
1181 public:
1182     CommandObjectBreakpointDisable (CommandInterpreter &interpreter) :
1183         CommandObjectParsed (interpreter,
1184                              "breakpoint disable",
1185                              "Disable the specified breakpoint(s) without removing it/them.  If no breakpoints are specified, disable them all.",
1186                              NULL)
1187     {
1188         SetHelpLong(
1189 "Disable the specified breakpoint(s) without removing it/them.  \n\
1190 If no breakpoints are specified, disable them all.\n\
1191 \n\
1192 Note: disabling a breakpoint will cause none of its locations to be hit\n\
1193 regardless of whether they are enabled or disabled.  So the sequence: \n\
1194 \n\
1195     (lldb) break disable 1\n\
1196     (lldb) break enable 1.1\n\
1197 \n\
1198 will NOT cause location 1.1 to get hit.  To achieve that, do:\n\
1199 \n\
1200     (lldb) break disable 1.*\n\
1201     (lldb) break enable 1.1\n\
1202 \n\
1203 The first command disables all the locations of breakpoint 1, \n\
1204 the second re-enables the first location."
1205                     );
1206         
1207         CommandArgumentEntry arg;
1208         CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
1209         // Add the entry for the first argument for this command to the object's arguments vector.
1210         m_arguments.push_back (arg);
1211
1212     }
1213
1214
1215     virtual
1216     ~CommandObjectBreakpointDisable () {}
1217
1218 protected:
1219     virtual bool
1220     DoExecute (Args& command, CommandReturnObject &result)
1221     {
1222         Target *target = GetSelectedOrDummyTarget();
1223         if (target == NULL)
1224         {
1225             result.AppendError ("Invalid target.  No existing target or breakpoints.");
1226             result.SetStatus (eReturnStatusFailed);
1227             return false;
1228         }
1229
1230         Mutex::Locker locker;
1231         target->GetBreakpointList().GetListMutex(locker);
1232
1233         const BreakpointList &breakpoints = target->GetBreakpointList();
1234         size_t num_breakpoints = breakpoints.GetSize();
1235
1236         if (num_breakpoints == 0)
1237         {
1238             result.AppendError ("No breakpoints exist to be disabled.");
1239             result.SetStatus (eReturnStatusFailed);
1240             return false;
1241         }
1242
1243         if (command.GetArgumentCount() == 0)
1244         {
1245             // No breakpoint selected; disable all currently set breakpoints.
1246             target->DisableAllBreakpoints ();
1247             result.AppendMessageWithFormat ("All breakpoints disabled. (%" PRIu64 " breakpoints)\n", (uint64_t)num_breakpoints);
1248             result.SetStatus (eReturnStatusSuccessFinishNoResult);
1249         }
1250         else
1251         {
1252             // Particular breakpoint selected; disable that breakpoint.
1253             BreakpointIDList valid_bp_ids;
1254
1255             CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
1256
1257             if (result.Succeeded())
1258             {
1259                 int disable_count = 0;
1260                 int loc_count = 0;
1261                 const size_t count = valid_bp_ids.GetSize();
1262                 for (size_t i = 0; i < count; ++i)
1263                 {
1264                     BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1265
1266                     if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
1267                     {
1268                         Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1269                         if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
1270                         {
1271                             BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
1272                             if (location)
1273                             {
1274                                 location->SetEnabled (false);
1275                                 ++loc_count;
1276                             }
1277                         }
1278                         else
1279                         {
1280                             breakpoint->SetEnabled (false);
1281                             ++disable_count;
1282                         }
1283                     }
1284                 }
1285                 result.AppendMessageWithFormat ("%d breakpoints disabled.\n", disable_count + loc_count);
1286                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1287             }
1288         }
1289
1290         return result.Succeeded();
1291     }
1292
1293 };
1294
1295 //-------------------------------------------------------------------------
1296 // CommandObjectBreakpointList
1297 //-------------------------------------------------------------------------
1298 #pragma mark List
1299
1300 class CommandObjectBreakpointList : public CommandObjectParsed
1301 {
1302 public:
1303     CommandObjectBreakpointList (CommandInterpreter &interpreter) :
1304         CommandObjectParsed (interpreter, 
1305                              "breakpoint list",
1306                              "List some or all breakpoints at configurable levels of detail.",
1307                              NULL),
1308         m_options (interpreter)
1309     {
1310         CommandArgumentEntry arg;
1311         CommandArgumentData bp_id_arg;
1312
1313         // Define the first (and only) variant of this arg.
1314         bp_id_arg.arg_type = eArgTypeBreakpointID;
1315         bp_id_arg.arg_repetition = eArgRepeatOptional;
1316
1317         // There is only one variant this argument could be; put it into the argument entry.
1318         arg.push_back (bp_id_arg);
1319
1320         // Push the data for the first argument into the m_arguments vector.
1321         m_arguments.push_back (arg);
1322     }
1323
1324
1325     virtual
1326     ~CommandObjectBreakpointList () {}
1327
1328     virtual Options *
1329     GetOptions ()
1330     {
1331         return &m_options;
1332     }
1333     
1334     class CommandOptions : public Options
1335     {
1336     public:
1337
1338         CommandOptions (CommandInterpreter &interpreter) :
1339             Options (interpreter),
1340             m_level (lldb::eDescriptionLevelBrief),
1341             m_use_dummy(false)
1342         {
1343         }
1344
1345         virtual
1346         ~CommandOptions () {}
1347
1348         virtual Error
1349         SetOptionValue (uint32_t option_idx, const char *option_arg)
1350         {
1351             Error error;
1352             const int short_option = m_getopt_table[option_idx].val;
1353
1354             switch (short_option)
1355             {
1356                 case 'b':
1357                     m_level = lldb::eDescriptionLevelBrief;
1358                     break;
1359                 case 'D':
1360                     m_use_dummy = true;
1361                     break;
1362                 case 'f':
1363                     m_level = lldb::eDescriptionLevelFull;
1364                     break;
1365                 case 'v':
1366                     m_level = lldb::eDescriptionLevelVerbose;
1367                     break;
1368                 case 'i':
1369                     m_internal = true;
1370                     break;
1371                 default:
1372                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1373                     break;
1374             }
1375
1376             return error;
1377         }
1378
1379         void
1380         OptionParsingStarting ()
1381         {
1382             m_level = lldb::eDescriptionLevelFull;
1383             m_internal = false;
1384             m_use_dummy = false;
1385         }
1386
1387         const OptionDefinition *
1388         GetDefinitions ()
1389         {
1390             return g_option_table;
1391         }
1392
1393         // Options table: Required for subclasses of Options.
1394
1395         static OptionDefinition g_option_table[];
1396
1397         // Instance variables to hold the values for command options.
1398
1399         lldb::DescriptionLevel m_level;
1400
1401         bool m_internal;
1402         bool m_use_dummy;
1403     };
1404
1405 protected:
1406     virtual bool
1407     DoExecute (Args& command, CommandReturnObject &result)
1408     {
1409         Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
1410
1411         if (target == NULL)
1412         {
1413             result.AppendError ("Invalid target. No current target or breakpoints.");
1414             result.SetStatus (eReturnStatusSuccessFinishNoResult);
1415             return true;
1416         }
1417
1418         const BreakpointList &breakpoints = target->GetBreakpointList(m_options.m_internal);
1419         Mutex::Locker locker;
1420         target->GetBreakpointList(m_options.m_internal).GetListMutex(locker);
1421
1422         size_t num_breakpoints = breakpoints.GetSize();
1423
1424         if (num_breakpoints == 0)
1425         {
1426             result.AppendMessage ("No breakpoints currently set.");
1427             result.SetStatus (eReturnStatusSuccessFinishNoResult);
1428             return true;
1429         }
1430
1431         Stream &output_stream = result.GetOutputStream();
1432
1433         if (command.GetArgumentCount() == 0)
1434         {
1435             // No breakpoint selected; show info about all currently set breakpoints.
1436             result.AppendMessage ("Current breakpoints:");
1437             for (size_t i = 0; i < num_breakpoints; ++i)
1438             {
1439                 Breakpoint *breakpoint = breakpoints.GetBreakpointAtIndex (i).get();
1440                 AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
1441             }
1442             result.SetStatus (eReturnStatusSuccessFinishNoResult);
1443         }
1444         else
1445         {
1446             // Particular breakpoints selected; show info about that breakpoint.
1447             BreakpointIDList valid_bp_ids;
1448             CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
1449
1450             if (result.Succeeded())
1451             {
1452                 for (size_t i = 0; i < valid_bp_ids.GetSize(); ++i)
1453                 {
1454                     BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1455                     Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1456                     AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
1457                 }
1458                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1459             }
1460             else
1461             {
1462                 result.AppendError ("Invalid breakpoint id.");
1463                 result.SetStatus (eReturnStatusFailed);
1464             }
1465         }
1466
1467         return result.Succeeded();
1468     }
1469
1470 private:
1471     CommandOptions m_options;
1472 };
1473
1474 #pragma mark List::CommandOptions
1475 OptionDefinition
1476 CommandObjectBreakpointList::CommandOptions::g_option_table[] =
1477 {
1478     { LLDB_OPT_SET_ALL, false, "internal", 'i', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
1479         "Show debugger internal breakpoints" },
1480
1481     { LLDB_OPT_SET_1, false, "brief",    'b', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
1482         "Give a brief description of the breakpoint (no location info)."},
1483
1484     // FIXME: We need to add an "internal" command, and then add this sort of thing to it.
1485     // But I need to see it for now, and don't want to wait.
1486     { LLDB_OPT_SET_2, false, "full",    'f', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
1487         "Give a full description of the breakpoint and its locations."},
1488
1489     { LLDB_OPT_SET_3, false, "verbose", 'v', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
1490         "Explain everything we know about the breakpoint (for debugging debugger bugs)." },
1491
1492     { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
1493         "List Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
1494
1495     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
1496 };
1497
1498 //-------------------------------------------------------------------------
1499 // CommandObjectBreakpointClear
1500 //-------------------------------------------------------------------------
1501 #pragma mark Clear
1502
1503 class CommandObjectBreakpointClear : public CommandObjectParsed
1504 {
1505 public:
1506
1507     typedef enum BreakpointClearType
1508     {
1509         eClearTypeInvalid,
1510         eClearTypeFileAndLine
1511     } BreakpointClearType;
1512
1513     CommandObjectBreakpointClear (CommandInterpreter &interpreter) :
1514         CommandObjectParsed (interpreter,
1515                              "breakpoint clear", 
1516                              "Clears a breakpoint or set of breakpoints in the executable.", 
1517                              "breakpoint clear <cmd-options>"),
1518         m_options (interpreter)
1519     {
1520     }
1521
1522     virtual
1523     ~CommandObjectBreakpointClear () {}
1524
1525     virtual Options *
1526     GetOptions ()
1527     {
1528         return &m_options;
1529     }
1530
1531     class CommandOptions : public Options
1532     {
1533     public:
1534
1535         CommandOptions (CommandInterpreter &interpreter) :
1536             Options (interpreter),
1537             m_filename (),
1538             m_line_num (0)
1539         {
1540         }
1541
1542         virtual
1543         ~CommandOptions () {}
1544
1545         virtual Error
1546         SetOptionValue (uint32_t option_idx, const char *option_arg)
1547         {
1548             Error error;
1549             const int short_option = m_getopt_table[option_idx].val;
1550
1551             switch (short_option)
1552             {
1553                 case 'f':
1554                     m_filename.assign (option_arg);
1555                     break;
1556
1557                 case 'l':
1558                     m_line_num = Args::StringToUInt32 (option_arg, 0);
1559                     break;
1560
1561                 default:
1562                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1563                     break;
1564             }
1565
1566             return error;
1567         }
1568
1569         void
1570         OptionParsingStarting ()
1571         {
1572             m_filename.clear();
1573             m_line_num = 0;
1574         }
1575
1576         const OptionDefinition*
1577         GetDefinitions ()
1578         {
1579             return g_option_table;
1580         }
1581
1582         // Options table: Required for subclasses of Options.
1583
1584         static OptionDefinition g_option_table[];
1585
1586         // Instance variables to hold the values for command options.
1587
1588         std::string m_filename;
1589         uint32_t m_line_num;
1590
1591     };
1592
1593 protected:
1594     virtual bool
1595     DoExecute (Args& command, CommandReturnObject &result)
1596     {
1597         Target *target = GetSelectedOrDummyTarget();
1598         if (target == NULL)
1599         {
1600             result.AppendError ("Invalid target. No existing target or breakpoints.");
1601             result.SetStatus (eReturnStatusFailed);
1602             return false;
1603         }
1604
1605         // The following are the various types of breakpoints that could be cleared:
1606         //   1). -f -l (clearing breakpoint by source location)
1607
1608         BreakpointClearType break_type = eClearTypeInvalid;
1609
1610         if (m_options.m_line_num != 0)
1611             break_type = eClearTypeFileAndLine;
1612
1613         Mutex::Locker locker;
1614         target->GetBreakpointList().GetListMutex(locker);
1615
1616         BreakpointList &breakpoints = target->GetBreakpointList();
1617         size_t num_breakpoints = breakpoints.GetSize();
1618
1619         // Early return if there's no breakpoint at all.
1620         if (num_breakpoints == 0)
1621         {
1622             result.AppendError ("Breakpoint clear: No breakpoint cleared.");
1623             result.SetStatus (eReturnStatusFailed);
1624             return result.Succeeded();
1625         }
1626
1627         // Find matching breakpoints and delete them.
1628
1629         // First create a copy of all the IDs.
1630         std::vector<break_id_t> BreakIDs;
1631         for (size_t i = 0; i < num_breakpoints; ++i)
1632             BreakIDs.push_back(breakpoints.GetBreakpointAtIndex(i).get()->GetID());
1633
1634         int num_cleared = 0;
1635         StreamString ss;
1636         switch (break_type)
1637         {
1638             case eClearTypeFileAndLine: // Breakpoint by source position
1639                 {
1640                     const ConstString filename(m_options.m_filename.c_str());
1641                     BreakpointLocationCollection loc_coll;
1642
1643                     for (size_t i = 0; i < num_breakpoints; ++i)
1644                     {
1645                         Breakpoint *bp = breakpoints.FindBreakpointByID(BreakIDs[i]).get();
1646                         
1647                         if (bp->GetMatchingFileLine(filename, m_options.m_line_num, loc_coll))
1648                         {
1649                             // If the collection size is 0, it's a full match and we can just remove the breakpoint.
1650                             if (loc_coll.GetSize() == 0)
1651                             {
1652                                 bp->GetDescription(&ss, lldb::eDescriptionLevelBrief);
1653                                 ss.EOL();
1654                                 target->RemoveBreakpointByID (bp->GetID());
1655                                 ++num_cleared;
1656                             }
1657                         }
1658                     }
1659                 }
1660                 break;
1661
1662             default:
1663                 break;
1664         }
1665
1666         if (num_cleared > 0)
1667         {
1668             Stream &output_stream = result.GetOutputStream();
1669             output_stream.Printf ("%d breakpoints cleared:\n", num_cleared);
1670             output_stream << ss.GetData();
1671             output_stream.EOL();
1672             result.SetStatus (eReturnStatusSuccessFinishNoResult);
1673         }
1674         else
1675         {
1676             result.AppendError ("Breakpoint clear: No breakpoint cleared.");
1677             result.SetStatus (eReturnStatusFailed);
1678         }
1679
1680         return result.Succeeded();
1681     }
1682
1683 private:
1684     CommandOptions m_options;
1685 };
1686
1687 #pragma mark Clear::CommandOptions
1688
1689 OptionDefinition
1690 CommandObjectBreakpointClear::CommandOptions::g_option_table[] =
1691 {
1692     { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
1693         "Specify the breakpoint by source location in this particular file."},
1694
1695     { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum,
1696         "Specify the breakpoint by source location at this particular line."},
1697
1698     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
1699 };
1700
1701 //-------------------------------------------------------------------------
1702 // CommandObjectBreakpointDelete
1703 //-------------------------------------------------------------------------
1704 #pragma mark Delete
1705
1706 class CommandObjectBreakpointDelete : public CommandObjectParsed
1707 {
1708 public:
1709     CommandObjectBreakpointDelete (CommandInterpreter &interpreter) :
1710         CommandObjectParsed (interpreter,
1711                              "breakpoint delete",
1712                              "Delete the specified breakpoint(s).  If no breakpoints are specified, delete them all.",
1713                              NULL),
1714         m_options (interpreter)
1715     {
1716         CommandArgumentEntry arg;
1717         CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
1718         // Add the entry for the first argument for this command to the object's arguments vector.
1719         m_arguments.push_back (arg);   
1720     }
1721
1722     virtual
1723     ~CommandObjectBreakpointDelete () {}
1724
1725     virtual Options *
1726     GetOptions ()
1727     {
1728         return &m_options;
1729     }
1730
1731     class CommandOptions : public Options
1732     {
1733     public:
1734
1735         CommandOptions (CommandInterpreter &interpreter) :
1736             Options (interpreter),
1737             m_use_dummy (false),
1738             m_force (false)
1739         {
1740         }
1741
1742         virtual
1743         ~CommandOptions () {}
1744
1745         virtual Error
1746         SetOptionValue (uint32_t option_idx, const char *option_arg)
1747         {
1748             Error error;
1749             const int short_option = m_getopt_table[option_idx].val;
1750
1751             switch (short_option)
1752             {
1753                 case 'f':
1754                     m_force = true;
1755                     break;
1756
1757                 case 'D':
1758                     m_use_dummy = true;
1759                     break;
1760
1761                 default:
1762                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1763                     break;
1764             }
1765
1766             return error;
1767         }
1768
1769         void
1770         OptionParsingStarting ()
1771         {
1772             m_use_dummy = false;
1773             m_force = false;
1774         }
1775
1776         const OptionDefinition*
1777         GetDefinitions ()
1778         {
1779             return g_option_table;
1780         }
1781
1782         // Options table: Required for subclasses of Options.
1783
1784         static OptionDefinition g_option_table[];
1785
1786         // Instance variables to hold the values for command options.
1787         bool m_use_dummy;
1788         bool m_force;
1789     };
1790
1791 protected:
1792     virtual bool
1793     DoExecute (Args& command, CommandReturnObject &result)
1794     {
1795         Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
1796
1797         if (target == NULL)
1798         {
1799             result.AppendError ("Invalid target. No existing target or breakpoints.");
1800             result.SetStatus (eReturnStatusFailed);
1801             return false;
1802         }
1803
1804         Mutex::Locker locker;
1805         target->GetBreakpointList().GetListMutex(locker);
1806         
1807         const BreakpointList &breakpoints = target->GetBreakpointList();
1808
1809         size_t num_breakpoints = breakpoints.GetSize();
1810
1811         if (num_breakpoints == 0)
1812         {
1813             result.AppendError ("No breakpoints exist to be deleted.");
1814             result.SetStatus (eReturnStatusFailed);
1815             return false;
1816         }
1817
1818         if (command.GetArgumentCount() == 0)
1819         {
1820             if (!m_options.m_force && !m_interpreter.Confirm ("About to delete all breakpoints, do you want to do that?", true))
1821             {
1822                 result.AppendMessage("Operation cancelled...");
1823             }
1824             else
1825             {
1826                 target->RemoveAllBreakpoints ();
1827                 result.AppendMessageWithFormat ("All breakpoints removed. (%" PRIu64 " breakpoint%s)\n", (uint64_t)num_breakpoints, num_breakpoints > 1 ? "s" : "");
1828             }
1829             result.SetStatus (eReturnStatusSuccessFinishNoResult);
1830         }
1831         else
1832         {
1833             // Particular breakpoint selected; disable that breakpoint.
1834             BreakpointIDList valid_bp_ids;
1835             CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
1836
1837             if (result.Succeeded())
1838             {
1839                 int delete_count = 0;
1840                 int disable_count = 0;
1841                 const size_t count = valid_bp_ids.GetSize();
1842                 for (size_t i = 0; i < count; ++i)
1843                 {
1844                     BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1845
1846                     if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
1847                     {
1848                         if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
1849                         {
1850                             Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1851                             BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
1852                             // It makes no sense to try to delete individual locations, so we disable them instead.
1853                             if (location)
1854                             {
1855                                 location->SetEnabled (false);
1856                                 ++disable_count;
1857                             }
1858                         }
1859                         else
1860                         {
1861                             target->RemoveBreakpointByID (cur_bp_id.GetBreakpointID());
1862                             ++delete_count;
1863                         }
1864                     }
1865                 }
1866                 result.AppendMessageWithFormat ("%d breakpoints deleted; %d breakpoint locations disabled.\n",
1867                                                delete_count, disable_count);
1868                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1869             }
1870         }
1871         return result.Succeeded();
1872     }
1873 private:
1874     CommandOptions m_options;
1875 };
1876
1877 OptionDefinition
1878 CommandObjectBreakpointDelete::CommandOptions::g_option_table[] =
1879 {
1880     { LLDB_OPT_SET_1, false, "force", 'f', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
1881         "Delete all breakpoints without querying for confirmation."},
1882
1883     { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
1884         "Delete Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
1885
1886     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
1887 };
1888
1889 //-------------------------------------------------------------------------
1890 // CommandObjectBreakpointName
1891 //-------------------------------------------------------------------------
1892
1893 static OptionDefinition
1894 g_breakpoint_name_options[] =
1895 {
1896     { LLDB_OPT_SET_1,   false, "name", 'N', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBreakpointName, "Specifies a breakpoint name to use."},
1897     { LLDB_OPT_SET_2,   false, "breakpoint-id", 'B', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBreakpointID,   "Specify a breakpoint id to use."},
1898     { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
1899         "Operate on Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
1900 };
1901 class BreakpointNameOptionGroup : public OptionGroup
1902 {
1903 public:
1904     BreakpointNameOptionGroup() :
1905         OptionGroup(),
1906         m_breakpoint(LLDB_INVALID_BREAK_ID),
1907         m_use_dummy (false)
1908     {
1909
1910     }
1911
1912     virtual
1913     ~BreakpointNameOptionGroup ()
1914     {
1915     }
1916     
1917     virtual uint32_t
1918     GetNumDefinitions ()
1919     {
1920       return sizeof (g_breakpoint_name_options) / sizeof (OptionDefinition);
1921     }
1922
1923     virtual const OptionDefinition*
1924     GetDefinitions ()
1925     {
1926         return g_breakpoint_name_options;
1927     }
1928
1929     virtual Error
1930     SetOptionValue (CommandInterpreter &interpreter,
1931                     uint32_t option_idx,
1932                     const char *option_value)
1933     {
1934         Error error;
1935         const int short_option = g_breakpoint_name_options[option_idx].short_option;
1936       
1937         switch (short_option)
1938         {
1939         case 'N':
1940             if (BreakpointID::StringIsBreakpointName(option_value, error) && error.Success())
1941                 m_name.SetValueFromCString(option_value);
1942             break;
1943           
1944         case 'B':
1945             if (m_breakpoint.SetValueFromCString(option_value).Fail())
1946                 error.SetErrorStringWithFormat ("unrecognized value \"%s\" for breakpoint", option_value);
1947             break;
1948         case 'D':
1949             if (m_use_dummy.SetValueFromCString(option_value).Fail())
1950                 error.SetErrorStringWithFormat ("unrecognized value \"%s\" for use-dummy", option_value);
1951             break;
1952
1953         default:
1954               error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option);
1955               break;
1956         }
1957         return error;
1958     }
1959
1960     virtual void
1961     OptionParsingStarting (CommandInterpreter &interpreter)
1962     {
1963         m_name.Clear();
1964         m_breakpoint.Clear();
1965         m_use_dummy.Clear();
1966         m_use_dummy.SetDefaultValue(false);
1967     }
1968
1969     OptionValueString m_name;
1970     OptionValueUInt64 m_breakpoint;
1971     OptionValueBoolean m_use_dummy;
1972 };
1973
1974
1975 class CommandObjectBreakpointNameAdd : public CommandObjectParsed
1976 {
1977 public:
1978     CommandObjectBreakpointNameAdd (CommandInterpreter &interpreter) :
1979         CommandObjectParsed (interpreter,
1980                              "add",
1981                              "Add a name to the breakpoints provided.",
1982                              "breakpoint name add <command-options> <breakpoint-id-list>"),
1983         m_name_options(),
1984         m_option_group(interpreter)
1985         {
1986             // Create the first variant for the first (and only) argument for this command.
1987             CommandArgumentEntry arg1;
1988             CommandArgumentData id_arg;
1989             id_arg.arg_type = eArgTypeBreakpointID;
1990             id_arg.arg_repetition = eArgRepeatOptional;
1991             arg1.push_back(id_arg);
1992             m_arguments.push_back (arg1);
1993
1994             m_option_group.Append (&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
1995             m_option_group.Finalize();
1996         }
1997
1998     virtual
1999     ~CommandObjectBreakpointNameAdd () {}
2000
2001   Options *
2002   GetOptions ()
2003   {
2004     return &m_option_group;
2005   }
2006   
2007 protected:
2008     virtual bool
2009     DoExecute (Args& command, CommandReturnObject &result)
2010     {
2011         if (!m_name_options.m_name.OptionWasSet())
2012         {
2013             result.SetError("No name option provided.");
2014             return false;
2015         }
2016
2017         Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
2018
2019         if (target == NULL)
2020         {
2021             result.AppendError ("Invalid target. No existing target or breakpoints.");
2022             result.SetStatus (eReturnStatusFailed);
2023             return false;
2024         }
2025
2026         Mutex::Locker locker;
2027         target->GetBreakpointList().GetListMutex(locker);
2028         
2029         const BreakpointList &breakpoints = target->GetBreakpointList();
2030
2031         size_t num_breakpoints = breakpoints.GetSize();
2032         if (num_breakpoints == 0)
2033         {
2034             result.SetError("No breakpoints, cannot add names.");
2035             result.SetStatus (eReturnStatusFailed);
2036             return false;
2037         }
2038
2039         // Particular breakpoint selected; disable that breakpoint.
2040         BreakpointIDList valid_bp_ids;
2041         CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
2042
2043         if (result.Succeeded())
2044         {
2045             if (valid_bp_ids.GetSize() == 0)
2046             {
2047                 result.SetError("No breakpoints specified, cannot add names.");
2048                 result.SetStatus (eReturnStatusFailed);
2049                 return false;
2050             }
2051             size_t num_valid_ids = valid_bp_ids.GetSize();
2052             for (size_t index = 0; index < num_valid_ids; index++)
2053             {
2054                 lldb::break_id_t bp_id = valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
2055                 BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
2056                 Error error;  // We don't need to check the error here, since the option parser checked it...
2057                 bp_sp->AddName(m_name_options.m_name.GetCurrentValue(), error);
2058             }
2059         }
2060
2061         return true;
2062     }
2063
2064 private:
2065     BreakpointNameOptionGroup m_name_options;
2066     OptionGroupOptions m_option_group;
2067 };
2068
2069
2070
2071 class CommandObjectBreakpointNameDelete : public CommandObjectParsed
2072 {
2073 public:
2074     CommandObjectBreakpointNameDelete (CommandInterpreter &interpreter) :
2075         CommandObjectParsed (interpreter,
2076                              "delete",
2077                              "Delete a name from the breakpoints provided.",
2078                              "breakpoint name delete <command-options> <breakpoint-id-list>"),
2079         m_name_options(),
2080         m_option_group(interpreter)
2081     {
2082         // Create the first variant for the first (and only) argument for this command.
2083         CommandArgumentEntry arg1;
2084         CommandArgumentData id_arg;
2085         id_arg.arg_type = eArgTypeBreakpointID;
2086         id_arg.arg_repetition = eArgRepeatOptional;
2087         arg1.push_back(id_arg);
2088         m_arguments.push_back (arg1);
2089
2090         m_option_group.Append (&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
2091         m_option_group.Finalize();
2092     }
2093
2094     virtual
2095     ~CommandObjectBreakpointNameDelete () {}
2096
2097   Options *
2098   GetOptions ()
2099   {
2100     return &m_option_group;
2101   }
2102   
2103 protected:
2104     virtual bool
2105     DoExecute (Args& command, CommandReturnObject &result)
2106     {
2107         if (!m_name_options.m_name.OptionWasSet())
2108         {
2109             result.SetError("No name option provided.");
2110             return false;
2111         }
2112
2113         Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
2114
2115         if (target == NULL)
2116         {
2117             result.AppendError ("Invalid target. No existing target or breakpoints.");
2118             result.SetStatus (eReturnStatusFailed);
2119             return false;
2120         }
2121
2122         Mutex::Locker locker;
2123         target->GetBreakpointList().GetListMutex(locker);
2124         
2125         const BreakpointList &breakpoints = target->GetBreakpointList();
2126
2127         size_t num_breakpoints = breakpoints.GetSize();
2128         if (num_breakpoints == 0)
2129         {
2130             result.SetError("No breakpoints, cannot delete names.");
2131             result.SetStatus (eReturnStatusFailed);
2132             return false;
2133         }
2134
2135         // Particular breakpoint selected; disable that breakpoint.
2136         BreakpointIDList valid_bp_ids;
2137         CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
2138
2139         if (result.Succeeded())
2140         {
2141             if (valid_bp_ids.GetSize() == 0)
2142             {
2143                 result.SetError("No breakpoints specified, cannot delete names.");
2144                 result.SetStatus (eReturnStatusFailed);
2145                 return false;
2146             }
2147             size_t num_valid_ids = valid_bp_ids.GetSize();
2148             for (size_t index = 0; index < num_valid_ids; index++)
2149             {
2150                 lldb::break_id_t bp_id = valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
2151                 BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
2152                 bp_sp->RemoveName(m_name_options.m_name.GetCurrentValue());
2153             }
2154         }
2155
2156         return true;
2157     }
2158
2159 private:
2160     BreakpointNameOptionGroup m_name_options;
2161     OptionGroupOptions m_option_group;
2162 };
2163
2164 class CommandObjectBreakpointNameList : public CommandObjectParsed
2165 {
2166 public:
2167     CommandObjectBreakpointNameList (CommandInterpreter &interpreter) :
2168         CommandObjectParsed (interpreter,
2169                              "list",
2170                              "List either the names for a breakpoint or the breakpoints for a given name.",
2171                              "breakpoint name list <command-options>"),
2172         m_name_options(),
2173         m_option_group(interpreter)
2174     {
2175         m_option_group.Append (&m_name_options);
2176         m_option_group.Finalize();
2177     }
2178
2179     virtual
2180     ~CommandObjectBreakpointNameList () {}
2181
2182   Options *
2183   GetOptions ()
2184   {
2185     return &m_option_group;
2186   }
2187   
2188 protected:
2189 protected:
2190     virtual bool
2191     DoExecute (Args& command, CommandReturnObject &result)
2192     {
2193         Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
2194
2195         if (target == NULL)
2196         {
2197             result.AppendError ("Invalid target. No existing target or breakpoints.");
2198             result.SetStatus (eReturnStatusFailed);
2199             return false;
2200         }
2201
2202         if (m_name_options.m_name.OptionWasSet())
2203         {
2204             const char *name = m_name_options.m_name.GetCurrentValue();
2205             Mutex::Locker locker;
2206             target->GetBreakpointList().GetListMutex(locker);
2207             
2208             BreakpointList &breakpoints = target->GetBreakpointList();
2209             for (BreakpointSP bp_sp : breakpoints.Breakpoints())
2210             {
2211                 if (bp_sp->MatchesName(name))
2212                 {
2213                     StreamString s;
2214                     bp_sp->GetDescription(&s, eDescriptionLevelBrief);
2215                     s.EOL();
2216                     result.AppendMessage(s.GetData());
2217                 }
2218             }
2219
2220         }
2221         else if (m_name_options.m_breakpoint.OptionWasSet())
2222         {
2223             BreakpointSP bp_sp = target->GetBreakpointList().FindBreakpointByID(m_name_options.m_breakpoint.GetCurrentValue());
2224             if (bp_sp)
2225             {
2226                 std::vector<std::string> names;
2227                 bp_sp->GetNames (names);
2228                 result.AppendMessage ("Names:");
2229                 for (auto name : names)
2230                     result.AppendMessageWithFormat ("    %s\n", name.c_str());
2231             }
2232             else
2233             {
2234                 result.AppendErrorWithFormat ("Could not find breakpoint %" PRId64 ".\n",
2235                                            m_name_options.m_breakpoint.GetCurrentValue());
2236                 result.SetStatus (eReturnStatusFailed);
2237                 return false;
2238             }
2239         }
2240         else
2241         {
2242             result.SetError ("Must specify -N or -B option to list.");
2243             result.SetStatus (eReturnStatusFailed);
2244             return false;
2245         }
2246         return true;
2247     }
2248
2249 private:
2250     BreakpointNameOptionGroup m_name_options;
2251     OptionGroupOptions m_option_group;
2252 };
2253
2254 //-------------------------------------------------------------------------
2255 // CommandObjectMultiwordBreakpoint
2256 //-------------------------------------------------------------------------
2257 class CommandObjectBreakpointName : public CommandObjectMultiword
2258 {
2259 public:
2260     CommandObjectBreakpointName (CommandInterpreter &interpreter) :
2261         CommandObjectMultiword(interpreter,
2262                                 "name",
2263                                 "A set of commands to manage name tags for breakpoints",
2264                                 "breakpoint name <command> [<command-options>]")
2265     {
2266         CommandObjectSP add_command_object (new CommandObjectBreakpointNameAdd (interpreter));
2267         CommandObjectSP delete_command_object (new CommandObjectBreakpointNameDelete (interpreter));
2268         CommandObjectSP list_command_object (new CommandObjectBreakpointNameList (interpreter));
2269
2270         LoadSubCommand ("add", add_command_object);
2271         LoadSubCommand ("delete", delete_command_object);
2272         LoadSubCommand ("list", list_command_object);
2273
2274     }
2275
2276     virtual
2277     ~CommandObjectBreakpointName ()
2278     {
2279     }
2280
2281 };
2282
2283
2284 //-------------------------------------------------------------------------
2285 // CommandObjectMultiwordBreakpoint
2286 //-------------------------------------------------------------------------
2287 #pragma mark MultiwordBreakpoint
2288
2289 CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint (CommandInterpreter &interpreter) :
2290     CommandObjectMultiword (interpreter, 
2291                             "breakpoint",
2292                             "A set of commands for operating on breakpoints. Also see _regexp-break.",
2293                             "breakpoint <command> [<command-options>]")
2294 {
2295     CommandObjectSP list_command_object (new CommandObjectBreakpointList (interpreter));
2296     CommandObjectSP enable_command_object (new CommandObjectBreakpointEnable (interpreter));
2297     CommandObjectSP disable_command_object (new CommandObjectBreakpointDisable (interpreter));
2298     CommandObjectSP clear_command_object (new CommandObjectBreakpointClear (interpreter));
2299     CommandObjectSP delete_command_object (new CommandObjectBreakpointDelete (interpreter));
2300     CommandObjectSP set_command_object (new CommandObjectBreakpointSet (interpreter));
2301     CommandObjectSP command_command_object (new CommandObjectBreakpointCommand (interpreter));
2302     CommandObjectSP modify_command_object (new CommandObjectBreakpointModify(interpreter));
2303     CommandObjectSP name_command_object (new CommandObjectBreakpointName(interpreter));
2304
2305     list_command_object->SetCommandName ("breakpoint list");
2306     enable_command_object->SetCommandName("breakpoint enable");
2307     disable_command_object->SetCommandName("breakpoint disable");
2308     clear_command_object->SetCommandName("breakpoint clear");
2309     delete_command_object->SetCommandName("breakpoint delete");
2310     set_command_object->SetCommandName("breakpoint set");
2311     command_command_object->SetCommandName ("breakpoint command");
2312     modify_command_object->SetCommandName ("breakpoint modify");
2313     name_command_object->SetCommandName ("breakpoint name");
2314
2315     LoadSubCommand ("list",       list_command_object);
2316     LoadSubCommand ("enable",     enable_command_object);
2317     LoadSubCommand ("disable",    disable_command_object);
2318     LoadSubCommand ("clear",      clear_command_object);
2319     LoadSubCommand ("delete",     delete_command_object);
2320     LoadSubCommand ("set",        set_command_object);
2321     LoadSubCommand ("command",    command_command_object);
2322     LoadSubCommand ("modify",     modify_command_object);
2323     LoadSubCommand ("name",       name_command_object);
2324 }
2325
2326 CommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint ()
2327 {
2328 }
2329
2330 void
2331 CommandObjectMultiwordBreakpoint::VerifyIDs (Args &args,
2332                                              Target *target,
2333                                              bool allow_locations,
2334                                              CommandReturnObject &result,
2335                                              BreakpointIDList *valid_ids)
2336 {
2337     // args can be strings representing 1). integers (for breakpoint ids)
2338     //                                  2). the full breakpoint & location canonical representation
2339     //                                  3). the word "to" or a hyphen, representing a range (in which case there
2340     //                                      had *better* be an entry both before & after of one of the first two types.
2341     //                                  4). A breakpoint name
2342     // If args is empty, we will use the last created breakpoint (if there is one.)
2343
2344     Args temp_args;
2345
2346     if (args.GetArgumentCount() == 0)
2347     {
2348         if (target->GetLastCreatedBreakpoint())
2349         {
2350             valid_ids->AddBreakpointID (BreakpointID(target->GetLastCreatedBreakpoint()->GetID(), LLDB_INVALID_BREAK_ID));
2351             result.SetStatus (eReturnStatusSuccessFinishNoResult);
2352         } 
2353         else
2354         {   
2355             result.AppendError("No breakpoint specified and no last created breakpoint.");
2356             result.SetStatus (eReturnStatusFailed);
2357         }
2358         return;
2359     }
2360     
2361     // Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff directly from the old ARGS to
2362     // the new TEMP_ARGS.  Do not copy breakpoint id range strings over; instead generate a list of strings for
2363     // all the breakpoint ids in the range, and shove all of those breakpoint id strings into TEMP_ARGS.
2364
2365     BreakpointIDList::FindAndReplaceIDRanges (args, target, allow_locations, result, temp_args);
2366
2367     // NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual BreakpointIDList:
2368
2369     valid_ids->InsertStringArray (temp_args.GetConstArgumentVector(), temp_args.GetArgumentCount(), result);
2370
2371     // At this point,  all of the breakpoint ids that the user passed in have been converted to breakpoint IDs
2372     // and put into valid_ids.
2373
2374     if (result.Succeeded())
2375     {
2376         // Now that we've converted everything from args into a list of breakpoint ids, go through our tentative list
2377         // of breakpoint id's and verify that they correspond to valid/currently set breakpoints.
2378
2379         const size_t count = valid_ids->GetSize();
2380         for (size_t i = 0; i < count; ++i)
2381         {
2382             BreakpointID cur_bp_id = valid_ids->GetBreakpointIDAtIndex (i);
2383             Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
2384             if (breakpoint != NULL)
2385             {
2386                 const size_t num_locations = breakpoint->GetNumLocations();
2387                 if (static_cast<size_t>(cur_bp_id.GetLocationID()) > num_locations)
2388                 {
2389                     StreamString id_str;
2390                     BreakpointID::GetCanonicalReference (&id_str, 
2391                                                          cur_bp_id.GetBreakpointID(),
2392                                                          cur_bp_id.GetLocationID());
2393                     i = valid_ids->GetSize() + 1;
2394                     result.AppendErrorWithFormat ("'%s' is not a currently valid breakpoint/location id.\n",
2395                                                  id_str.GetData());
2396                     result.SetStatus (eReturnStatusFailed);
2397                 }
2398             }
2399             else
2400             {
2401                 i = valid_ids->GetSize() + 1;
2402                 result.AppendErrorWithFormat ("'%d' is not a currently valid breakpoint id.\n", cur_bp_id.GetBreakpointID());
2403                 result.SetStatus (eReturnStatusFailed);
2404             }
2405         }
2406     }
2407 }