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