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