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