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"
2240af72e1SJim Ingham #include "lldb/Interpreter/Options.h"
2330fdc8d8SChris Lattner #include "lldb/Core/RegularExpression.h"
2430fdc8d8SChris Lattner #include "lldb/Core/StreamString.h"
2530fdc8d8SChris Lattner #include "lldb/Interpreter/CommandInterpreter.h"
2630fdc8d8SChris Lattner #include "lldb/Interpreter/CommandReturnObject.h"
2730fdc8d8SChris Lattner #include "lldb/Target/Target.h"
2830fdc8d8SChris Lattner #include "lldb/Interpreter/CommandCompletions.h"
29b57e4a1bSJason Molenda #include "lldb/Target/StackFrame.h"
301b54c88cSJim Ingham #include "lldb/Target/Thread.h"
311b54c88cSJim Ingham #include "lldb/Target/ThreadSpec.h"
3230fdc8d8SChris Lattner 
33b7234e40SJohnny Chen #include <vector>
34b7234e40SJohnny Chen 
3530fdc8d8SChris Lattner using namespace lldb;
3630fdc8d8SChris Lattner using namespace lldb_private;
3730fdc8d8SChris Lattner 
3830fdc8d8SChris Lattner static void
3985e8b814SJim Ingham AddBreakpointDescription (Stream *s, Breakpoint *bp, lldb::DescriptionLevel level)
4030fdc8d8SChris Lattner {
4130fdc8d8SChris Lattner     s->IndentMore();
4230fdc8d8SChris Lattner     bp->GetDescription (s, level, true);
4330fdc8d8SChris Lattner     s->IndentLess();
4430fdc8d8SChris Lattner     s->EOL();
4530fdc8d8SChris Lattner }
4630fdc8d8SChris Lattner 
4730fdc8d8SChris Lattner //-------------------------------------------------------------------------
485a988416SJim Ingham // CommandObjectBreakpointSet
4930fdc8d8SChris Lattner //-------------------------------------------------------------------------
5030fdc8d8SChris Lattner 
515a988416SJim Ingham 
525a988416SJim Ingham class CommandObjectBreakpointSet : public CommandObjectParsed
535a988416SJim Ingham {
545a988416SJim Ingham public:
555a988416SJim Ingham 
565a988416SJim Ingham     typedef enum BreakpointSetType
575a988416SJim Ingham     {
585a988416SJim Ingham         eSetTypeInvalid,
595a988416SJim Ingham         eSetTypeFileAndLine,
605a988416SJim Ingham         eSetTypeAddress,
615a988416SJim Ingham         eSetTypeFunctionName,
625a988416SJim Ingham         eSetTypeFunctionRegexp,
635a988416SJim Ingham         eSetTypeSourceRegexp,
645a988416SJim Ingham         eSetTypeException
655a988416SJim Ingham     } BreakpointSetType;
665a988416SJim Ingham 
675a988416SJim Ingham     CommandObjectBreakpointSet (CommandInterpreter &interpreter) :
685a988416SJim Ingham         CommandObjectParsed (interpreter,
695a988416SJim Ingham                              "breakpoint set",
705a988416SJim Ingham                              "Sets a breakpoint or set of breakpoints in the executable.",
715a988416SJim Ingham                              "breakpoint set <cmd-options>"),
725a988416SJim Ingham         m_options (interpreter)
735a988416SJim Ingham     {
745a988416SJim Ingham     }
755a988416SJim Ingham 
765a988416SJim Ingham 
775a988416SJim Ingham     virtual
785a988416SJim Ingham     ~CommandObjectBreakpointSet () {}
795a988416SJim Ingham 
805a988416SJim Ingham     virtual Options *
815a988416SJim Ingham     GetOptions ()
825a988416SJim Ingham     {
835a988416SJim Ingham         return &m_options;
845a988416SJim Ingham     }
855a988416SJim Ingham 
865a988416SJim Ingham     class CommandOptions : public Options
875a988416SJim Ingham     {
885a988416SJim Ingham     public:
895a988416SJim Ingham 
905a988416SJim Ingham         CommandOptions (CommandInterpreter &interpreter) :
91eb0103f2SGreg Clayton             Options (interpreter),
927d49c9c8SJohnny Chen             m_condition (),
9387df91b8SJim Ingham             m_filenames (),
9430fdc8d8SChris Lattner             m_line_num (0),
9530fdc8d8SChris Lattner             m_column (0),
96fab10e89SJim Ingham             m_func_names (),
97fab10e89SJim Ingham             m_func_name_type_mask (eFunctionNameTypeNone),
9830fdc8d8SChris Lattner             m_func_regexp (),
99969795f1SJim Ingham             m_source_text_regexp(),
10030fdc8d8SChris Lattner             m_modules (),
1011b54c88cSJim Ingham             m_load_addr(),
102c982c768SGreg Clayton             m_ignore_count (0),
1031b54c88cSJim Ingham             m_thread_id(LLDB_INVALID_THREAD_ID),
104c982c768SGreg Clayton             m_thread_index (UINT32_MAX),
1051b54c88cSJim Ingham             m_thread_name(),
106fab10e89SJim Ingham             m_queue_name(),
107fab10e89SJim Ingham             m_catch_bp (false),
1081f746071SGreg Clayton             m_throw_bp (true),
109eb023e75SGreg Clayton             m_hardware (false),
110a8558b62SJim Ingham             m_language (eLanguageTypeUnknown),
111ca36cd16SJim Ingham             m_skip_prologue (eLazyBoolCalculate),
112ca36cd16SJim Ingham             m_one_shot (false)
11330fdc8d8SChris Lattner         {
11430fdc8d8SChris Lattner         }
11530fdc8d8SChris Lattner 
11630fdc8d8SChris Lattner 
1175a988416SJim Ingham         virtual
1185a988416SJim Ingham         ~CommandOptions () {}
11987df91b8SJim Ingham 
1205a988416SJim Ingham         virtual Error
1215a988416SJim Ingham         SetOptionValue (uint32_t option_idx, const char *option_arg)
12230fdc8d8SChris Lattner         {
12330fdc8d8SChris Lattner             Error error;
1243bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
12530fdc8d8SChris Lattner 
12630fdc8d8SChris Lattner             switch (short_option)
12730fdc8d8SChris Lattner             {
12830fdc8d8SChris Lattner                 case 'a':
129b9d5df58SGreg Clayton                     {
130b9d5df58SGreg Clayton                         ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
131b9d5df58SGreg Clayton                         m_load_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
132b9d5df58SGreg Clayton                     }
13330fdc8d8SChris Lattner                     break;
13430fdc8d8SChris Lattner 
135ca36cd16SJim Ingham                 case 'b':
136ca36cd16SJim Ingham                     m_func_names.push_back (option_arg);
137ca36cd16SJim Ingham                     m_func_name_type_mask |= eFunctionNameTypeBase;
138ca36cd16SJim Ingham                     break;
139ca36cd16SJim Ingham 
1407d49c9c8SJohnny Chen                 case 'C':
14130fdc8d8SChris Lattner                     m_column = Args::StringToUInt32 (option_arg, 0);
14230fdc8d8SChris Lattner                     break;
1430c5cd90dSGreg Clayton 
1447d49c9c8SJohnny Chen                 case 'c':
1457d49c9c8SJohnny Chen                     m_condition.assign(option_arg);
1467d49c9c8SJohnny Chen                     break;
1477d49c9c8SJohnny Chen 
148*33df7cd3SJim Ingham                 case 'D':
149*33df7cd3SJim Ingham                     m_use_dummy = true;
150*33df7cd3SJim Ingham                     break;
151*33df7cd3SJim Ingham 
152fab10e89SJim Ingham                 case 'E':
153fab10e89SJim Ingham                 {
154fab10e89SJim Ingham                     LanguageType language = LanguageRuntime::GetLanguageTypeFromString (option_arg);
155fab10e89SJim Ingham 
156fab10e89SJim Ingham                     switch (language)
157fab10e89SJim Ingham                     {
158fab10e89SJim Ingham                         case eLanguageTypeC89:
159fab10e89SJim Ingham                         case eLanguageTypeC:
160fab10e89SJim Ingham                         case eLanguageTypeC99:
1611d0089faSBruce Mitchener                         case eLanguageTypeC11:
162fab10e89SJim Ingham                             m_language = eLanguageTypeC;
163fab10e89SJim Ingham                             break;
164fab10e89SJim Ingham                         case eLanguageTypeC_plus_plus:
1651d0089faSBruce Mitchener                         case eLanguageTypeC_plus_plus_03:
1661d0089faSBruce Mitchener                         case eLanguageTypeC_plus_plus_11:
167fab10e89SJim Ingham                             m_language = eLanguageTypeC_plus_plus;
168fab10e89SJim Ingham                             break;
169fab10e89SJim Ingham                         case eLanguageTypeObjC:
170fab10e89SJim Ingham                             m_language = eLanguageTypeObjC;
171fab10e89SJim Ingham                             break;
172fab10e89SJim Ingham                         case eLanguageTypeObjC_plus_plus:
173fab10e89SJim Ingham                             error.SetErrorStringWithFormat ("Set exception breakpoints separately for c++ and objective-c");
174fab10e89SJim Ingham                             break;
175fab10e89SJim Ingham                         case eLanguageTypeUnknown:
176fab10e89SJim Ingham                             error.SetErrorStringWithFormat ("Unknown language type: '%s' for exception breakpoint", option_arg);
177fab10e89SJim Ingham                             break;
178fab10e89SJim Ingham                         default:
179fab10e89SJim Ingham                             error.SetErrorStringWithFormat ("Unsupported language type: '%s' for exception breakpoint", option_arg);
180fab10e89SJim Ingham                     }
181fab10e89SJim Ingham                 }
182fab10e89SJim Ingham                 break;
183ca36cd16SJim Ingham 
184ca36cd16SJim Ingham                 case 'f':
185ca36cd16SJim Ingham                     m_filenames.AppendIfUnique (FileSpec(option_arg, false));
186fab10e89SJim Ingham                     break;
187ca36cd16SJim Ingham 
188ca36cd16SJim Ingham                 case 'F':
189ca36cd16SJim Ingham                     m_func_names.push_back (option_arg);
190ca36cd16SJim Ingham                     m_func_name_type_mask |= eFunctionNameTypeFull;
191ca36cd16SJim Ingham                     break;
192ca36cd16SJim Ingham 
193fab10e89SJim Ingham                 case 'h':
194fab10e89SJim Ingham                     {
195fab10e89SJim Ingham                         bool success;
196fab10e89SJim Ingham                         m_catch_bp = Args::StringToBoolean (option_arg, true, &success);
197fab10e89SJim Ingham                         if (!success)
198fab10e89SJim Ingham                             error.SetErrorStringWithFormat ("Invalid boolean value for on-catch option: '%s'", option_arg);
199fab10e89SJim Ingham                     }
200168d469aSJim Ingham                     break;
201eb023e75SGreg Clayton 
202eb023e75SGreg Clayton                 case 'H':
203eb023e75SGreg Clayton                     m_hardware = true;
204eb023e75SGreg Clayton                     break;
205eb023e75SGreg Clayton 
206ca36cd16SJim Ingham                 case 'i':
207ca36cd16SJim Ingham                 {
208ca36cd16SJim Ingham                     m_ignore_count = Args::StringToUInt32(option_arg, UINT32_MAX, 0);
209ca36cd16SJim Ingham                     if (m_ignore_count == UINT32_MAX)
210ca36cd16SJim Ingham                        error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
211ca36cd16SJim Ingham                     break;
212ca36cd16SJim Ingham                 }
213ca36cd16SJim Ingham 
214a8558b62SJim Ingham                 case 'K':
215a8558b62SJim Ingham                 {
216a8558b62SJim Ingham                     bool success;
217a8558b62SJim Ingham                     bool value;
218a8558b62SJim Ingham                     value = Args::StringToBoolean (option_arg, true, &success);
219a8558b62SJim Ingham                     if (value)
220a8558b62SJim Ingham                         m_skip_prologue = eLazyBoolYes;
221a8558b62SJim Ingham                     else
222a8558b62SJim Ingham                         m_skip_prologue = eLazyBoolNo;
223a8558b62SJim Ingham 
224a8558b62SJim Ingham                     if (!success)
225a8558b62SJim Ingham                         error.SetErrorStringWithFormat ("Invalid boolean value for skip prologue option: '%s'", option_arg);
226a8558b62SJim Ingham                 }
227fab10e89SJim Ingham                 break;
228ca36cd16SJim Ingham 
229ca36cd16SJim Ingham                 case 'l':
230ca36cd16SJim Ingham                     m_line_num = Args::StringToUInt32 (option_arg, 0);
231ca36cd16SJim Ingham                     break;
232ca36cd16SJim Ingham 
233ca36cd16SJim Ingham                 case 'M':
234ca36cd16SJim Ingham                     m_func_names.push_back (option_arg);
235ca36cd16SJim Ingham                     m_func_name_type_mask |= eFunctionNameTypeMethod;
236ca36cd16SJim Ingham                     break;
237ca36cd16SJim Ingham 
238ca36cd16SJim Ingham                 case 'n':
239ca36cd16SJim Ingham                     m_func_names.push_back (option_arg);
240ca36cd16SJim Ingham                     m_func_name_type_mask |= eFunctionNameTypeAuto;
241ca36cd16SJim Ingham                     break;
242ca36cd16SJim Ingham 
243ca36cd16SJim Ingham                 case 'o':
244ca36cd16SJim Ingham                     m_one_shot = true;
245ca36cd16SJim Ingham                     break;
246ca36cd16SJim Ingham 
247ca36cd16SJim Ingham                 case 'p':
248ca36cd16SJim Ingham                     m_source_text_regexp.assign (option_arg);
249ca36cd16SJim Ingham                     break;
250ca36cd16SJim Ingham 
251ca36cd16SJim Ingham                 case 'q':
252ca36cd16SJim Ingham                     m_queue_name.assign (option_arg);
253ca36cd16SJim Ingham                     break;
254ca36cd16SJim Ingham 
255ca36cd16SJim Ingham                 case 'r':
256ca36cd16SJim Ingham                     m_func_regexp.assign (option_arg);
257ca36cd16SJim Ingham                     break;
258ca36cd16SJim Ingham 
259ca36cd16SJim Ingham                 case 's':
260ca36cd16SJim Ingham                 {
261ca36cd16SJim Ingham                     m_modules.AppendIfUnique (FileSpec (option_arg, false));
262ca36cd16SJim Ingham                     break;
263ca36cd16SJim Ingham                 }
264ca36cd16SJim Ingham 
265ca36cd16SJim Ingham                 case 'S':
266ca36cd16SJim Ingham                     m_func_names.push_back (option_arg);
267ca36cd16SJim Ingham                     m_func_name_type_mask |= eFunctionNameTypeSelector;
268ca36cd16SJim Ingham                     break;
269ca36cd16SJim Ingham 
270ca36cd16SJim Ingham                 case 't' :
271ca36cd16SJim Ingham                 {
272ca36cd16SJim Ingham                     m_thread_id = Args::StringToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
273ca36cd16SJim Ingham                     if (m_thread_id == LLDB_INVALID_THREAD_ID)
274ca36cd16SJim Ingham                        error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
275ca36cd16SJim Ingham                 }
276ca36cd16SJim Ingham                 break;
277ca36cd16SJim Ingham 
278ca36cd16SJim Ingham                 case 'T':
279ca36cd16SJim Ingham                     m_thread_name.assign (option_arg);
280ca36cd16SJim Ingham                     break;
281ca36cd16SJim Ingham 
282ca36cd16SJim Ingham                 case 'w':
283ca36cd16SJim Ingham                 {
284ca36cd16SJim Ingham                     bool success;
285ca36cd16SJim Ingham                     m_throw_bp = Args::StringToBoolean (option_arg, true, &success);
286ca36cd16SJim Ingham                     if (!success)
287ca36cd16SJim Ingham                         error.SetErrorStringWithFormat ("Invalid boolean value for on-throw option: '%s'", option_arg);
288ca36cd16SJim Ingham                 }
289ca36cd16SJim Ingham                 break;
290ca36cd16SJim Ingham 
291ca36cd16SJim Ingham                 case 'x':
292ca36cd16SJim Ingham                 {
293ca36cd16SJim Ingham                     m_thread_index = Args::StringToUInt32(option_arg, UINT32_MAX, 0);
294ca36cd16SJim Ingham                     if (m_thread_id == UINT32_MAX)
295ca36cd16SJim Ingham                        error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
296ca36cd16SJim Ingham 
297ca36cd16SJim Ingham                 }
298ca36cd16SJim Ingham                 break;
299ca36cd16SJim Ingham 
30030fdc8d8SChris Lattner                 default:
30186edbf41SGreg Clayton                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
30230fdc8d8SChris Lattner                     break;
30330fdc8d8SChris Lattner             }
30430fdc8d8SChris Lattner 
30530fdc8d8SChris Lattner             return error;
30630fdc8d8SChris Lattner         }
30730fdc8d8SChris Lattner         void
3085a988416SJim Ingham         OptionParsingStarting ()
30930fdc8d8SChris Lattner         {
3107d49c9c8SJohnny Chen             m_condition.clear();
31187df91b8SJim Ingham             m_filenames.Clear();
31230fdc8d8SChris Lattner             m_line_num = 0;
31330fdc8d8SChris Lattner             m_column = 0;
314fab10e89SJim Ingham             m_func_names.clear();
3151f746071SGreg Clayton             m_func_name_type_mask = eFunctionNameTypeNone;
31630fdc8d8SChris Lattner             m_func_regexp.clear();
3171f746071SGreg Clayton             m_source_text_regexp.clear();
31887df91b8SJim Ingham             m_modules.Clear();
3191f746071SGreg Clayton             m_load_addr = LLDB_INVALID_ADDRESS;
320c982c768SGreg Clayton             m_ignore_count = 0;
3211b54c88cSJim Ingham             m_thread_id = LLDB_INVALID_THREAD_ID;
322c982c768SGreg Clayton             m_thread_index = UINT32_MAX;
3231b54c88cSJim Ingham             m_thread_name.clear();
3241b54c88cSJim Ingham             m_queue_name.clear();
325fab10e89SJim Ingham             m_catch_bp = false;
326fab10e89SJim Ingham             m_throw_bp = true;
327eb023e75SGreg Clayton             m_hardware = false;
3281f746071SGreg Clayton             m_language = eLanguageTypeUnknown;
329a8558b62SJim Ingham             m_skip_prologue = eLazyBoolCalculate;
330ca36cd16SJim Ingham             m_one_shot = false;
331*33df7cd3SJim Ingham             m_use_dummy = false;
33230fdc8d8SChris Lattner         }
33330fdc8d8SChris Lattner 
3345a988416SJim Ingham         const OptionDefinition*
3355a988416SJim Ingham         GetDefinitions ()
33630fdc8d8SChris Lattner         {
3375a988416SJim Ingham             return g_option_table;
33830fdc8d8SChris Lattner         }
33930fdc8d8SChris Lattner 
3405a988416SJim Ingham         // Options table: Required for subclasses of Options.
34130fdc8d8SChris Lattner 
3425a988416SJim Ingham         static OptionDefinition g_option_table[];
34330fdc8d8SChris Lattner 
3445a988416SJim Ingham         // Instance variables to hold the values for command options.
345969795f1SJim Ingham 
3465a988416SJim Ingham         std::string m_condition;
3475a988416SJim Ingham         FileSpecList m_filenames;
3485a988416SJim Ingham         uint32_t m_line_num;
3495a988416SJim Ingham         uint32_t m_column;
3505a988416SJim Ingham         std::vector<std::string> m_func_names;
3515a988416SJim Ingham         uint32_t m_func_name_type_mask;
3525a988416SJim Ingham         std::string m_func_regexp;
3535a988416SJim Ingham         std::string m_source_text_regexp;
3545a988416SJim Ingham         FileSpecList m_modules;
3555a988416SJim Ingham         lldb::addr_t m_load_addr;
3565a988416SJim Ingham         uint32_t m_ignore_count;
3575a988416SJim Ingham         lldb::tid_t m_thread_id;
3585a988416SJim Ingham         uint32_t m_thread_index;
3595a988416SJim Ingham         std::string m_thread_name;
3605a988416SJim Ingham         std::string m_queue_name;
3615a988416SJim Ingham         bool m_catch_bp;
3625a988416SJim Ingham         bool m_throw_bp;
363eb023e75SGreg Clayton         bool m_hardware; // Request to use hardware breakpoints
3645a988416SJim Ingham         lldb::LanguageType m_language;
3655a988416SJim Ingham         LazyBool m_skip_prologue;
366ca36cd16SJim Ingham         bool m_one_shot;
367*33df7cd3SJim Ingham         bool m_use_dummy;
3685a988416SJim Ingham 
3695a988416SJim Ingham     };
3705a988416SJim Ingham 
3715a988416SJim Ingham protected:
3725a988416SJim Ingham     virtual bool
3735a988416SJim Ingham     DoExecute (Args& command,
3745a988416SJim Ingham               CommandReturnObject &result)
37530fdc8d8SChris Lattner     {
376*33df7cd3SJim Ingham         Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
377*33df7cd3SJim Ingham 
378893c932aSJim Ingham         if (target == nullptr)
37930fdc8d8SChris Lattner         {
380effe5c95SGreg Clayton             result.AppendError ("Invalid target.  Must set target before setting breakpoints (see 'target create' command).");
38130fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
38230fdc8d8SChris Lattner             return false;
38330fdc8d8SChris Lattner         }
38430fdc8d8SChris Lattner 
38530fdc8d8SChris Lattner         // The following are the various types of breakpoints that could be set:
38630fdc8d8SChris Lattner         //   1).  -f -l -p  [-s -g]   (setting breakpoint by source location)
38730fdc8d8SChris Lattner         //   2).  -a  [-s -g]         (setting breakpoint by address)
38830fdc8d8SChris Lattner         //   3).  -n  [-s -g]         (setting breakpoint by function name)
38930fdc8d8SChris Lattner         //   4).  -r  [-s -g]         (setting breakpoint by function name regular expression)
390969795f1SJim Ingham         //   5).  -p -f               (setting a breakpoint by comparing a reg-exp to source text)
391fab10e89SJim Ingham         //   6).  -E [-w -h]          (setting a breakpoint for exceptions for a given language.)
39230fdc8d8SChris Lattner 
39330fdc8d8SChris Lattner         BreakpointSetType break_type = eSetTypeInvalid;
39430fdc8d8SChris Lattner 
39530fdc8d8SChris Lattner         if (m_options.m_line_num != 0)
39630fdc8d8SChris Lattner             break_type = eSetTypeFileAndLine;
39730fdc8d8SChris Lattner         else if (m_options.m_load_addr != LLDB_INVALID_ADDRESS)
39830fdc8d8SChris Lattner             break_type = eSetTypeAddress;
399fab10e89SJim Ingham         else if (!m_options.m_func_names.empty())
40030fdc8d8SChris Lattner             break_type = eSetTypeFunctionName;
40130fdc8d8SChris Lattner         else if  (!m_options.m_func_regexp.empty())
40230fdc8d8SChris Lattner             break_type = eSetTypeFunctionRegexp;
403969795f1SJim Ingham         else if (!m_options.m_source_text_regexp.empty())
404969795f1SJim Ingham             break_type = eSetTypeSourceRegexp;
405fab10e89SJim Ingham         else if (m_options.m_language != eLanguageTypeUnknown)
406fab10e89SJim Ingham             break_type = eSetTypeException;
40730fdc8d8SChris Lattner 
40830fdc8d8SChris Lattner         Breakpoint *bp = NULL;
409274060b6SGreg Clayton         FileSpec module_spec;
410a8558b62SJim Ingham         const bool internal = false;
411a8558b62SJim Ingham 
41230fdc8d8SChris Lattner         switch (break_type)
41330fdc8d8SChris Lattner         {
41430fdc8d8SChris Lattner             case eSetTypeFileAndLine: // Breakpoint by source position
41530fdc8d8SChris Lattner                 {
41630fdc8d8SChris Lattner                     FileSpec file;
417c7bece56SGreg Clayton                     const size_t num_files = m_options.m_filenames.GetSize();
41887df91b8SJim Ingham                     if (num_files == 0)
41987df91b8SJim Ingham                     {
42087df91b8SJim Ingham                         if (!GetDefaultFile (target, file, result))
42187df91b8SJim Ingham                         {
42287df91b8SJim Ingham                             result.AppendError("No file supplied and no default file available.");
42387df91b8SJim Ingham                             result.SetStatus (eReturnStatusFailed);
42487df91b8SJim Ingham                             return false;
42587df91b8SJim Ingham                         }
42687df91b8SJim Ingham                     }
42787df91b8SJim Ingham                     else if (num_files > 1)
42887df91b8SJim Ingham                     {
42987df91b8SJim Ingham                         result.AppendError("Only one file at a time is allowed for file and line breakpoints.");
43087df91b8SJim Ingham                         result.SetStatus (eReturnStatusFailed);
43187df91b8SJim Ingham                         return false;
43287df91b8SJim Ingham                     }
43387df91b8SJim Ingham                     else
43487df91b8SJim Ingham                         file = m_options.m_filenames.GetFileSpecAtIndex(0);
43530fdc8d8SChris Lattner 
4361f746071SGreg Clayton                     // Only check for inline functions if
4371f746071SGreg Clayton                     LazyBool check_inlines = eLazyBoolCalculate;
4381f746071SGreg Clayton 
43987df91b8SJim Ingham                     bp = target->CreateBreakpoint (&(m_options.m_modules),
44030fdc8d8SChris Lattner                                                    file,
44130fdc8d8SChris Lattner                                                    m_options.m_line_num,
4421f746071SGreg Clayton                                                    check_inlines,
443a8558b62SJim Ingham                                                    m_options.m_skip_prologue,
444eb023e75SGreg Clayton                                                    internal,
445eb023e75SGreg Clayton                                                    m_options.m_hardware).get();
44630fdc8d8SChris Lattner                 }
44730fdc8d8SChris Lattner                 break;
4486eee5aa0SGreg Clayton 
44930fdc8d8SChris Lattner             case eSetTypeAddress: // Breakpoint by address
450eb023e75SGreg Clayton                 bp = target->CreateBreakpoint (m_options.m_load_addr,
451eb023e75SGreg Clayton                                                internal,
452eb023e75SGreg Clayton                                                m_options.m_hardware).get();
45330fdc8d8SChris Lattner                 break;
4540c5cd90dSGreg Clayton 
45530fdc8d8SChris Lattner             case eSetTypeFunctionName: // Breakpoint by function name
4560c5cd90dSGreg Clayton                 {
4570c5cd90dSGreg Clayton                     uint32_t name_type_mask = m_options.m_func_name_type_mask;
4580c5cd90dSGreg Clayton 
4590c5cd90dSGreg Clayton                     if (name_type_mask == 0)
460e02b8504SGreg Clayton                         name_type_mask = eFunctionNameTypeAuto;
4610c5cd90dSGreg Clayton 
46287df91b8SJim Ingham                     bp = target->CreateBreakpoint (&(m_options.m_modules),
46387df91b8SJim Ingham                                                    &(m_options.m_filenames),
464fab10e89SJim Ingham                                                    m_options.m_func_names,
465274060b6SGreg Clayton                                                    name_type_mask,
466a8558b62SJim Ingham                                                    m_options.m_skip_prologue,
467eb023e75SGreg Clayton                                                    internal,
468eb023e75SGreg Clayton                                                    m_options.m_hardware).get();
4690c5cd90dSGreg Clayton                 }
47030fdc8d8SChris Lattner                 break;
4710c5cd90dSGreg Clayton 
47230fdc8d8SChris Lattner             case eSetTypeFunctionRegexp: // Breakpoint by regular expression function name
47330fdc8d8SChris Lattner                 {
47430fdc8d8SChris Lattner                     RegularExpression regexp(m_options.m_func_regexp.c_str());
475969795f1SJim Ingham                     if (!regexp.IsValid())
47630fdc8d8SChris Lattner                     {
477969795f1SJim Ingham                         char err_str[1024];
478969795f1SJim Ingham                         regexp.GetErrorAsCString(err_str, sizeof(err_str));
479969795f1SJim Ingham                         result.AppendErrorWithFormat("Function name regular expression could not be compiled: \"%s\"",
480969795f1SJim Ingham                                                      err_str);
48130fdc8d8SChris Lattner                         result.SetStatus (eReturnStatusFailed);
482969795f1SJim Ingham                         return false;
48330fdc8d8SChris Lattner                     }
48487df91b8SJim Ingham 
485a8558b62SJim Ingham                     bp = target->CreateFuncRegexBreakpoint (&(m_options.m_modules),
486a8558b62SJim Ingham                                                             &(m_options.m_filenames),
487a8558b62SJim Ingham                                                             regexp,
488a8558b62SJim Ingham                                                             m_options.m_skip_prologue,
489eb023e75SGreg Clayton                                                             internal,
490eb023e75SGreg Clayton                                                             m_options.m_hardware).get();
49130fdc8d8SChris Lattner                 }
49230fdc8d8SChris Lattner                 break;
493969795f1SJim Ingham             case eSetTypeSourceRegexp: // Breakpoint by regexp on source text.
494969795f1SJim Ingham                 {
495c7bece56SGreg Clayton                     const size_t num_files = m_options.m_filenames.GetSize();
49687df91b8SJim Ingham 
49787df91b8SJim Ingham                     if (num_files == 0)
49887df91b8SJim Ingham                     {
499969795f1SJim Ingham                         FileSpec file;
50087df91b8SJim Ingham                         if (!GetDefaultFile (target, file, result))
50187df91b8SJim Ingham                         {
50287df91b8SJim Ingham                             result.AppendError ("No files provided and could not find default file.");
50387df91b8SJim Ingham                             result.SetStatus (eReturnStatusFailed);
50487df91b8SJim Ingham                             return false;
50587df91b8SJim Ingham                         }
50687df91b8SJim Ingham                         else
50787df91b8SJim Ingham                         {
50887df91b8SJim Ingham                             m_options.m_filenames.Append (file);
50987df91b8SJim Ingham                         }
51087df91b8SJim Ingham                     }
5110c5cd90dSGreg Clayton 
512969795f1SJim Ingham                     RegularExpression regexp(m_options.m_source_text_regexp.c_str());
513969795f1SJim Ingham                     if (!regexp.IsValid())
514969795f1SJim Ingham                     {
515969795f1SJim Ingham                         char err_str[1024];
516969795f1SJim Ingham                         regexp.GetErrorAsCString(err_str, sizeof(err_str));
517969795f1SJim Ingham                         result.AppendErrorWithFormat("Source text regular expression could not be compiled: \"%s\"",
518969795f1SJim Ingham                                                      err_str);
519969795f1SJim Ingham                         result.SetStatus (eReturnStatusFailed);
520969795f1SJim Ingham                         return false;
521969795f1SJim Ingham                     }
522eb023e75SGreg Clayton                     bp = target->CreateSourceRegexBreakpoint (&(m_options.m_modules),
523eb023e75SGreg Clayton                                                               &(m_options.m_filenames),
524eb023e75SGreg Clayton                                                               regexp,
525eb023e75SGreg Clayton                                                               internal,
526eb023e75SGreg Clayton                                                               m_options.m_hardware).get();
527969795f1SJim Ingham                 }
528969795f1SJim Ingham                 break;
529fab10e89SJim Ingham             case eSetTypeException:
530fab10e89SJim Ingham                 {
531eb023e75SGreg Clayton                     bp = target->CreateExceptionBreakpoint (m_options.m_language,
532eb023e75SGreg Clayton                                                             m_options.m_catch_bp,
533eb023e75SGreg Clayton                                                             m_options.m_throw_bp,
534eb023e75SGreg Clayton                                                             m_options.m_hardware).get();
535fab10e89SJim Ingham                 }
536fab10e89SJim Ingham                 break;
53730fdc8d8SChris Lattner             default:
53830fdc8d8SChris Lattner                 break;
53930fdc8d8SChris Lattner         }
54030fdc8d8SChris Lattner 
5411b54c88cSJim Ingham         // Now set the various options that were passed in:
5421b54c88cSJim Ingham         if (bp)
5431b54c88cSJim Ingham         {
5441b54c88cSJim Ingham             if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
5451b54c88cSJim Ingham                 bp->SetThreadID (m_options.m_thread_id);
5461b54c88cSJim Ingham 
547c982c768SGreg Clayton             if (m_options.m_thread_index != UINT32_MAX)
5481b54c88cSJim Ingham                 bp->GetOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index);
5491b54c88cSJim Ingham 
5501b54c88cSJim Ingham             if (!m_options.m_thread_name.empty())
5511b54c88cSJim Ingham                 bp->GetOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str());
5521b54c88cSJim Ingham 
5531b54c88cSJim Ingham             if (!m_options.m_queue_name.empty())
5541b54c88cSJim Ingham                 bp->GetOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str());
5551b54c88cSJim Ingham 
556c982c768SGreg Clayton             if (m_options.m_ignore_count != 0)
5571b54c88cSJim Ingham                 bp->GetOptions()->SetIgnoreCount(m_options.m_ignore_count);
5587d49c9c8SJohnny Chen 
5597d49c9c8SJohnny Chen             if (!m_options.m_condition.empty())
5607d49c9c8SJohnny Chen                 bp->GetOptions()->SetCondition(m_options.m_condition.c_str());
561ca36cd16SJim Ingham 
562ca36cd16SJim Ingham             bp->SetOneShot (m_options.m_one_shot);
5631b54c88cSJim Ingham         }
5641b54c88cSJim Ingham 
565969795f1SJim Ingham         if (bp)
56630fdc8d8SChris Lattner         {
56785e8b814SJim Ingham             Stream &output_stream = result.GetOutputStream();
5681391cc7dSJim Ingham             const bool show_locations = false;
5691391cc7dSJim Ingham             bp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial, show_locations);
570fab10e89SJim Ingham             // Don't print out this warning for exception breakpoints.  They can get set before the target
571fab10e89SJim Ingham             // is set, but we won't know how to actually set the breakpoint till we run.
572fab10e89SJim Ingham             if (bp->GetNumLocations() == 0 && break_type != eSetTypeException)
573be484f41SCaroline Tice                 output_stream.Printf ("WARNING:  Unable to resolve breakpoint to any actual locations.\n");
57430fdc8d8SChris Lattner             result.SetStatus (eReturnStatusSuccessFinishResult);
57530fdc8d8SChris Lattner         }
57630fdc8d8SChris Lattner         else if (!bp)
57730fdc8d8SChris Lattner         {
57830fdc8d8SChris Lattner             result.AppendError ("Breakpoint creation failed: No breakpoint created.");
57930fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
58030fdc8d8SChris Lattner         }
58130fdc8d8SChris Lattner 
58230fdc8d8SChris Lattner         return result.Succeeded();
58330fdc8d8SChris Lattner     }
58430fdc8d8SChris Lattner 
5855a988416SJim Ingham private:
5865a988416SJim Ingham     bool
5875a988416SJim Ingham     GetDefaultFile (Target *target, FileSpec &file, CommandReturnObject &result)
5885a988416SJim Ingham     {
5895a988416SJim Ingham         uint32_t default_line;
5905a988416SJim Ingham         // First use the Source Manager's default file.
5915a988416SJim Ingham         // Then use the current stack frame's file.
5925a988416SJim Ingham         if (!target->GetSourceManager().GetDefaultFileAndLine(file, default_line))
5935a988416SJim Ingham         {
594b57e4a1bSJason Molenda             StackFrame *cur_frame = m_exe_ctx.GetFramePtr();
5955a988416SJim Ingham             if (cur_frame == NULL)
5965a988416SJim Ingham             {
5975a988416SJim Ingham                 result.AppendError ("No selected frame to use to find the default file.");
5985a988416SJim Ingham                 result.SetStatus (eReturnStatusFailed);
5995a988416SJim Ingham                 return false;
6005a988416SJim Ingham             }
6015a988416SJim Ingham             else if (!cur_frame->HasDebugInformation())
6025a988416SJim Ingham             {
6035a988416SJim Ingham                 result.AppendError ("Cannot use the selected frame to find the default file, it has no debug info.");
6045a988416SJim Ingham                 result.SetStatus (eReturnStatusFailed);
6055a988416SJim Ingham                 return false;
6065a988416SJim Ingham             }
6075a988416SJim Ingham             else
6085a988416SJim Ingham             {
6095a988416SJim Ingham                 const SymbolContext &sc = cur_frame->GetSymbolContext (eSymbolContextLineEntry);
6105a988416SJim Ingham                 if (sc.line_entry.file)
6115a988416SJim Ingham                 {
6125a988416SJim Ingham                     file = sc.line_entry.file;
6135a988416SJim Ingham                 }
6145a988416SJim Ingham                 else
6155a988416SJim Ingham                 {
6165a988416SJim Ingham                     result.AppendError ("Can't find the file for the selected frame to use as the default file.");
6175a988416SJim Ingham                     result.SetStatus (eReturnStatusFailed);
6185a988416SJim Ingham                     return false;
6195a988416SJim Ingham                 }
6205a988416SJim Ingham             }
6215a988416SJim Ingham         }
6225a988416SJim Ingham         return true;
6235a988416SJim Ingham     }
6245a988416SJim Ingham 
6255a988416SJim Ingham     CommandOptions m_options;
6265a988416SJim Ingham };
6275a988416SJim Ingham // If an additional option set beyond LLDB_OPTION_SET_10 is added, make sure to
6285a988416SJim Ingham // update the numbers passed to LLDB_OPT_SET_FROM_TO(...) appropriately.
6295a988416SJim Ingham #define LLDB_OPT_FILE ( LLDB_OPT_SET_FROM_TO(1, 9) & ~LLDB_OPT_SET_2 )
6305a988416SJim Ingham #define LLDB_OPT_NOT_10 ( LLDB_OPT_SET_FROM_TO(1, 10) & ~LLDB_OPT_SET_10 )
6315a988416SJim Ingham #define LLDB_OPT_SKIP_PROLOGUE ( LLDB_OPT_SET_1 | LLDB_OPT_SET_FROM_TO(3,8) )
6325a988416SJim Ingham 
6335a988416SJim Ingham OptionDefinition
6345a988416SJim Ingham CommandObjectBreakpointSet::CommandOptions::g_option_table[] =
6355a988416SJim Ingham {
636d37221dcSZachary Turner     { LLDB_OPT_NOT_10, false, "shlib", 's', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName,
6375a988416SJim Ingham         "Set the breakpoint only in this shared library.  "
6385a988416SJim Ingham         "Can repeat this option multiple times to specify multiple shared libraries."},
6395a988416SJim Ingham 
640d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', OptionParser::eRequiredArgument,   NULL, NULL, 0, eArgTypeCount,
6415a988416SJim Ingham         "Set the number of times this breakpoint is skipped before stopping." },
6425a988416SJim Ingham 
643d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "one-shot", 'o', OptionParser::eNoArgument,   NULL, NULL, 0, eArgTypeNone,
644b2b256afSJim Ingham         "The breakpoint is deleted the first time it causes a stop." },
645ca36cd16SJim Ingham 
646d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "condition",    'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeExpression,
6475a988416SJim Ingham         "The breakpoint stops only if this condition expression evaluates to true."},
6485a988416SJim Ingham 
649d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadIndex,
650a89be91fSJim Ingham         "The breakpoint stops only for the thread whose indeX matches this argument."},
6515a988416SJim Ingham 
652d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadID,
6535a988416SJim Ingham         "The breakpoint stops only for the thread whose TID matches this argument."},
6545a988416SJim Ingham 
655d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadName,
6565a988416SJim Ingham         "The breakpoint stops only for the thread whose thread name matches this argument."},
6575a988416SJim Ingham 
658d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "hardware", 'H', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
659eb023e75SGreg Clayton         "Require the breakpoint to use hardware breakpoints."},
660eb023e75SGreg Clayton 
661d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeQueueName,
6625a988416SJim Ingham         "The breakpoint stops only for threads in the queue whose name is given by this argument."},
6635a988416SJim Ingham 
664d37221dcSZachary Turner     { LLDB_OPT_FILE, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
665289aca64SJim Ingham         "Specifies the source file in which to set this breakpoint.  "
666289aca64SJim Ingham         "Note, by default lldb only looks for files that are #included if they use the standard include file extensions.  "
6676394479eSJim Ingham         "To set breakpoints on .c/.cpp/.m/.mm files that are #included, set target.inline-breakpoint-strategy"
668289aca64SJim Ingham         " to \"always\"."},
6695a988416SJim Ingham 
670d37221dcSZachary Turner     { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum,
6715a988416SJim Ingham         "Specifies the line number on which to set this breakpoint."},
6725a988416SJim Ingham 
6735a988416SJim Ingham     // Comment out this option for the moment, as we don't actually use it, but will in the future.
6745a988416SJim Ingham     // This way users won't see it, but the infrastructure is left in place.
675e2607b50SVirgile Bello     //    { 0, false, "column",     'C', OptionParser::eRequiredArgument, NULL, "<column>",
6765a988416SJim Ingham     //    "Set the breakpoint by source location at this particular column."},
6775a988416SJim Ingham 
678d37221dcSZachary Turner     { LLDB_OPT_SET_2, true, "address", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression,
6795a988416SJim Ingham         "Set the breakpoint by address, at the specified address."},
6805a988416SJim Ingham 
681d37221dcSZachary Turner     { LLDB_OPT_SET_3, true, "name", 'n', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
682551262d7SJim Ingham         "Set the breakpoint by function name.  Can be repeated multiple times to make one breakpoint for multiple names" },
6835a988416SJim Ingham 
684d37221dcSZachary Turner     { LLDB_OPT_SET_4, true, "fullname", 'F', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFullName,
6855a988416SJim Ingham         "Set the breakpoint by fully qualified function names. For C++ this means namespaces and all arguments, and "
6865a988416SJim Ingham         "for Objective C this means a full function prototype with class and selector.   "
6875a988416SJim Ingham         "Can be repeated multiple times to make one breakpoint for multiple names." },
6885a988416SJim Ingham 
689d37221dcSZachary Turner     { LLDB_OPT_SET_5, true, "selector", 'S', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeSelector,
6905a988416SJim Ingham         "Set the breakpoint by ObjC selector name. Can be repeated multiple times to make one breakpoint for multiple Selectors." },
6915a988416SJim Ingham 
692d37221dcSZachary Turner     { LLDB_OPT_SET_6, true, "method", 'M', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeMethod,
6935a988416SJim Ingham         "Set the breakpoint by C++ method names.  Can be repeated multiple times to make one breakpoint for multiple methods." },
6945a988416SJim Ingham 
695d37221dcSZachary Turner     { LLDB_OPT_SET_7, true, "func-regex", 'r', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeRegularExpression,
6965a988416SJim Ingham         "Set the breakpoint by function name, evaluating a regular-expression to find the function name(s)." },
6975a988416SJim Ingham 
698d37221dcSZachary Turner     { LLDB_OPT_SET_8, true, "basename", 'b', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
6995a988416SJim Ingham         "Set the breakpoint by function basename (C++ namespaces and arguments will be ignored). "
7005a988416SJim Ingham         "Can be repeated multiple times to make one breakpoint for multiple symbols." },
7015a988416SJim Ingham 
702d37221dcSZachary Turner     { LLDB_OPT_SET_9, true, "source-pattern-regexp", 'p', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeRegularExpression,
703e96ade8bSJim Ingham         "Set the breakpoint by specifying a regular expression which is matched against the source text in a source file or files "
704e96ade8bSJim Ingham         "specified with the -f option.  The -f option can be specified more than once.  "
705e96ade8bSJim Ingham         "If no source files are specified, uses the current \"default source file\"" },
7065a988416SJim Ingham 
707d37221dcSZachary Turner     { LLDB_OPT_SET_10, true, "language-exception", 'E', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage,
7085a988416SJim Ingham         "Set the breakpoint on exceptions thrown by the specified language (without options, on throw but not catch.)" },
7095a988416SJim Ingham 
710d37221dcSZachary Turner     { LLDB_OPT_SET_10, false, "on-throw", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,
7115a988416SJim Ingham         "Set the breakpoint on exception throW." },
7125a988416SJim Ingham 
713d37221dcSZachary Turner     { LLDB_OPT_SET_10, false, "on-catch", 'h', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,
7145a988416SJim Ingham         "Set the breakpoint on exception catcH." },
7155a988416SJim Ingham 
716d37221dcSZachary Turner     { LLDB_OPT_SKIP_PROLOGUE, false, "skip-prologue", 'K', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,
7175a988416SJim Ingham         "sKip the prologue if the breakpoint is at the beginning of a function.  If not set the target.skip-prologue setting is used." },
7185a988416SJim Ingham 
719*33df7cd3SJim Ingham     { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
720*33df7cd3SJim Ingham         "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
721*33df7cd3SJim Ingham 
722d37221dcSZachary Turner     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
7235a988416SJim Ingham };
7245a988416SJim Ingham 
7255a988416SJim Ingham //-------------------------------------------------------------------------
7265a988416SJim Ingham // CommandObjectBreakpointModify
7275a988416SJim Ingham //-------------------------------------------------------------------------
7285a988416SJim Ingham #pragma mark Modify
7295a988416SJim Ingham 
7305a988416SJim Ingham class CommandObjectBreakpointModify : public CommandObjectParsed
7315a988416SJim Ingham {
7325a988416SJim Ingham public:
7335a988416SJim Ingham 
7345a988416SJim Ingham     CommandObjectBreakpointModify (CommandInterpreter &interpreter) :
7355a988416SJim Ingham         CommandObjectParsed (interpreter,
7365a988416SJim Ingham                              "breakpoint modify",
7375a988416SJim Ingham                              "Modify the options on a breakpoint or set of breakpoints in the executable.  "
7385a988416SJim Ingham                              "If no breakpoint is specified, acts on the last created breakpoint.  "
7395a988416SJim Ingham                              "With the exception of -e, -d and -i, passing an empty argument clears the modification.",
7405a988416SJim Ingham                              NULL),
7415a988416SJim Ingham         m_options (interpreter)
7425a988416SJim Ingham     {
7435a988416SJim Ingham         CommandArgumentEntry arg;
7445a988416SJim Ingham         CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
7455a988416SJim Ingham         // Add the entry for the first argument for this command to the object's arguments vector.
7465a988416SJim Ingham         m_arguments.push_back (arg);
7475a988416SJim Ingham     }
7485a988416SJim Ingham 
7495a988416SJim Ingham 
7505a988416SJim Ingham     virtual
7515a988416SJim Ingham     ~CommandObjectBreakpointModify () {}
7525a988416SJim Ingham 
7535a988416SJim Ingham     virtual Options *
7545a988416SJim Ingham     GetOptions ()
7555a988416SJim Ingham     {
7565a988416SJim Ingham         return &m_options;
7575a988416SJim Ingham     }
7585a988416SJim Ingham 
7595a988416SJim Ingham     class CommandOptions : public Options
7605a988416SJim Ingham     {
7615a988416SJim Ingham     public:
7625a988416SJim Ingham 
7635a988416SJim Ingham         CommandOptions (CommandInterpreter &interpreter) :
7645a988416SJim Ingham             Options (interpreter),
7655a988416SJim Ingham             m_ignore_count (0),
7665a988416SJim Ingham             m_thread_id(LLDB_INVALID_THREAD_ID),
7675a988416SJim Ingham             m_thread_id_passed(false),
7685a988416SJim Ingham             m_thread_index (UINT32_MAX),
7695a988416SJim Ingham             m_thread_index_passed(false),
7705a988416SJim Ingham             m_thread_name(),
7715a988416SJim Ingham             m_queue_name(),
7725a988416SJim Ingham             m_condition (),
773ca36cd16SJim Ingham             m_one_shot (false),
7745a988416SJim Ingham             m_enable_passed (false),
7755a988416SJim Ingham             m_enable_value (false),
7765a988416SJim Ingham             m_name_passed (false),
7775a988416SJim Ingham             m_queue_passed (false),
778ca36cd16SJim Ingham             m_condition_passed (false),
779*33df7cd3SJim Ingham             m_one_shot_passed (false),
780*33df7cd3SJim Ingham             m_use_dummy (false)
7815a988416SJim Ingham         {
7825a988416SJim Ingham         }
7835a988416SJim Ingham 
7845a988416SJim Ingham         virtual
7855a988416SJim Ingham         ~CommandOptions () {}
7865a988416SJim Ingham 
7875a988416SJim Ingham         virtual Error
7885a988416SJim Ingham         SetOptionValue (uint32_t option_idx, const char *option_arg)
7895a988416SJim Ingham         {
7905a988416SJim Ingham             Error error;
7913bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
7925a988416SJim Ingham 
7935a988416SJim Ingham             switch (short_option)
7945a988416SJim Ingham             {
7955a988416SJim Ingham                 case 'c':
7965a988416SJim Ingham                     if (option_arg != NULL)
7975a988416SJim Ingham                         m_condition.assign (option_arg);
7985a988416SJim Ingham                     else
7995a988416SJim Ingham                         m_condition.clear();
8005a988416SJim Ingham                     m_condition_passed = true;
8015a988416SJim Ingham                     break;
8025a988416SJim Ingham                 case 'd':
8035a988416SJim Ingham                     m_enable_passed = true;
8045a988416SJim Ingham                     m_enable_value = false;
8055a988416SJim Ingham                     break;
806*33df7cd3SJim Ingham                 case 'D':
807*33df7cd3SJim Ingham                     m_use_dummy = true;
808*33df7cd3SJim Ingham                     break;
8095a988416SJim Ingham                 case 'e':
8105a988416SJim Ingham                     m_enable_passed = true;
8115a988416SJim Ingham                     m_enable_value = true;
8125a988416SJim Ingham                     break;
8135a988416SJim Ingham                 case 'i':
8145a988416SJim Ingham                 {
8155a988416SJim Ingham                     m_ignore_count = Args::StringToUInt32(option_arg, UINT32_MAX, 0);
8165a988416SJim Ingham                     if (m_ignore_count == UINT32_MAX)
8175a988416SJim Ingham                        error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
8185a988416SJim Ingham                 }
8195a988416SJim Ingham                 break;
820ca36cd16SJim Ingham                 case 'o':
821ca36cd16SJim Ingham                 {
822ca36cd16SJim Ingham                     bool value, success;
823ca36cd16SJim Ingham                     value = Args::StringToBoolean(option_arg, false, &success);
824ca36cd16SJim Ingham                     if (success)
825ca36cd16SJim Ingham                     {
826ca36cd16SJim Ingham                         m_one_shot_passed = true;
827ca36cd16SJim Ingham                         m_one_shot = value;
828ca36cd16SJim Ingham                     }
829ca36cd16SJim Ingham                     else
830ca36cd16SJim Ingham                         error.SetErrorStringWithFormat("invalid boolean value '%s' passed for -o option", option_arg);
831ca36cd16SJim Ingham                 }
832ca36cd16SJim Ingham                 break;
8335a988416SJim Ingham                 case 't' :
8345a988416SJim Ingham                 {
8355a988416SJim Ingham                     if (option_arg[0] == '\0')
8365a988416SJim Ingham                     {
8375a988416SJim Ingham                         m_thread_id = LLDB_INVALID_THREAD_ID;
8385a988416SJim Ingham                         m_thread_id_passed = true;
8395a988416SJim Ingham                     }
8405a988416SJim Ingham                     else
8415a988416SJim Ingham                     {
8425a988416SJim Ingham                         m_thread_id = Args::StringToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
8435a988416SJim Ingham                         if (m_thread_id == LLDB_INVALID_THREAD_ID)
8445a988416SJim Ingham                            error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
8455a988416SJim Ingham                         else
8465a988416SJim Ingham                             m_thread_id_passed = true;
8475a988416SJim Ingham                     }
8485a988416SJim Ingham                 }
8495a988416SJim Ingham                 break;
8505a988416SJim Ingham                 case 'T':
8515a988416SJim Ingham                     if (option_arg != NULL)
8525a988416SJim Ingham                         m_thread_name.assign (option_arg);
8535a988416SJim Ingham                     else
8545a988416SJim Ingham                         m_thread_name.clear();
8555a988416SJim Ingham                     m_name_passed = true;
8565a988416SJim Ingham                     break;
8575a988416SJim Ingham                 case 'q':
8585a988416SJim Ingham                     if (option_arg != NULL)
8595a988416SJim Ingham                         m_queue_name.assign (option_arg);
8605a988416SJim Ingham                     else
8615a988416SJim Ingham                         m_queue_name.clear();
8625a988416SJim Ingham                     m_queue_passed = true;
8635a988416SJim Ingham                     break;
8645a988416SJim Ingham                 case 'x':
8655a988416SJim Ingham                 {
8665a988416SJim Ingham                     if (option_arg[0] == '\n')
8675a988416SJim Ingham                     {
8685a988416SJim Ingham                         m_thread_index = UINT32_MAX;
8695a988416SJim Ingham                         m_thread_index_passed = true;
8705a988416SJim Ingham                     }
8715a988416SJim Ingham                     else
8725a988416SJim Ingham                     {
8735a988416SJim Ingham                         m_thread_index = Args::StringToUInt32 (option_arg, UINT32_MAX, 0);
8745a988416SJim Ingham                         if (m_thread_id == UINT32_MAX)
8755a988416SJim Ingham                            error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
8765a988416SJim Ingham                         else
8775a988416SJim Ingham                             m_thread_index_passed = true;
8785a988416SJim Ingham                     }
8795a988416SJim Ingham                 }
8805a988416SJim Ingham                 break;
8815a988416SJim Ingham                 default:
8825a988416SJim Ingham                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
8835a988416SJim Ingham                     break;
8845a988416SJim Ingham             }
8855a988416SJim Ingham 
8865a988416SJim Ingham             return error;
8875a988416SJim Ingham         }
8885a988416SJim Ingham         void
8895a988416SJim Ingham         OptionParsingStarting ()
8905a988416SJim Ingham         {
8915a988416SJim Ingham             m_ignore_count = 0;
8925a988416SJim Ingham             m_thread_id = LLDB_INVALID_THREAD_ID;
8935a988416SJim Ingham             m_thread_id_passed = false;
8945a988416SJim Ingham             m_thread_index = UINT32_MAX;
8955a988416SJim Ingham             m_thread_index_passed = false;
8965a988416SJim Ingham             m_thread_name.clear();
8975a988416SJim Ingham             m_queue_name.clear();
8985a988416SJim Ingham             m_condition.clear();
899ca36cd16SJim Ingham             m_one_shot = false;
9005a988416SJim Ingham             m_enable_passed = false;
9015a988416SJim Ingham             m_queue_passed = false;
9025a988416SJim Ingham             m_name_passed = false;
9035a988416SJim Ingham             m_condition_passed = false;
904ca36cd16SJim Ingham             m_one_shot_passed = false;
905*33df7cd3SJim Ingham             m_use_dummy = false;
9065a988416SJim Ingham         }
9075a988416SJim Ingham 
9085a988416SJim Ingham         const OptionDefinition*
9095a988416SJim Ingham         GetDefinitions ()
9105a988416SJim Ingham         {
9115a988416SJim Ingham             return g_option_table;
9125a988416SJim Ingham         }
9135a988416SJim Ingham 
9145a988416SJim Ingham 
9155a988416SJim Ingham         // Options table: Required for subclasses of Options.
9165a988416SJim Ingham 
9175a988416SJim Ingham         static OptionDefinition g_option_table[];
9185a988416SJim Ingham 
9195a988416SJim Ingham         // Instance variables to hold the values for command options.
9205a988416SJim Ingham 
9215a988416SJim Ingham         uint32_t m_ignore_count;
9225a988416SJim Ingham         lldb::tid_t m_thread_id;
9235a988416SJim Ingham         bool m_thread_id_passed;
9245a988416SJim Ingham         uint32_t m_thread_index;
9255a988416SJim Ingham         bool m_thread_index_passed;
9265a988416SJim Ingham         std::string m_thread_name;
9275a988416SJim Ingham         std::string m_queue_name;
9285a988416SJim Ingham         std::string m_condition;
929ca36cd16SJim Ingham         bool m_one_shot;
9305a988416SJim Ingham         bool m_enable_passed;
9315a988416SJim Ingham         bool m_enable_value;
9325a988416SJim Ingham         bool m_name_passed;
9335a988416SJim Ingham         bool m_queue_passed;
9345a988416SJim Ingham         bool m_condition_passed;
935ca36cd16SJim Ingham         bool m_one_shot_passed;
936*33df7cd3SJim Ingham         bool m_use_dummy;
9375a988416SJim Ingham 
9385a988416SJim Ingham     };
9395a988416SJim Ingham 
9405a988416SJim Ingham protected:
9415a988416SJim Ingham     virtual bool
9425a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
9435a988416SJim Ingham     {
944*33df7cd3SJim Ingham         Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
9455a988416SJim Ingham         if (target == NULL)
9465a988416SJim Ingham         {
9475a988416SJim Ingham             result.AppendError ("Invalid target.  No existing target or breakpoints.");
9485a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
9495a988416SJim Ingham             return false;
9505a988416SJim Ingham         }
9515a988416SJim Ingham 
9525a988416SJim Ingham         Mutex::Locker locker;
9535a988416SJim Ingham         target->GetBreakpointList().GetListMutex(locker);
9545a988416SJim Ingham 
9555a988416SJim Ingham         BreakpointIDList valid_bp_ids;
9565a988416SJim Ingham 
9575a988416SJim Ingham         CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
9585a988416SJim Ingham 
9595a988416SJim Ingham         if (result.Succeeded())
9605a988416SJim Ingham         {
9615a988416SJim Ingham             const size_t count = valid_bp_ids.GetSize();
9625a988416SJim Ingham             for (size_t i = 0; i < count; ++i)
9635a988416SJim Ingham             {
9645a988416SJim Ingham                 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
9655a988416SJim Ingham 
9665a988416SJim Ingham                 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
9675a988416SJim Ingham                 {
9685a988416SJim Ingham                     Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
9695a988416SJim Ingham                     if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
9705a988416SJim Ingham                     {
9715a988416SJim Ingham                         BreakpointLocation *location = bp->FindLocationByID (cur_bp_id.GetLocationID()).get();
9725a988416SJim Ingham                         if (location)
9735a988416SJim Ingham                         {
9745a988416SJim Ingham                             if (m_options.m_thread_id_passed)
9755a988416SJim Ingham                                 location->SetThreadID (m_options.m_thread_id);
9765a988416SJim Ingham 
9775a988416SJim Ingham                             if (m_options.m_thread_index_passed)
9785a988416SJim Ingham                                 location->SetThreadIndex(m_options.m_thread_index);
9795a988416SJim Ingham 
9805a988416SJim Ingham                             if (m_options.m_name_passed)
9815a988416SJim Ingham                                 location->SetThreadName(m_options.m_thread_name.c_str());
9825a988416SJim Ingham 
9835a988416SJim Ingham                             if (m_options.m_queue_passed)
9845a988416SJim Ingham                                 location->SetQueueName(m_options.m_queue_name.c_str());
9855a988416SJim Ingham 
9865a988416SJim Ingham                             if (m_options.m_ignore_count != 0)
9875a988416SJim Ingham                                 location->SetIgnoreCount(m_options.m_ignore_count);
9885a988416SJim Ingham 
9895a988416SJim Ingham                             if (m_options.m_enable_passed)
9905a988416SJim Ingham                                 location->SetEnabled (m_options.m_enable_value);
9915a988416SJim Ingham 
9925a988416SJim Ingham                             if (m_options.m_condition_passed)
9935a988416SJim Ingham                                 location->SetCondition (m_options.m_condition.c_str());
9945a988416SJim Ingham                         }
9955a988416SJim Ingham                     }
9965a988416SJim Ingham                     else
9975a988416SJim Ingham                     {
9985a988416SJim Ingham                         if (m_options.m_thread_id_passed)
9995a988416SJim Ingham                             bp->SetThreadID (m_options.m_thread_id);
10005a988416SJim Ingham 
10015a988416SJim Ingham                         if (m_options.m_thread_index_passed)
10025a988416SJim Ingham                             bp->SetThreadIndex(m_options.m_thread_index);
10035a988416SJim Ingham 
10045a988416SJim Ingham                         if (m_options.m_name_passed)
10055a988416SJim Ingham                             bp->SetThreadName(m_options.m_thread_name.c_str());
10065a988416SJim Ingham 
10075a988416SJim Ingham                         if (m_options.m_queue_passed)
10085a988416SJim Ingham                             bp->SetQueueName(m_options.m_queue_name.c_str());
10095a988416SJim Ingham 
10105a988416SJim Ingham                         if (m_options.m_ignore_count != 0)
10115a988416SJim Ingham                             bp->SetIgnoreCount(m_options.m_ignore_count);
10125a988416SJim Ingham 
10135a988416SJim Ingham                         if (m_options.m_enable_passed)
10145a988416SJim Ingham                             bp->SetEnabled (m_options.m_enable_value);
10155a988416SJim Ingham 
10165a988416SJim Ingham                         if (m_options.m_condition_passed)
10175a988416SJim Ingham                             bp->SetCondition (m_options.m_condition.c_str());
10185a988416SJim Ingham                     }
10195a988416SJim Ingham                 }
10205a988416SJim Ingham             }
10215a988416SJim Ingham         }
10225a988416SJim Ingham 
10235a988416SJim Ingham         return result.Succeeded();
10245a988416SJim Ingham     }
10255a988416SJim Ingham 
10265a988416SJim Ingham private:
10275a988416SJim Ingham     CommandOptions m_options;
10285a988416SJim Ingham };
10295a988416SJim Ingham 
10305a988416SJim Ingham #pragma mark Modify::CommandOptions
10315a988416SJim Ingham OptionDefinition
10325a988416SJim Ingham CommandObjectBreakpointModify::CommandOptions::g_option_table[] =
10335a988416SJim Ingham {
1034d37221dcSZachary 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." },
1035d37221dcSZachary 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." },
1036d37221dcSZachary 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."},
1037d37221dcSZachary 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."},
1038d37221dcSZachary 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."},
1039d37221dcSZachary 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."},
1040d37221dcSZachary 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."},
1041d37221dcSZachary Turner { LLDB_OPT_SET_1,   false, "enable",       'e', OptionParser::eNoArgument,       NULL, NULL, 0, eArgTypeNone, "Enable the breakpoint."},
1042d37221dcSZachary Turner { LLDB_OPT_SET_2,   false, "disable",      'd', OptionParser::eNoArgument,       NULL, NULL, 0, eArgTypeNone, "Disable the breakpoint."},
1043*33df7cd3SJim 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."},
1044*33df7cd3SJim Ingham 
1045d37221dcSZachary Turner { 0,                false, NULL,            0 , 0,                 NULL, NULL, 0, eArgTypeNone, NULL }
10465a988416SJim Ingham };
10475a988416SJim Ingham 
10485a988416SJim Ingham //-------------------------------------------------------------------------
10495a988416SJim Ingham // CommandObjectBreakpointEnable
10505a988416SJim Ingham //-------------------------------------------------------------------------
10515a988416SJim Ingham #pragma mark Enable
10525a988416SJim Ingham 
10535a988416SJim Ingham class CommandObjectBreakpointEnable : public CommandObjectParsed
10545a988416SJim Ingham {
10555a988416SJim Ingham public:
10565a988416SJim Ingham     CommandObjectBreakpointEnable (CommandInterpreter &interpreter) :
10575a988416SJim Ingham         CommandObjectParsed (interpreter,
10585a988416SJim Ingham                              "enable",
10595a988416SJim Ingham                              "Enable the specified disabled breakpoint(s). If no breakpoints are specified, enable all of them.",
10605a988416SJim Ingham                              NULL)
10615a988416SJim Ingham     {
10625a988416SJim Ingham         CommandArgumentEntry arg;
10635a988416SJim Ingham         CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
10645a988416SJim Ingham         // Add the entry for the first argument for this command to the object's arguments vector.
10655a988416SJim Ingham         m_arguments.push_back (arg);
10665a988416SJim Ingham     }
10675a988416SJim Ingham 
10685a988416SJim Ingham 
10695a988416SJim Ingham     virtual
10705a988416SJim Ingham     ~CommandObjectBreakpointEnable () {}
10715a988416SJim Ingham 
10725a988416SJim Ingham protected:
10735a988416SJim Ingham     virtual bool
10745a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
10755a988416SJim Ingham     {
1076893c932aSJim Ingham         Target *target = GetSelectedOrDummyTarget();
10775a988416SJim Ingham         if (target == NULL)
10785a988416SJim Ingham         {
10795a988416SJim Ingham             result.AppendError ("Invalid target.  No existing target or breakpoints.");
10805a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
10815a988416SJim Ingham             return false;
10825a988416SJim Ingham         }
10835a988416SJim Ingham 
10845a988416SJim Ingham         Mutex::Locker locker;
10855a988416SJim Ingham         target->GetBreakpointList().GetListMutex(locker);
10865a988416SJim Ingham 
10875a988416SJim Ingham         const BreakpointList &breakpoints = target->GetBreakpointList();
10885a988416SJim Ingham 
10895a988416SJim Ingham         size_t num_breakpoints = breakpoints.GetSize();
10905a988416SJim Ingham 
10915a988416SJim Ingham         if (num_breakpoints == 0)
10925a988416SJim Ingham         {
10935a988416SJim Ingham             result.AppendError ("No breakpoints exist to be enabled.");
10945a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
10955a988416SJim Ingham             return false;
10965a988416SJim Ingham         }
10975a988416SJim Ingham 
10985a988416SJim Ingham         if (command.GetArgumentCount() == 0)
10995a988416SJim Ingham         {
11005a988416SJim Ingham             // No breakpoint selected; enable all currently set breakpoints.
11015a988416SJim Ingham             target->EnableAllBreakpoints ();
11026fea17e8SGreg Clayton             result.AppendMessageWithFormat ("All breakpoints enabled. (%" PRIu64 " breakpoints)\n", (uint64_t)num_breakpoints);
11035a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
11045a988416SJim Ingham         }
11055a988416SJim Ingham         else
11065a988416SJim Ingham         {
11075a988416SJim Ingham             // Particular breakpoint selected; enable that breakpoint.
11085a988416SJim Ingham             BreakpointIDList valid_bp_ids;
11095a988416SJim Ingham             CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
11105a988416SJim Ingham 
11115a988416SJim Ingham             if (result.Succeeded())
11125a988416SJim Ingham             {
11135a988416SJim Ingham                 int enable_count = 0;
11145a988416SJim Ingham                 int loc_count = 0;
11155a988416SJim Ingham                 const size_t count = valid_bp_ids.GetSize();
11165a988416SJim Ingham                 for (size_t i = 0; i < count; ++i)
11175a988416SJim Ingham                 {
11185a988416SJim Ingham                     BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
11195a988416SJim Ingham 
11205a988416SJim Ingham                     if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
11215a988416SJim Ingham                     {
11225a988416SJim Ingham                         Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
11235a988416SJim Ingham                         if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
11245a988416SJim Ingham                         {
11255a988416SJim Ingham                             BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
11265a988416SJim Ingham                             if (location)
11275a988416SJim Ingham                             {
11285a988416SJim Ingham                                 location->SetEnabled (true);
11295a988416SJim Ingham                                 ++loc_count;
11305a988416SJim Ingham                             }
11315a988416SJim Ingham                         }
11325a988416SJim Ingham                         else
11335a988416SJim Ingham                         {
11345a988416SJim Ingham                             breakpoint->SetEnabled (true);
11355a988416SJim Ingham                             ++enable_count;
11365a988416SJim Ingham                         }
11375a988416SJim Ingham                     }
11385a988416SJim Ingham                 }
11395a988416SJim Ingham                 result.AppendMessageWithFormat ("%d breakpoints enabled.\n", enable_count + loc_count);
11405a988416SJim Ingham                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
11415a988416SJim Ingham             }
11425a988416SJim Ingham         }
11435a988416SJim Ingham 
11445a988416SJim Ingham         return result.Succeeded();
11455a988416SJim Ingham     }
11465a988416SJim Ingham };
11475a988416SJim Ingham 
11485a988416SJim Ingham //-------------------------------------------------------------------------
11495a988416SJim Ingham // CommandObjectBreakpointDisable
11505a988416SJim Ingham //-------------------------------------------------------------------------
11515a988416SJim Ingham #pragma mark Disable
11525a988416SJim Ingham 
11535a988416SJim Ingham class CommandObjectBreakpointDisable : public CommandObjectParsed
11545a988416SJim Ingham {
11555a988416SJim Ingham public:
11565a988416SJim Ingham     CommandObjectBreakpointDisable (CommandInterpreter &interpreter) :
11575a988416SJim Ingham         CommandObjectParsed (interpreter,
11585a988416SJim Ingham                              "breakpoint disable",
11595a988416SJim Ingham                              "Disable the specified breakpoint(s) without removing it/them.  If no breakpoints are specified, disable them all.",
11605a988416SJim Ingham                              NULL)
11615a988416SJim Ingham     {
1162b0fac509SJim Ingham         SetHelpLong(
1163b0fac509SJim Ingham "Disable the specified breakpoint(s) without removing it/them.  \n\
1164b0fac509SJim Ingham If no breakpoints are specified, disable them all.\n\
1165b0fac509SJim Ingham \n\
1166b0fac509SJim Ingham Note: disabling a breakpoint will cause none of its locations to be hit\n\
1167b0fac509SJim Ingham regardless of whether they are enabled or disabled.  So the sequence: \n\
1168b0fac509SJim Ingham \n\
1169b0fac509SJim Ingham     (lldb) break disable 1\n\
1170b0fac509SJim Ingham     (lldb) break enable 1.1\n\
1171b0fac509SJim Ingham \n\
1172b0fac509SJim Ingham will NOT cause location 1.1 to get hit.  To achieve that, do:\n\
1173b0fac509SJim Ingham \n\
1174b0fac509SJim Ingham     (lldb) break disable 1.*\n\
1175b0fac509SJim Ingham     (lldb) break enable 1.1\n\
1176b0fac509SJim Ingham \n\
1177b0fac509SJim Ingham The first command disables all the locations of breakpoint 1, \n\
1178b0fac509SJim Ingham the second re-enables the first location."
1179b0fac509SJim Ingham                     );
1180b0fac509SJim Ingham 
11815a988416SJim Ingham         CommandArgumentEntry arg;
11825a988416SJim Ingham         CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
11835a988416SJim Ingham         // Add the entry for the first argument for this command to the object's arguments vector.
11845a988416SJim Ingham         m_arguments.push_back (arg);
1185b0fac509SJim Ingham 
11865a988416SJim Ingham     }
11875a988416SJim Ingham 
11885a988416SJim Ingham 
11895a988416SJim Ingham     virtual
11905a988416SJim Ingham     ~CommandObjectBreakpointDisable () {}
11915a988416SJim Ingham 
11925a988416SJim Ingham protected:
11935a988416SJim Ingham     virtual bool
11945a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
11955a988416SJim Ingham     {
1196893c932aSJim Ingham         Target *target = GetSelectedOrDummyTarget();
11975a988416SJim Ingham         if (target == NULL)
11985a988416SJim Ingham         {
11995a988416SJim Ingham             result.AppendError ("Invalid target.  No existing target or breakpoints.");
12005a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
12015a988416SJim Ingham             return false;
12025a988416SJim Ingham         }
12035a988416SJim Ingham 
12045a988416SJim Ingham         Mutex::Locker locker;
12055a988416SJim Ingham         target->GetBreakpointList().GetListMutex(locker);
12065a988416SJim Ingham 
12075a988416SJim Ingham         const BreakpointList &breakpoints = target->GetBreakpointList();
12085a988416SJim Ingham         size_t num_breakpoints = breakpoints.GetSize();
12095a988416SJim Ingham 
12105a988416SJim Ingham         if (num_breakpoints == 0)
12115a988416SJim Ingham         {
12125a988416SJim Ingham             result.AppendError ("No breakpoints exist to be disabled.");
12135a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
12145a988416SJim Ingham             return false;
12155a988416SJim Ingham         }
12165a988416SJim Ingham 
12175a988416SJim Ingham         if (command.GetArgumentCount() == 0)
12185a988416SJim Ingham         {
12195a988416SJim Ingham             // No breakpoint selected; disable all currently set breakpoints.
12205a988416SJim Ingham             target->DisableAllBreakpoints ();
12216fea17e8SGreg Clayton             result.AppendMessageWithFormat ("All breakpoints disabled. (%" PRIu64 " breakpoints)\n", (uint64_t)num_breakpoints);
12225a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
12235a988416SJim Ingham         }
12245a988416SJim Ingham         else
12255a988416SJim Ingham         {
12265a988416SJim Ingham             // Particular breakpoint selected; disable that breakpoint.
12275a988416SJim Ingham             BreakpointIDList valid_bp_ids;
12285a988416SJim Ingham 
12295a988416SJim Ingham             CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
12305a988416SJim Ingham 
12315a988416SJim Ingham             if (result.Succeeded())
12325a988416SJim Ingham             {
12335a988416SJim Ingham                 int disable_count = 0;
12345a988416SJim Ingham                 int loc_count = 0;
12355a988416SJim Ingham                 const size_t count = valid_bp_ids.GetSize();
12365a988416SJim Ingham                 for (size_t i = 0; i < count; ++i)
12375a988416SJim Ingham                 {
12385a988416SJim Ingham                     BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
12395a988416SJim Ingham 
12405a988416SJim Ingham                     if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
12415a988416SJim Ingham                     {
12425a988416SJim Ingham                         Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
12435a988416SJim Ingham                         if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
12445a988416SJim Ingham                         {
12455a988416SJim Ingham                             BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
12465a988416SJim Ingham                             if (location)
12475a988416SJim Ingham                             {
12485a988416SJim Ingham                                 location->SetEnabled (false);
12495a988416SJim Ingham                                 ++loc_count;
12505a988416SJim Ingham                             }
12515a988416SJim Ingham                         }
12525a988416SJim Ingham                         else
12535a988416SJim Ingham                         {
12545a988416SJim Ingham                             breakpoint->SetEnabled (false);
12555a988416SJim Ingham                             ++disable_count;
12565a988416SJim Ingham                         }
12575a988416SJim Ingham                     }
12585a988416SJim Ingham                 }
12595a988416SJim Ingham                 result.AppendMessageWithFormat ("%d breakpoints disabled.\n", disable_count + loc_count);
12605a988416SJim Ingham                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
12615a988416SJim Ingham             }
12625a988416SJim Ingham         }
12635a988416SJim Ingham 
12645a988416SJim Ingham         return result.Succeeded();
12655a988416SJim Ingham     }
12665a988416SJim Ingham 
12675a988416SJim Ingham };
12685a988416SJim Ingham 
12695a988416SJim Ingham //-------------------------------------------------------------------------
12705a988416SJim Ingham // CommandObjectBreakpointList
12715a988416SJim Ingham //-------------------------------------------------------------------------
12725a988416SJim Ingham #pragma mark List
12735a988416SJim Ingham 
12745a988416SJim Ingham class CommandObjectBreakpointList : public CommandObjectParsed
12755a988416SJim Ingham {
12765a988416SJim Ingham public:
12775a988416SJim Ingham     CommandObjectBreakpointList (CommandInterpreter &interpreter) :
12785a988416SJim Ingham         CommandObjectParsed (interpreter,
12795a988416SJim Ingham                              "breakpoint list",
12805a988416SJim Ingham                              "List some or all breakpoints at configurable levels of detail.",
12815a988416SJim Ingham                              NULL),
12825a988416SJim Ingham         m_options (interpreter)
12835a988416SJim Ingham     {
12845a988416SJim Ingham         CommandArgumentEntry arg;
12855a988416SJim Ingham         CommandArgumentData bp_id_arg;
12865a988416SJim Ingham 
12875a988416SJim Ingham         // Define the first (and only) variant of this arg.
12885a988416SJim Ingham         bp_id_arg.arg_type = eArgTypeBreakpointID;
12895a988416SJim Ingham         bp_id_arg.arg_repetition = eArgRepeatOptional;
12905a988416SJim Ingham 
12915a988416SJim Ingham         // There is only one variant this argument could be; put it into the argument entry.
12925a988416SJim Ingham         arg.push_back (bp_id_arg);
12935a988416SJim Ingham 
12945a988416SJim Ingham         // Push the data for the first argument into the m_arguments vector.
12955a988416SJim Ingham         m_arguments.push_back (arg);
12965a988416SJim Ingham     }
12975a988416SJim Ingham 
12985a988416SJim Ingham 
12995a988416SJim Ingham     virtual
13005a988416SJim Ingham     ~CommandObjectBreakpointList () {}
13015a988416SJim Ingham 
13025a988416SJim Ingham     virtual Options *
13035a988416SJim Ingham     GetOptions ()
13045a988416SJim Ingham     {
13055a988416SJim Ingham         return &m_options;
13065a988416SJim Ingham     }
13075a988416SJim Ingham 
13085a988416SJim Ingham     class CommandOptions : public Options
13095a988416SJim Ingham     {
13105a988416SJim Ingham     public:
13115a988416SJim Ingham 
13125a988416SJim Ingham         CommandOptions (CommandInterpreter &interpreter) :
13135a988416SJim Ingham             Options (interpreter),
1314*33df7cd3SJim Ingham             m_level (lldb::eDescriptionLevelBrief),
1315*33df7cd3SJim Ingham             m_use_dummy(false)
13165a988416SJim Ingham         {
13175a988416SJim Ingham         }
13185a988416SJim Ingham 
13195a988416SJim Ingham         virtual
13205a988416SJim Ingham         ~CommandOptions () {}
13215a988416SJim Ingham 
13225a988416SJim Ingham         virtual Error
13235a988416SJim Ingham         SetOptionValue (uint32_t option_idx, const char *option_arg)
13245a988416SJim Ingham         {
13255a988416SJim Ingham             Error error;
13263bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
13275a988416SJim Ingham 
13285a988416SJim Ingham             switch (short_option)
13295a988416SJim Ingham             {
13305a988416SJim Ingham                 case 'b':
13315a988416SJim Ingham                     m_level = lldb::eDescriptionLevelBrief;
13325a988416SJim Ingham                     break;
1333*33df7cd3SJim Ingham                 case 'D':
1334*33df7cd3SJim Ingham                     m_use_dummy = true;
1335*33df7cd3SJim Ingham                     break;
13365a988416SJim Ingham                 case 'f':
13375a988416SJim Ingham                     m_level = lldb::eDescriptionLevelFull;
13385a988416SJim Ingham                     break;
13395a988416SJim Ingham                 case 'v':
13405a988416SJim Ingham                     m_level = lldb::eDescriptionLevelVerbose;
13415a988416SJim Ingham                     break;
13425a988416SJim Ingham                 case 'i':
13435a988416SJim Ingham                     m_internal = true;
13445a988416SJim Ingham                     break;
13455a988416SJim Ingham                 default:
13465a988416SJim Ingham                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
13475a988416SJim Ingham                     break;
13485a988416SJim Ingham             }
13495a988416SJim Ingham 
13505a988416SJim Ingham             return error;
13515a988416SJim Ingham         }
13525a988416SJim Ingham 
13535a988416SJim Ingham         void
13545a988416SJim Ingham         OptionParsingStarting ()
13555a988416SJim Ingham         {
13565a988416SJim Ingham             m_level = lldb::eDescriptionLevelFull;
13575a988416SJim Ingham             m_internal = false;
1358*33df7cd3SJim Ingham             m_use_dummy = false;
13595a988416SJim Ingham         }
13605a988416SJim Ingham 
13615a988416SJim Ingham         const OptionDefinition *
13625a988416SJim Ingham         GetDefinitions ()
13635a988416SJim Ingham         {
13645a988416SJim Ingham             return g_option_table;
13655a988416SJim Ingham         }
13665a988416SJim Ingham 
13675a988416SJim Ingham         // Options table: Required for subclasses of Options.
13685a988416SJim Ingham 
13695a988416SJim Ingham         static OptionDefinition g_option_table[];
13705a988416SJim Ingham 
13715a988416SJim Ingham         // Instance variables to hold the values for command options.
13725a988416SJim Ingham 
13735a988416SJim Ingham         lldb::DescriptionLevel m_level;
13745a988416SJim Ingham 
13755a988416SJim Ingham         bool m_internal;
1376*33df7cd3SJim Ingham         bool m_use_dummy;
13775a988416SJim Ingham     };
13785a988416SJim Ingham 
13795a988416SJim Ingham protected:
13805a988416SJim Ingham     virtual bool
13815a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
13825a988416SJim Ingham     {
1383*33df7cd3SJim Ingham         Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
1384*33df7cd3SJim Ingham 
13855a988416SJim Ingham         if (target == NULL)
13865a988416SJim Ingham         {
13875a988416SJim Ingham             result.AppendError ("Invalid target. No current target or breakpoints.");
13885a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
13895a988416SJim Ingham             return true;
13905a988416SJim Ingham         }
13915a988416SJim Ingham 
13925a988416SJim Ingham         const BreakpointList &breakpoints = target->GetBreakpointList(m_options.m_internal);
13935a988416SJim Ingham         Mutex::Locker locker;
13945a988416SJim Ingham         target->GetBreakpointList(m_options.m_internal).GetListMutex(locker);
13955a988416SJim Ingham 
13965a988416SJim Ingham         size_t num_breakpoints = breakpoints.GetSize();
13975a988416SJim Ingham 
13985a988416SJim Ingham         if (num_breakpoints == 0)
13995a988416SJim Ingham         {
14005a988416SJim Ingham             result.AppendMessage ("No breakpoints currently set.");
14015a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
14025a988416SJim Ingham             return true;
14035a988416SJim Ingham         }
14045a988416SJim Ingham 
14055a988416SJim Ingham         Stream &output_stream = result.GetOutputStream();
14065a988416SJim Ingham 
14075a988416SJim Ingham         if (command.GetArgumentCount() == 0)
14085a988416SJim Ingham         {
14095a988416SJim Ingham             // No breakpoint selected; show info about all currently set breakpoints.
14105a988416SJim Ingham             result.AppendMessage ("Current breakpoints:");
14115a988416SJim Ingham             for (size_t i = 0; i < num_breakpoints; ++i)
14125a988416SJim Ingham             {
14135a988416SJim Ingham                 Breakpoint *breakpoint = breakpoints.GetBreakpointAtIndex (i).get();
14145a988416SJim Ingham                 AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
14155a988416SJim Ingham             }
14165a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
14175a988416SJim Ingham         }
14185a988416SJim Ingham         else
14195a988416SJim Ingham         {
14205a988416SJim Ingham             // Particular breakpoints selected; show info about that breakpoint.
14215a988416SJim Ingham             BreakpointIDList valid_bp_ids;
14225a988416SJim Ingham             CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
14235a988416SJim Ingham 
14245a988416SJim Ingham             if (result.Succeeded())
14255a988416SJim Ingham             {
14265a988416SJim Ingham                 for (size_t i = 0; i < valid_bp_ids.GetSize(); ++i)
14275a988416SJim Ingham                 {
14285a988416SJim Ingham                     BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
14295a988416SJim Ingham                     Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
14305a988416SJim Ingham                     AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
14315a988416SJim Ingham                 }
14325a988416SJim Ingham                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
14335a988416SJim Ingham             }
14345a988416SJim Ingham             else
14355a988416SJim Ingham             {
14365a988416SJim Ingham                 result.AppendError ("Invalid breakpoint id.");
14375a988416SJim Ingham                 result.SetStatus (eReturnStatusFailed);
14385a988416SJim Ingham             }
14395a988416SJim Ingham         }
14405a988416SJim Ingham 
14415a988416SJim Ingham         return result.Succeeded();
14425a988416SJim Ingham     }
14435a988416SJim Ingham 
14445a988416SJim Ingham private:
14455a988416SJim Ingham     CommandOptions m_options;
14465a988416SJim Ingham };
14475a988416SJim Ingham 
14485a988416SJim Ingham #pragma mark List::CommandOptions
14495a988416SJim Ingham OptionDefinition
14505a988416SJim Ingham CommandObjectBreakpointList::CommandOptions::g_option_table[] =
14515a988416SJim Ingham {
1452d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "internal", 'i', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
14535a988416SJim Ingham         "Show debugger internal breakpoints" },
14545a988416SJim Ingham 
1455d37221dcSZachary Turner     { LLDB_OPT_SET_1, false, "brief",    'b', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
14565a988416SJim Ingham         "Give a brief description of the breakpoint (no location info)."},
14575a988416SJim Ingham 
14585a988416SJim Ingham     // FIXME: We need to add an "internal" command, and then add this sort of thing to it.
14595a988416SJim Ingham     // But I need to see it for now, and don't want to wait.
1460d37221dcSZachary Turner     { LLDB_OPT_SET_2, false, "full",    'f', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
14615a988416SJim Ingham         "Give a full description of the breakpoint and its locations."},
14625a988416SJim Ingham 
1463d37221dcSZachary Turner     { LLDB_OPT_SET_3, false, "verbose", 'v', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
14645a988416SJim Ingham         "Explain everything we know about the breakpoint (for debugging debugger bugs)." },
14655a988416SJim Ingham 
1466*33df7cd3SJim Ingham     { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
1467*33df7cd3SJim Ingham         "List Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
1468*33df7cd3SJim Ingham 
1469d37221dcSZachary Turner     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
14705a988416SJim Ingham };
14715a988416SJim Ingham 
14725a988416SJim Ingham //-------------------------------------------------------------------------
14735a988416SJim Ingham // CommandObjectBreakpointClear
14745a988416SJim Ingham //-------------------------------------------------------------------------
14755a988416SJim Ingham #pragma mark Clear
14765a988416SJim Ingham 
14775a988416SJim Ingham class CommandObjectBreakpointClear : public CommandObjectParsed
14785a988416SJim Ingham {
14795a988416SJim Ingham public:
14805a988416SJim Ingham 
14815a988416SJim Ingham     typedef enum BreakpointClearType
14825a988416SJim Ingham     {
14835a988416SJim Ingham         eClearTypeInvalid,
14845a988416SJim Ingham         eClearTypeFileAndLine
14855a988416SJim Ingham     } BreakpointClearType;
14865a988416SJim Ingham 
14875a988416SJim Ingham     CommandObjectBreakpointClear (CommandInterpreter &interpreter) :
14885a988416SJim Ingham         CommandObjectParsed (interpreter,
14895a988416SJim Ingham                              "breakpoint clear",
14905a988416SJim Ingham                              "Clears a breakpoint or set of breakpoints in the executable.",
14915a988416SJim Ingham                              "breakpoint clear <cmd-options>"),
14925a988416SJim Ingham         m_options (interpreter)
14935a988416SJim Ingham     {
14945a988416SJim Ingham     }
14955a988416SJim Ingham 
14965a988416SJim Ingham     virtual
14975a988416SJim Ingham     ~CommandObjectBreakpointClear () {}
14985a988416SJim Ingham 
14995a988416SJim Ingham     virtual Options *
15005a988416SJim Ingham     GetOptions ()
15015a988416SJim Ingham     {
15025a988416SJim Ingham         return &m_options;
15035a988416SJim Ingham     }
15045a988416SJim Ingham 
15055a988416SJim Ingham     class CommandOptions : public Options
15065a988416SJim Ingham     {
15075a988416SJim Ingham     public:
15085a988416SJim Ingham 
15095a988416SJim Ingham         CommandOptions (CommandInterpreter &interpreter) :
15105a988416SJim Ingham             Options (interpreter),
15115a988416SJim Ingham             m_filename (),
15125a988416SJim Ingham             m_line_num (0)
15135a988416SJim Ingham         {
15145a988416SJim Ingham         }
15155a988416SJim Ingham 
15165a988416SJim Ingham         virtual
15175a988416SJim Ingham         ~CommandOptions () {}
15185a988416SJim Ingham 
15195a988416SJim Ingham         virtual Error
15205a988416SJim Ingham         SetOptionValue (uint32_t option_idx, const char *option_arg)
15215a988416SJim Ingham         {
15225a988416SJim Ingham             Error error;
15233bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
15245a988416SJim Ingham 
15255a988416SJim Ingham             switch (short_option)
15265a988416SJim Ingham             {
15275a988416SJim Ingham                 case 'f':
15285a988416SJim Ingham                     m_filename.assign (option_arg);
15295a988416SJim Ingham                     break;
15305a988416SJim Ingham 
15315a988416SJim Ingham                 case 'l':
15325a988416SJim Ingham                     m_line_num = Args::StringToUInt32 (option_arg, 0);
15335a988416SJim Ingham                     break;
15345a988416SJim Ingham 
15355a988416SJim Ingham                 default:
15365a988416SJim Ingham                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
15375a988416SJim Ingham                     break;
15385a988416SJim Ingham             }
15395a988416SJim Ingham 
15405a988416SJim Ingham             return error;
15415a988416SJim Ingham         }
15425a988416SJim Ingham 
15435a988416SJim Ingham         void
15445a988416SJim Ingham         OptionParsingStarting ()
15455a988416SJim Ingham         {
15465a988416SJim Ingham             m_filename.clear();
15475a988416SJim Ingham             m_line_num = 0;
15485a988416SJim Ingham         }
15495a988416SJim Ingham 
15505a988416SJim Ingham         const OptionDefinition*
15515a988416SJim Ingham         GetDefinitions ()
15525a988416SJim Ingham         {
15535a988416SJim Ingham             return g_option_table;
15545a988416SJim Ingham         }
15555a988416SJim Ingham 
15565a988416SJim Ingham         // Options table: Required for subclasses of Options.
15575a988416SJim Ingham 
15585a988416SJim Ingham         static OptionDefinition g_option_table[];
15595a988416SJim Ingham 
15605a988416SJim Ingham         // Instance variables to hold the values for command options.
15615a988416SJim Ingham 
15625a988416SJim Ingham         std::string m_filename;
15635a988416SJim Ingham         uint32_t m_line_num;
15645a988416SJim Ingham 
15655a988416SJim Ingham     };
15665a988416SJim Ingham 
15675a988416SJim Ingham protected:
15685a988416SJim Ingham     virtual bool
15695a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
15705a988416SJim Ingham     {
1571893c932aSJim Ingham         Target *target = GetSelectedOrDummyTarget();
15725a988416SJim Ingham         if (target == NULL)
15735a988416SJim Ingham         {
15745a988416SJim Ingham             result.AppendError ("Invalid target. No existing target or breakpoints.");
15755a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
15765a988416SJim Ingham             return false;
15775a988416SJim Ingham         }
15785a988416SJim Ingham 
15795a988416SJim Ingham         // The following are the various types of breakpoints that could be cleared:
15805a988416SJim Ingham         //   1). -f -l (clearing breakpoint by source location)
15815a988416SJim Ingham 
15825a988416SJim Ingham         BreakpointClearType break_type = eClearTypeInvalid;
15835a988416SJim Ingham 
15845a988416SJim Ingham         if (m_options.m_line_num != 0)
15855a988416SJim Ingham             break_type = eClearTypeFileAndLine;
15865a988416SJim Ingham 
15875a988416SJim Ingham         Mutex::Locker locker;
15885a988416SJim Ingham         target->GetBreakpointList().GetListMutex(locker);
15895a988416SJim Ingham 
15905a988416SJim Ingham         BreakpointList &breakpoints = target->GetBreakpointList();
15915a988416SJim Ingham         size_t num_breakpoints = breakpoints.GetSize();
15925a988416SJim Ingham 
15935a988416SJim Ingham         // Early return if there's no breakpoint at all.
15945a988416SJim Ingham         if (num_breakpoints == 0)
15955a988416SJim Ingham         {
15965a988416SJim Ingham             result.AppendError ("Breakpoint clear: No breakpoint cleared.");
15975a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
15985a988416SJim Ingham             return result.Succeeded();
15995a988416SJim Ingham         }
16005a988416SJim Ingham 
16015a988416SJim Ingham         // Find matching breakpoints and delete them.
16025a988416SJim Ingham 
16035a988416SJim Ingham         // First create a copy of all the IDs.
16045a988416SJim Ingham         std::vector<break_id_t> BreakIDs;
16055a988416SJim Ingham         for (size_t i = 0; i < num_breakpoints; ++i)
16065a988416SJim Ingham             BreakIDs.push_back(breakpoints.GetBreakpointAtIndex(i).get()->GetID());
16075a988416SJim Ingham 
16085a988416SJim Ingham         int num_cleared = 0;
16095a988416SJim Ingham         StreamString ss;
16105a988416SJim Ingham         switch (break_type)
16115a988416SJim Ingham         {
16125a988416SJim Ingham             case eClearTypeFileAndLine: // Breakpoint by source position
16135a988416SJim Ingham                 {
16145a988416SJim Ingham                     const ConstString filename(m_options.m_filename.c_str());
16155a988416SJim Ingham                     BreakpointLocationCollection loc_coll;
16165a988416SJim Ingham 
16175a988416SJim Ingham                     for (size_t i = 0; i < num_breakpoints; ++i)
16185a988416SJim Ingham                     {
16195a988416SJim Ingham                         Breakpoint *bp = breakpoints.FindBreakpointByID(BreakIDs[i]).get();
16205a988416SJim Ingham 
16215a988416SJim Ingham                         if (bp->GetMatchingFileLine(filename, m_options.m_line_num, loc_coll))
16225a988416SJim Ingham                         {
16235a988416SJim Ingham                             // If the collection size is 0, it's a full match and we can just remove the breakpoint.
16245a988416SJim Ingham                             if (loc_coll.GetSize() == 0)
16255a988416SJim Ingham                             {
16265a988416SJim Ingham                                 bp->GetDescription(&ss, lldb::eDescriptionLevelBrief);
16275a988416SJim Ingham                                 ss.EOL();
16285a988416SJim Ingham                                 target->RemoveBreakpointByID (bp->GetID());
16295a988416SJim Ingham                                 ++num_cleared;
16305a988416SJim Ingham                             }
16315a988416SJim Ingham                         }
16325a988416SJim Ingham                     }
16335a988416SJim Ingham                 }
16345a988416SJim Ingham                 break;
16355a988416SJim Ingham 
16365a988416SJim Ingham             default:
16375a988416SJim Ingham                 break;
16385a988416SJim Ingham         }
16395a988416SJim Ingham 
16405a988416SJim Ingham         if (num_cleared > 0)
16415a988416SJim Ingham         {
16425a988416SJim Ingham             Stream &output_stream = result.GetOutputStream();
16435a988416SJim Ingham             output_stream.Printf ("%d breakpoints cleared:\n", num_cleared);
16445a988416SJim Ingham             output_stream << ss.GetData();
16455a988416SJim Ingham             output_stream.EOL();
16465a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
16475a988416SJim Ingham         }
16485a988416SJim Ingham         else
16495a988416SJim Ingham         {
16505a988416SJim Ingham             result.AppendError ("Breakpoint clear: No breakpoint cleared.");
16515a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
16525a988416SJim Ingham         }
16535a988416SJim Ingham 
16545a988416SJim Ingham         return result.Succeeded();
16555a988416SJim Ingham     }
16565a988416SJim Ingham 
16575a988416SJim Ingham private:
16585a988416SJim Ingham     CommandOptions m_options;
16595a988416SJim Ingham };
16605a988416SJim Ingham 
16615a988416SJim Ingham #pragma mark Clear::CommandOptions
16625a988416SJim Ingham 
16635a988416SJim Ingham OptionDefinition
16645a988416SJim Ingham CommandObjectBreakpointClear::CommandOptions::g_option_table[] =
16655a988416SJim Ingham {
1666d37221dcSZachary Turner     { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
16675a988416SJim Ingham         "Specify the breakpoint by source location in this particular file."},
16685a988416SJim Ingham 
1669d37221dcSZachary Turner     { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum,
16705a988416SJim Ingham         "Specify the breakpoint by source location at this particular line."},
16715a988416SJim Ingham 
1672d37221dcSZachary Turner     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
16735a988416SJim Ingham };
16745a988416SJim Ingham 
16755a988416SJim Ingham //-------------------------------------------------------------------------
16765a988416SJim Ingham // CommandObjectBreakpointDelete
16775a988416SJim Ingham //-------------------------------------------------------------------------
16785a988416SJim Ingham #pragma mark Delete
16795a988416SJim Ingham 
16805a988416SJim Ingham class CommandObjectBreakpointDelete : public CommandObjectParsed
16815a988416SJim Ingham {
16825a988416SJim Ingham public:
16835a988416SJim Ingham     CommandObjectBreakpointDelete (CommandInterpreter &interpreter) :
16845a988416SJim Ingham         CommandObjectParsed (interpreter,
16855a988416SJim Ingham                              "breakpoint delete",
16865a988416SJim Ingham                              "Delete the specified breakpoint(s).  If no breakpoints are specified, delete them all.",
1687*33df7cd3SJim Ingham                              NULL),
1688*33df7cd3SJim Ingham         m_options (interpreter)
16895a988416SJim Ingham     {
16905a988416SJim Ingham         CommandArgumentEntry arg;
16915a988416SJim Ingham         CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
16925a988416SJim Ingham         // Add the entry for the first argument for this command to the object's arguments vector.
16935a988416SJim Ingham         m_arguments.push_back (arg);
16945a988416SJim Ingham     }
16955a988416SJim Ingham 
16965a988416SJim Ingham     virtual
16975a988416SJim Ingham     ~CommandObjectBreakpointDelete () {}
16985a988416SJim Ingham 
1699*33df7cd3SJim Ingham     virtual Options *
1700*33df7cd3SJim Ingham     GetOptions ()
1701*33df7cd3SJim Ingham     {
1702*33df7cd3SJim Ingham         return &m_options;
1703*33df7cd3SJim Ingham     }
1704*33df7cd3SJim Ingham 
1705*33df7cd3SJim Ingham     class CommandOptions : public Options
1706*33df7cd3SJim Ingham     {
1707*33df7cd3SJim Ingham     public:
1708*33df7cd3SJim Ingham 
1709*33df7cd3SJim Ingham         CommandOptions (CommandInterpreter &interpreter) :
1710*33df7cd3SJim Ingham             Options (interpreter),
1711*33df7cd3SJim Ingham             m_use_dummy (false),
1712*33df7cd3SJim Ingham             m_force (false)
1713*33df7cd3SJim Ingham         {
1714*33df7cd3SJim Ingham         }
1715*33df7cd3SJim Ingham 
1716*33df7cd3SJim Ingham         virtual
1717*33df7cd3SJim Ingham         ~CommandOptions () {}
1718*33df7cd3SJim Ingham 
1719*33df7cd3SJim Ingham         virtual Error
1720*33df7cd3SJim Ingham         SetOptionValue (uint32_t option_idx, const char *option_arg)
1721*33df7cd3SJim Ingham         {
1722*33df7cd3SJim Ingham             Error error;
1723*33df7cd3SJim Ingham             const int short_option = m_getopt_table[option_idx].val;
1724*33df7cd3SJim Ingham 
1725*33df7cd3SJim Ingham             switch (short_option)
1726*33df7cd3SJim Ingham             {
1727*33df7cd3SJim Ingham                 case 'f':
1728*33df7cd3SJim Ingham                     m_force = true;
1729*33df7cd3SJim Ingham                     break;
1730*33df7cd3SJim Ingham 
1731*33df7cd3SJim Ingham                 case 'D':
1732*33df7cd3SJim Ingham                     m_use_dummy = true;
1733*33df7cd3SJim Ingham                     break;
1734*33df7cd3SJim Ingham 
1735*33df7cd3SJim Ingham                 default:
1736*33df7cd3SJim Ingham                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1737*33df7cd3SJim Ingham                     break;
1738*33df7cd3SJim Ingham             }
1739*33df7cd3SJim Ingham 
1740*33df7cd3SJim Ingham             return error;
1741*33df7cd3SJim Ingham         }
1742*33df7cd3SJim Ingham 
1743*33df7cd3SJim Ingham         void
1744*33df7cd3SJim Ingham         OptionParsingStarting ()
1745*33df7cd3SJim Ingham         {
1746*33df7cd3SJim Ingham             m_use_dummy = false;
1747*33df7cd3SJim Ingham             m_force = false;
1748*33df7cd3SJim Ingham         }
1749*33df7cd3SJim Ingham 
1750*33df7cd3SJim Ingham         const OptionDefinition*
1751*33df7cd3SJim Ingham         GetDefinitions ()
1752*33df7cd3SJim Ingham         {
1753*33df7cd3SJim Ingham             return g_option_table;
1754*33df7cd3SJim Ingham         }
1755*33df7cd3SJim Ingham 
1756*33df7cd3SJim Ingham         // Options table: Required for subclasses of Options.
1757*33df7cd3SJim Ingham 
1758*33df7cd3SJim Ingham         static OptionDefinition g_option_table[];
1759*33df7cd3SJim Ingham 
1760*33df7cd3SJim Ingham         // Instance variables to hold the values for command options.
1761*33df7cd3SJim Ingham         bool m_use_dummy;
1762*33df7cd3SJim Ingham         bool m_force;
1763*33df7cd3SJim Ingham     };
1764*33df7cd3SJim Ingham 
17655a988416SJim Ingham protected:
17665a988416SJim Ingham     virtual bool
17675a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
17685a988416SJim Ingham     {
1769*33df7cd3SJim Ingham         Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
1770*33df7cd3SJim Ingham 
17715a988416SJim Ingham         if (target == NULL)
17725a988416SJim Ingham         {
17735a988416SJim Ingham             result.AppendError ("Invalid target. No existing target or breakpoints.");
17745a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
17755a988416SJim Ingham             return false;
17765a988416SJim Ingham         }
17775a988416SJim Ingham 
17785a988416SJim Ingham         Mutex::Locker locker;
17795a988416SJim Ingham         target->GetBreakpointList().GetListMutex(locker);
17805a988416SJim Ingham 
17815a988416SJim Ingham         const BreakpointList &breakpoints = target->GetBreakpointList();
17825a988416SJim Ingham 
17835a988416SJim Ingham         size_t num_breakpoints = breakpoints.GetSize();
17845a988416SJim Ingham 
17855a988416SJim Ingham         if (num_breakpoints == 0)
17865a988416SJim Ingham         {
17875a988416SJim Ingham             result.AppendError ("No breakpoints exist to be deleted.");
17885a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
17895a988416SJim Ingham             return false;
17905a988416SJim Ingham         }
17915a988416SJim Ingham 
17925a988416SJim Ingham         if (command.GetArgumentCount() == 0)
17935a988416SJim Ingham         {
1794*33df7cd3SJim Ingham             if (!m_options.m_force && !m_interpreter.Confirm ("About to delete all breakpoints, do you want to do that?", true))
17955a988416SJim Ingham             {
17965a988416SJim Ingham                 result.AppendMessage("Operation cancelled...");
17975a988416SJim Ingham             }
17985a988416SJim Ingham             else
17995a988416SJim Ingham             {
18005a988416SJim Ingham                 target->RemoveAllBreakpoints ();
18016fea17e8SGreg Clayton                 result.AppendMessageWithFormat ("All breakpoints removed. (%" PRIu64 " breakpoint%s)\n", (uint64_t)num_breakpoints, num_breakpoints > 1 ? "s" : "");
18025a988416SJim Ingham             }
18035a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
18045a988416SJim Ingham         }
18055a988416SJim Ingham         else
18065a988416SJim Ingham         {
18075a988416SJim Ingham             // Particular breakpoint selected; disable that breakpoint.
18085a988416SJim Ingham             BreakpointIDList valid_bp_ids;
18095a988416SJim Ingham             CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
18105a988416SJim Ingham 
18115a988416SJim Ingham             if (result.Succeeded())
18125a988416SJim Ingham             {
18135a988416SJim Ingham                 int delete_count = 0;
18145a988416SJim Ingham                 int disable_count = 0;
18155a988416SJim Ingham                 const size_t count = valid_bp_ids.GetSize();
18165a988416SJim Ingham                 for (size_t i = 0; i < count; ++i)
18175a988416SJim Ingham                 {
18185a988416SJim Ingham                     BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
18195a988416SJim Ingham 
18205a988416SJim Ingham                     if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
18215a988416SJim Ingham                     {
18225a988416SJim Ingham                         if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
18235a988416SJim Ingham                         {
18245a988416SJim Ingham                             Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
18255a988416SJim Ingham                             BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
18265a988416SJim Ingham                             // It makes no sense to try to delete individual locations, so we disable them instead.
18275a988416SJim Ingham                             if (location)
18285a988416SJim Ingham                             {
18295a988416SJim Ingham                                 location->SetEnabled (false);
18305a988416SJim Ingham                                 ++disable_count;
18315a988416SJim Ingham                             }
18325a988416SJim Ingham                         }
18335a988416SJim Ingham                         else
18345a988416SJim Ingham                         {
18355a988416SJim Ingham                             target->RemoveBreakpointByID (cur_bp_id.GetBreakpointID());
18365a988416SJim Ingham                             ++delete_count;
18375a988416SJim Ingham                         }
18385a988416SJim Ingham                     }
18395a988416SJim Ingham                 }
18405a988416SJim Ingham                 result.AppendMessageWithFormat ("%d breakpoints deleted; %d breakpoint locations disabled.\n",
18415a988416SJim Ingham                                                delete_count, disable_count);
18425a988416SJim Ingham                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
18435a988416SJim Ingham             }
18445a988416SJim Ingham         }
18455a988416SJim Ingham         return result.Succeeded();
18465a988416SJim Ingham     }
1847*33df7cd3SJim Ingham private:
1848*33df7cd3SJim Ingham     CommandOptions m_options;
1849*33df7cd3SJim Ingham };
1850*33df7cd3SJim Ingham 
1851*33df7cd3SJim Ingham OptionDefinition
1852*33df7cd3SJim Ingham CommandObjectBreakpointDelete::CommandOptions::g_option_table[] =
1853*33df7cd3SJim Ingham {
1854*33df7cd3SJim Ingham     { LLDB_OPT_SET_1, false, "force", 'f', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
1855*33df7cd3SJim Ingham         "Delete all breakpoints without querying for confirmation."},
1856*33df7cd3SJim Ingham 
1857*33df7cd3SJim Ingham     { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
1858*33df7cd3SJim Ingham         "Delete Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
1859*33df7cd3SJim Ingham 
1860*33df7cd3SJim Ingham     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
18615a988416SJim Ingham };
18625a988416SJim Ingham 
186330fdc8d8SChris Lattner //-------------------------------------------------------------------------
186430fdc8d8SChris Lattner // CommandObjectMultiwordBreakpoint
186530fdc8d8SChris Lattner //-------------------------------------------------------------------------
1866ae1c4cf5SJim Ingham #pragma mark MultiwordBreakpoint
186730fdc8d8SChris Lattner 
18686611103cSGreg Clayton CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint (CommandInterpreter &interpreter) :
1869a7015092SGreg Clayton     CommandObjectMultiword (interpreter,
1870a7015092SGreg Clayton                             "breakpoint",
187146fbc60fSJim Ingham                             "A set of commands for operating on breakpoints. Also see _regexp-break.",
187230fdc8d8SChris Lattner                             "breakpoint <command> [<command-options>]")
187330fdc8d8SChris Lattner {
1874a7015092SGreg Clayton     CommandObjectSP list_command_object (new CommandObjectBreakpointList (interpreter));
1875a7015092SGreg Clayton     CommandObjectSP enable_command_object (new CommandObjectBreakpointEnable (interpreter));
1876a7015092SGreg Clayton     CommandObjectSP disable_command_object (new CommandObjectBreakpointDisable (interpreter));
1877b7234e40SJohnny Chen     CommandObjectSP clear_command_object (new CommandObjectBreakpointClear (interpreter));
1878b7234e40SJohnny Chen     CommandObjectSP delete_command_object (new CommandObjectBreakpointDelete (interpreter));
1879a7015092SGreg Clayton     CommandObjectSP set_command_object (new CommandObjectBreakpointSet (interpreter));
188030fdc8d8SChris Lattner     CommandObjectSP command_command_object (new CommandObjectBreakpointCommand (interpreter));
1881a7015092SGreg Clayton     CommandObjectSP modify_command_object (new CommandObjectBreakpointModify(interpreter));
188230fdc8d8SChris Lattner 
1883b7234e40SJohnny Chen     list_command_object->SetCommandName ("breakpoint list");
188430fdc8d8SChris Lattner     enable_command_object->SetCommandName("breakpoint enable");
188530fdc8d8SChris Lattner     disable_command_object->SetCommandName("breakpoint disable");
1886b7234e40SJohnny Chen     clear_command_object->SetCommandName("breakpoint clear");
1887b7234e40SJohnny Chen     delete_command_object->SetCommandName("breakpoint delete");
1888ae1c4cf5SJim Ingham     set_command_object->SetCommandName("breakpoint set");
1889b7234e40SJohnny Chen     command_command_object->SetCommandName ("breakpoint command");
1890b7234e40SJohnny Chen     modify_command_object->SetCommandName ("breakpoint modify");
189130fdc8d8SChris Lattner 
189223f59509SGreg Clayton     LoadSubCommand ("list",       list_command_object);
189323f59509SGreg Clayton     LoadSubCommand ("enable",     enable_command_object);
189423f59509SGreg Clayton     LoadSubCommand ("disable",    disable_command_object);
189523f59509SGreg Clayton     LoadSubCommand ("clear",      clear_command_object);
189623f59509SGreg Clayton     LoadSubCommand ("delete",     delete_command_object);
189723f59509SGreg Clayton     LoadSubCommand ("set",        set_command_object);
189823f59509SGreg Clayton     LoadSubCommand ("command",    command_command_object);
189923f59509SGreg Clayton     LoadSubCommand ("modify",     modify_command_object);
190030fdc8d8SChris Lattner }
190130fdc8d8SChris Lattner 
190230fdc8d8SChris Lattner CommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint ()
190330fdc8d8SChris Lattner {
190430fdc8d8SChris Lattner }
190530fdc8d8SChris Lattner 
190630fdc8d8SChris Lattner void
190730fdc8d8SChris Lattner CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (Args &args, Target *target, CommandReturnObject &result,
190830fdc8d8SChris Lattner                                                          BreakpointIDList *valid_ids)
190930fdc8d8SChris Lattner {
191030fdc8d8SChris Lattner     // args can be strings representing 1). integers (for breakpoint ids)
191130fdc8d8SChris Lattner     //                                  2). the full breakpoint & location canonical representation
191230fdc8d8SChris Lattner     //                                  3). the word "to" or a hyphen, representing a range (in which case there
191330fdc8d8SChris Lattner     //                                      had *better* be an entry both before & after of one of the first two types.
191436f3b369SJim Ingham     // If args is empty, we will use the last created breakpoint (if there is one.)
191530fdc8d8SChris Lattner 
191630fdc8d8SChris Lattner     Args temp_args;
191730fdc8d8SChris Lattner 
191836f3b369SJim Ingham     if (args.GetArgumentCount() == 0)
191936f3b369SJim Ingham     {
19204d122c40SGreg Clayton         if (target->GetLastCreatedBreakpoint())
192136f3b369SJim Ingham         {
192236f3b369SJim Ingham             valid_ids->AddBreakpointID (BreakpointID(target->GetLastCreatedBreakpoint()->GetID(), LLDB_INVALID_BREAK_ID));
192336f3b369SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
192436f3b369SJim Ingham         }
192536f3b369SJim Ingham         else
192636f3b369SJim Ingham         {
192736f3b369SJim Ingham             result.AppendError("No breakpoint specified and no last created breakpoint.");
192836f3b369SJim Ingham             result.SetStatus (eReturnStatusFailed);
192936f3b369SJim Ingham         }
193036f3b369SJim Ingham         return;
193136f3b369SJim Ingham     }
193236f3b369SJim Ingham 
193330fdc8d8SChris Lattner     // Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff directly from the old ARGS to
193430fdc8d8SChris Lattner     // the new TEMP_ARGS.  Do not copy breakpoint id range strings over; instead generate a list of strings for
193530fdc8d8SChris Lattner     // all the breakpoint ids in the range, and shove all of those breakpoint id strings into TEMP_ARGS.
193630fdc8d8SChris Lattner 
193730fdc8d8SChris Lattner     BreakpointIDList::FindAndReplaceIDRanges (args, target, result, temp_args);
193830fdc8d8SChris Lattner 
193930fdc8d8SChris Lattner     // NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual BreakpointIDList:
194030fdc8d8SChris Lattner 
1941c982c768SGreg Clayton     valid_ids->InsertStringArray (temp_args.GetConstArgumentVector(), temp_args.GetArgumentCount(), result);
194230fdc8d8SChris Lattner 
194330fdc8d8SChris Lattner     // At this point,  all of the breakpoint ids that the user passed in have been converted to breakpoint IDs
194430fdc8d8SChris Lattner     // and put into valid_ids.
194530fdc8d8SChris Lattner 
194630fdc8d8SChris Lattner     if (result.Succeeded())
194730fdc8d8SChris Lattner     {
194830fdc8d8SChris Lattner         // Now that we've converted everything from args into a list of breakpoint ids, go through our tentative list
194930fdc8d8SChris Lattner         // of breakpoint id's and verify that they correspond to valid/currently set breakpoints.
195030fdc8d8SChris Lattner 
1951c982c768SGreg Clayton         const size_t count = valid_ids->GetSize();
1952c982c768SGreg Clayton         for (size_t i = 0; i < count; ++i)
195330fdc8d8SChris Lattner         {
195430fdc8d8SChris Lattner             BreakpointID cur_bp_id = valid_ids->GetBreakpointIDAtIndex (i);
195530fdc8d8SChris Lattner             Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
195630fdc8d8SChris Lattner             if (breakpoint != NULL)
195730fdc8d8SChris Lattner             {
1958c7bece56SGreg Clayton                 const size_t num_locations = breakpoint->GetNumLocations();
19593985c8c6SSaleem Abdulrasool                 if (static_cast<size_t>(cur_bp_id.GetLocationID()) > num_locations)
196030fdc8d8SChris Lattner                 {
196130fdc8d8SChris Lattner                     StreamString id_str;
1962c982c768SGreg Clayton                     BreakpointID::GetCanonicalReference (&id_str,
1963c982c768SGreg Clayton                                                          cur_bp_id.GetBreakpointID(),
196430fdc8d8SChris Lattner                                                          cur_bp_id.GetLocationID());
1965c982c768SGreg Clayton                     i = valid_ids->GetSize() + 1;
196630fdc8d8SChris Lattner                     result.AppendErrorWithFormat ("'%s' is not a currently valid breakpoint/location id.\n",
196730fdc8d8SChris Lattner                                                  id_str.GetData());
196830fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusFailed);
196930fdc8d8SChris Lattner                 }
197030fdc8d8SChris Lattner             }
197130fdc8d8SChris Lattner             else
197230fdc8d8SChris Lattner             {
1973c982c768SGreg Clayton                 i = valid_ids->GetSize() + 1;
197430fdc8d8SChris Lattner                 result.AppendErrorWithFormat ("'%d' is not a currently valid breakpoint id.\n", cur_bp_id.GetBreakpointID());
197530fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
197630fdc8d8SChris Lattner             }
197730fdc8d8SChris Lattner         }
197830fdc8d8SChris Lattner     }
197930fdc8d8SChris Lattner }
1980