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