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