130fdc8d8SChris Lattner //===-- CommandObjectBreakpoint.cpp -----------------------------*- C++ -*-===//
230fdc8d8SChris Lattner //
330fdc8d8SChris Lattner //                     The LLVM Compiler Infrastructure
430fdc8d8SChris Lattner //
530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source
630fdc8d8SChris Lattner // License. See LICENSE.TXT for details.
730fdc8d8SChris Lattner //
830fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
930fdc8d8SChris Lattner 
1093a64300SDaniel Malea #include "lldb/lldb-python.h"
1193a64300SDaniel Malea 
1230fdc8d8SChris Lattner #include "CommandObjectBreakpoint.h"
1330fdc8d8SChris Lattner #include "CommandObjectBreakpointCommand.h"
1430fdc8d8SChris Lattner 
1530fdc8d8SChris Lattner // C Includes
1630fdc8d8SChris Lattner // C++ Includes
1730fdc8d8SChris Lattner // Other libraries and framework includes
1830fdc8d8SChris Lattner // Project includes
1930fdc8d8SChris Lattner #include "lldb/Breakpoint/Breakpoint.h"
2030fdc8d8SChris Lattner #include "lldb/Breakpoint/BreakpointIDList.h"
2130fdc8d8SChris Lattner #include "lldb/Breakpoint/BreakpointLocation.h"
225275aaa0SVince Harron #include "lldb/Host/StringConvert.h"
2340af72e1SJim Ingham #include "lldb/Interpreter/Options.h"
2432abc6edSZachary Turner #include "lldb/Interpreter/OptionValueBoolean.h"
255e09c8c3SJim Ingham #include "lldb/Interpreter/OptionValueString.h"
265e09c8c3SJim Ingham #include "lldb/Interpreter/OptionValueUInt64.h"
2730fdc8d8SChris Lattner #include "lldb/Core/RegularExpression.h"
2830fdc8d8SChris Lattner #include "lldb/Core/StreamString.h"
2930fdc8d8SChris Lattner #include "lldb/Interpreter/CommandInterpreter.h"
3030fdc8d8SChris Lattner #include "lldb/Interpreter/CommandReturnObject.h"
31a78bd7ffSZachary Turner #include "lldb/Target/LanguageRuntime.h"
3230fdc8d8SChris Lattner #include "lldb/Target/Target.h"
3330fdc8d8SChris Lattner #include "lldb/Interpreter/CommandCompletions.h"
34b57e4a1bSJason Molenda #include "lldb/Target/StackFrame.h"
351b54c88cSJim Ingham #include "lldb/Target/Thread.h"
361b54c88cSJim Ingham #include "lldb/Target/ThreadSpec.h"
3730fdc8d8SChris Lattner 
38b7234e40SJohnny Chen #include <vector>
39b7234e40SJohnny Chen 
4030fdc8d8SChris Lattner using namespace lldb;
4130fdc8d8SChris Lattner using namespace lldb_private;
4230fdc8d8SChris Lattner 
4330fdc8d8SChris Lattner static void
4485e8b814SJim Ingham AddBreakpointDescription (Stream *s, Breakpoint *bp, lldb::DescriptionLevel level)
4530fdc8d8SChris Lattner {
4630fdc8d8SChris Lattner     s->IndentMore();
4730fdc8d8SChris Lattner     bp->GetDescription (s, level, true);
4830fdc8d8SChris Lattner     s->IndentLess();
4930fdc8d8SChris Lattner     s->EOL();
5030fdc8d8SChris Lattner }
5130fdc8d8SChris Lattner 
5230fdc8d8SChris Lattner //-------------------------------------------------------------------------
535a988416SJim Ingham // CommandObjectBreakpointSet
5430fdc8d8SChris Lattner //-------------------------------------------------------------------------
5530fdc8d8SChris Lattner 
565a988416SJim Ingham 
575a988416SJim Ingham class CommandObjectBreakpointSet : public CommandObjectParsed
585a988416SJim Ingham {
595a988416SJim Ingham public:
605a988416SJim Ingham 
615a988416SJim Ingham     typedef enum BreakpointSetType
625a988416SJim Ingham     {
635a988416SJim Ingham         eSetTypeInvalid,
645a988416SJim Ingham         eSetTypeFileAndLine,
655a988416SJim Ingham         eSetTypeAddress,
665a988416SJim Ingham         eSetTypeFunctionName,
675a988416SJim Ingham         eSetTypeFunctionRegexp,
685a988416SJim Ingham         eSetTypeSourceRegexp,
695a988416SJim Ingham         eSetTypeException
705a988416SJim Ingham     } BreakpointSetType;
715a988416SJim Ingham 
725a988416SJim Ingham     CommandObjectBreakpointSet (CommandInterpreter &interpreter) :
735a988416SJim Ingham         CommandObjectParsed (interpreter,
745a988416SJim Ingham                              "breakpoint set",
755a988416SJim Ingham                              "Sets a breakpoint or set of breakpoints in the executable.",
765a988416SJim Ingham                              "breakpoint set <cmd-options>"),
775a988416SJim Ingham         m_options (interpreter)
785a988416SJim Ingham     {
795a988416SJim Ingham     }
805a988416SJim Ingham 
815a988416SJim Ingham 
825a988416SJim Ingham     virtual
835a988416SJim Ingham     ~CommandObjectBreakpointSet () {}
845a988416SJim Ingham 
855a988416SJim Ingham     virtual Options *
865a988416SJim Ingham     GetOptions ()
875a988416SJim Ingham     {
885a988416SJim Ingham         return &m_options;
895a988416SJim Ingham     }
905a988416SJim Ingham 
915a988416SJim Ingham     class CommandOptions : public Options
925a988416SJim Ingham     {
935a988416SJim Ingham     public:
945a988416SJim Ingham 
955a988416SJim Ingham         CommandOptions (CommandInterpreter &interpreter) :
96eb0103f2SGreg Clayton             Options (interpreter),
977d49c9c8SJohnny Chen             m_condition (),
9887df91b8SJim Ingham             m_filenames (),
9930fdc8d8SChris Lattner             m_line_num (0),
10030fdc8d8SChris Lattner             m_column (0),
101fab10e89SJim Ingham             m_func_names (),
102fab10e89SJim Ingham             m_func_name_type_mask (eFunctionNameTypeNone),
10330fdc8d8SChris Lattner             m_func_regexp (),
104969795f1SJim Ingham             m_source_text_regexp(),
10530fdc8d8SChris Lattner             m_modules (),
1061b54c88cSJim Ingham             m_load_addr(),
107c982c768SGreg Clayton             m_ignore_count (0),
1081b54c88cSJim Ingham             m_thread_id(LLDB_INVALID_THREAD_ID),
109c982c768SGreg Clayton             m_thread_index (UINT32_MAX),
1101b54c88cSJim Ingham             m_thread_name(),
111fab10e89SJim Ingham             m_queue_name(),
112fab10e89SJim Ingham             m_catch_bp (false),
1131f746071SGreg Clayton             m_throw_bp (true),
114eb023e75SGreg Clayton             m_hardware (false),
115a72b31c7SJim Ingham             m_exception_language (eLanguageTypeUnknown),
116ca36cd16SJim Ingham             m_skip_prologue (eLazyBoolCalculate),
117e732052fSJim Ingham             m_one_shot (false),
118*055ad9beSIlia K             m_all_files (false),
119*055ad9beSIlia K             m_move_to_nearest_code (eLazyBoolCalculate)
12030fdc8d8SChris Lattner         {
12130fdc8d8SChris Lattner         }
12230fdc8d8SChris Lattner 
12330fdc8d8SChris Lattner 
1245a988416SJim Ingham         virtual
1255a988416SJim Ingham         ~CommandOptions () {}
12687df91b8SJim Ingham 
1275a988416SJim Ingham         virtual Error
1285a988416SJim Ingham         SetOptionValue (uint32_t option_idx, const char *option_arg)
12930fdc8d8SChris Lattner         {
13030fdc8d8SChris Lattner             Error error;
1313bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
13230fdc8d8SChris Lattner 
13330fdc8d8SChris Lattner             switch (short_option)
13430fdc8d8SChris Lattner             {
13530fdc8d8SChris Lattner                 case 'a':
136b9d5df58SGreg Clayton                     {
137b9d5df58SGreg Clayton                         ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
138b9d5df58SGreg Clayton                         m_load_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
139b9d5df58SGreg Clayton                     }
14030fdc8d8SChris Lattner                     break;
14130fdc8d8SChris Lattner 
142e732052fSJim Ingham                 case 'A':
143e732052fSJim Ingham                     m_all_files = true;
144e732052fSJim Ingham                     break;
145e732052fSJim Ingham 
146ca36cd16SJim Ingham                 case 'b':
147ca36cd16SJim Ingham                     m_func_names.push_back (option_arg);
148ca36cd16SJim Ingham                     m_func_name_type_mask |= eFunctionNameTypeBase;
149ca36cd16SJim Ingham                     break;
150ca36cd16SJim Ingham 
1517d49c9c8SJohnny Chen                 case 'C':
1526312991cSJim Ingham                 {
1536312991cSJim Ingham                     bool success;
1546312991cSJim Ingham                     m_column = StringConvert::ToUInt32 (option_arg, 0, 0, &success);
1556312991cSJim Ingham                     if (!success)
1566312991cSJim Ingham                         error.SetErrorStringWithFormat("invalid column number: %s", option_arg);
15730fdc8d8SChris Lattner                     break;
1586312991cSJim Ingham                 }
1597d49c9c8SJohnny Chen                 case 'c':
1607d49c9c8SJohnny Chen                     m_condition.assign(option_arg);
1617d49c9c8SJohnny Chen                     break;
1627d49c9c8SJohnny Chen 
16333df7cd3SJim Ingham                 case 'D':
16433df7cd3SJim Ingham                     m_use_dummy = true;
16533df7cd3SJim Ingham                     break;
16633df7cd3SJim Ingham 
167fab10e89SJim Ingham                 case 'E':
168fab10e89SJim Ingham                 {
169fab10e89SJim Ingham                     LanguageType language = LanguageRuntime::GetLanguageTypeFromString (option_arg);
170fab10e89SJim Ingham 
171fab10e89SJim Ingham                     switch (language)
172fab10e89SJim Ingham                     {
173fab10e89SJim Ingham                         case eLanguageTypeC89:
174fab10e89SJim Ingham                         case eLanguageTypeC:
175fab10e89SJim Ingham                         case eLanguageTypeC99:
1761d0089faSBruce Mitchener                         case eLanguageTypeC11:
177a72b31c7SJim Ingham                             m_exception_language = eLanguageTypeC;
178fab10e89SJim Ingham                             break;
179fab10e89SJim Ingham                         case eLanguageTypeC_plus_plus:
1801d0089faSBruce Mitchener                         case eLanguageTypeC_plus_plus_03:
1811d0089faSBruce Mitchener                         case eLanguageTypeC_plus_plus_11:
1822ba84a6aSBruce Mitchener                         case eLanguageTypeC_plus_plus_14:
183a72b31c7SJim Ingham                             m_exception_language = eLanguageTypeC_plus_plus;
184fab10e89SJim Ingham                             break;
185fab10e89SJim Ingham                         case eLanguageTypeObjC:
186a72b31c7SJim Ingham                             m_exception_language = eLanguageTypeObjC;
187fab10e89SJim Ingham                             break;
188fab10e89SJim Ingham                         case eLanguageTypeObjC_plus_plus:
189fab10e89SJim Ingham                             error.SetErrorStringWithFormat ("Set exception breakpoints separately for c++ and objective-c");
190fab10e89SJim Ingham                             break;
191fab10e89SJim Ingham                         case eLanguageTypeUnknown:
192fab10e89SJim Ingham                             error.SetErrorStringWithFormat ("Unknown language type: '%s' for exception breakpoint", option_arg);
193fab10e89SJim Ingham                             break;
194fab10e89SJim Ingham                         default:
195fab10e89SJim Ingham                             error.SetErrorStringWithFormat ("Unsupported language type: '%s' for exception breakpoint", option_arg);
196fab10e89SJim Ingham                     }
197fab10e89SJim Ingham                 }
198fab10e89SJim Ingham                 break;
199ca36cd16SJim Ingham 
200ca36cd16SJim Ingham                 case 'f':
201ca36cd16SJim Ingham                     m_filenames.AppendIfUnique (FileSpec(option_arg, false));
202fab10e89SJim Ingham                     break;
203ca36cd16SJim Ingham 
204ca36cd16SJim Ingham                 case 'F':
205ca36cd16SJim Ingham                     m_func_names.push_back (option_arg);
206ca36cd16SJim Ingham                     m_func_name_type_mask |= eFunctionNameTypeFull;
207ca36cd16SJim Ingham                     break;
208ca36cd16SJim Ingham 
209fab10e89SJim Ingham                 case 'h':
210fab10e89SJim Ingham                     {
211fab10e89SJim Ingham                         bool success;
212fab10e89SJim Ingham                         m_catch_bp = Args::StringToBoolean (option_arg, true, &success);
213fab10e89SJim Ingham                         if (!success)
214fab10e89SJim Ingham                             error.SetErrorStringWithFormat ("Invalid boolean value for on-catch option: '%s'", option_arg);
215fab10e89SJim Ingham                     }
216168d469aSJim Ingham                     break;
217eb023e75SGreg Clayton 
218eb023e75SGreg Clayton                 case 'H':
219eb023e75SGreg Clayton                     m_hardware = true;
220eb023e75SGreg Clayton                     break;
221eb023e75SGreg Clayton 
222ca36cd16SJim Ingham                 case 'i':
223ca36cd16SJim Ingham                 {
2245275aaa0SVince Harron                     m_ignore_count = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
225ca36cd16SJim Ingham                     if (m_ignore_count == UINT32_MAX)
226ca36cd16SJim Ingham                        error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
227ca36cd16SJim Ingham                     break;
228ca36cd16SJim Ingham                 }
229ca36cd16SJim Ingham 
230a8558b62SJim Ingham                 case 'K':
231a8558b62SJim Ingham                 {
232a8558b62SJim Ingham                     bool success;
233a8558b62SJim Ingham                     bool value;
234a8558b62SJim Ingham                     value = Args::StringToBoolean (option_arg, true, &success);
235a8558b62SJim Ingham                     if (value)
236a8558b62SJim Ingham                         m_skip_prologue = eLazyBoolYes;
237a8558b62SJim Ingham                     else
238a8558b62SJim Ingham                         m_skip_prologue = eLazyBoolNo;
239a8558b62SJim Ingham 
240a8558b62SJim Ingham                     if (!success)
241a8558b62SJim Ingham                         error.SetErrorStringWithFormat ("Invalid boolean value for skip prologue option: '%s'", option_arg);
242a8558b62SJim Ingham                 }
243fab10e89SJim Ingham                 break;
244ca36cd16SJim Ingham 
245ca36cd16SJim Ingham                 case 'l':
2466312991cSJim Ingham                 {
2476312991cSJim Ingham                     bool success;
2486312991cSJim Ingham                     m_line_num = StringConvert::ToUInt32 (option_arg, 0, 0, &success);
2496312991cSJim Ingham                     if (!success)
2506312991cSJim Ingham                         error.SetErrorStringWithFormat ("invalid line number: %s.", option_arg);
251ca36cd16SJim Ingham                     break;
2526312991cSJim Ingham                 }
253*055ad9beSIlia K 
254*055ad9beSIlia K                 case 'm':
255*055ad9beSIlia K                 {
256*055ad9beSIlia K                     bool success;
257*055ad9beSIlia K                     bool value;
258*055ad9beSIlia K                     value = Args::StringToBoolean (option_arg, true, &success);
259*055ad9beSIlia K                     if (value)
260*055ad9beSIlia K                         m_move_to_nearest_code = eLazyBoolYes;
261*055ad9beSIlia K                     else
262*055ad9beSIlia K                         m_move_to_nearest_code = eLazyBoolNo;
263*055ad9beSIlia K 
264*055ad9beSIlia K                     if (!success)
265*055ad9beSIlia K                         error.SetErrorStringWithFormat ("Invalid boolean value for move-to-nearest-code option: '%s'", option_arg);
266*055ad9beSIlia K                     break;
267*055ad9beSIlia K                 }
268*055ad9beSIlia K 
269ca36cd16SJim Ingham                 case 'M':
270ca36cd16SJim Ingham                     m_func_names.push_back (option_arg);
271ca36cd16SJim Ingham                     m_func_name_type_mask |= eFunctionNameTypeMethod;
272ca36cd16SJim Ingham                     break;
273ca36cd16SJim Ingham 
274ca36cd16SJim Ingham                 case 'n':
275ca36cd16SJim Ingham                     m_func_names.push_back (option_arg);
276ca36cd16SJim Ingham                     m_func_name_type_mask |= eFunctionNameTypeAuto;
277ca36cd16SJim Ingham                     break;
278ca36cd16SJim Ingham 
2795e09c8c3SJim Ingham                 case 'N':
2805e09c8c3SJim Ingham                     if (BreakpointID::StringIsBreakpointName(option_arg, error))
2815e09c8c3SJim Ingham                         m_breakpoint_names.push_back (option_arg);
2825e09c8c3SJim Ingham                     break;
2835e09c8c3SJim Ingham 
284ca36cd16SJim Ingham                 case 'o':
285ca36cd16SJim Ingham                     m_one_shot = true;
286ca36cd16SJim Ingham                     break;
287ca36cd16SJim Ingham 
288a72b31c7SJim Ingham                 case 'O':
289a72b31c7SJim Ingham                     m_exception_extra_args.AppendArgument ("-O");
290a72b31c7SJim Ingham                     m_exception_extra_args.AppendArgument (option_arg);
291a72b31c7SJim Ingham                     break;
292a72b31c7SJim Ingham 
293ca36cd16SJim Ingham                 case 'p':
294ca36cd16SJim Ingham                     m_source_text_regexp.assign (option_arg);
295ca36cd16SJim Ingham                     break;
296ca36cd16SJim Ingham 
297ca36cd16SJim Ingham                 case 'q':
298ca36cd16SJim Ingham                     m_queue_name.assign (option_arg);
299ca36cd16SJim Ingham                     break;
300ca36cd16SJim Ingham 
301ca36cd16SJim Ingham                 case 'r':
302ca36cd16SJim Ingham                     m_func_regexp.assign (option_arg);
303ca36cd16SJim Ingham                     break;
304ca36cd16SJim Ingham 
305ca36cd16SJim Ingham                 case 's':
306ca36cd16SJim Ingham                 {
307ca36cd16SJim Ingham                     m_modules.AppendIfUnique (FileSpec (option_arg, false));
308ca36cd16SJim Ingham                     break;
309ca36cd16SJim Ingham                 }
310ca36cd16SJim Ingham 
311ca36cd16SJim Ingham                 case 'S':
312ca36cd16SJim Ingham                     m_func_names.push_back (option_arg);
313ca36cd16SJim Ingham                     m_func_name_type_mask |= eFunctionNameTypeSelector;
314ca36cd16SJim Ingham                     break;
315ca36cd16SJim Ingham 
316ca36cd16SJim Ingham                 case 't' :
317ca36cd16SJim Ingham                 {
3185275aaa0SVince Harron                     m_thread_id = StringConvert::ToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
319ca36cd16SJim Ingham                     if (m_thread_id == LLDB_INVALID_THREAD_ID)
320ca36cd16SJim Ingham                        error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
321ca36cd16SJim Ingham                 }
322ca36cd16SJim Ingham                 break;
323ca36cd16SJim Ingham 
324ca36cd16SJim Ingham                 case 'T':
325ca36cd16SJim Ingham                     m_thread_name.assign (option_arg);
326ca36cd16SJim Ingham                     break;
327ca36cd16SJim Ingham 
328ca36cd16SJim Ingham                 case 'w':
329ca36cd16SJim Ingham                 {
330ca36cd16SJim Ingham                     bool success;
331ca36cd16SJim Ingham                     m_throw_bp = Args::StringToBoolean (option_arg, true, &success);
332ca36cd16SJim Ingham                     if (!success)
333ca36cd16SJim Ingham                         error.SetErrorStringWithFormat ("Invalid boolean value for on-throw option: '%s'", option_arg);
334ca36cd16SJim Ingham                 }
335ca36cd16SJim Ingham                 break;
336ca36cd16SJim Ingham 
337ca36cd16SJim Ingham                 case 'x':
338ca36cd16SJim Ingham                 {
3395275aaa0SVince Harron                     m_thread_index = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
340ca36cd16SJim Ingham                     if (m_thread_id == UINT32_MAX)
341ca36cd16SJim Ingham                        error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
342ca36cd16SJim Ingham 
343ca36cd16SJim Ingham                 }
344ca36cd16SJim Ingham                 break;
345ca36cd16SJim Ingham 
34630fdc8d8SChris Lattner                 default:
34786edbf41SGreg Clayton                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
34830fdc8d8SChris Lattner                     break;
34930fdc8d8SChris Lattner             }
35030fdc8d8SChris Lattner 
35130fdc8d8SChris Lattner             return error;
35230fdc8d8SChris Lattner         }
35330fdc8d8SChris Lattner         void
3545a988416SJim Ingham         OptionParsingStarting ()
35530fdc8d8SChris Lattner         {
3567d49c9c8SJohnny Chen             m_condition.clear();
35787df91b8SJim Ingham             m_filenames.Clear();
35830fdc8d8SChris Lattner             m_line_num = 0;
35930fdc8d8SChris Lattner             m_column = 0;
360fab10e89SJim Ingham             m_func_names.clear();
3611f746071SGreg Clayton             m_func_name_type_mask = eFunctionNameTypeNone;
36230fdc8d8SChris Lattner             m_func_regexp.clear();
3631f746071SGreg Clayton             m_source_text_regexp.clear();
36487df91b8SJim Ingham             m_modules.Clear();
3651f746071SGreg Clayton             m_load_addr = LLDB_INVALID_ADDRESS;
366c982c768SGreg Clayton             m_ignore_count = 0;
3671b54c88cSJim Ingham             m_thread_id = LLDB_INVALID_THREAD_ID;
368c982c768SGreg Clayton             m_thread_index = UINT32_MAX;
3691b54c88cSJim Ingham             m_thread_name.clear();
3701b54c88cSJim Ingham             m_queue_name.clear();
371fab10e89SJim Ingham             m_catch_bp = false;
372fab10e89SJim Ingham             m_throw_bp = true;
373eb023e75SGreg Clayton             m_hardware = false;
374a72b31c7SJim Ingham             m_exception_language = eLanguageTypeUnknown;
375a8558b62SJim Ingham             m_skip_prologue = eLazyBoolCalculate;
376ca36cd16SJim Ingham             m_one_shot = false;
37733df7cd3SJim Ingham             m_use_dummy = false;
3785e09c8c3SJim Ingham             m_breakpoint_names.clear();
379e732052fSJim Ingham             m_all_files = false;
380a72b31c7SJim Ingham             m_exception_extra_args.Clear();
381*055ad9beSIlia K             m_move_to_nearest_code = eLazyBoolCalculate;
38230fdc8d8SChris Lattner         }
38330fdc8d8SChris Lattner 
3845a988416SJim Ingham         const OptionDefinition*
3855a988416SJim Ingham         GetDefinitions ()
38630fdc8d8SChris Lattner         {
3875a988416SJim Ingham             return g_option_table;
38830fdc8d8SChris Lattner         }
38930fdc8d8SChris Lattner 
3905a988416SJim Ingham         // Options table: Required for subclasses of Options.
39130fdc8d8SChris Lattner 
3925a988416SJim Ingham         static OptionDefinition g_option_table[];
39330fdc8d8SChris Lattner 
3945a988416SJim Ingham         // Instance variables to hold the values for command options.
395969795f1SJim Ingham 
3965a988416SJim Ingham         std::string m_condition;
3975a988416SJim Ingham         FileSpecList m_filenames;
3985a988416SJim Ingham         uint32_t m_line_num;
3995a988416SJim Ingham         uint32_t m_column;
4005a988416SJim Ingham         std::vector<std::string> m_func_names;
4015e09c8c3SJim Ingham         std::vector<std::string> m_breakpoint_names;
4025a988416SJim Ingham         uint32_t m_func_name_type_mask;
4035a988416SJim Ingham         std::string m_func_regexp;
4045a988416SJim Ingham         std::string m_source_text_regexp;
4055a988416SJim Ingham         FileSpecList m_modules;
4065a988416SJim Ingham         lldb::addr_t m_load_addr;
4075a988416SJim Ingham         uint32_t m_ignore_count;
4085a988416SJim Ingham         lldb::tid_t m_thread_id;
4095a988416SJim Ingham         uint32_t m_thread_index;
4105a988416SJim Ingham         std::string m_thread_name;
4115a988416SJim Ingham         std::string m_queue_name;
4125a988416SJim Ingham         bool m_catch_bp;
4135a988416SJim Ingham         bool m_throw_bp;
414eb023e75SGreg Clayton         bool m_hardware; // Request to use hardware breakpoints
415a72b31c7SJim Ingham         lldb::LanguageType m_exception_language;
4165a988416SJim Ingham         LazyBool m_skip_prologue;
417ca36cd16SJim Ingham         bool m_one_shot;
41833df7cd3SJim Ingham         bool m_use_dummy;
419e732052fSJim Ingham         bool m_all_files;
420a72b31c7SJim Ingham         Args m_exception_extra_args;
421*055ad9beSIlia K         LazyBool m_move_to_nearest_code;
4225a988416SJim Ingham 
4235a988416SJim Ingham     };
4245a988416SJim Ingham 
4255a988416SJim Ingham protected:
4265a988416SJim Ingham     virtual bool
4275a988416SJim Ingham     DoExecute (Args& command,
4285a988416SJim Ingham               CommandReturnObject &result)
42930fdc8d8SChris Lattner     {
43033df7cd3SJim Ingham         Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
43133df7cd3SJim Ingham 
432893c932aSJim Ingham         if (target == nullptr)
43330fdc8d8SChris Lattner         {
434effe5c95SGreg Clayton             result.AppendError ("Invalid target.  Must set target before setting breakpoints (see 'target create' command).");
43530fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
43630fdc8d8SChris Lattner             return false;
43730fdc8d8SChris Lattner         }
43830fdc8d8SChris Lattner 
43930fdc8d8SChris Lattner         // The following are the various types of breakpoints that could be set:
44030fdc8d8SChris Lattner         //   1).  -f -l -p  [-s -g]   (setting breakpoint by source location)
44130fdc8d8SChris Lattner         //   2).  -a  [-s -g]         (setting breakpoint by address)
44230fdc8d8SChris Lattner         //   3).  -n  [-s -g]         (setting breakpoint by function name)
44330fdc8d8SChris Lattner         //   4).  -r  [-s -g]         (setting breakpoint by function name regular expression)
444969795f1SJim Ingham         //   5).  -p -f               (setting a breakpoint by comparing a reg-exp to source text)
445fab10e89SJim Ingham         //   6).  -E [-w -h]          (setting a breakpoint for exceptions for a given language.)
44630fdc8d8SChris Lattner 
44730fdc8d8SChris Lattner         BreakpointSetType break_type = eSetTypeInvalid;
44830fdc8d8SChris Lattner 
44930fdc8d8SChris Lattner         if (m_options.m_line_num != 0)
45030fdc8d8SChris Lattner             break_type = eSetTypeFileAndLine;
45130fdc8d8SChris Lattner         else if (m_options.m_load_addr != LLDB_INVALID_ADDRESS)
45230fdc8d8SChris Lattner             break_type = eSetTypeAddress;
453fab10e89SJim Ingham         else if (!m_options.m_func_names.empty())
45430fdc8d8SChris Lattner             break_type = eSetTypeFunctionName;
45530fdc8d8SChris Lattner         else if  (!m_options.m_func_regexp.empty())
45630fdc8d8SChris Lattner             break_type = eSetTypeFunctionRegexp;
457969795f1SJim Ingham         else if (!m_options.m_source_text_regexp.empty())
458969795f1SJim Ingham             break_type = eSetTypeSourceRegexp;
459a72b31c7SJim Ingham         else if (m_options.m_exception_language != eLanguageTypeUnknown)
460fab10e89SJim Ingham             break_type = eSetTypeException;
46130fdc8d8SChris Lattner 
46230fdc8d8SChris Lattner         Breakpoint *bp = NULL;
463274060b6SGreg Clayton         FileSpec module_spec;
464a8558b62SJim Ingham         const bool internal = false;
465a8558b62SJim Ingham 
46630fdc8d8SChris Lattner         switch (break_type)
46730fdc8d8SChris Lattner         {
46830fdc8d8SChris Lattner             case eSetTypeFileAndLine: // Breakpoint by source position
46930fdc8d8SChris Lattner                 {
47030fdc8d8SChris Lattner                     FileSpec file;
471c7bece56SGreg Clayton                     const size_t num_files = m_options.m_filenames.GetSize();
47287df91b8SJim Ingham                     if (num_files == 0)
47387df91b8SJim Ingham                     {
47487df91b8SJim Ingham                         if (!GetDefaultFile (target, file, result))
47587df91b8SJim Ingham                         {
47687df91b8SJim Ingham                             result.AppendError("No file supplied and no default file available.");
47787df91b8SJim Ingham                             result.SetStatus (eReturnStatusFailed);
47887df91b8SJim Ingham                             return false;
47987df91b8SJim Ingham                         }
48087df91b8SJim Ingham                     }
48187df91b8SJim Ingham                     else if (num_files > 1)
48287df91b8SJim Ingham                     {
48387df91b8SJim Ingham                         result.AppendError("Only one file at a time is allowed for file and line breakpoints.");
48487df91b8SJim Ingham                         result.SetStatus (eReturnStatusFailed);
48587df91b8SJim Ingham                         return false;
48687df91b8SJim Ingham                     }
48787df91b8SJim Ingham                     else
48887df91b8SJim Ingham                         file = m_options.m_filenames.GetFileSpecAtIndex(0);
48930fdc8d8SChris Lattner 
4901f746071SGreg Clayton                     // Only check for inline functions if
4911f746071SGreg Clayton                     LazyBool check_inlines = eLazyBoolCalculate;
4921f746071SGreg Clayton 
49387df91b8SJim Ingham                     bp = target->CreateBreakpoint (&(m_options.m_modules),
49430fdc8d8SChris Lattner                                                    file,
49530fdc8d8SChris Lattner                                                    m_options.m_line_num,
4961f746071SGreg Clayton                                                    check_inlines,
497a8558b62SJim Ingham                                                    m_options.m_skip_prologue,
498eb023e75SGreg Clayton                                                    internal,
499*055ad9beSIlia K                                                    m_options.m_hardware,
500*055ad9beSIlia K                                                    m_options.m_move_to_nearest_code).get();
50130fdc8d8SChris Lattner                 }
50230fdc8d8SChris Lattner                 break;
5036eee5aa0SGreg Clayton 
50430fdc8d8SChris Lattner             case eSetTypeAddress: // Breakpoint by address
505eb023e75SGreg Clayton                 bp = target->CreateBreakpoint (m_options.m_load_addr,
506eb023e75SGreg Clayton                                                internal,
507eb023e75SGreg Clayton                                                m_options.m_hardware).get();
50830fdc8d8SChris Lattner                 break;
5090c5cd90dSGreg Clayton 
51030fdc8d8SChris Lattner             case eSetTypeFunctionName: // Breakpoint by function name
5110c5cd90dSGreg Clayton                 {
5120c5cd90dSGreg Clayton                     uint32_t name_type_mask = m_options.m_func_name_type_mask;
5130c5cd90dSGreg Clayton 
5140c5cd90dSGreg Clayton                     if (name_type_mask == 0)
515e02b8504SGreg Clayton                         name_type_mask = eFunctionNameTypeAuto;
5160c5cd90dSGreg Clayton 
51787df91b8SJim Ingham                     bp = target->CreateBreakpoint (&(m_options.m_modules),
51887df91b8SJim Ingham                                                    &(m_options.m_filenames),
519fab10e89SJim Ingham                                                    m_options.m_func_names,
520274060b6SGreg Clayton                                                    name_type_mask,
521a8558b62SJim Ingham                                                    m_options.m_skip_prologue,
522eb023e75SGreg Clayton                                                    internal,
523eb023e75SGreg Clayton                                                    m_options.m_hardware).get();
5240c5cd90dSGreg Clayton                 }
52530fdc8d8SChris Lattner                 break;
5260c5cd90dSGreg Clayton 
52730fdc8d8SChris Lattner             case eSetTypeFunctionRegexp: // Breakpoint by regular expression function name
52830fdc8d8SChris Lattner                 {
52930fdc8d8SChris Lattner                     RegularExpression regexp(m_options.m_func_regexp.c_str());
530969795f1SJim Ingham                     if (!regexp.IsValid())
53130fdc8d8SChris Lattner                     {
532969795f1SJim Ingham                         char err_str[1024];
533969795f1SJim Ingham                         regexp.GetErrorAsCString(err_str, sizeof(err_str));
534969795f1SJim Ingham                         result.AppendErrorWithFormat("Function name regular expression could not be compiled: \"%s\"",
535969795f1SJim Ingham                                                      err_str);
53630fdc8d8SChris Lattner                         result.SetStatus (eReturnStatusFailed);
537969795f1SJim Ingham                         return false;
53830fdc8d8SChris Lattner                     }
53987df91b8SJim Ingham 
540a8558b62SJim Ingham                     bp = target->CreateFuncRegexBreakpoint (&(m_options.m_modules),
541a8558b62SJim Ingham                                                             &(m_options.m_filenames),
542a8558b62SJim Ingham                                                             regexp,
543a8558b62SJim Ingham                                                             m_options.m_skip_prologue,
544eb023e75SGreg Clayton                                                             internal,
545eb023e75SGreg Clayton                                                             m_options.m_hardware).get();
54630fdc8d8SChris Lattner                 }
54730fdc8d8SChris Lattner                 break;
548969795f1SJim Ingham             case eSetTypeSourceRegexp: // Breakpoint by regexp on source text.
549969795f1SJim Ingham                 {
550c7bece56SGreg Clayton                     const size_t num_files = m_options.m_filenames.GetSize();
55187df91b8SJim Ingham 
552e732052fSJim Ingham                     if (num_files == 0 && !m_options.m_all_files)
55387df91b8SJim Ingham                     {
554969795f1SJim Ingham                         FileSpec file;
55587df91b8SJim Ingham                         if (!GetDefaultFile (target, file, result))
55687df91b8SJim Ingham                         {
55787df91b8SJim Ingham                             result.AppendError ("No files provided and could not find default file.");
55887df91b8SJim Ingham                             result.SetStatus (eReturnStatusFailed);
55987df91b8SJim Ingham                             return false;
56087df91b8SJim Ingham                         }
56187df91b8SJim Ingham                         else
56287df91b8SJim Ingham                         {
56387df91b8SJim Ingham                             m_options.m_filenames.Append (file);
56487df91b8SJim Ingham                         }
56587df91b8SJim Ingham                     }
5660c5cd90dSGreg Clayton 
567969795f1SJim Ingham                     RegularExpression regexp(m_options.m_source_text_regexp.c_str());
568969795f1SJim Ingham                     if (!regexp.IsValid())
569969795f1SJim Ingham                     {
570969795f1SJim Ingham                         char err_str[1024];
571969795f1SJim Ingham                         regexp.GetErrorAsCString(err_str, sizeof(err_str));
572969795f1SJim Ingham                         result.AppendErrorWithFormat("Source text regular expression could not be compiled: \"%s\"",
573969795f1SJim Ingham                                                      err_str);
574969795f1SJim Ingham                         result.SetStatus (eReturnStatusFailed);
575969795f1SJim Ingham                         return false;
576969795f1SJim Ingham                     }
577eb023e75SGreg Clayton                     bp = target->CreateSourceRegexBreakpoint (&(m_options.m_modules),
578eb023e75SGreg Clayton                                                               &(m_options.m_filenames),
579eb023e75SGreg Clayton                                                               regexp,
580eb023e75SGreg Clayton                                                               internal,
581*055ad9beSIlia K                                                               m_options.m_hardware,
582*055ad9beSIlia K                                                               m_options.m_move_to_nearest_code).get();
583969795f1SJim Ingham                 }
584969795f1SJim Ingham                 break;
585fab10e89SJim Ingham             case eSetTypeException:
586fab10e89SJim Ingham                 {
587a72b31c7SJim Ingham                     Error precond_error;
588a72b31c7SJim Ingham                     bp = target->CreateExceptionBreakpoint (m_options.m_exception_language,
589eb023e75SGreg Clayton                                                             m_options.m_catch_bp,
590eb023e75SGreg Clayton                                                             m_options.m_throw_bp,
591a72b31c7SJim Ingham                                                             internal,
592a72b31c7SJim Ingham                                                             &m_options.m_exception_extra_args,
593a72b31c7SJim Ingham                                                             &precond_error).get();
594a72b31c7SJim Ingham                     if (precond_error.Fail())
595a72b31c7SJim Ingham                     {
596a72b31c7SJim Ingham                         result.AppendErrorWithFormat("Error setting extra exception arguments: %s",
597a72b31c7SJim Ingham                                                      precond_error.AsCString());
598a72b31c7SJim Ingham                         target->RemoveBreakpointByID(bp->GetID());
599a72b31c7SJim Ingham                         result.SetStatus(eReturnStatusFailed);
600a72b31c7SJim Ingham                         return false;
601a72b31c7SJim Ingham                     }
602fab10e89SJim Ingham                 }
603fab10e89SJim Ingham                 break;
60430fdc8d8SChris Lattner             default:
60530fdc8d8SChris Lattner                 break;
60630fdc8d8SChris Lattner         }
60730fdc8d8SChris Lattner 
6081b54c88cSJim Ingham         // Now set the various options that were passed in:
6091b54c88cSJim Ingham         if (bp)
6101b54c88cSJim Ingham         {
6111b54c88cSJim Ingham             if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
6121b54c88cSJim Ingham                 bp->SetThreadID (m_options.m_thread_id);
6131b54c88cSJim Ingham 
614c982c768SGreg Clayton             if (m_options.m_thread_index != UINT32_MAX)
6151b54c88cSJim Ingham                 bp->GetOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index);
6161b54c88cSJim Ingham 
6171b54c88cSJim Ingham             if (!m_options.m_thread_name.empty())
6181b54c88cSJim Ingham                 bp->GetOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str());
6191b54c88cSJim Ingham 
6201b54c88cSJim Ingham             if (!m_options.m_queue_name.empty())
6211b54c88cSJim Ingham                 bp->GetOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str());
6221b54c88cSJim Ingham 
623c982c768SGreg Clayton             if (m_options.m_ignore_count != 0)
6241b54c88cSJim Ingham                 bp->GetOptions()->SetIgnoreCount(m_options.m_ignore_count);
6257d49c9c8SJohnny Chen 
6267d49c9c8SJohnny Chen             if (!m_options.m_condition.empty())
6277d49c9c8SJohnny Chen                 bp->GetOptions()->SetCondition(m_options.m_condition.c_str());
628ca36cd16SJim Ingham 
6295e09c8c3SJim Ingham             if (!m_options.m_breakpoint_names.empty())
6305e09c8c3SJim Ingham             {
6315e09c8c3SJim Ingham                 Error error;  // We don't need to check the error here, since the option parser checked it...
6325e09c8c3SJim Ingham                 for (auto name : m_options.m_breakpoint_names)
6335e09c8c3SJim Ingham                     bp->AddName(name.c_str(), error);
6345e09c8c3SJim Ingham             }
6355e09c8c3SJim Ingham 
636ca36cd16SJim Ingham             bp->SetOneShot (m_options.m_one_shot);
6371b54c88cSJim Ingham         }
6381b54c88cSJim Ingham 
639969795f1SJim Ingham         if (bp)
64030fdc8d8SChris Lattner         {
64185e8b814SJim Ingham             Stream &output_stream = result.GetOutputStream();
6421391cc7dSJim Ingham             const bool show_locations = false;
6431391cc7dSJim Ingham             bp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial, show_locations);
6444aeb1989SJim Ingham             if (target == m_interpreter.GetDebugger().GetDummyTarget())
6454aeb1989SJim Ingham                     output_stream.Printf ("Breakpoint set in dummy target, will get copied into future targets.\n");
6464aeb1989SJim Ingham             else
6474aeb1989SJim Ingham             {
648fab10e89SJim Ingham                 // Don't print out this warning for exception breakpoints.  They can get set before the target
649fab10e89SJim Ingham                 // is set, but we won't know how to actually set the breakpoint till we run.
650fab10e89SJim Ingham                 if (bp->GetNumLocations() == 0 && break_type != eSetTypeException)
6514aeb1989SJim Ingham                 {
652be484f41SCaroline Tice                     output_stream.Printf ("WARNING:  Unable to resolve breakpoint to any actual locations.\n");
6534aeb1989SJim Ingham                 }
6544aeb1989SJim Ingham             }
65530fdc8d8SChris Lattner             result.SetStatus (eReturnStatusSuccessFinishResult);
65630fdc8d8SChris Lattner         }
65730fdc8d8SChris Lattner         else if (!bp)
65830fdc8d8SChris Lattner         {
65930fdc8d8SChris Lattner             result.AppendError ("Breakpoint creation failed: No breakpoint created.");
66030fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
66130fdc8d8SChris Lattner         }
66230fdc8d8SChris Lattner 
66330fdc8d8SChris Lattner         return result.Succeeded();
66430fdc8d8SChris Lattner     }
66530fdc8d8SChris Lattner 
6665a988416SJim Ingham private:
6675a988416SJim Ingham     bool
6685a988416SJim Ingham     GetDefaultFile (Target *target, FileSpec &file, CommandReturnObject &result)
6695a988416SJim Ingham     {
6705a988416SJim Ingham         uint32_t default_line;
6715a988416SJim Ingham         // First use the Source Manager's default file.
6725a988416SJim Ingham         // Then use the current stack frame's file.
6735a988416SJim Ingham         if (!target->GetSourceManager().GetDefaultFileAndLine(file, default_line))
6745a988416SJim Ingham         {
675b57e4a1bSJason Molenda             StackFrame *cur_frame = m_exe_ctx.GetFramePtr();
6765a988416SJim Ingham             if (cur_frame == NULL)
6775a988416SJim Ingham             {
6785a988416SJim Ingham                 result.AppendError ("No selected frame to use to find the default file.");
6795a988416SJim Ingham                 result.SetStatus (eReturnStatusFailed);
6805a988416SJim Ingham                 return false;
6815a988416SJim Ingham             }
6825a988416SJim Ingham             else if (!cur_frame->HasDebugInformation())
6835a988416SJim Ingham             {
6845a988416SJim Ingham                 result.AppendError ("Cannot use the selected frame to find the default file, it has no debug info.");
6855a988416SJim Ingham                 result.SetStatus (eReturnStatusFailed);
6865a988416SJim Ingham                 return false;
6875a988416SJim Ingham             }
6885a988416SJim Ingham             else
6895a988416SJim Ingham             {
6905a988416SJim Ingham                 const SymbolContext &sc = cur_frame->GetSymbolContext (eSymbolContextLineEntry);
6915a988416SJim Ingham                 if (sc.line_entry.file)
6925a988416SJim Ingham                 {
6935a988416SJim Ingham                     file = sc.line_entry.file;
6945a988416SJim Ingham                 }
6955a988416SJim Ingham                 else
6965a988416SJim Ingham                 {
6975a988416SJim Ingham                     result.AppendError ("Can't find the file for the selected frame to use as the default file.");
6985a988416SJim Ingham                     result.SetStatus (eReturnStatusFailed);
6995a988416SJim Ingham                     return false;
7005a988416SJim Ingham                 }
7015a988416SJim Ingham             }
7025a988416SJim Ingham         }
7035a988416SJim Ingham         return true;
7045a988416SJim Ingham     }
7055a988416SJim Ingham 
7065a988416SJim Ingham     CommandOptions m_options;
7075a988416SJim Ingham };
7085a988416SJim Ingham // If an additional option set beyond LLDB_OPTION_SET_10 is added, make sure to
7095a988416SJim Ingham // update the numbers passed to LLDB_OPT_SET_FROM_TO(...) appropriately.
7105a988416SJim Ingham #define LLDB_OPT_FILE ( LLDB_OPT_SET_FROM_TO(1, 9) & ~LLDB_OPT_SET_2 )
7115a988416SJim Ingham #define LLDB_OPT_NOT_10 ( LLDB_OPT_SET_FROM_TO(1, 10) & ~LLDB_OPT_SET_10 )
7125a988416SJim Ingham #define LLDB_OPT_SKIP_PROLOGUE ( LLDB_OPT_SET_1 | LLDB_OPT_SET_FROM_TO(3,8) )
713*055ad9beSIlia K #define LLDB_OPT_MOVE_TO_NEAREST_CODE ( LLDB_OPT_SET_1 | LLDB_OPT_SET_9 )
7145a988416SJim Ingham 
7155a988416SJim Ingham OptionDefinition
7165a988416SJim Ingham CommandObjectBreakpointSet::CommandOptions::g_option_table[] =
7175a988416SJim Ingham {
718d37221dcSZachary Turner     { LLDB_OPT_NOT_10, false, "shlib", 's', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName,
7195a988416SJim Ingham         "Set the breakpoint only in this shared library.  "
7205a988416SJim Ingham         "Can repeat this option multiple times to specify multiple shared libraries."},
7215a988416SJim Ingham 
722d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', OptionParser::eRequiredArgument,   NULL, NULL, 0, eArgTypeCount,
7235a988416SJim Ingham         "Set the number of times this breakpoint is skipped before stopping." },
7245a988416SJim Ingham 
725d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "one-shot", 'o', OptionParser::eNoArgument,   NULL, NULL, 0, eArgTypeNone,
726b2b256afSJim Ingham         "The breakpoint is deleted the first time it causes a stop." },
727ca36cd16SJim Ingham 
728d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "condition",    'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeExpression,
7295a988416SJim Ingham         "The breakpoint stops only if this condition expression evaluates to true."},
7305a988416SJim Ingham 
731d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadIndex,
732a89be91fSJim Ingham         "The breakpoint stops only for the thread whose indeX matches this argument."},
7335a988416SJim Ingham 
734d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadID,
7355a988416SJim Ingham         "The breakpoint stops only for the thread whose TID matches this argument."},
7365a988416SJim Ingham 
737d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadName,
7385a988416SJim Ingham         "The breakpoint stops only for the thread whose thread name matches this argument."},
7395a988416SJim Ingham 
740d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "hardware", 'H', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
741eb023e75SGreg Clayton         "Require the breakpoint to use hardware breakpoints."},
742eb023e75SGreg Clayton 
743d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeQueueName,
7445a988416SJim Ingham         "The breakpoint stops only for threads in the queue whose name is given by this argument."},
7455a988416SJim Ingham 
746d37221dcSZachary Turner     { LLDB_OPT_FILE, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
747289aca64SJim Ingham         "Specifies the source file in which to set this breakpoint.  "
748289aca64SJim Ingham         "Note, by default lldb only looks for files that are #included if they use the standard include file extensions.  "
7496394479eSJim Ingham         "To set breakpoints on .c/.cpp/.m/.mm files that are #included, set target.inline-breakpoint-strategy"
750289aca64SJim Ingham         " to \"always\"."},
7515a988416SJim Ingham 
752d37221dcSZachary Turner     { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum,
7535a988416SJim Ingham         "Specifies the line number on which to set this breakpoint."},
7545a988416SJim Ingham 
7555a988416SJim Ingham     // Comment out this option for the moment, as we don't actually use it, but will in the future.
7565a988416SJim Ingham     // This way users won't see it, but the infrastructure is left in place.
757e2607b50SVirgile Bello     //    { 0, false, "column",     'C', OptionParser::eRequiredArgument, NULL, "<column>",
7585a988416SJim Ingham     //    "Set the breakpoint by source location at this particular column."},
7595a988416SJim Ingham 
760d37221dcSZachary Turner     { LLDB_OPT_SET_2, true, "address", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression,
7615a988416SJim Ingham         "Set the breakpoint by address, at the specified address."},
7625a988416SJim Ingham 
763d37221dcSZachary Turner     { LLDB_OPT_SET_3, true, "name", 'n', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
764551262d7SJim Ingham         "Set the breakpoint by function name.  Can be repeated multiple times to make one breakpoint for multiple names" },
7655a988416SJim Ingham 
766d37221dcSZachary Turner     { LLDB_OPT_SET_4, true, "fullname", 'F', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFullName,
7675a988416SJim Ingham         "Set the breakpoint by fully qualified function names. For C++ this means namespaces and all arguments, and "
7685a988416SJim Ingham         "for Objective C this means a full function prototype with class and selector.   "
7695a988416SJim Ingham         "Can be repeated multiple times to make one breakpoint for multiple names." },
7705a988416SJim Ingham 
771d37221dcSZachary Turner     { LLDB_OPT_SET_5, true, "selector", 'S', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeSelector,
7725a988416SJim Ingham         "Set the breakpoint by ObjC selector name. Can be repeated multiple times to make one breakpoint for multiple Selectors." },
7735a988416SJim Ingham 
774d37221dcSZachary Turner     { LLDB_OPT_SET_6, true, "method", 'M', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeMethod,
7755a988416SJim Ingham         "Set the breakpoint by C++ method names.  Can be repeated multiple times to make one breakpoint for multiple methods." },
7765a988416SJim Ingham 
777d37221dcSZachary Turner     { LLDB_OPT_SET_7, true, "func-regex", 'r', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeRegularExpression,
7785a988416SJim Ingham         "Set the breakpoint by function name, evaluating a regular-expression to find the function name(s)." },
7795a988416SJim Ingham 
780d37221dcSZachary Turner     { LLDB_OPT_SET_8, true, "basename", 'b', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
7815a988416SJim Ingham         "Set the breakpoint by function basename (C++ namespaces and arguments will be ignored). "
7825a988416SJim Ingham         "Can be repeated multiple times to make one breakpoint for multiple symbols." },
7835a988416SJim Ingham 
784d37221dcSZachary Turner     { LLDB_OPT_SET_9, true, "source-pattern-regexp", 'p', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeRegularExpression,
785e96ade8bSJim Ingham         "Set the breakpoint by specifying a regular expression which is matched against the source text in a source file or files "
786e96ade8bSJim Ingham         "specified with the -f option.  The -f option can be specified more than once.  "
787e96ade8bSJim Ingham         "If no source files are specified, uses the current \"default source file\"" },
7885a988416SJim Ingham 
789e732052fSJim Ingham     { LLDB_OPT_SET_9, false, "all-files", 'A', OptionParser::eNoArgument,   NULL, NULL, 0, eArgTypeNone,
790e732052fSJim Ingham         "All files are searched for source pattern matches." },
791e732052fSJim Ingham 
792d37221dcSZachary Turner     { LLDB_OPT_SET_10, true, "language-exception", 'E', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage,
7935a988416SJim Ingham         "Set the breakpoint on exceptions thrown by the specified language (without options, on throw but not catch.)" },
7945a988416SJim Ingham 
795d37221dcSZachary Turner     { LLDB_OPT_SET_10, false, "on-throw", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,
7965a988416SJim Ingham         "Set the breakpoint on exception throW." },
7975a988416SJim Ingham 
798d37221dcSZachary Turner     { LLDB_OPT_SET_10, false, "on-catch", 'h', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,
7995a988416SJim Ingham         "Set the breakpoint on exception catcH." },
8005a988416SJim Ingham 
801a72b31c7SJim Ingham //  Don't add this option till it actually does something useful...
802a72b31c7SJim Ingham //    { LLDB_OPT_SET_10, false, "exception-typename", 'O', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeTypeName,
803a72b31c7SJim Ingham //        "The breakpoint will only stop if an exception Object of this type is thrown.  Can be repeated multiple times to stop for multiple object types" },
804a72b31c7SJim Ingham 
805d37221dcSZachary Turner     { LLDB_OPT_SKIP_PROLOGUE, false, "skip-prologue", 'K', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,
8065a988416SJim Ingham         "sKip the prologue if the breakpoint is at the beginning of a function.  If not set the target.skip-prologue setting is used." },
8075a988416SJim Ingham 
80833df7cd3SJim Ingham     { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
80933df7cd3SJim Ingham         "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
81033df7cd3SJim Ingham 
8115e09c8c3SJim Ingham     { LLDB_OPT_SET_ALL, false, "breakpoint-name", 'N', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBreakpointName,
8125e09c8c3SJim Ingham         "Adds this to the list of names for this breakopint."},
8135e09c8c3SJim Ingham 
814*055ad9beSIlia K     { LLDB_OPT_MOVE_TO_NEAREST_CODE, false, "move-to-nearest-code", 'm', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,
815*055ad9beSIlia K         "Move breakpoints to nearest code. If not set the target.move-to-nearest-code setting is used." },
816*055ad9beSIlia K 
817d37221dcSZachary Turner     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
8185a988416SJim Ingham };
8195a988416SJim Ingham 
8205a988416SJim Ingham //-------------------------------------------------------------------------
8215a988416SJim Ingham // CommandObjectBreakpointModify
8225a988416SJim Ingham //-------------------------------------------------------------------------
8235a988416SJim Ingham #pragma mark Modify
8245a988416SJim Ingham 
8255a988416SJim Ingham class CommandObjectBreakpointModify : public CommandObjectParsed
8265a988416SJim Ingham {
8275a988416SJim Ingham public:
8285a988416SJim Ingham 
8295a988416SJim Ingham     CommandObjectBreakpointModify (CommandInterpreter &interpreter) :
8305a988416SJim Ingham         CommandObjectParsed (interpreter,
8315a988416SJim Ingham                              "breakpoint modify",
8325a988416SJim Ingham                              "Modify the options on a breakpoint or set of breakpoints in the executable.  "
8335a988416SJim Ingham                              "If no breakpoint is specified, acts on the last created breakpoint.  "
8345a988416SJim Ingham                              "With the exception of -e, -d and -i, passing an empty argument clears the modification.",
8355a988416SJim Ingham                              NULL),
8365a988416SJim Ingham         m_options (interpreter)
8375a988416SJim Ingham     {
8385a988416SJim Ingham         CommandArgumentEntry arg;
8395a988416SJim Ingham         CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
8405a988416SJim Ingham         // Add the entry for the first argument for this command to the object's arguments vector.
8415a988416SJim Ingham         m_arguments.push_back (arg);
8425a988416SJim Ingham     }
8435a988416SJim Ingham 
8445a988416SJim Ingham 
8455a988416SJim Ingham     virtual
8465a988416SJim Ingham     ~CommandObjectBreakpointModify () {}
8475a988416SJim Ingham 
8485a988416SJim Ingham     virtual Options *
8495a988416SJim Ingham     GetOptions ()
8505a988416SJim Ingham     {
8515a988416SJim Ingham         return &m_options;
8525a988416SJim Ingham     }
8535a988416SJim Ingham 
8545a988416SJim Ingham     class CommandOptions : public Options
8555a988416SJim Ingham     {
8565a988416SJim Ingham     public:
8575a988416SJim Ingham 
8585a988416SJim Ingham         CommandOptions (CommandInterpreter &interpreter) :
8595a988416SJim Ingham             Options (interpreter),
8605a988416SJim Ingham             m_ignore_count (0),
8615a988416SJim Ingham             m_thread_id(LLDB_INVALID_THREAD_ID),
8625a988416SJim Ingham             m_thread_id_passed(false),
8635a988416SJim Ingham             m_thread_index (UINT32_MAX),
8645a988416SJim Ingham             m_thread_index_passed(false),
8655a988416SJim Ingham             m_thread_name(),
8665a988416SJim Ingham             m_queue_name(),
8675a988416SJim Ingham             m_condition (),
868ca36cd16SJim Ingham             m_one_shot (false),
8695a988416SJim Ingham             m_enable_passed (false),
8705a988416SJim Ingham             m_enable_value (false),
8715a988416SJim Ingham             m_name_passed (false),
8725a988416SJim Ingham             m_queue_passed (false),
873ca36cd16SJim Ingham             m_condition_passed (false),
87433df7cd3SJim Ingham             m_one_shot_passed (false),
87533df7cd3SJim Ingham             m_use_dummy (false)
8765a988416SJim Ingham         {
8775a988416SJim Ingham         }
8785a988416SJim Ingham 
8795a988416SJim Ingham         virtual
8805a988416SJim Ingham         ~CommandOptions () {}
8815a988416SJim Ingham 
8825a988416SJim Ingham         virtual Error
8835a988416SJim Ingham         SetOptionValue (uint32_t option_idx, const char *option_arg)
8845a988416SJim Ingham         {
8855a988416SJim Ingham             Error error;
8863bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
8875a988416SJim Ingham 
8885a988416SJim Ingham             switch (short_option)
8895a988416SJim Ingham             {
8905a988416SJim Ingham                 case 'c':
8915a988416SJim Ingham                     if (option_arg != NULL)
8925a988416SJim Ingham                         m_condition.assign (option_arg);
8935a988416SJim Ingham                     else
8945a988416SJim Ingham                         m_condition.clear();
8955a988416SJim Ingham                     m_condition_passed = true;
8965a988416SJim Ingham                     break;
8975a988416SJim Ingham                 case 'd':
8985a988416SJim Ingham                     m_enable_passed = true;
8995a988416SJim Ingham                     m_enable_value = false;
9005a988416SJim Ingham                     break;
90133df7cd3SJim Ingham                 case 'D':
90233df7cd3SJim Ingham                     m_use_dummy = true;
90333df7cd3SJim Ingham                     break;
9045a988416SJim Ingham                 case 'e':
9055a988416SJim Ingham                     m_enable_passed = true;
9065a988416SJim Ingham                     m_enable_value = true;
9075a988416SJim Ingham                     break;
9085a988416SJim Ingham                 case 'i':
9095a988416SJim Ingham                 {
9105275aaa0SVince Harron                     m_ignore_count = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
9115a988416SJim Ingham                     if (m_ignore_count == UINT32_MAX)
9125a988416SJim Ingham                        error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
9135a988416SJim Ingham                 }
9145a988416SJim Ingham                 break;
915ca36cd16SJim Ingham                 case 'o':
916ca36cd16SJim Ingham                 {
917ca36cd16SJim Ingham                     bool value, success;
918ca36cd16SJim Ingham                     value = Args::StringToBoolean(option_arg, false, &success);
919ca36cd16SJim Ingham                     if (success)
920ca36cd16SJim Ingham                     {
921ca36cd16SJim Ingham                         m_one_shot_passed = true;
922ca36cd16SJim Ingham                         m_one_shot = value;
923ca36cd16SJim Ingham                     }
924ca36cd16SJim Ingham                     else
925ca36cd16SJim Ingham                         error.SetErrorStringWithFormat("invalid boolean value '%s' passed for -o option", option_arg);
926ca36cd16SJim Ingham                 }
927ca36cd16SJim Ingham                 break;
9285a988416SJim Ingham                 case 't' :
9295a988416SJim Ingham                 {
9305a988416SJim Ingham                     if (option_arg[0] == '\0')
9315a988416SJim Ingham                     {
9325a988416SJim Ingham                         m_thread_id = LLDB_INVALID_THREAD_ID;
9335a988416SJim Ingham                         m_thread_id_passed = true;
9345a988416SJim Ingham                     }
9355a988416SJim Ingham                     else
9365a988416SJim Ingham                     {
9375275aaa0SVince Harron                         m_thread_id = StringConvert::ToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
9385a988416SJim Ingham                         if (m_thread_id == LLDB_INVALID_THREAD_ID)
9395a988416SJim Ingham                            error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
9405a988416SJim Ingham                         else
9415a988416SJim Ingham                             m_thread_id_passed = true;
9425a988416SJim Ingham                     }
9435a988416SJim Ingham                 }
9445a988416SJim Ingham                 break;
9455a988416SJim Ingham                 case 'T':
9465a988416SJim Ingham                     if (option_arg != NULL)
9475a988416SJim Ingham                         m_thread_name.assign (option_arg);
9485a988416SJim Ingham                     else
9495a988416SJim Ingham                         m_thread_name.clear();
9505a988416SJim Ingham                     m_name_passed = true;
9515a988416SJim Ingham                     break;
9525a988416SJim Ingham                 case 'q':
9535a988416SJim Ingham                     if (option_arg != NULL)
9545a988416SJim Ingham                         m_queue_name.assign (option_arg);
9555a988416SJim Ingham                     else
9565a988416SJim Ingham                         m_queue_name.clear();
9575a988416SJim Ingham                     m_queue_passed = true;
9585a988416SJim Ingham                     break;
9595a988416SJim Ingham                 case 'x':
9605a988416SJim Ingham                 {
9615a988416SJim Ingham                     if (option_arg[0] == '\n')
9625a988416SJim Ingham                     {
9635a988416SJim Ingham                         m_thread_index = UINT32_MAX;
9645a988416SJim Ingham                         m_thread_index_passed = true;
9655a988416SJim Ingham                     }
9665a988416SJim Ingham                     else
9675a988416SJim Ingham                     {
9685275aaa0SVince Harron                         m_thread_index = StringConvert::ToUInt32 (option_arg, UINT32_MAX, 0);
9695a988416SJim Ingham                         if (m_thread_id == UINT32_MAX)
9705a988416SJim Ingham                            error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
9715a988416SJim Ingham                         else
9725a988416SJim Ingham                             m_thread_index_passed = true;
9735a988416SJim Ingham                     }
9745a988416SJim Ingham                 }
9755a988416SJim Ingham                 break;
9765a988416SJim Ingham                 default:
9775a988416SJim Ingham                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
9785a988416SJim Ingham                     break;
9795a988416SJim Ingham             }
9805a988416SJim Ingham 
9815a988416SJim Ingham             return error;
9825a988416SJim Ingham         }
9835a988416SJim Ingham         void
9845a988416SJim Ingham         OptionParsingStarting ()
9855a988416SJim Ingham         {
9865a988416SJim Ingham             m_ignore_count = 0;
9875a988416SJim Ingham             m_thread_id = LLDB_INVALID_THREAD_ID;
9885a988416SJim Ingham             m_thread_id_passed = false;
9895a988416SJim Ingham             m_thread_index = UINT32_MAX;
9905a988416SJim Ingham             m_thread_index_passed = false;
9915a988416SJim Ingham             m_thread_name.clear();
9925a988416SJim Ingham             m_queue_name.clear();
9935a988416SJim Ingham             m_condition.clear();
994ca36cd16SJim Ingham             m_one_shot = false;
9955a988416SJim Ingham             m_enable_passed = false;
9965a988416SJim Ingham             m_queue_passed = false;
9975a988416SJim Ingham             m_name_passed = false;
9985a988416SJim Ingham             m_condition_passed = false;
999ca36cd16SJim Ingham             m_one_shot_passed = false;
100033df7cd3SJim Ingham             m_use_dummy = false;
10015a988416SJim Ingham         }
10025a988416SJim Ingham 
10035a988416SJim Ingham         const OptionDefinition*
10045a988416SJim Ingham         GetDefinitions ()
10055a988416SJim Ingham         {
10065a988416SJim Ingham             return g_option_table;
10075a988416SJim Ingham         }
10085a988416SJim Ingham 
10095a988416SJim Ingham 
10105a988416SJim Ingham         // Options table: Required for subclasses of Options.
10115a988416SJim Ingham 
10125a988416SJim Ingham         static OptionDefinition g_option_table[];
10135a988416SJim Ingham 
10145a988416SJim Ingham         // Instance variables to hold the values for command options.
10155a988416SJim Ingham 
10165a988416SJim Ingham         uint32_t m_ignore_count;
10175a988416SJim Ingham         lldb::tid_t m_thread_id;
10185a988416SJim Ingham         bool m_thread_id_passed;
10195a988416SJim Ingham         uint32_t m_thread_index;
10205a988416SJim Ingham         bool m_thread_index_passed;
10215a988416SJim Ingham         std::string m_thread_name;
10225a988416SJim Ingham         std::string m_queue_name;
10235a988416SJim Ingham         std::string m_condition;
1024ca36cd16SJim Ingham         bool m_one_shot;
10255a988416SJim Ingham         bool m_enable_passed;
10265a988416SJim Ingham         bool m_enable_value;
10275a988416SJim Ingham         bool m_name_passed;
10285a988416SJim Ingham         bool m_queue_passed;
10295a988416SJim Ingham         bool m_condition_passed;
1030ca36cd16SJim Ingham         bool m_one_shot_passed;
103133df7cd3SJim Ingham         bool m_use_dummy;
10325a988416SJim Ingham 
10335a988416SJim Ingham     };
10345a988416SJim Ingham 
10355a988416SJim Ingham protected:
10365a988416SJim Ingham     virtual bool
10375a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
10385a988416SJim Ingham     {
103933df7cd3SJim Ingham         Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
10405a988416SJim Ingham         if (target == NULL)
10415a988416SJim Ingham         {
10425a988416SJim Ingham             result.AppendError ("Invalid target.  No existing target or breakpoints.");
10435a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
10445a988416SJim Ingham             return false;
10455a988416SJim Ingham         }
10465a988416SJim Ingham 
10475a988416SJim Ingham         Mutex::Locker locker;
10485a988416SJim Ingham         target->GetBreakpointList().GetListMutex(locker);
10495a988416SJim Ingham 
10505a988416SJim Ingham         BreakpointIDList valid_bp_ids;
10515a988416SJim Ingham 
10525e09c8c3SJim Ingham         CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
10535a988416SJim Ingham 
10545a988416SJim Ingham         if (result.Succeeded())
10555a988416SJim Ingham         {
10565a988416SJim Ingham             const size_t count = valid_bp_ids.GetSize();
10575a988416SJim Ingham             for (size_t i = 0; i < count; ++i)
10585a988416SJim Ingham             {
10595a988416SJim Ingham                 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
10605a988416SJim Ingham 
10615a988416SJim Ingham                 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
10625a988416SJim Ingham                 {
10635a988416SJim Ingham                     Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
10645a988416SJim Ingham                     if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
10655a988416SJim Ingham                     {
10665a988416SJim Ingham                         BreakpointLocation *location = bp->FindLocationByID (cur_bp_id.GetLocationID()).get();
10675a988416SJim Ingham                         if (location)
10685a988416SJim Ingham                         {
10695a988416SJim Ingham                             if (m_options.m_thread_id_passed)
10705a988416SJim Ingham                                 location->SetThreadID (m_options.m_thread_id);
10715a988416SJim Ingham 
10725a988416SJim Ingham                             if (m_options.m_thread_index_passed)
10735a988416SJim Ingham                                 location->SetThreadIndex(m_options.m_thread_index);
10745a988416SJim Ingham 
10755a988416SJim Ingham                             if (m_options.m_name_passed)
10765a988416SJim Ingham                                 location->SetThreadName(m_options.m_thread_name.c_str());
10775a988416SJim Ingham 
10785a988416SJim Ingham                             if (m_options.m_queue_passed)
10795a988416SJim Ingham                                 location->SetQueueName(m_options.m_queue_name.c_str());
10805a988416SJim Ingham 
10815a988416SJim Ingham                             if (m_options.m_ignore_count != 0)
10825a988416SJim Ingham                                 location->SetIgnoreCount(m_options.m_ignore_count);
10835a988416SJim Ingham 
10845a988416SJim Ingham                             if (m_options.m_enable_passed)
10855a988416SJim Ingham                                 location->SetEnabled (m_options.m_enable_value);
10865a988416SJim Ingham 
10875a988416SJim Ingham                             if (m_options.m_condition_passed)
10885a988416SJim Ingham                                 location->SetCondition (m_options.m_condition.c_str());
10895a988416SJim Ingham                         }
10905a988416SJim Ingham                     }
10915a988416SJim Ingham                     else
10925a988416SJim Ingham                     {
10935a988416SJim Ingham                         if (m_options.m_thread_id_passed)
10945a988416SJim Ingham                             bp->SetThreadID (m_options.m_thread_id);
10955a988416SJim Ingham 
10965a988416SJim Ingham                         if (m_options.m_thread_index_passed)
10975a988416SJim Ingham                             bp->SetThreadIndex(m_options.m_thread_index);
10985a988416SJim Ingham 
10995a988416SJim Ingham                         if (m_options.m_name_passed)
11005a988416SJim Ingham                             bp->SetThreadName(m_options.m_thread_name.c_str());
11015a988416SJim Ingham 
11025a988416SJim Ingham                         if (m_options.m_queue_passed)
11035a988416SJim Ingham                             bp->SetQueueName(m_options.m_queue_name.c_str());
11045a988416SJim Ingham 
11055a988416SJim Ingham                         if (m_options.m_ignore_count != 0)
11065a988416SJim Ingham                             bp->SetIgnoreCount(m_options.m_ignore_count);
11075a988416SJim Ingham 
11085a988416SJim Ingham                         if (m_options.m_enable_passed)
11095a988416SJim Ingham                             bp->SetEnabled (m_options.m_enable_value);
11105a988416SJim Ingham 
11115a988416SJim Ingham                         if (m_options.m_condition_passed)
11125a988416SJim Ingham                             bp->SetCondition (m_options.m_condition.c_str());
11135a988416SJim Ingham                     }
11145a988416SJim Ingham                 }
11155a988416SJim Ingham             }
11165a988416SJim Ingham         }
11175a988416SJim Ingham 
11185a988416SJim Ingham         return result.Succeeded();
11195a988416SJim Ingham     }
11205a988416SJim Ingham 
11215a988416SJim Ingham private:
11225a988416SJim Ingham     CommandOptions m_options;
11235a988416SJim Ingham };
11245a988416SJim Ingham 
11255a988416SJim Ingham #pragma mark Modify::CommandOptions
11265a988416SJim Ingham OptionDefinition
11275a988416SJim Ingham CommandObjectBreakpointModify::CommandOptions::g_option_table[] =
11285a988416SJim Ingham {
1129d37221dcSZachary Turner { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeCount, "Set the number of times this breakpoint is skipped before stopping." },
1130d37221dcSZachary Turner { LLDB_OPT_SET_ALL, false, "one-shot",     'o', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "The breakpoint is deleted the first time it stop causes a stop." },
1131d37221dcSZachary Turner { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadIndex, "The breakpoint stops only for the thread whose index matches this argument."},
1132d37221dcSZachary Turner { LLDB_OPT_SET_ALL, false, "thread-id",    't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadID, "The breakpoint stops only for the thread whose TID matches this argument."},
1133d37221dcSZachary Turner { LLDB_OPT_SET_ALL, false, "thread-name",  'T', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadName, "The breakpoint stops only for the thread whose thread name matches this argument."},
1134d37221dcSZachary Turner { LLDB_OPT_SET_ALL, false, "queue-name",   'q', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeQueueName, "The breakpoint stops only for threads in the queue whose name is given by this argument."},
1135d37221dcSZachary Turner { LLDB_OPT_SET_ALL, false, "condition",    'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeExpression, "The breakpoint stops only if this condition expression evaluates to true."},
1136d37221dcSZachary Turner { LLDB_OPT_SET_1,   false, "enable",       'e', OptionParser::eNoArgument,       NULL, NULL, 0, eArgTypeNone, "Enable the breakpoint."},
1137d37221dcSZachary Turner { LLDB_OPT_SET_2,   false, "disable",      'd', OptionParser::eNoArgument,       NULL, NULL, 0, eArgTypeNone, "Disable the breakpoint."},
113833df7cd3SJim Ingham { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
113933df7cd3SJim Ingham 
1140d37221dcSZachary Turner { 0,                false, NULL,            0 , 0,                 NULL, NULL, 0, eArgTypeNone, NULL }
11415a988416SJim Ingham };
11425a988416SJim Ingham 
11435a988416SJim Ingham //-------------------------------------------------------------------------
11445a988416SJim Ingham // CommandObjectBreakpointEnable
11455a988416SJim Ingham //-------------------------------------------------------------------------
11465a988416SJim Ingham #pragma mark Enable
11475a988416SJim Ingham 
11485a988416SJim Ingham class CommandObjectBreakpointEnable : public CommandObjectParsed
11495a988416SJim Ingham {
11505a988416SJim Ingham public:
11515a988416SJim Ingham     CommandObjectBreakpointEnable (CommandInterpreter &interpreter) :
11525a988416SJim Ingham         CommandObjectParsed (interpreter,
11535a988416SJim Ingham                              "enable",
11545a988416SJim Ingham                              "Enable the specified disabled breakpoint(s). If no breakpoints are specified, enable all of them.",
11555a988416SJim Ingham                              NULL)
11565a988416SJim Ingham     {
11575a988416SJim Ingham         CommandArgumentEntry arg;
11585a988416SJim Ingham         CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
11595a988416SJim Ingham         // Add the entry for the first argument for this command to the object's arguments vector.
11605a988416SJim Ingham         m_arguments.push_back (arg);
11615a988416SJim Ingham     }
11625a988416SJim Ingham 
11635a988416SJim Ingham 
11645a988416SJim Ingham     virtual
11655a988416SJim Ingham     ~CommandObjectBreakpointEnable () {}
11665a988416SJim Ingham 
11675a988416SJim Ingham protected:
11685a988416SJim Ingham     virtual bool
11695a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
11705a988416SJim Ingham     {
1171893c932aSJim Ingham         Target *target = GetSelectedOrDummyTarget();
11725a988416SJim Ingham         if (target == NULL)
11735a988416SJim Ingham         {
11745a988416SJim Ingham             result.AppendError ("Invalid target.  No existing target or breakpoints.");
11755a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
11765a988416SJim Ingham             return false;
11775a988416SJim Ingham         }
11785a988416SJim Ingham 
11795a988416SJim Ingham         Mutex::Locker locker;
11805a988416SJim Ingham         target->GetBreakpointList().GetListMutex(locker);
11815a988416SJim Ingham 
11825a988416SJim Ingham         const BreakpointList &breakpoints = target->GetBreakpointList();
11835a988416SJim Ingham 
11845a988416SJim Ingham         size_t num_breakpoints = breakpoints.GetSize();
11855a988416SJim Ingham 
11865a988416SJim Ingham         if (num_breakpoints == 0)
11875a988416SJim Ingham         {
11885a988416SJim Ingham             result.AppendError ("No breakpoints exist to be enabled.");
11895a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
11905a988416SJim Ingham             return false;
11915a988416SJim Ingham         }
11925a988416SJim Ingham 
11935a988416SJim Ingham         if (command.GetArgumentCount() == 0)
11945a988416SJim Ingham         {
11955a988416SJim Ingham             // No breakpoint selected; enable all currently set breakpoints.
11965a988416SJim Ingham             target->EnableAllBreakpoints ();
11976fea17e8SGreg Clayton             result.AppendMessageWithFormat ("All breakpoints enabled. (%" PRIu64 " breakpoints)\n", (uint64_t)num_breakpoints);
11985a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
11995a988416SJim Ingham         }
12005a988416SJim Ingham         else
12015a988416SJim Ingham         {
12025a988416SJim Ingham             // Particular breakpoint selected; enable that breakpoint.
12035a988416SJim Ingham             BreakpointIDList valid_bp_ids;
12045e09c8c3SJim Ingham             CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
12055a988416SJim Ingham 
12065a988416SJim Ingham             if (result.Succeeded())
12075a988416SJim Ingham             {
12085a988416SJim Ingham                 int enable_count = 0;
12095a988416SJim Ingham                 int loc_count = 0;
12105a988416SJim Ingham                 const size_t count = valid_bp_ids.GetSize();
12115a988416SJim Ingham                 for (size_t i = 0; i < count; ++i)
12125a988416SJim Ingham                 {
12135a988416SJim Ingham                     BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
12145a988416SJim Ingham 
12155a988416SJim Ingham                     if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
12165a988416SJim Ingham                     {
12175a988416SJim Ingham                         Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
12185a988416SJim Ingham                         if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
12195a988416SJim Ingham                         {
12205a988416SJim Ingham                             BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
12215a988416SJim Ingham                             if (location)
12225a988416SJim Ingham                             {
12235a988416SJim Ingham                                 location->SetEnabled (true);
12245a988416SJim Ingham                                 ++loc_count;
12255a988416SJim Ingham                             }
12265a988416SJim Ingham                         }
12275a988416SJim Ingham                         else
12285a988416SJim Ingham                         {
12295a988416SJim Ingham                             breakpoint->SetEnabled (true);
12305a988416SJim Ingham                             ++enable_count;
12315a988416SJim Ingham                         }
12325a988416SJim Ingham                     }
12335a988416SJim Ingham                 }
12345a988416SJim Ingham                 result.AppendMessageWithFormat ("%d breakpoints enabled.\n", enable_count + loc_count);
12355a988416SJim Ingham                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
12365a988416SJim Ingham             }
12375a988416SJim Ingham         }
12385a988416SJim Ingham 
12395a988416SJim Ingham         return result.Succeeded();
12405a988416SJim Ingham     }
12415a988416SJim Ingham };
12425a988416SJim Ingham 
12435a988416SJim Ingham //-------------------------------------------------------------------------
12445a988416SJim Ingham // CommandObjectBreakpointDisable
12455a988416SJim Ingham //-------------------------------------------------------------------------
12465a988416SJim Ingham #pragma mark Disable
12475a988416SJim Ingham 
12485a988416SJim Ingham class CommandObjectBreakpointDisable : public CommandObjectParsed
12495a988416SJim Ingham {
12505a988416SJim Ingham public:
12515a988416SJim Ingham     CommandObjectBreakpointDisable (CommandInterpreter &interpreter) :
12525a988416SJim Ingham         CommandObjectParsed (interpreter,
12535a988416SJim Ingham                              "breakpoint disable",
12545a988416SJim Ingham                              "Disable the specified breakpoint(s) without removing it/them.  If no breakpoints are specified, disable them all.",
12555a988416SJim Ingham                              NULL)
12565a988416SJim Ingham     {
1257b0fac509SJim Ingham         SetHelpLong(
1258b0fac509SJim Ingham "Disable the specified breakpoint(s) without removing it/them.  \n\
1259b0fac509SJim Ingham If no breakpoints are specified, disable them all.\n\
1260b0fac509SJim Ingham \n\
1261b0fac509SJim Ingham Note: disabling a breakpoint will cause none of its locations to be hit\n\
1262b0fac509SJim Ingham regardless of whether they are enabled or disabled.  So the sequence: \n\
1263b0fac509SJim Ingham \n\
1264b0fac509SJim Ingham     (lldb) break disable 1\n\
1265b0fac509SJim Ingham     (lldb) break enable 1.1\n\
1266b0fac509SJim Ingham \n\
1267b0fac509SJim Ingham will NOT cause location 1.1 to get hit.  To achieve that, do:\n\
1268b0fac509SJim Ingham \n\
1269b0fac509SJim Ingham     (lldb) break disable 1.*\n\
1270b0fac509SJim Ingham     (lldb) break enable 1.1\n\
1271b0fac509SJim Ingham \n\
1272b0fac509SJim Ingham The first command disables all the locations of breakpoint 1, \n\
1273b0fac509SJim Ingham the second re-enables the first location."
1274b0fac509SJim Ingham                     );
1275b0fac509SJim Ingham 
12765a988416SJim Ingham         CommandArgumentEntry arg;
12775a988416SJim Ingham         CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
12785a988416SJim Ingham         // Add the entry for the first argument for this command to the object's arguments vector.
12795a988416SJim Ingham         m_arguments.push_back (arg);
1280b0fac509SJim Ingham 
12815a988416SJim Ingham     }
12825a988416SJim Ingham 
12835a988416SJim Ingham 
12845a988416SJim Ingham     virtual
12855a988416SJim Ingham     ~CommandObjectBreakpointDisable () {}
12865a988416SJim Ingham 
12875a988416SJim Ingham protected:
12885a988416SJim Ingham     virtual bool
12895a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
12905a988416SJim Ingham     {
1291893c932aSJim Ingham         Target *target = GetSelectedOrDummyTarget();
12925a988416SJim Ingham         if (target == NULL)
12935a988416SJim Ingham         {
12945a988416SJim Ingham             result.AppendError ("Invalid target.  No existing target or breakpoints.");
12955a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
12965a988416SJim Ingham             return false;
12975a988416SJim Ingham         }
12985a988416SJim Ingham 
12995a988416SJim Ingham         Mutex::Locker locker;
13005a988416SJim Ingham         target->GetBreakpointList().GetListMutex(locker);
13015a988416SJim Ingham 
13025a988416SJim Ingham         const BreakpointList &breakpoints = target->GetBreakpointList();
13035a988416SJim Ingham         size_t num_breakpoints = breakpoints.GetSize();
13045a988416SJim Ingham 
13055a988416SJim Ingham         if (num_breakpoints == 0)
13065a988416SJim Ingham         {
13075a988416SJim Ingham             result.AppendError ("No breakpoints exist to be disabled.");
13085a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
13095a988416SJim Ingham             return false;
13105a988416SJim Ingham         }
13115a988416SJim Ingham 
13125a988416SJim Ingham         if (command.GetArgumentCount() == 0)
13135a988416SJim Ingham         {
13145a988416SJim Ingham             // No breakpoint selected; disable all currently set breakpoints.
13155a988416SJim Ingham             target->DisableAllBreakpoints ();
13166fea17e8SGreg Clayton             result.AppendMessageWithFormat ("All breakpoints disabled. (%" PRIu64 " breakpoints)\n", (uint64_t)num_breakpoints);
13175a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
13185a988416SJim Ingham         }
13195a988416SJim Ingham         else
13205a988416SJim Ingham         {
13215a988416SJim Ingham             // Particular breakpoint selected; disable that breakpoint.
13225a988416SJim Ingham             BreakpointIDList valid_bp_ids;
13235a988416SJim Ingham 
13245e09c8c3SJim Ingham             CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
13255a988416SJim Ingham 
13265a988416SJim Ingham             if (result.Succeeded())
13275a988416SJim Ingham             {
13285a988416SJim Ingham                 int disable_count = 0;
13295a988416SJim Ingham                 int loc_count = 0;
13305a988416SJim Ingham                 const size_t count = valid_bp_ids.GetSize();
13315a988416SJim Ingham                 for (size_t i = 0; i < count; ++i)
13325a988416SJim Ingham                 {
13335a988416SJim Ingham                     BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
13345a988416SJim Ingham 
13355a988416SJim Ingham                     if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
13365a988416SJim Ingham                     {
13375a988416SJim Ingham                         Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
13385a988416SJim Ingham                         if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
13395a988416SJim Ingham                         {
13405a988416SJim Ingham                             BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
13415a988416SJim Ingham                             if (location)
13425a988416SJim Ingham                             {
13435a988416SJim Ingham                                 location->SetEnabled (false);
13445a988416SJim Ingham                                 ++loc_count;
13455a988416SJim Ingham                             }
13465a988416SJim Ingham                         }
13475a988416SJim Ingham                         else
13485a988416SJim Ingham                         {
13495a988416SJim Ingham                             breakpoint->SetEnabled (false);
13505a988416SJim Ingham                             ++disable_count;
13515a988416SJim Ingham                         }
13525a988416SJim Ingham                     }
13535a988416SJim Ingham                 }
13545a988416SJim Ingham                 result.AppendMessageWithFormat ("%d breakpoints disabled.\n", disable_count + loc_count);
13555a988416SJim Ingham                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
13565a988416SJim Ingham             }
13575a988416SJim Ingham         }
13585a988416SJim Ingham 
13595a988416SJim Ingham         return result.Succeeded();
13605a988416SJim Ingham     }
13615a988416SJim Ingham 
13625a988416SJim Ingham };
13635a988416SJim Ingham 
13645a988416SJim Ingham //-------------------------------------------------------------------------
13655a988416SJim Ingham // CommandObjectBreakpointList
13665a988416SJim Ingham //-------------------------------------------------------------------------
13675a988416SJim Ingham #pragma mark List
13685a988416SJim Ingham 
13695a988416SJim Ingham class CommandObjectBreakpointList : public CommandObjectParsed
13705a988416SJim Ingham {
13715a988416SJim Ingham public:
13725a988416SJim Ingham     CommandObjectBreakpointList (CommandInterpreter &interpreter) :
13735a988416SJim Ingham         CommandObjectParsed (interpreter,
13745a988416SJim Ingham                              "breakpoint list",
13755a988416SJim Ingham                              "List some or all breakpoints at configurable levels of detail.",
13765a988416SJim Ingham                              NULL),
13775a988416SJim Ingham         m_options (interpreter)
13785a988416SJim Ingham     {
13795a988416SJim Ingham         CommandArgumentEntry arg;
13805a988416SJim Ingham         CommandArgumentData bp_id_arg;
13815a988416SJim Ingham 
13825a988416SJim Ingham         // Define the first (and only) variant of this arg.
13835a988416SJim Ingham         bp_id_arg.arg_type = eArgTypeBreakpointID;
13845a988416SJim Ingham         bp_id_arg.arg_repetition = eArgRepeatOptional;
13855a988416SJim Ingham 
13865a988416SJim Ingham         // There is only one variant this argument could be; put it into the argument entry.
13875a988416SJim Ingham         arg.push_back (bp_id_arg);
13885a988416SJim Ingham 
13895a988416SJim Ingham         // Push the data for the first argument into the m_arguments vector.
13905a988416SJim Ingham         m_arguments.push_back (arg);
13915a988416SJim Ingham     }
13925a988416SJim Ingham 
13935a988416SJim Ingham 
13945a988416SJim Ingham     virtual
13955a988416SJim Ingham     ~CommandObjectBreakpointList () {}
13965a988416SJim Ingham 
13975a988416SJim Ingham     virtual Options *
13985a988416SJim Ingham     GetOptions ()
13995a988416SJim Ingham     {
14005a988416SJim Ingham         return &m_options;
14015a988416SJim Ingham     }
14025a988416SJim Ingham 
14035a988416SJim Ingham     class CommandOptions : public Options
14045a988416SJim Ingham     {
14055a988416SJim Ingham     public:
14065a988416SJim Ingham 
14075a988416SJim Ingham         CommandOptions (CommandInterpreter &interpreter) :
14085a988416SJim Ingham             Options (interpreter),
140933df7cd3SJim Ingham             m_level (lldb::eDescriptionLevelBrief),
141033df7cd3SJim Ingham             m_use_dummy(false)
14115a988416SJim Ingham         {
14125a988416SJim Ingham         }
14135a988416SJim Ingham 
14145a988416SJim Ingham         virtual
14155a988416SJim Ingham         ~CommandOptions () {}
14165a988416SJim Ingham 
14175a988416SJim Ingham         virtual Error
14185a988416SJim Ingham         SetOptionValue (uint32_t option_idx, const char *option_arg)
14195a988416SJim Ingham         {
14205a988416SJim Ingham             Error error;
14213bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
14225a988416SJim Ingham 
14235a988416SJim Ingham             switch (short_option)
14245a988416SJim Ingham             {
14255a988416SJim Ingham                 case 'b':
14265a988416SJim Ingham                     m_level = lldb::eDescriptionLevelBrief;
14275a988416SJim Ingham                     break;
142833df7cd3SJim Ingham                 case 'D':
142933df7cd3SJim Ingham                     m_use_dummy = true;
143033df7cd3SJim Ingham                     break;
14315a988416SJim Ingham                 case 'f':
14325a988416SJim Ingham                     m_level = lldb::eDescriptionLevelFull;
14335a988416SJim Ingham                     break;
14345a988416SJim Ingham                 case 'v':
14355a988416SJim Ingham                     m_level = lldb::eDescriptionLevelVerbose;
14365a988416SJim Ingham                     break;
14375a988416SJim Ingham                 case 'i':
14385a988416SJim Ingham                     m_internal = true;
14395a988416SJim Ingham                     break;
14405a988416SJim Ingham                 default:
14415a988416SJim Ingham                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
14425a988416SJim Ingham                     break;
14435a988416SJim Ingham             }
14445a988416SJim Ingham 
14455a988416SJim Ingham             return error;
14465a988416SJim Ingham         }
14475a988416SJim Ingham 
14485a988416SJim Ingham         void
14495a988416SJim Ingham         OptionParsingStarting ()
14505a988416SJim Ingham         {
14515a988416SJim Ingham             m_level = lldb::eDescriptionLevelFull;
14525a988416SJim Ingham             m_internal = false;
145333df7cd3SJim Ingham             m_use_dummy = false;
14545a988416SJim Ingham         }
14555a988416SJim Ingham 
14565a988416SJim Ingham         const OptionDefinition *
14575a988416SJim Ingham         GetDefinitions ()
14585a988416SJim Ingham         {
14595a988416SJim Ingham             return g_option_table;
14605a988416SJim Ingham         }
14615a988416SJim Ingham 
14625a988416SJim Ingham         // Options table: Required for subclasses of Options.
14635a988416SJim Ingham 
14645a988416SJim Ingham         static OptionDefinition g_option_table[];
14655a988416SJim Ingham 
14665a988416SJim Ingham         // Instance variables to hold the values for command options.
14675a988416SJim Ingham 
14685a988416SJim Ingham         lldb::DescriptionLevel m_level;
14695a988416SJim Ingham 
14705a988416SJim Ingham         bool m_internal;
147133df7cd3SJim Ingham         bool m_use_dummy;
14725a988416SJim Ingham     };
14735a988416SJim Ingham 
14745a988416SJim Ingham protected:
14755a988416SJim Ingham     virtual bool
14765a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
14775a988416SJim Ingham     {
147833df7cd3SJim Ingham         Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
147933df7cd3SJim Ingham 
14805a988416SJim Ingham         if (target == NULL)
14815a988416SJim Ingham         {
14825a988416SJim Ingham             result.AppendError ("Invalid target. No current target or breakpoints.");
14835a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
14845a988416SJim Ingham             return true;
14855a988416SJim Ingham         }
14865a988416SJim Ingham 
14875a988416SJim Ingham         const BreakpointList &breakpoints = target->GetBreakpointList(m_options.m_internal);
14885a988416SJim Ingham         Mutex::Locker locker;
14895a988416SJim Ingham         target->GetBreakpointList(m_options.m_internal).GetListMutex(locker);
14905a988416SJim Ingham 
14915a988416SJim Ingham         size_t num_breakpoints = breakpoints.GetSize();
14925a988416SJim Ingham 
14935a988416SJim Ingham         if (num_breakpoints == 0)
14945a988416SJim Ingham         {
14955a988416SJim Ingham             result.AppendMessage ("No breakpoints currently set.");
14965a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
14975a988416SJim Ingham             return true;
14985a988416SJim Ingham         }
14995a988416SJim Ingham 
15005a988416SJim Ingham         Stream &output_stream = result.GetOutputStream();
15015a988416SJim Ingham 
15025a988416SJim Ingham         if (command.GetArgumentCount() == 0)
15035a988416SJim Ingham         {
15045a988416SJim Ingham             // No breakpoint selected; show info about all currently set breakpoints.
15055a988416SJim Ingham             result.AppendMessage ("Current breakpoints:");
15065a988416SJim Ingham             for (size_t i = 0; i < num_breakpoints; ++i)
15075a988416SJim Ingham             {
15085a988416SJim Ingham                 Breakpoint *breakpoint = breakpoints.GetBreakpointAtIndex (i).get();
15095a988416SJim Ingham                 AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
15105a988416SJim Ingham             }
15115a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
15125a988416SJim Ingham         }
15135a988416SJim Ingham         else
15145a988416SJim Ingham         {
15155a988416SJim Ingham             // Particular breakpoints selected; show info about that breakpoint.
15165a988416SJim Ingham             BreakpointIDList valid_bp_ids;
15175e09c8c3SJim Ingham             CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
15185a988416SJim Ingham 
15195a988416SJim Ingham             if (result.Succeeded())
15205a988416SJim Ingham             {
15215a988416SJim Ingham                 for (size_t i = 0; i < valid_bp_ids.GetSize(); ++i)
15225a988416SJim Ingham                 {
15235a988416SJim Ingham                     BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
15245a988416SJim Ingham                     Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
15255a988416SJim Ingham                     AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
15265a988416SJim Ingham                 }
15275a988416SJim Ingham                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
15285a988416SJim Ingham             }
15295a988416SJim Ingham             else
15305a988416SJim Ingham             {
15315a988416SJim Ingham                 result.AppendError ("Invalid breakpoint id.");
15325a988416SJim Ingham                 result.SetStatus (eReturnStatusFailed);
15335a988416SJim Ingham             }
15345a988416SJim Ingham         }
15355a988416SJim Ingham 
15365a988416SJim Ingham         return result.Succeeded();
15375a988416SJim Ingham     }
15385a988416SJim Ingham 
15395a988416SJim Ingham private:
15405a988416SJim Ingham     CommandOptions m_options;
15415a988416SJim Ingham };
15425a988416SJim Ingham 
15435a988416SJim Ingham #pragma mark List::CommandOptions
15445a988416SJim Ingham OptionDefinition
15455a988416SJim Ingham CommandObjectBreakpointList::CommandOptions::g_option_table[] =
15465a988416SJim Ingham {
1547d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "internal", 'i', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
15485a988416SJim Ingham         "Show debugger internal breakpoints" },
15495a988416SJim Ingham 
1550d37221dcSZachary Turner     { LLDB_OPT_SET_1, false, "brief",    'b', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
15515a988416SJim Ingham         "Give a brief description of the breakpoint (no location info)."},
15525a988416SJim Ingham 
15535a988416SJim Ingham     // FIXME: We need to add an "internal" command, and then add this sort of thing to it.
15545a988416SJim Ingham     // But I need to see it for now, and don't want to wait.
1555d37221dcSZachary Turner     { LLDB_OPT_SET_2, false, "full",    'f', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
15565a988416SJim Ingham         "Give a full description of the breakpoint and its locations."},
15575a988416SJim Ingham 
1558d37221dcSZachary Turner     { LLDB_OPT_SET_3, false, "verbose", 'v', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
15595a988416SJim Ingham         "Explain everything we know about the breakpoint (for debugging debugger bugs)." },
15605a988416SJim Ingham 
156133df7cd3SJim Ingham     { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
156233df7cd3SJim Ingham         "List Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
156333df7cd3SJim Ingham 
1564d37221dcSZachary Turner     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
15655a988416SJim Ingham };
15665a988416SJim Ingham 
15675a988416SJim Ingham //-------------------------------------------------------------------------
15685a988416SJim Ingham // CommandObjectBreakpointClear
15695a988416SJim Ingham //-------------------------------------------------------------------------
15705a988416SJim Ingham #pragma mark Clear
15715a988416SJim Ingham 
15725a988416SJim Ingham class CommandObjectBreakpointClear : public CommandObjectParsed
15735a988416SJim Ingham {
15745a988416SJim Ingham public:
15755a988416SJim Ingham 
15765a988416SJim Ingham     typedef enum BreakpointClearType
15775a988416SJim Ingham     {
15785a988416SJim Ingham         eClearTypeInvalid,
15795a988416SJim Ingham         eClearTypeFileAndLine
15805a988416SJim Ingham     } BreakpointClearType;
15815a988416SJim Ingham 
15825a988416SJim Ingham     CommandObjectBreakpointClear (CommandInterpreter &interpreter) :
15835a988416SJim Ingham         CommandObjectParsed (interpreter,
15845a988416SJim Ingham                              "breakpoint clear",
15855a988416SJim Ingham                              "Clears a breakpoint or set of breakpoints in the executable.",
15865a988416SJim Ingham                              "breakpoint clear <cmd-options>"),
15875a988416SJim Ingham         m_options (interpreter)
15885a988416SJim Ingham     {
15895a988416SJim Ingham     }
15905a988416SJim Ingham 
15915a988416SJim Ingham     virtual
15925a988416SJim Ingham     ~CommandObjectBreakpointClear () {}
15935a988416SJim Ingham 
15945a988416SJim Ingham     virtual Options *
15955a988416SJim Ingham     GetOptions ()
15965a988416SJim Ingham     {
15975a988416SJim Ingham         return &m_options;
15985a988416SJim Ingham     }
15995a988416SJim Ingham 
16005a988416SJim Ingham     class CommandOptions : public Options
16015a988416SJim Ingham     {
16025a988416SJim Ingham     public:
16035a988416SJim Ingham 
16045a988416SJim Ingham         CommandOptions (CommandInterpreter &interpreter) :
16055a988416SJim Ingham             Options (interpreter),
16065a988416SJim Ingham             m_filename (),
16075a988416SJim Ingham             m_line_num (0)
16085a988416SJim Ingham         {
16095a988416SJim Ingham         }
16105a988416SJim Ingham 
16115a988416SJim Ingham         virtual
16125a988416SJim Ingham         ~CommandOptions () {}
16135a988416SJim Ingham 
16145a988416SJim Ingham         virtual Error
16155a988416SJim Ingham         SetOptionValue (uint32_t option_idx, const char *option_arg)
16165a988416SJim Ingham         {
16175a988416SJim Ingham             Error error;
16183bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
16195a988416SJim Ingham 
16205a988416SJim Ingham             switch (short_option)
16215a988416SJim Ingham             {
16225a988416SJim Ingham                 case 'f':
16235a988416SJim Ingham                     m_filename.assign (option_arg);
16245a988416SJim Ingham                     break;
16255a988416SJim Ingham 
16265a988416SJim Ingham                 case 'l':
16275275aaa0SVince Harron                     m_line_num = StringConvert::ToUInt32 (option_arg, 0);
16285a988416SJim Ingham                     break;
16295a988416SJim Ingham 
16305a988416SJim Ingham                 default:
16315a988416SJim Ingham                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
16325a988416SJim Ingham                     break;
16335a988416SJim Ingham             }
16345a988416SJim Ingham 
16355a988416SJim Ingham             return error;
16365a988416SJim Ingham         }
16375a988416SJim Ingham 
16385a988416SJim Ingham         void
16395a988416SJim Ingham         OptionParsingStarting ()
16405a988416SJim Ingham         {
16415a988416SJim Ingham             m_filename.clear();
16425a988416SJim Ingham             m_line_num = 0;
16435a988416SJim Ingham         }
16445a988416SJim Ingham 
16455a988416SJim Ingham         const OptionDefinition*
16465a988416SJim Ingham         GetDefinitions ()
16475a988416SJim Ingham         {
16485a988416SJim Ingham             return g_option_table;
16495a988416SJim Ingham         }
16505a988416SJim Ingham 
16515a988416SJim Ingham         // Options table: Required for subclasses of Options.
16525a988416SJim Ingham 
16535a988416SJim Ingham         static OptionDefinition g_option_table[];
16545a988416SJim Ingham 
16555a988416SJim Ingham         // Instance variables to hold the values for command options.
16565a988416SJim Ingham 
16575a988416SJim Ingham         std::string m_filename;
16585a988416SJim Ingham         uint32_t m_line_num;
16595a988416SJim Ingham 
16605a988416SJim Ingham     };
16615a988416SJim Ingham 
16625a988416SJim Ingham protected:
16635a988416SJim Ingham     virtual bool
16645a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
16655a988416SJim Ingham     {
1666893c932aSJim Ingham         Target *target = GetSelectedOrDummyTarget();
16675a988416SJim Ingham         if (target == NULL)
16685a988416SJim Ingham         {
16695a988416SJim Ingham             result.AppendError ("Invalid target. No existing target or breakpoints.");
16705a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
16715a988416SJim Ingham             return false;
16725a988416SJim Ingham         }
16735a988416SJim Ingham 
16745a988416SJim Ingham         // The following are the various types of breakpoints that could be cleared:
16755a988416SJim Ingham         //   1). -f -l (clearing breakpoint by source location)
16765a988416SJim Ingham 
16775a988416SJim Ingham         BreakpointClearType break_type = eClearTypeInvalid;
16785a988416SJim Ingham 
16795a988416SJim Ingham         if (m_options.m_line_num != 0)
16805a988416SJim Ingham             break_type = eClearTypeFileAndLine;
16815a988416SJim Ingham 
16825a988416SJim Ingham         Mutex::Locker locker;
16835a988416SJim Ingham         target->GetBreakpointList().GetListMutex(locker);
16845a988416SJim Ingham 
16855a988416SJim Ingham         BreakpointList &breakpoints = target->GetBreakpointList();
16865a988416SJim Ingham         size_t num_breakpoints = breakpoints.GetSize();
16875a988416SJim Ingham 
16885a988416SJim Ingham         // Early return if there's no breakpoint at all.
16895a988416SJim Ingham         if (num_breakpoints == 0)
16905a988416SJim Ingham         {
16915a988416SJim Ingham             result.AppendError ("Breakpoint clear: No breakpoint cleared.");
16925a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
16935a988416SJim Ingham             return result.Succeeded();
16945a988416SJim Ingham         }
16955a988416SJim Ingham 
16965a988416SJim Ingham         // Find matching breakpoints and delete them.
16975a988416SJim Ingham 
16985a988416SJim Ingham         // First create a copy of all the IDs.
16995a988416SJim Ingham         std::vector<break_id_t> BreakIDs;
17005a988416SJim Ingham         for (size_t i = 0; i < num_breakpoints; ++i)
17015a988416SJim Ingham             BreakIDs.push_back(breakpoints.GetBreakpointAtIndex(i).get()->GetID());
17025a988416SJim Ingham 
17035a988416SJim Ingham         int num_cleared = 0;
17045a988416SJim Ingham         StreamString ss;
17055a988416SJim Ingham         switch (break_type)
17065a988416SJim Ingham         {
17075a988416SJim Ingham             case eClearTypeFileAndLine: // Breakpoint by source position
17085a988416SJim Ingham                 {
17095a988416SJim Ingham                     const ConstString filename(m_options.m_filename.c_str());
17105a988416SJim Ingham                     BreakpointLocationCollection loc_coll;
17115a988416SJim Ingham 
17125a988416SJim Ingham                     for (size_t i = 0; i < num_breakpoints; ++i)
17135a988416SJim Ingham                     {
17145a988416SJim Ingham                         Breakpoint *bp = breakpoints.FindBreakpointByID(BreakIDs[i]).get();
17155a988416SJim Ingham 
17165a988416SJim Ingham                         if (bp->GetMatchingFileLine(filename, m_options.m_line_num, loc_coll))
17175a988416SJim Ingham                         {
17185a988416SJim Ingham                             // If the collection size is 0, it's a full match and we can just remove the breakpoint.
17195a988416SJim Ingham                             if (loc_coll.GetSize() == 0)
17205a988416SJim Ingham                             {
17215a988416SJim Ingham                                 bp->GetDescription(&ss, lldb::eDescriptionLevelBrief);
17225a988416SJim Ingham                                 ss.EOL();
17235a988416SJim Ingham                                 target->RemoveBreakpointByID (bp->GetID());
17245a988416SJim Ingham                                 ++num_cleared;
17255a988416SJim Ingham                             }
17265a988416SJim Ingham                         }
17275a988416SJim Ingham                     }
17285a988416SJim Ingham                 }
17295a988416SJim Ingham                 break;
17305a988416SJim Ingham 
17315a988416SJim Ingham             default:
17325a988416SJim Ingham                 break;
17335a988416SJim Ingham         }
17345a988416SJim Ingham 
17355a988416SJim Ingham         if (num_cleared > 0)
17365a988416SJim Ingham         {
17375a988416SJim Ingham             Stream &output_stream = result.GetOutputStream();
17385a988416SJim Ingham             output_stream.Printf ("%d breakpoints cleared:\n", num_cleared);
17395a988416SJim Ingham             output_stream << ss.GetData();
17405a988416SJim Ingham             output_stream.EOL();
17415a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
17425a988416SJim Ingham         }
17435a988416SJim Ingham         else
17445a988416SJim Ingham         {
17455a988416SJim Ingham             result.AppendError ("Breakpoint clear: No breakpoint cleared.");
17465a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
17475a988416SJim Ingham         }
17485a988416SJim Ingham 
17495a988416SJim Ingham         return result.Succeeded();
17505a988416SJim Ingham     }
17515a988416SJim Ingham 
17525a988416SJim Ingham private:
17535a988416SJim Ingham     CommandOptions m_options;
17545a988416SJim Ingham };
17555a988416SJim Ingham 
17565a988416SJim Ingham #pragma mark Clear::CommandOptions
17575a988416SJim Ingham 
17585a988416SJim Ingham OptionDefinition
17595a988416SJim Ingham CommandObjectBreakpointClear::CommandOptions::g_option_table[] =
17605a988416SJim Ingham {
1761d37221dcSZachary Turner     { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
17625a988416SJim Ingham         "Specify the breakpoint by source location in this particular file."},
17635a988416SJim Ingham 
1764d37221dcSZachary Turner     { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum,
17655a988416SJim Ingham         "Specify the breakpoint by source location at this particular line."},
17665a988416SJim Ingham 
1767d37221dcSZachary Turner     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
17685a988416SJim Ingham };
17695a988416SJim Ingham 
17705a988416SJim Ingham //-------------------------------------------------------------------------
17715a988416SJim Ingham // CommandObjectBreakpointDelete
17725a988416SJim Ingham //-------------------------------------------------------------------------
17735a988416SJim Ingham #pragma mark Delete
17745a988416SJim Ingham 
17755a988416SJim Ingham class CommandObjectBreakpointDelete : public CommandObjectParsed
17765a988416SJim Ingham {
17775a988416SJim Ingham public:
17785a988416SJim Ingham     CommandObjectBreakpointDelete (CommandInterpreter &interpreter) :
17795a988416SJim Ingham         CommandObjectParsed (interpreter,
17805a988416SJim Ingham                              "breakpoint delete",
17815a988416SJim Ingham                              "Delete the specified breakpoint(s).  If no breakpoints are specified, delete them all.",
178233df7cd3SJim Ingham                              NULL),
178333df7cd3SJim Ingham         m_options (interpreter)
17845a988416SJim Ingham     {
17855a988416SJim Ingham         CommandArgumentEntry arg;
17865a988416SJim Ingham         CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
17875a988416SJim Ingham         // Add the entry for the first argument for this command to the object's arguments vector.
17885a988416SJim Ingham         m_arguments.push_back (arg);
17895a988416SJim Ingham     }
17905a988416SJim Ingham 
17915a988416SJim Ingham     virtual
17925a988416SJim Ingham     ~CommandObjectBreakpointDelete () {}
17935a988416SJim Ingham 
179433df7cd3SJim Ingham     virtual Options *
179533df7cd3SJim Ingham     GetOptions ()
179633df7cd3SJim Ingham     {
179733df7cd3SJim Ingham         return &m_options;
179833df7cd3SJim Ingham     }
179933df7cd3SJim Ingham 
180033df7cd3SJim Ingham     class CommandOptions : public Options
180133df7cd3SJim Ingham     {
180233df7cd3SJim Ingham     public:
180333df7cd3SJim Ingham 
180433df7cd3SJim Ingham         CommandOptions (CommandInterpreter &interpreter) :
180533df7cd3SJim Ingham             Options (interpreter),
180633df7cd3SJim Ingham             m_use_dummy (false),
180733df7cd3SJim Ingham             m_force (false)
180833df7cd3SJim Ingham         {
180933df7cd3SJim Ingham         }
181033df7cd3SJim Ingham 
181133df7cd3SJim Ingham         virtual
181233df7cd3SJim Ingham         ~CommandOptions () {}
181333df7cd3SJim Ingham 
181433df7cd3SJim Ingham         virtual Error
181533df7cd3SJim Ingham         SetOptionValue (uint32_t option_idx, const char *option_arg)
181633df7cd3SJim Ingham         {
181733df7cd3SJim Ingham             Error error;
181833df7cd3SJim Ingham             const int short_option = m_getopt_table[option_idx].val;
181933df7cd3SJim Ingham 
182033df7cd3SJim Ingham             switch (short_option)
182133df7cd3SJim Ingham             {
182233df7cd3SJim Ingham                 case 'f':
182333df7cd3SJim Ingham                     m_force = true;
182433df7cd3SJim Ingham                     break;
182533df7cd3SJim Ingham 
182633df7cd3SJim Ingham                 case 'D':
182733df7cd3SJim Ingham                     m_use_dummy = true;
182833df7cd3SJim Ingham                     break;
182933df7cd3SJim Ingham 
183033df7cd3SJim Ingham                 default:
183133df7cd3SJim Ingham                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
183233df7cd3SJim Ingham                     break;
183333df7cd3SJim Ingham             }
183433df7cd3SJim Ingham 
183533df7cd3SJim Ingham             return error;
183633df7cd3SJim Ingham         }
183733df7cd3SJim Ingham 
183833df7cd3SJim Ingham         void
183933df7cd3SJim Ingham         OptionParsingStarting ()
184033df7cd3SJim Ingham         {
184133df7cd3SJim Ingham             m_use_dummy = false;
184233df7cd3SJim Ingham             m_force = false;
184333df7cd3SJim Ingham         }
184433df7cd3SJim Ingham 
184533df7cd3SJim Ingham         const OptionDefinition*
184633df7cd3SJim Ingham         GetDefinitions ()
184733df7cd3SJim Ingham         {
184833df7cd3SJim Ingham             return g_option_table;
184933df7cd3SJim Ingham         }
185033df7cd3SJim Ingham 
185133df7cd3SJim Ingham         // Options table: Required for subclasses of Options.
185233df7cd3SJim Ingham 
185333df7cd3SJim Ingham         static OptionDefinition g_option_table[];
185433df7cd3SJim Ingham 
185533df7cd3SJim Ingham         // Instance variables to hold the values for command options.
185633df7cd3SJim Ingham         bool m_use_dummy;
185733df7cd3SJim Ingham         bool m_force;
185833df7cd3SJim Ingham     };
185933df7cd3SJim Ingham 
18605a988416SJim Ingham protected:
18615a988416SJim Ingham     virtual bool
18625a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
18635a988416SJim Ingham     {
186433df7cd3SJim Ingham         Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
186533df7cd3SJim Ingham 
18665a988416SJim Ingham         if (target == NULL)
18675a988416SJim Ingham         {
18685a988416SJim Ingham             result.AppendError ("Invalid target. No existing target or breakpoints.");
18695a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
18705a988416SJim Ingham             return false;
18715a988416SJim Ingham         }
18725a988416SJim Ingham 
18735a988416SJim Ingham         Mutex::Locker locker;
18745a988416SJim Ingham         target->GetBreakpointList().GetListMutex(locker);
18755a988416SJim Ingham 
18765a988416SJim Ingham         const BreakpointList &breakpoints = target->GetBreakpointList();
18775a988416SJim Ingham 
18785a988416SJim Ingham         size_t num_breakpoints = breakpoints.GetSize();
18795a988416SJim Ingham 
18805a988416SJim Ingham         if (num_breakpoints == 0)
18815a988416SJim Ingham         {
18825a988416SJim Ingham             result.AppendError ("No breakpoints exist to be deleted.");
18835a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
18845a988416SJim Ingham             return false;
18855a988416SJim Ingham         }
18865a988416SJim Ingham 
18875a988416SJim Ingham         if (command.GetArgumentCount() == 0)
18885a988416SJim Ingham         {
188933df7cd3SJim Ingham             if (!m_options.m_force && !m_interpreter.Confirm ("About to delete all breakpoints, do you want to do that?", true))
18905a988416SJim Ingham             {
18915a988416SJim Ingham                 result.AppendMessage("Operation cancelled...");
18925a988416SJim Ingham             }
18935a988416SJim Ingham             else
18945a988416SJim Ingham             {
18955a988416SJim Ingham                 target->RemoveAllBreakpoints ();
18966fea17e8SGreg Clayton                 result.AppendMessageWithFormat ("All breakpoints removed. (%" PRIu64 " breakpoint%s)\n", (uint64_t)num_breakpoints, num_breakpoints > 1 ? "s" : "");
18975a988416SJim Ingham             }
18985a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
18995a988416SJim Ingham         }
19005a988416SJim Ingham         else
19015a988416SJim Ingham         {
19025a988416SJim Ingham             // Particular breakpoint selected; disable that breakpoint.
19035a988416SJim Ingham             BreakpointIDList valid_bp_ids;
19045e09c8c3SJim Ingham             CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
19055a988416SJim Ingham 
19065a988416SJim Ingham             if (result.Succeeded())
19075a988416SJim Ingham             {
19085a988416SJim Ingham                 int delete_count = 0;
19095a988416SJim Ingham                 int disable_count = 0;
19105a988416SJim Ingham                 const size_t count = valid_bp_ids.GetSize();
19115a988416SJim Ingham                 for (size_t i = 0; i < count; ++i)
19125a988416SJim Ingham                 {
19135a988416SJim Ingham                     BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
19145a988416SJim Ingham 
19155a988416SJim Ingham                     if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
19165a988416SJim Ingham                     {
19175a988416SJim Ingham                         if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
19185a988416SJim Ingham                         {
19195a988416SJim Ingham                             Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
19205a988416SJim Ingham                             BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
19215a988416SJim Ingham                             // It makes no sense to try to delete individual locations, so we disable them instead.
19225a988416SJim Ingham                             if (location)
19235a988416SJim Ingham                             {
19245a988416SJim Ingham                                 location->SetEnabled (false);
19255a988416SJim Ingham                                 ++disable_count;
19265a988416SJim Ingham                             }
19275a988416SJim Ingham                         }
19285a988416SJim Ingham                         else
19295a988416SJim Ingham                         {
19305a988416SJim Ingham                             target->RemoveBreakpointByID (cur_bp_id.GetBreakpointID());
19315a988416SJim Ingham                             ++delete_count;
19325a988416SJim Ingham                         }
19335a988416SJim Ingham                     }
19345a988416SJim Ingham                 }
19355a988416SJim Ingham                 result.AppendMessageWithFormat ("%d breakpoints deleted; %d breakpoint locations disabled.\n",
19365a988416SJim Ingham                                                delete_count, disable_count);
19375a988416SJim Ingham                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
19385a988416SJim Ingham             }
19395a988416SJim Ingham         }
19405a988416SJim Ingham         return result.Succeeded();
19415a988416SJim Ingham     }
194233df7cd3SJim Ingham private:
194333df7cd3SJim Ingham     CommandOptions m_options;
194433df7cd3SJim Ingham };
194533df7cd3SJim Ingham 
194633df7cd3SJim Ingham OptionDefinition
194733df7cd3SJim Ingham CommandObjectBreakpointDelete::CommandOptions::g_option_table[] =
194833df7cd3SJim Ingham {
194933df7cd3SJim Ingham     { LLDB_OPT_SET_1, false, "force", 'f', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
195033df7cd3SJim Ingham         "Delete all breakpoints without querying for confirmation."},
195133df7cd3SJim Ingham 
195233df7cd3SJim Ingham     { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
195333df7cd3SJim Ingham         "Delete Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
195433df7cd3SJim Ingham 
195533df7cd3SJim Ingham     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
19565a988416SJim Ingham };
19575a988416SJim Ingham 
195830fdc8d8SChris Lattner //-------------------------------------------------------------------------
19595e09c8c3SJim Ingham // CommandObjectBreakpointName
19605e09c8c3SJim Ingham //-------------------------------------------------------------------------
19615e09c8c3SJim Ingham 
19625e09c8c3SJim Ingham static OptionDefinition
19635e09c8c3SJim Ingham g_breakpoint_name_options[] =
19645e09c8c3SJim Ingham {
19655e09c8c3SJim Ingham     { LLDB_OPT_SET_1,   false, "name", 'N', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBreakpointName, "Specifies a breakpoint name to use."},
19665e09c8c3SJim Ingham     { LLDB_OPT_SET_2,   false, "breakpoint-id", 'B', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBreakpointID,   "Specify a breakpoint id to use."},
19675e09c8c3SJim Ingham     { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
19685e09c8c3SJim Ingham         "Operate on Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
19695e09c8c3SJim Ingham };
19705e09c8c3SJim Ingham class BreakpointNameOptionGroup : public OptionGroup
19715e09c8c3SJim Ingham {
19725e09c8c3SJim Ingham public:
19735e09c8c3SJim Ingham     BreakpointNameOptionGroup() :
19745e09c8c3SJim Ingham         OptionGroup(),
19755e09c8c3SJim Ingham         m_breakpoint(LLDB_INVALID_BREAK_ID),
19765e09c8c3SJim Ingham         m_use_dummy (false)
19775e09c8c3SJim Ingham     {
19785e09c8c3SJim Ingham 
19795e09c8c3SJim Ingham     }
19805e09c8c3SJim Ingham 
19815e09c8c3SJim Ingham     virtual
19825e09c8c3SJim Ingham     ~BreakpointNameOptionGroup ()
19835e09c8c3SJim Ingham     {
19845e09c8c3SJim Ingham     }
19855e09c8c3SJim Ingham 
19865e09c8c3SJim Ingham     virtual uint32_t
19875e09c8c3SJim Ingham     GetNumDefinitions ()
19885e09c8c3SJim Ingham     {
19895e09c8c3SJim Ingham       return sizeof (g_breakpoint_name_options) / sizeof (OptionDefinition);
19905e09c8c3SJim Ingham     }
19915e09c8c3SJim Ingham 
19925e09c8c3SJim Ingham     virtual const OptionDefinition*
19935e09c8c3SJim Ingham     GetDefinitions ()
19945e09c8c3SJim Ingham     {
19955e09c8c3SJim Ingham         return g_breakpoint_name_options;
19965e09c8c3SJim Ingham     }
19975e09c8c3SJim Ingham 
19985e09c8c3SJim Ingham     virtual Error
19995e09c8c3SJim Ingham     SetOptionValue (CommandInterpreter &interpreter,
20005e09c8c3SJim Ingham                     uint32_t option_idx,
20015e09c8c3SJim Ingham                     const char *option_value)
20025e09c8c3SJim Ingham     {
20035e09c8c3SJim Ingham         Error error;
20045e09c8c3SJim Ingham         const int short_option = g_breakpoint_name_options[option_idx].short_option;
20055e09c8c3SJim Ingham 
20065e09c8c3SJim Ingham         switch (short_option)
20075e09c8c3SJim Ingham         {
20085e09c8c3SJim Ingham         case 'N':
20095e09c8c3SJim Ingham             if (BreakpointID::StringIsBreakpointName(option_value, error) && error.Success())
2010c95f7e2aSPavel Labath                 m_name.SetValueFromString(option_value);
20115e09c8c3SJim Ingham             break;
20125e09c8c3SJim Ingham 
20135e09c8c3SJim Ingham         case 'B':
2014c95f7e2aSPavel Labath             if (m_breakpoint.SetValueFromString(option_value).Fail())
20155e09c8c3SJim Ingham                 error.SetErrorStringWithFormat ("unrecognized value \"%s\" for breakpoint", option_value);
20165e09c8c3SJim Ingham             break;
20175e09c8c3SJim Ingham         case 'D':
2018c95f7e2aSPavel Labath             if (m_use_dummy.SetValueFromString(option_value).Fail())
20195e09c8c3SJim Ingham                 error.SetErrorStringWithFormat ("unrecognized value \"%s\" for use-dummy", option_value);
20205e09c8c3SJim Ingham             break;
20215e09c8c3SJim Ingham 
20225e09c8c3SJim Ingham         default:
20235e09c8c3SJim Ingham               error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option);
20245e09c8c3SJim Ingham               break;
20255e09c8c3SJim Ingham         }
20265e09c8c3SJim Ingham         return error;
20275e09c8c3SJim Ingham     }
20285e09c8c3SJim Ingham 
20295e09c8c3SJim Ingham     virtual void
20305e09c8c3SJim Ingham     OptionParsingStarting (CommandInterpreter &interpreter)
20315e09c8c3SJim Ingham     {
20325e09c8c3SJim Ingham         m_name.Clear();
20335e09c8c3SJim Ingham         m_breakpoint.Clear();
20345e09c8c3SJim Ingham         m_use_dummy.Clear();
20355e09c8c3SJim Ingham         m_use_dummy.SetDefaultValue(false);
20365e09c8c3SJim Ingham     }
20375e09c8c3SJim Ingham 
20385e09c8c3SJim Ingham     OptionValueString m_name;
20395e09c8c3SJim Ingham     OptionValueUInt64 m_breakpoint;
20405e09c8c3SJim Ingham     OptionValueBoolean m_use_dummy;
20415e09c8c3SJim Ingham };
20425e09c8c3SJim Ingham 
20435e09c8c3SJim Ingham 
20445e09c8c3SJim Ingham class CommandObjectBreakpointNameAdd : public CommandObjectParsed
20455e09c8c3SJim Ingham {
20465e09c8c3SJim Ingham public:
20475e09c8c3SJim Ingham     CommandObjectBreakpointNameAdd (CommandInterpreter &interpreter) :
20485e09c8c3SJim Ingham         CommandObjectParsed (interpreter,
20495e09c8c3SJim Ingham                              "add",
20505e09c8c3SJim Ingham                              "Add a name to the breakpoints provided.",
20515e09c8c3SJim Ingham                              "breakpoint name add <command-options> <breakpoint-id-list>"),
20525e09c8c3SJim Ingham         m_name_options(),
20535e09c8c3SJim Ingham         m_option_group(interpreter)
20545e09c8c3SJim Ingham         {
20555e09c8c3SJim Ingham             // Create the first variant for the first (and only) argument for this command.
20565e09c8c3SJim Ingham             CommandArgumentEntry arg1;
20575e09c8c3SJim Ingham             CommandArgumentData id_arg;
20585e09c8c3SJim Ingham             id_arg.arg_type = eArgTypeBreakpointID;
20595e09c8c3SJim Ingham             id_arg.arg_repetition = eArgRepeatOptional;
20605e09c8c3SJim Ingham             arg1.push_back(id_arg);
20615e09c8c3SJim Ingham             m_arguments.push_back (arg1);
20625e09c8c3SJim Ingham 
20635e09c8c3SJim Ingham             m_option_group.Append (&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
20645e09c8c3SJim Ingham             m_option_group.Finalize();
20655e09c8c3SJim Ingham         }
20665e09c8c3SJim Ingham 
20675e09c8c3SJim Ingham     virtual
20685e09c8c3SJim Ingham     ~CommandObjectBreakpointNameAdd () {}
20695e09c8c3SJim Ingham 
20705e09c8c3SJim Ingham   Options *
20715e09c8c3SJim Ingham   GetOptions ()
20725e09c8c3SJim Ingham   {
20735e09c8c3SJim Ingham     return &m_option_group;
20745e09c8c3SJim Ingham   }
20755e09c8c3SJim Ingham 
20765e09c8c3SJim Ingham protected:
20775e09c8c3SJim Ingham     virtual bool
20785e09c8c3SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
20795e09c8c3SJim Ingham     {
20805e09c8c3SJim Ingham         if (!m_name_options.m_name.OptionWasSet())
20815e09c8c3SJim Ingham         {
20825e09c8c3SJim Ingham             result.SetError("No name option provided.");
20835e09c8c3SJim Ingham             return false;
20845e09c8c3SJim Ingham         }
20855e09c8c3SJim Ingham 
20865e09c8c3SJim Ingham         Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
20875e09c8c3SJim Ingham 
20885e09c8c3SJim Ingham         if (target == NULL)
20895e09c8c3SJim Ingham         {
20905e09c8c3SJim Ingham             result.AppendError ("Invalid target. No existing target or breakpoints.");
20915e09c8c3SJim Ingham             result.SetStatus (eReturnStatusFailed);
20925e09c8c3SJim Ingham             return false;
20935e09c8c3SJim Ingham         }
20945e09c8c3SJim Ingham 
20955e09c8c3SJim Ingham         Mutex::Locker locker;
20965e09c8c3SJim Ingham         target->GetBreakpointList().GetListMutex(locker);
20975e09c8c3SJim Ingham 
20985e09c8c3SJim Ingham         const BreakpointList &breakpoints = target->GetBreakpointList();
20995e09c8c3SJim Ingham 
21005e09c8c3SJim Ingham         size_t num_breakpoints = breakpoints.GetSize();
21015e09c8c3SJim Ingham         if (num_breakpoints == 0)
21025e09c8c3SJim Ingham         {
21035e09c8c3SJim Ingham             result.SetError("No breakpoints, cannot add names.");
21045e09c8c3SJim Ingham             result.SetStatus (eReturnStatusFailed);
21055e09c8c3SJim Ingham             return false;
21065e09c8c3SJim Ingham         }
21075e09c8c3SJim Ingham 
21085e09c8c3SJim Ingham         // Particular breakpoint selected; disable that breakpoint.
21095e09c8c3SJim Ingham         BreakpointIDList valid_bp_ids;
21105e09c8c3SJim Ingham         CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
21115e09c8c3SJim Ingham 
21125e09c8c3SJim Ingham         if (result.Succeeded())
21135e09c8c3SJim Ingham         {
21145e09c8c3SJim Ingham             if (valid_bp_ids.GetSize() == 0)
21155e09c8c3SJim Ingham             {
21165e09c8c3SJim Ingham                 result.SetError("No breakpoints specified, cannot add names.");
21175e09c8c3SJim Ingham                 result.SetStatus (eReturnStatusFailed);
21185e09c8c3SJim Ingham                 return false;
21195e09c8c3SJim Ingham             }
21205e09c8c3SJim Ingham             size_t num_valid_ids = valid_bp_ids.GetSize();
21215e09c8c3SJim Ingham             for (size_t index = 0; index < num_valid_ids; index++)
21225e09c8c3SJim Ingham             {
21235e09c8c3SJim Ingham                 lldb::break_id_t bp_id = valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
21245e09c8c3SJim Ingham                 BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
21255e09c8c3SJim Ingham                 Error error;  // We don't need to check the error here, since the option parser checked it...
21265e09c8c3SJim Ingham                 bp_sp->AddName(m_name_options.m_name.GetCurrentValue(), error);
21275e09c8c3SJim Ingham             }
21285e09c8c3SJim Ingham         }
21295e09c8c3SJim Ingham 
21305e09c8c3SJim Ingham         return true;
21315e09c8c3SJim Ingham     }
21325e09c8c3SJim Ingham 
21335e09c8c3SJim Ingham private:
21345e09c8c3SJim Ingham     BreakpointNameOptionGroup m_name_options;
21355e09c8c3SJim Ingham     OptionGroupOptions m_option_group;
21365e09c8c3SJim Ingham };
21375e09c8c3SJim Ingham 
21385e09c8c3SJim Ingham 
21395e09c8c3SJim Ingham 
21405e09c8c3SJim Ingham class CommandObjectBreakpointNameDelete : public CommandObjectParsed
21415e09c8c3SJim Ingham {
21425e09c8c3SJim Ingham public:
21435e09c8c3SJim Ingham     CommandObjectBreakpointNameDelete (CommandInterpreter &interpreter) :
21445e09c8c3SJim Ingham         CommandObjectParsed (interpreter,
21455e09c8c3SJim Ingham                              "delete",
21465e09c8c3SJim Ingham                              "Delete a name from the breakpoints provided.",
21475e09c8c3SJim Ingham                              "breakpoint name delete <command-options> <breakpoint-id-list>"),
21485e09c8c3SJim Ingham         m_name_options(),
21495e09c8c3SJim Ingham         m_option_group(interpreter)
21505e09c8c3SJim Ingham     {
21515e09c8c3SJim Ingham         // Create the first variant for the first (and only) argument for this command.
21525e09c8c3SJim Ingham         CommandArgumentEntry arg1;
21535e09c8c3SJim Ingham         CommandArgumentData id_arg;
21545e09c8c3SJim Ingham         id_arg.arg_type = eArgTypeBreakpointID;
21555e09c8c3SJim Ingham         id_arg.arg_repetition = eArgRepeatOptional;
21565e09c8c3SJim Ingham         arg1.push_back(id_arg);
21575e09c8c3SJim Ingham         m_arguments.push_back (arg1);
21585e09c8c3SJim Ingham 
21595e09c8c3SJim Ingham         m_option_group.Append (&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
21605e09c8c3SJim Ingham         m_option_group.Finalize();
21615e09c8c3SJim Ingham     }
21625e09c8c3SJim Ingham 
21635e09c8c3SJim Ingham     virtual
21645e09c8c3SJim Ingham     ~CommandObjectBreakpointNameDelete () {}
21655e09c8c3SJim Ingham 
21665e09c8c3SJim Ingham   Options *
21675e09c8c3SJim Ingham   GetOptions ()
21685e09c8c3SJim Ingham   {
21695e09c8c3SJim Ingham     return &m_option_group;
21705e09c8c3SJim Ingham   }
21715e09c8c3SJim Ingham 
21725e09c8c3SJim Ingham protected:
21735e09c8c3SJim Ingham     virtual bool
21745e09c8c3SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
21755e09c8c3SJim Ingham     {
21765e09c8c3SJim Ingham         if (!m_name_options.m_name.OptionWasSet())
21775e09c8c3SJim Ingham         {
21785e09c8c3SJim Ingham             result.SetError("No name option provided.");
21795e09c8c3SJim Ingham             return false;
21805e09c8c3SJim Ingham         }
21815e09c8c3SJim Ingham 
21825e09c8c3SJim Ingham         Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
21835e09c8c3SJim Ingham 
21845e09c8c3SJim Ingham         if (target == NULL)
21855e09c8c3SJim Ingham         {
21865e09c8c3SJim Ingham             result.AppendError ("Invalid target. No existing target or breakpoints.");
21875e09c8c3SJim Ingham             result.SetStatus (eReturnStatusFailed);
21885e09c8c3SJim Ingham             return false;
21895e09c8c3SJim Ingham         }
21905e09c8c3SJim Ingham 
21915e09c8c3SJim Ingham         Mutex::Locker locker;
21925e09c8c3SJim Ingham         target->GetBreakpointList().GetListMutex(locker);
21935e09c8c3SJim Ingham 
21945e09c8c3SJim Ingham         const BreakpointList &breakpoints = target->GetBreakpointList();
21955e09c8c3SJim Ingham 
21965e09c8c3SJim Ingham         size_t num_breakpoints = breakpoints.GetSize();
21975e09c8c3SJim Ingham         if (num_breakpoints == 0)
21985e09c8c3SJim Ingham         {
21995e09c8c3SJim Ingham             result.SetError("No breakpoints, cannot delete names.");
22005e09c8c3SJim Ingham             result.SetStatus (eReturnStatusFailed);
22015e09c8c3SJim Ingham             return false;
22025e09c8c3SJim Ingham         }
22035e09c8c3SJim Ingham 
22045e09c8c3SJim Ingham         // Particular breakpoint selected; disable that breakpoint.
22055e09c8c3SJim Ingham         BreakpointIDList valid_bp_ids;
22065e09c8c3SJim Ingham         CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
22075e09c8c3SJim Ingham 
22085e09c8c3SJim Ingham         if (result.Succeeded())
22095e09c8c3SJim Ingham         {
22105e09c8c3SJim Ingham             if (valid_bp_ids.GetSize() == 0)
22115e09c8c3SJim Ingham             {
22125e09c8c3SJim Ingham                 result.SetError("No breakpoints specified, cannot delete names.");
22135e09c8c3SJim Ingham                 result.SetStatus (eReturnStatusFailed);
22145e09c8c3SJim Ingham                 return false;
22155e09c8c3SJim Ingham             }
22165e09c8c3SJim Ingham             size_t num_valid_ids = valid_bp_ids.GetSize();
22175e09c8c3SJim Ingham             for (size_t index = 0; index < num_valid_ids; index++)
22185e09c8c3SJim Ingham             {
22195e09c8c3SJim Ingham                 lldb::break_id_t bp_id = valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
22205e09c8c3SJim Ingham                 BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
22215e09c8c3SJim Ingham                 bp_sp->RemoveName(m_name_options.m_name.GetCurrentValue());
22225e09c8c3SJim Ingham             }
22235e09c8c3SJim Ingham         }
22245e09c8c3SJim Ingham 
22255e09c8c3SJim Ingham         return true;
22265e09c8c3SJim Ingham     }
22275e09c8c3SJim Ingham 
22285e09c8c3SJim Ingham private:
22295e09c8c3SJim Ingham     BreakpointNameOptionGroup m_name_options;
22305e09c8c3SJim Ingham     OptionGroupOptions m_option_group;
22315e09c8c3SJim Ingham };
22325e09c8c3SJim Ingham 
22335e09c8c3SJim Ingham class CommandObjectBreakpointNameList : public CommandObjectParsed
22345e09c8c3SJim Ingham {
22355e09c8c3SJim Ingham public:
22365e09c8c3SJim Ingham     CommandObjectBreakpointNameList (CommandInterpreter &interpreter) :
22375e09c8c3SJim Ingham         CommandObjectParsed (interpreter,
22385e09c8c3SJim Ingham                              "list",
22395e09c8c3SJim Ingham                              "List either the names for a breakpoint or the breakpoints for a given name.",
22405e09c8c3SJim Ingham                              "breakpoint name list <command-options>"),
22415e09c8c3SJim Ingham         m_name_options(),
22425e09c8c3SJim Ingham         m_option_group(interpreter)
22435e09c8c3SJim Ingham     {
22445e09c8c3SJim Ingham         m_option_group.Append (&m_name_options);
22455e09c8c3SJim Ingham         m_option_group.Finalize();
22465e09c8c3SJim Ingham     }
22475e09c8c3SJim Ingham 
22485e09c8c3SJim Ingham     virtual
22495e09c8c3SJim Ingham     ~CommandObjectBreakpointNameList () {}
22505e09c8c3SJim Ingham 
22515e09c8c3SJim Ingham   Options *
22525e09c8c3SJim Ingham   GetOptions ()
22535e09c8c3SJim Ingham   {
22545e09c8c3SJim Ingham     return &m_option_group;
22555e09c8c3SJim Ingham   }
22565e09c8c3SJim Ingham 
22575e09c8c3SJim Ingham protected:
22585e09c8c3SJim Ingham     virtual bool
22595e09c8c3SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
22605e09c8c3SJim Ingham     {
22615e09c8c3SJim Ingham         Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
22625e09c8c3SJim Ingham 
22635e09c8c3SJim Ingham         if (target == NULL)
22645e09c8c3SJim Ingham         {
22655e09c8c3SJim Ingham             result.AppendError ("Invalid target. No existing target or breakpoints.");
22665e09c8c3SJim Ingham             result.SetStatus (eReturnStatusFailed);
22675e09c8c3SJim Ingham             return false;
22685e09c8c3SJim Ingham         }
22695e09c8c3SJim Ingham 
22705e09c8c3SJim Ingham         if (m_name_options.m_name.OptionWasSet())
22715e09c8c3SJim Ingham         {
22725e09c8c3SJim Ingham             const char *name = m_name_options.m_name.GetCurrentValue();
22735e09c8c3SJim Ingham             Mutex::Locker locker;
22745e09c8c3SJim Ingham             target->GetBreakpointList().GetListMutex(locker);
22755e09c8c3SJim Ingham 
22765e09c8c3SJim Ingham             BreakpointList &breakpoints = target->GetBreakpointList();
22775e09c8c3SJim Ingham             for (BreakpointSP bp_sp : breakpoints.Breakpoints())
22785e09c8c3SJim Ingham             {
22795e09c8c3SJim Ingham                 if (bp_sp->MatchesName(name))
22805e09c8c3SJim Ingham                 {
22815e09c8c3SJim Ingham                     StreamString s;
22825e09c8c3SJim Ingham                     bp_sp->GetDescription(&s, eDescriptionLevelBrief);
22835e09c8c3SJim Ingham                     s.EOL();
22845e09c8c3SJim Ingham                     result.AppendMessage(s.GetData());
22855e09c8c3SJim Ingham                 }
22865e09c8c3SJim Ingham             }
22875e09c8c3SJim Ingham 
22885e09c8c3SJim Ingham         }
22895e09c8c3SJim Ingham         else if (m_name_options.m_breakpoint.OptionWasSet())
22905e09c8c3SJim Ingham         {
22915e09c8c3SJim Ingham             BreakpointSP bp_sp = target->GetBreakpointList().FindBreakpointByID(m_name_options.m_breakpoint.GetCurrentValue());
22925e09c8c3SJim Ingham             if (bp_sp)
22935e09c8c3SJim Ingham             {
22945e09c8c3SJim Ingham                 std::vector<std::string> names;
22955e09c8c3SJim Ingham                 bp_sp->GetNames (names);
22965e09c8c3SJim Ingham                 result.AppendMessage ("Names:");
22975e09c8c3SJim Ingham                 for (auto name : names)
22985e09c8c3SJim Ingham                     result.AppendMessageWithFormat ("    %s\n", name.c_str());
22995e09c8c3SJim Ingham             }
23005e09c8c3SJim Ingham             else
23015e09c8c3SJim Ingham             {
23025e09c8c3SJim Ingham                 result.AppendErrorWithFormat ("Could not find breakpoint %" PRId64 ".\n",
23035e09c8c3SJim Ingham                                            m_name_options.m_breakpoint.GetCurrentValue());
23045e09c8c3SJim Ingham                 result.SetStatus (eReturnStatusFailed);
23055e09c8c3SJim Ingham                 return false;
23065e09c8c3SJim Ingham             }
23075e09c8c3SJim Ingham         }
23085e09c8c3SJim Ingham         else
23095e09c8c3SJim Ingham         {
23105e09c8c3SJim Ingham             result.SetError ("Must specify -N or -B option to list.");
23115e09c8c3SJim Ingham             result.SetStatus (eReturnStatusFailed);
23125e09c8c3SJim Ingham             return false;
23135e09c8c3SJim Ingham         }
23145e09c8c3SJim Ingham         return true;
23155e09c8c3SJim Ingham     }
23165e09c8c3SJim Ingham 
23175e09c8c3SJim Ingham private:
23185e09c8c3SJim Ingham     BreakpointNameOptionGroup m_name_options;
23195e09c8c3SJim Ingham     OptionGroupOptions m_option_group;
23205e09c8c3SJim Ingham };
23215e09c8c3SJim Ingham 
23225e09c8c3SJim Ingham //-------------------------------------------------------------------------
23235e09c8c3SJim Ingham // CommandObjectMultiwordBreakpoint
23245e09c8c3SJim Ingham //-------------------------------------------------------------------------
23255e09c8c3SJim Ingham class CommandObjectBreakpointName : public CommandObjectMultiword
23265e09c8c3SJim Ingham {
23275e09c8c3SJim Ingham public:
23285e09c8c3SJim Ingham     CommandObjectBreakpointName (CommandInterpreter &interpreter) :
23295e09c8c3SJim Ingham         CommandObjectMultiword(interpreter,
23305e09c8c3SJim Ingham                                 "name",
23315e09c8c3SJim Ingham                                 "A set of commands to manage name tags for breakpoints",
23325e09c8c3SJim Ingham                                 "breakpoint name <command> [<command-options>]")
23335e09c8c3SJim Ingham     {
23345e09c8c3SJim Ingham         CommandObjectSP add_command_object (new CommandObjectBreakpointNameAdd (interpreter));
23355e09c8c3SJim Ingham         CommandObjectSP delete_command_object (new CommandObjectBreakpointNameDelete (interpreter));
23365e09c8c3SJim Ingham         CommandObjectSP list_command_object (new CommandObjectBreakpointNameList (interpreter));
23375e09c8c3SJim Ingham 
23385e09c8c3SJim Ingham         LoadSubCommand ("add", add_command_object);
23395e09c8c3SJim Ingham         LoadSubCommand ("delete", delete_command_object);
23405e09c8c3SJim Ingham         LoadSubCommand ("list", list_command_object);
23415e09c8c3SJim Ingham 
23425e09c8c3SJim Ingham     }
23435e09c8c3SJim Ingham 
23445e09c8c3SJim Ingham     virtual
23455e09c8c3SJim Ingham     ~CommandObjectBreakpointName ()
23465e09c8c3SJim Ingham     {
23475e09c8c3SJim Ingham     }
23485e09c8c3SJim Ingham 
23495e09c8c3SJim Ingham };
23505e09c8c3SJim Ingham 
23515e09c8c3SJim Ingham 
23525e09c8c3SJim Ingham //-------------------------------------------------------------------------
235330fdc8d8SChris Lattner // CommandObjectMultiwordBreakpoint
235430fdc8d8SChris Lattner //-------------------------------------------------------------------------
2355ae1c4cf5SJim Ingham #pragma mark MultiwordBreakpoint
235630fdc8d8SChris Lattner 
23576611103cSGreg Clayton CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint (CommandInterpreter &interpreter) :
2358a7015092SGreg Clayton     CommandObjectMultiword (interpreter,
2359a7015092SGreg Clayton                             "breakpoint",
236046fbc60fSJim Ingham                             "A set of commands for operating on breakpoints. Also see _regexp-break.",
236130fdc8d8SChris Lattner                             "breakpoint <command> [<command-options>]")
236230fdc8d8SChris Lattner {
2363a7015092SGreg Clayton     CommandObjectSP list_command_object (new CommandObjectBreakpointList (interpreter));
2364a7015092SGreg Clayton     CommandObjectSP enable_command_object (new CommandObjectBreakpointEnable (interpreter));
2365a7015092SGreg Clayton     CommandObjectSP disable_command_object (new CommandObjectBreakpointDisable (interpreter));
2366b7234e40SJohnny Chen     CommandObjectSP clear_command_object (new CommandObjectBreakpointClear (interpreter));
2367b7234e40SJohnny Chen     CommandObjectSP delete_command_object (new CommandObjectBreakpointDelete (interpreter));
2368a7015092SGreg Clayton     CommandObjectSP set_command_object (new CommandObjectBreakpointSet (interpreter));
236930fdc8d8SChris Lattner     CommandObjectSP command_command_object (new CommandObjectBreakpointCommand (interpreter));
2370a7015092SGreg Clayton     CommandObjectSP modify_command_object (new CommandObjectBreakpointModify(interpreter));
23715e09c8c3SJim Ingham     CommandObjectSP name_command_object (new CommandObjectBreakpointName(interpreter));
237230fdc8d8SChris Lattner 
2373b7234e40SJohnny Chen     list_command_object->SetCommandName ("breakpoint list");
237430fdc8d8SChris Lattner     enable_command_object->SetCommandName("breakpoint enable");
237530fdc8d8SChris Lattner     disable_command_object->SetCommandName("breakpoint disable");
2376b7234e40SJohnny Chen     clear_command_object->SetCommandName("breakpoint clear");
2377b7234e40SJohnny Chen     delete_command_object->SetCommandName("breakpoint delete");
2378ae1c4cf5SJim Ingham     set_command_object->SetCommandName("breakpoint set");
2379b7234e40SJohnny Chen     command_command_object->SetCommandName ("breakpoint command");
2380b7234e40SJohnny Chen     modify_command_object->SetCommandName ("breakpoint modify");
23815e09c8c3SJim Ingham     name_command_object->SetCommandName ("breakpoint name");
238230fdc8d8SChris Lattner 
238323f59509SGreg Clayton     LoadSubCommand ("list",       list_command_object);
238423f59509SGreg Clayton     LoadSubCommand ("enable",     enable_command_object);
238523f59509SGreg Clayton     LoadSubCommand ("disable",    disable_command_object);
238623f59509SGreg Clayton     LoadSubCommand ("clear",      clear_command_object);
238723f59509SGreg Clayton     LoadSubCommand ("delete",     delete_command_object);
238823f59509SGreg Clayton     LoadSubCommand ("set",        set_command_object);
238923f59509SGreg Clayton     LoadSubCommand ("command",    command_command_object);
239023f59509SGreg Clayton     LoadSubCommand ("modify",     modify_command_object);
23915e09c8c3SJim Ingham     LoadSubCommand ("name",       name_command_object);
239230fdc8d8SChris Lattner }
239330fdc8d8SChris Lattner 
239430fdc8d8SChris Lattner CommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint ()
239530fdc8d8SChris Lattner {
239630fdc8d8SChris Lattner }
239730fdc8d8SChris Lattner 
239830fdc8d8SChris Lattner void
23995e09c8c3SJim Ingham CommandObjectMultiwordBreakpoint::VerifyIDs (Args &args,
24005e09c8c3SJim Ingham                                              Target *target,
24015e09c8c3SJim Ingham                                              bool allow_locations,
24025e09c8c3SJim Ingham                                              CommandReturnObject &result,
240330fdc8d8SChris Lattner                                              BreakpointIDList *valid_ids)
240430fdc8d8SChris Lattner {
240530fdc8d8SChris Lattner     // args can be strings representing 1). integers (for breakpoint ids)
240630fdc8d8SChris Lattner     //                                  2). the full breakpoint & location canonical representation
240730fdc8d8SChris Lattner     //                                  3). the word "to" or a hyphen, representing a range (in which case there
240830fdc8d8SChris Lattner     //                                      had *better* be an entry both before & after of one of the first two types.
24095e09c8c3SJim Ingham     //                                  4). A breakpoint name
241036f3b369SJim Ingham     // If args is empty, we will use the last created breakpoint (if there is one.)
241130fdc8d8SChris Lattner 
241230fdc8d8SChris Lattner     Args temp_args;
241330fdc8d8SChris Lattner 
241436f3b369SJim Ingham     if (args.GetArgumentCount() == 0)
241536f3b369SJim Ingham     {
24164d122c40SGreg Clayton         if (target->GetLastCreatedBreakpoint())
241736f3b369SJim Ingham         {
241836f3b369SJim Ingham             valid_ids->AddBreakpointID (BreakpointID(target->GetLastCreatedBreakpoint()->GetID(), LLDB_INVALID_BREAK_ID));
241936f3b369SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
242036f3b369SJim Ingham         }
242136f3b369SJim Ingham         else
242236f3b369SJim Ingham         {
242336f3b369SJim Ingham             result.AppendError("No breakpoint specified and no last created breakpoint.");
242436f3b369SJim Ingham             result.SetStatus (eReturnStatusFailed);
242536f3b369SJim Ingham         }
242636f3b369SJim Ingham         return;
242736f3b369SJim Ingham     }
242836f3b369SJim Ingham 
242930fdc8d8SChris Lattner     // Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff directly from the old ARGS to
243030fdc8d8SChris Lattner     // the new TEMP_ARGS.  Do not copy breakpoint id range strings over; instead generate a list of strings for
243130fdc8d8SChris Lattner     // all the breakpoint ids in the range, and shove all of those breakpoint id strings into TEMP_ARGS.
243230fdc8d8SChris Lattner 
24335e09c8c3SJim Ingham     BreakpointIDList::FindAndReplaceIDRanges (args, target, allow_locations, result, temp_args);
243430fdc8d8SChris Lattner 
243530fdc8d8SChris Lattner     // NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual BreakpointIDList:
243630fdc8d8SChris Lattner 
2437c982c768SGreg Clayton     valid_ids->InsertStringArray (temp_args.GetConstArgumentVector(), temp_args.GetArgumentCount(), result);
243830fdc8d8SChris Lattner 
243930fdc8d8SChris Lattner     // At this point,  all of the breakpoint ids that the user passed in have been converted to breakpoint IDs
244030fdc8d8SChris Lattner     // and put into valid_ids.
244130fdc8d8SChris Lattner 
244230fdc8d8SChris Lattner     if (result.Succeeded())
244330fdc8d8SChris Lattner     {
244430fdc8d8SChris Lattner         // Now that we've converted everything from args into a list of breakpoint ids, go through our tentative list
244530fdc8d8SChris Lattner         // of breakpoint id's and verify that they correspond to valid/currently set breakpoints.
244630fdc8d8SChris Lattner 
2447c982c768SGreg Clayton         const size_t count = valid_ids->GetSize();
2448c982c768SGreg Clayton         for (size_t i = 0; i < count; ++i)
244930fdc8d8SChris Lattner         {
245030fdc8d8SChris Lattner             BreakpointID cur_bp_id = valid_ids->GetBreakpointIDAtIndex (i);
245130fdc8d8SChris Lattner             Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
245230fdc8d8SChris Lattner             if (breakpoint != NULL)
245330fdc8d8SChris Lattner             {
2454c7bece56SGreg Clayton                 const size_t num_locations = breakpoint->GetNumLocations();
24553985c8c6SSaleem Abdulrasool                 if (static_cast<size_t>(cur_bp_id.GetLocationID()) > num_locations)
245630fdc8d8SChris Lattner                 {
245730fdc8d8SChris Lattner                     StreamString id_str;
2458c982c768SGreg Clayton                     BreakpointID::GetCanonicalReference (&id_str,
2459c982c768SGreg Clayton                                                          cur_bp_id.GetBreakpointID(),
246030fdc8d8SChris Lattner                                                          cur_bp_id.GetLocationID());
2461c982c768SGreg Clayton                     i = valid_ids->GetSize() + 1;
246230fdc8d8SChris Lattner                     result.AppendErrorWithFormat ("'%s' is not a currently valid breakpoint/location id.\n",
246330fdc8d8SChris Lattner                                                  id_str.GetData());
246430fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusFailed);
246530fdc8d8SChris Lattner                 }
246630fdc8d8SChris Lattner             }
246730fdc8d8SChris Lattner             else
246830fdc8d8SChris Lattner             {
2469c982c768SGreg Clayton                 i = valid_ids->GetSize() + 1;
247030fdc8d8SChris Lattner                 result.AppendErrorWithFormat ("'%d' is not a currently valid breakpoint id.\n", cur_bp_id.GetBreakpointID());
247130fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
247230fdc8d8SChris Lattner             }
247330fdc8d8SChris Lattner         }
247430fdc8d8SChris Lattner     }
247530fdc8d8SChris Lattner }
2476