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 
148fab10e89SJim Ingham                 case 'E':
149fab10e89SJim Ingham                 {
150fab10e89SJim Ingham                     LanguageType language = LanguageRuntime::GetLanguageTypeFromString (option_arg);
151fab10e89SJim Ingham 
152fab10e89SJim Ingham                     switch (language)
153fab10e89SJim Ingham                     {
154fab10e89SJim Ingham                         case eLanguageTypeC89:
155fab10e89SJim Ingham                         case eLanguageTypeC:
156fab10e89SJim Ingham                         case eLanguageTypeC99:
1571d0089faSBruce Mitchener                         case eLanguageTypeC11:
158fab10e89SJim Ingham                             m_language = eLanguageTypeC;
159fab10e89SJim Ingham                             break;
160fab10e89SJim Ingham                         case eLanguageTypeC_plus_plus:
1611d0089faSBruce Mitchener                         case eLanguageTypeC_plus_plus_03:
1621d0089faSBruce Mitchener                         case eLanguageTypeC_plus_plus_11:
163fab10e89SJim Ingham                             m_language = eLanguageTypeC_plus_plus;
164fab10e89SJim Ingham                             break;
165fab10e89SJim Ingham                         case eLanguageTypeObjC:
166fab10e89SJim Ingham                             m_language = eLanguageTypeObjC;
167fab10e89SJim Ingham                             break;
168fab10e89SJim Ingham                         case eLanguageTypeObjC_plus_plus:
169fab10e89SJim Ingham                             error.SetErrorStringWithFormat ("Set exception breakpoints separately for c++ and objective-c");
170fab10e89SJim Ingham                             break;
171fab10e89SJim Ingham                         case eLanguageTypeUnknown:
172fab10e89SJim Ingham                             error.SetErrorStringWithFormat ("Unknown language type: '%s' for exception breakpoint", option_arg);
173fab10e89SJim Ingham                             break;
174fab10e89SJim Ingham                         default:
175fab10e89SJim Ingham                             error.SetErrorStringWithFormat ("Unsupported language type: '%s' for exception breakpoint", option_arg);
176fab10e89SJim Ingham                     }
177fab10e89SJim Ingham                 }
178fab10e89SJim Ingham                 break;
179ca36cd16SJim Ingham 
180ca36cd16SJim Ingham                 case 'f':
181ca36cd16SJim Ingham                     m_filenames.AppendIfUnique (FileSpec(option_arg, false));
182fab10e89SJim Ingham                     break;
183ca36cd16SJim Ingham 
184ca36cd16SJim Ingham                 case 'F':
185ca36cd16SJim Ingham                     m_func_names.push_back (option_arg);
186ca36cd16SJim Ingham                     m_func_name_type_mask |= eFunctionNameTypeFull;
187ca36cd16SJim Ingham                     break;
188ca36cd16SJim Ingham 
189fab10e89SJim Ingham                 case 'h':
190fab10e89SJim Ingham                     {
191fab10e89SJim Ingham                         bool success;
192fab10e89SJim Ingham                         m_catch_bp = Args::StringToBoolean (option_arg, true, &success);
193fab10e89SJim Ingham                         if (!success)
194fab10e89SJim Ingham                             error.SetErrorStringWithFormat ("Invalid boolean value for on-catch option: '%s'", option_arg);
195fab10e89SJim Ingham                     }
196168d469aSJim Ingham                     break;
197eb023e75SGreg Clayton 
198eb023e75SGreg Clayton                 case 'H':
199eb023e75SGreg Clayton                     m_hardware = true;
200eb023e75SGreg Clayton                     break;
201eb023e75SGreg Clayton 
202ca36cd16SJim Ingham                 case 'i':
203ca36cd16SJim Ingham                 {
204ca36cd16SJim Ingham                     m_ignore_count = Args::StringToUInt32(option_arg, UINT32_MAX, 0);
205ca36cd16SJim Ingham                     if (m_ignore_count == UINT32_MAX)
206ca36cd16SJim Ingham                        error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
207ca36cd16SJim Ingham                     break;
208ca36cd16SJim Ingham                 }
209ca36cd16SJim Ingham 
210a8558b62SJim Ingham                 case 'K':
211a8558b62SJim Ingham                 {
212a8558b62SJim Ingham                     bool success;
213a8558b62SJim Ingham                     bool value;
214a8558b62SJim Ingham                     value = Args::StringToBoolean (option_arg, true, &success);
215a8558b62SJim Ingham                     if (value)
216a8558b62SJim Ingham                         m_skip_prologue = eLazyBoolYes;
217a8558b62SJim Ingham                     else
218a8558b62SJim Ingham                         m_skip_prologue = eLazyBoolNo;
219a8558b62SJim Ingham 
220a8558b62SJim Ingham                     if (!success)
221a8558b62SJim Ingham                         error.SetErrorStringWithFormat ("Invalid boolean value for skip prologue option: '%s'", option_arg);
222a8558b62SJim Ingham                 }
223fab10e89SJim Ingham                 break;
224ca36cd16SJim Ingham 
225ca36cd16SJim Ingham                 case 'l':
226ca36cd16SJim Ingham                     m_line_num = Args::StringToUInt32 (option_arg, 0);
227ca36cd16SJim Ingham                     break;
228ca36cd16SJim Ingham 
229ca36cd16SJim Ingham                 case 'M':
230ca36cd16SJim Ingham                     m_func_names.push_back (option_arg);
231ca36cd16SJim Ingham                     m_func_name_type_mask |= eFunctionNameTypeMethod;
232ca36cd16SJim Ingham                     break;
233ca36cd16SJim Ingham 
234ca36cd16SJim Ingham                 case 'n':
235ca36cd16SJim Ingham                     m_func_names.push_back (option_arg);
236ca36cd16SJim Ingham                     m_func_name_type_mask |= eFunctionNameTypeAuto;
237ca36cd16SJim Ingham                     break;
238ca36cd16SJim Ingham 
239ca36cd16SJim Ingham                 case 'o':
240ca36cd16SJim Ingham                     m_one_shot = true;
241ca36cd16SJim Ingham                     break;
242ca36cd16SJim Ingham 
243ca36cd16SJim Ingham                 case 'p':
244ca36cd16SJim Ingham                     m_source_text_regexp.assign (option_arg);
245ca36cd16SJim Ingham                     break;
246ca36cd16SJim Ingham 
247ca36cd16SJim Ingham                 case 'q':
248ca36cd16SJim Ingham                     m_queue_name.assign (option_arg);
249ca36cd16SJim Ingham                     break;
250ca36cd16SJim Ingham 
251ca36cd16SJim Ingham                 case 'r':
252ca36cd16SJim Ingham                     m_func_regexp.assign (option_arg);
253ca36cd16SJim Ingham                     break;
254ca36cd16SJim Ingham 
255ca36cd16SJim Ingham                 case 's':
256ca36cd16SJim Ingham                 {
257ca36cd16SJim Ingham                     m_modules.AppendIfUnique (FileSpec (option_arg, false));
258ca36cd16SJim Ingham                     break;
259ca36cd16SJim Ingham                 }
260ca36cd16SJim Ingham 
261ca36cd16SJim Ingham                 case 'S':
262ca36cd16SJim Ingham                     m_func_names.push_back (option_arg);
263ca36cd16SJim Ingham                     m_func_name_type_mask |= eFunctionNameTypeSelector;
264ca36cd16SJim Ingham                     break;
265ca36cd16SJim Ingham 
266ca36cd16SJim Ingham                 case 't' :
267ca36cd16SJim Ingham                 {
268ca36cd16SJim Ingham                     m_thread_id = Args::StringToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
269ca36cd16SJim Ingham                     if (m_thread_id == LLDB_INVALID_THREAD_ID)
270ca36cd16SJim Ingham                        error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
271ca36cd16SJim Ingham                 }
272ca36cd16SJim Ingham                 break;
273ca36cd16SJim Ingham 
274ca36cd16SJim Ingham                 case 'T':
275ca36cd16SJim Ingham                     m_thread_name.assign (option_arg);
276ca36cd16SJim Ingham                     break;
277ca36cd16SJim Ingham 
278ca36cd16SJim Ingham                 case 'w':
279ca36cd16SJim Ingham                 {
280ca36cd16SJim Ingham                     bool success;
281ca36cd16SJim Ingham                     m_throw_bp = Args::StringToBoolean (option_arg, true, &success);
282ca36cd16SJim Ingham                     if (!success)
283ca36cd16SJim Ingham                         error.SetErrorStringWithFormat ("Invalid boolean value for on-throw option: '%s'", option_arg);
284ca36cd16SJim Ingham                 }
285ca36cd16SJim Ingham                 break;
286ca36cd16SJim Ingham 
287ca36cd16SJim Ingham                 case 'x':
288ca36cd16SJim Ingham                 {
289ca36cd16SJim Ingham                     m_thread_index = Args::StringToUInt32(option_arg, UINT32_MAX, 0);
290ca36cd16SJim Ingham                     if (m_thread_id == UINT32_MAX)
291ca36cd16SJim Ingham                        error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
292ca36cd16SJim Ingham 
293ca36cd16SJim Ingham                 }
294ca36cd16SJim Ingham                 break;
295ca36cd16SJim Ingham 
29630fdc8d8SChris Lattner                 default:
29786edbf41SGreg Clayton                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
29830fdc8d8SChris Lattner                     break;
29930fdc8d8SChris Lattner             }
30030fdc8d8SChris Lattner 
30130fdc8d8SChris Lattner             return error;
30230fdc8d8SChris Lattner         }
30330fdc8d8SChris Lattner         void
3045a988416SJim Ingham         OptionParsingStarting ()
30530fdc8d8SChris Lattner         {
3067d49c9c8SJohnny Chen             m_condition.clear();
30787df91b8SJim Ingham             m_filenames.Clear();
30830fdc8d8SChris Lattner             m_line_num = 0;
30930fdc8d8SChris Lattner             m_column = 0;
310fab10e89SJim Ingham             m_func_names.clear();
3111f746071SGreg Clayton             m_func_name_type_mask = eFunctionNameTypeNone;
31230fdc8d8SChris Lattner             m_func_regexp.clear();
3131f746071SGreg Clayton             m_source_text_regexp.clear();
31487df91b8SJim Ingham             m_modules.Clear();
3151f746071SGreg Clayton             m_load_addr = LLDB_INVALID_ADDRESS;
316c982c768SGreg Clayton             m_ignore_count = 0;
3171b54c88cSJim Ingham             m_thread_id = LLDB_INVALID_THREAD_ID;
318c982c768SGreg Clayton             m_thread_index = UINT32_MAX;
3191b54c88cSJim Ingham             m_thread_name.clear();
3201b54c88cSJim Ingham             m_queue_name.clear();
321fab10e89SJim Ingham             m_catch_bp = false;
322fab10e89SJim Ingham             m_throw_bp = true;
323eb023e75SGreg Clayton             m_hardware = false;
3241f746071SGreg Clayton             m_language = eLanguageTypeUnknown;
325a8558b62SJim Ingham             m_skip_prologue = eLazyBoolCalculate;
326ca36cd16SJim Ingham             m_one_shot = false;
32730fdc8d8SChris Lattner         }
32830fdc8d8SChris Lattner 
3295a988416SJim Ingham         const OptionDefinition*
3305a988416SJim Ingham         GetDefinitions ()
33130fdc8d8SChris Lattner         {
3325a988416SJim Ingham             return g_option_table;
33330fdc8d8SChris Lattner         }
33430fdc8d8SChris Lattner 
3355a988416SJim Ingham         // Options table: Required for subclasses of Options.
33630fdc8d8SChris Lattner 
3375a988416SJim Ingham         static OptionDefinition g_option_table[];
33830fdc8d8SChris Lattner 
3395a988416SJim Ingham         // Instance variables to hold the values for command options.
340969795f1SJim Ingham 
3415a988416SJim Ingham         std::string m_condition;
3425a988416SJim Ingham         FileSpecList m_filenames;
3435a988416SJim Ingham         uint32_t m_line_num;
3445a988416SJim Ingham         uint32_t m_column;
3455a988416SJim Ingham         std::vector<std::string> m_func_names;
3465a988416SJim Ingham         uint32_t m_func_name_type_mask;
3475a988416SJim Ingham         std::string m_func_regexp;
3485a988416SJim Ingham         std::string m_source_text_regexp;
3495a988416SJim Ingham         FileSpecList m_modules;
3505a988416SJim Ingham         lldb::addr_t m_load_addr;
3515a988416SJim Ingham         uint32_t m_ignore_count;
3525a988416SJim Ingham         lldb::tid_t m_thread_id;
3535a988416SJim Ingham         uint32_t m_thread_index;
3545a988416SJim Ingham         std::string m_thread_name;
3555a988416SJim Ingham         std::string m_queue_name;
3565a988416SJim Ingham         bool m_catch_bp;
3575a988416SJim Ingham         bool m_throw_bp;
358eb023e75SGreg Clayton         bool m_hardware; // Request to use hardware breakpoints
3595a988416SJim Ingham         lldb::LanguageType m_language;
3605a988416SJim Ingham         LazyBool m_skip_prologue;
361ca36cd16SJim Ingham         bool m_one_shot;
3625a988416SJim Ingham 
3635a988416SJim Ingham     };
3645a988416SJim Ingham 
3655a988416SJim Ingham protected:
3665a988416SJim Ingham     virtual bool
3675a988416SJim Ingham     DoExecute (Args& command,
3685a988416SJim Ingham              CommandReturnObject &result)
36930fdc8d8SChris Lattner     {
370a7015092SGreg Clayton         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
37130fdc8d8SChris Lattner         if (target == NULL)
37230fdc8d8SChris Lattner         {
373effe5c95SGreg Clayton             result.AppendError ("Invalid target.  Must set target before setting breakpoints (see 'target create' command).");
37430fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
37530fdc8d8SChris Lattner             return false;
37630fdc8d8SChris Lattner         }
37730fdc8d8SChris Lattner 
37830fdc8d8SChris Lattner         // The following are the various types of breakpoints that could be set:
37930fdc8d8SChris Lattner         //   1).  -f -l -p  [-s -g]   (setting breakpoint by source location)
38030fdc8d8SChris Lattner         //   2).  -a  [-s -g]         (setting breakpoint by address)
38130fdc8d8SChris Lattner         //   3).  -n  [-s -g]         (setting breakpoint by function name)
38230fdc8d8SChris Lattner         //   4).  -r  [-s -g]         (setting breakpoint by function name regular expression)
383969795f1SJim Ingham         //   5).  -p -f               (setting a breakpoint by comparing a reg-exp to source text)
384fab10e89SJim Ingham         //   6).  -E [-w -h]          (setting a breakpoint for exceptions for a given language.)
38530fdc8d8SChris Lattner 
38630fdc8d8SChris Lattner         BreakpointSetType break_type = eSetTypeInvalid;
38730fdc8d8SChris Lattner 
38830fdc8d8SChris Lattner         if (m_options.m_line_num != 0)
38930fdc8d8SChris Lattner             break_type = eSetTypeFileAndLine;
39030fdc8d8SChris Lattner         else if (m_options.m_load_addr != LLDB_INVALID_ADDRESS)
39130fdc8d8SChris Lattner             break_type = eSetTypeAddress;
392fab10e89SJim Ingham         else if (!m_options.m_func_names.empty())
39330fdc8d8SChris Lattner             break_type = eSetTypeFunctionName;
39430fdc8d8SChris Lattner         else if  (!m_options.m_func_regexp.empty())
39530fdc8d8SChris Lattner             break_type = eSetTypeFunctionRegexp;
396969795f1SJim Ingham         else if (!m_options.m_source_text_regexp.empty())
397969795f1SJim Ingham             break_type = eSetTypeSourceRegexp;
398fab10e89SJim Ingham         else if (m_options.m_language != eLanguageTypeUnknown)
399fab10e89SJim Ingham             break_type = eSetTypeException;
40030fdc8d8SChris Lattner 
40130fdc8d8SChris Lattner         Breakpoint *bp = NULL;
402274060b6SGreg Clayton         FileSpec module_spec;
403a8558b62SJim Ingham         const bool internal = false;
404a8558b62SJim Ingham 
40530fdc8d8SChris Lattner         switch (break_type)
40630fdc8d8SChris Lattner         {
40730fdc8d8SChris Lattner             case eSetTypeFileAndLine: // Breakpoint by source position
40830fdc8d8SChris Lattner                 {
40930fdc8d8SChris Lattner                     FileSpec file;
410c7bece56SGreg Clayton                     const size_t num_files = m_options.m_filenames.GetSize();
41187df91b8SJim Ingham                     if (num_files == 0)
41287df91b8SJim Ingham                     {
41387df91b8SJim Ingham                         if (!GetDefaultFile (target, file, result))
41487df91b8SJim Ingham                         {
41587df91b8SJim Ingham                             result.AppendError("No file supplied and no default file available.");
41687df91b8SJim Ingham                             result.SetStatus (eReturnStatusFailed);
41787df91b8SJim Ingham                             return false;
41887df91b8SJim Ingham                         }
41987df91b8SJim Ingham                     }
42087df91b8SJim Ingham                     else if (num_files > 1)
42187df91b8SJim Ingham                     {
42287df91b8SJim Ingham                         result.AppendError("Only one file at a time is allowed for file and line breakpoints.");
42387df91b8SJim Ingham                         result.SetStatus (eReturnStatusFailed);
42487df91b8SJim Ingham                         return false;
42587df91b8SJim Ingham                     }
42687df91b8SJim Ingham                     else
42787df91b8SJim Ingham                         file = m_options.m_filenames.GetFileSpecAtIndex(0);
42830fdc8d8SChris Lattner 
4291f746071SGreg Clayton                     // Only check for inline functions if
4301f746071SGreg Clayton                     LazyBool check_inlines = eLazyBoolCalculate;
4311f746071SGreg Clayton 
43287df91b8SJim Ingham                     bp = target->CreateBreakpoint (&(m_options.m_modules),
43330fdc8d8SChris Lattner                                                    file,
43430fdc8d8SChris Lattner                                                    m_options.m_line_num,
4351f746071SGreg Clayton                                                    check_inlines,
436a8558b62SJim Ingham                                                    m_options.m_skip_prologue,
437eb023e75SGreg Clayton                                                    internal,
438eb023e75SGreg Clayton                                                    m_options.m_hardware).get();
43930fdc8d8SChris Lattner                 }
44030fdc8d8SChris Lattner                 break;
4416eee5aa0SGreg Clayton 
44230fdc8d8SChris Lattner             case eSetTypeAddress: // Breakpoint by address
443eb023e75SGreg Clayton                 bp = target->CreateBreakpoint (m_options.m_load_addr,
444eb023e75SGreg Clayton                                                internal,
445eb023e75SGreg Clayton                                                m_options.m_hardware).get();
44630fdc8d8SChris Lattner                 break;
4470c5cd90dSGreg Clayton 
44830fdc8d8SChris Lattner             case eSetTypeFunctionName: // Breakpoint by function name
4490c5cd90dSGreg Clayton                 {
4500c5cd90dSGreg Clayton                     uint32_t name_type_mask = m_options.m_func_name_type_mask;
4510c5cd90dSGreg Clayton 
4520c5cd90dSGreg Clayton                     if (name_type_mask == 0)
453e02b8504SGreg Clayton                         name_type_mask = eFunctionNameTypeAuto;
4540c5cd90dSGreg Clayton 
45587df91b8SJim Ingham                     bp = target->CreateBreakpoint (&(m_options.m_modules),
45687df91b8SJim Ingham                                                    &(m_options.m_filenames),
457fab10e89SJim Ingham                                                    m_options.m_func_names,
458274060b6SGreg Clayton                                                    name_type_mask,
459a8558b62SJim Ingham                                                    m_options.m_skip_prologue,
460eb023e75SGreg Clayton                                                    internal,
461eb023e75SGreg Clayton                                                    m_options.m_hardware).get();
4620c5cd90dSGreg Clayton                 }
46330fdc8d8SChris Lattner                 break;
4640c5cd90dSGreg Clayton 
46530fdc8d8SChris Lattner             case eSetTypeFunctionRegexp: // Breakpoint by regular expression function name
46630fdc8d8SChris Lattner                 {
46730fdc8d8SChris Lattner                     RegularExpression regexp(m_options.m_func_regexp.c_str());
468969795f1SJim Ingham                     if (!regexp.IsValid())
46930fdc8d8SChris Lattner                     {
470969795f1SJim Ingham                         char err_str[1024];
471969795f1SJim Ingham                         regexp.GetErrorAsCString(err_str, sizeof(err_str));
472969795f1SJim Ingham                         result.AppendErrorWithFormat("Function name regular expression could not be compiled: \"%s\"",
473969795f1SJim Ingham                                                      err_str);
47430fdc8d8SChris Lattner                         result.SetStatus (eReturnStatusFailed);
475969795f1SJim Ingham                         return false;
47630fdc8d8SChris Lattner                     }
47787df91b8SJim Ingham 
478a8558b62SJim Ingham                     bp = target->CreateFuncRegexBreakpoint (&(m_options.m_modules),
479a8558b62SJim Ingham                                                             &(m_options.m_filenames),
480a8558b62SJim Ingham                                                             regexp,
481a8558b62SJim Ingham                                                             m_options.m_skip_prologue,
482eb023e75SGreg Clayton                                                             internal,
483eb023e75SGreg Clayton                                                             m_options.m_hardware).get();
48430fdc8d8SChris Lattner                 }
48530fdc8d8SChris Lattner                 break;
486969795f1SJim Ingham             case eSetTypeSourceRegexp: // Breakpoint by regexp on source text.
487969795f1SJim Ingham                 {
488c7bece56SGreg Clayton                     const size_t num_files = m_options.m_filenames.GetSize();
48987df91b8SJim Ingham 
49087df91b8SJim Ingham                     if (num_files == 0)
49187df91b8SJim Ingham                     {
492969795f1SJim Ingham                         FileSpec file;
49387df91b8SJim Ingham                         if (!GetDefaultFile (target, file, result))
49487df91b8SJim Ingham                         {
49587df91b8SJim Ingham                             result.AppendError ("No files provided and could not find default file.");
49687df91b8SJim Ingham                             result.SetStatus (eReturnStatusFailed);
49787df91b8SJim Ingham                             return false;
49887df91b8SJim Ingham                         }
49987df91b8SJim Ingham                         else
50087df91b8SJim Ingham                         {
50187df91b8SJim Ingham                             m_options.m_filenames.Append (file);
50287df91b8SJim Ingham                         }
50387df91b8SJim Ingham                     }
5040c5cd90dSGreg Clayton 
505969795f1SJim Ingham                     RegularExpression regexp(m_options.m_source_text_regexp.c_str());
506969795f1SJim Ingham                     if (!regexp.IsValid())
507969795f1SJim Ingham                     {
508969795f1SJim Ingham                         char err_str[1024];
509969795f1SJim Ingham                         regexp.GetErrorAsCString(err_str, sizeof(err_str));
510969795f1SJim Ingham                         result.AppendErrorWithFormat("Source text regular expression could not be compiled: \"%s\"",
511969795f1SJim Ingham                                                      err_str);
512969795f1SJim Ingham                         result.SetStatus (eReturnStatusFailed);
513969795f1SJim Ingham                         return false;
514969795f1SJim Ingham                     }
515eb023e75SGreg Clayton                     bp = target->CreateSourceRegexBreakpoint (&(m_options.m_modules),
516eb023e75SGreg Clayton                                                               &(m_options.m_filenames),
517eb023e75SGreg Clayton                                                               regexp,
518eb023e75SGreg Clayton                                                               internal,
519eb023e75SGreg Clayton                                                               m_options.m_hardware).get();
520969795f1SJim Ingham                 }
521969795f1SJim Ingham                 break;
522fab10e89SJim Ingham             case eSetTypeException:
523fab10e89SJim Ingham                 {
524eb023e75SGreg Clayton                     bp = target->CreateExceptionBreakpoint (m_options.m_language,
525eb023e75SGreg Clayton                                                             m_options.m_catch_bp,
526eb023e75SGreg Clayton                                                             m_options.m_throw_bp,
527eb023e75SGreg Clayton                                                             m_options.m_hardware).get();
528fab10e89SJim Ingham                 }
529fab10e89SJim Ingham                 break;
53030fdc8d8SChris Lattner             default:
53130fdc8d8SChris Lattner                 break;
53230fdc8d8SChris Lattner         }
53330fdc8d8SChris Lattner 
5341b54c88cSJim Ingham         // Now set the various options that were passed in:
5351b54c88cSJim Ingham         if (bp)
5361b54c88cSJim Ingham         {
5371b54c88cSJim Ingham             if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
5381b54c88cSJim Ingham                 bp->SetThreadID (m_options.m_thread_id);
5391b54c88cSJim Ingham 
540c982c768SGreg Clayton             if (m_options.m_thread_index != UINT32_MAX)
5411b54c88cSJim Ingham                 bp->GetOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index);
5421b54c88cSJim Ingham 
5431b54c88cSJim Ingham             if (!m_options.m_thread_name.empty())
5441b54c88cSJim Ingham                 bp->GetOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str());
5451b54c88cSJim Ingham 
5461b54c88cSJim Ingham             if (!m_options.m_queue_name.empty())
5471b54c88cSJim Ingham                 bp->GetOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str());
5481b54c88cSJim Ingham 
549c982c768SGreg Clayton             if (m_options.m_ignore_count != 0)
5501b54c88cSJim Ingham                 bp->GetOptions()->SetIgnoreCount(m_options.m_ignore_count);
5517d49c9c8SJohnny Chen 
5527d49c9c8SJohnny Chen             if (!m_options.m_condition.empty())
5537d49c9c8SJohnny Chen                 bp->GetOptions()->SetCondition(m_options.m_condition.c_str());
554ca36cd16SJim Ingham 
555ca36cd16SJim Ingham             bp->SetOneShot (m_options.m_one_shot);
5561b54c88cSJim Ingham         }
5571b54c88cSJim Ingham 
558969795f1SJim Ingham         if (bp)
55930fdc8d8SChris Lattner         {
56085e8b814SJim Ingham             Stream &output_stream = result.GetOutputStream();
5611391cc7dSJim Ingham             const bool show_locations = false;
5621391cc7dSJim Ingham             bp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial, show_locations);
563fab10e89SJim Ingham             // Don't print out this warning for exception breakpoints.  They can get set before the target
564fab10e89SJim Ingham             // is set, but we won't know how to actually set the breakpoint till we run.
565fab10e89SJim Ingham             if (bp->GetNumLocations() == 0 && break_type != eSetTypeException)
566be484f41SCaroline Tice                 output_stream.Printf ("WARNING:  Unable to resolve breakpoint to any actual locations.\n");
56730fdc8d8SChris Lattner             result.SetStatus (eReturnStatusSuccessFinishResult);
56830fdc8d8SChris Lattner         }
56930fdc8d8SChris Lattner         else if (!bp)
57030fdc8d8SChris Lattner         {
57130fdc8d8SChris Lattner             result.AppendError ("Breakpoint creation failed: No breakpoint created.");
57230fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
57330fdc8d8SChris Lattner         }
57430fdc8d8SChris Lattner 
57530fdc8d8SChris Lattner         return result.Succeeded();
57630fdc8d8SChris Lattner     }
57730fdc8d8SChris Lattner 
5785a988416SJim Ingham private:
5795a988416SJim Ingham     bool
5805a988416SJim Ingham     GetDefaultFile (Target *target, FileSpec &file, CommandReturnObject &result)
5815a988416SJim Ingham     {
5825a988416SJim Ingham         uint32_t default_line;
5835a988416SJim Ingham         // First use the Source Manager's default file.
5845a988416SJim Ingham         // Then use the current stack frame's file.
5855a988416SJim Ingham         if (!target->GetSourceManager().GetDefaultFileAndLine(file, default_line))
5865a988416SJim Ingham         {
587b57e4a1bSJason Molenda             StackFrame *cur_frame = m_exe_ctx.GetFramePtr();
5885a988416SJim Ingham             if (cur_frame == NULL)
5895a988416SJim Ingham             {
5905a988416SJim Ingham                 result.AppendError ("No selected frame to use to find the default file.");
5915a988416SJim Ingham                 result.SetStatus (eReturnStatusFailed);
5925a988416SJim Ingham                 return false;
5935a988416SJim Ingham             }
5945a988416SJim Ingham             else if (!cur_frame->HasDebugInformation())
5955a988416SJim Ingham             {
5965a988416SJim Ingham                 result.AppendError ("Cannot use the selected frame to find the default file, it has no debug info.");
5975a988416SJim Ingham                 result.SetStatus (eReturnStatusFailed);
5985a988416SJim Ingham                 return false;
5995a988416SJim Ingham             }
6005a988416SJim Ingham             else
6015a988416SJim Ingham             {
6025a988416SJim Ingham                 const SymbolContext &sc = cur_frame->GetSymbolContext (eSymbolContextLineEntry);
6035a988416SJim Ingham                 if (sc.line_entry.file)
6045a988416SJim Ingham                 {
6055a988416SJim Ingham                     file = sc.line_entry.file;
6065a988416SJim Ingham                 }
6075a988416SJim Ingham                 else
6085a988416SJim Ingham                 {
6095a988416SJim Ingham                     result.AppendError ("Can't find the file for the selected frame to use as the default file.");
6105a988416SJim Ingham                     result.SetStatus (eReturnStatusFailed);
6115a988416SJim Ingham                     return false;
6125a988416SJim Ingham                 }
6135a988416SJim Ingham             }
6145a988416SJim Ingham         }
6155a988416SJim Ingham         return true;
6165a988416SJim Ingham     }
6175a988416SJim Ingham 
6185a988416SJim Ingham     CommandOptions m_options;
6195a988416SJim Ingham };
6205a988416SJim Ingham // If an additional option set beyond LLDB_OPTION_SET_10 is added, make sure to
6215a988416SJim Ingham // update the numbers passed to LLDB_OPT_SET_FROM_TO(...) appropriately.
6225a988416SJim Ingham #define LLDB_OPT_FILE ( LLDB_OPT_SET_FROM_TO(1, 9) & ~LLDB_OPT_SET_2 )
6235a988416SJim Ingham #define LLDB_OPT_NOT_10 ( LLDB_OPT_SET_FROM_TO(1, 10) & ~LLDB_OPT_SET_10 )
6245a988416SJim Ingham #define LLDB_OPT_SKIP_PROLOGUE ( LLDB_OPT_SET_1 | LLDB_OPT_SET_FROM_TO(3,8) )
6255a988416SJim Ingham 
6265a988416SJim Ingham OptionDefinition
6275a988416SJim Ingham CommandObjectBreakpointSet::CommandOptions::g_option_table[] =
6285a988416SJim Ingham {
629*d37221dcSZachary Turner     { LLDB_OPT_NOT_10, false, "shlib", 's', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName,
6305a988416SJim Ingham         "Set the breakpoint only in this shared library.  "
6315a988416SJim Ingham         "Can repeat this option multiple times to specify multiple shared libraries."},
6325a988416SJim Ingham 
633*d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', OptionParser::eRequiredArgument,   NULL, NULL, 0, eArgTypeCount,
6345a988416SJim Ingham         "Set the number of times this breakpoint is skipped before stopping." },
6355a988416SJim Ingham 
636*d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "one-shot", 'o', OptionParser::eNoArgument,   NULL, NULL, 0, eArgTypeNone,
637b2b256afSJim Ingham         "The breakpoint is deleted the first time it causes a stop." },
638ca36cd16SJim Ingham 
639*d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "condition",    'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeExpression,
6405a988416SJim Ingham         "The breakpoint stops only if this condition expression evaluates to true."},
6415a988416SJim Ingham 
642*d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadIndex,
643a89be91fSJim Ingham         "The breakpoint stops only for the thread whose indeX matches this argument."},
6445a988416SJim Ingham 
645*d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadID,
6465a988416SJim Ingham         "The breakpoint stops only for the thread whose TID matches this argument."},
6475a988416SJim Ingham 
648*d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadName,
6495a988416SJim Ingham         "The breakpoint stops only for the thread whose thread name matches this argument."},
6505a988416SJim Ingham 
651*d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "hardware", 'H', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
652eb023e75SGreg Clayton         "Require the breakpoint to use hardware breakpoints."},
653eb023e75SGreg Clayton 
654*d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeQueueName,
6555a988416SJim Ingham         "The breakpoint stops only for threads in the queue whose name is given by this argument."},
6565a988416SJim Ingham 
657*d37221dcSZachary Turner     { LLDB_OPT_FILE, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
658289aca64SJim Ingham         "Specifies the source file in which to set this breakpoint.  "
659289aca64SJim Ingham         "Note, by default lldb only looks for files that are #included if they use the standard include file extensions.  "
6606394479eSJim Ingham         "To set breakpoints on .c/.cpp/.m/.mm files that are #included, set target.inline-breakpoint-strategy"
661289aca64SJim Ingham         " to \"always\"."},
6625a988416SJim Ingham 
663*d37221dcSZachary Turner     { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum,
6645a988416SJim Ingham         "Specifies the line number on which to set this breakpoint."},
6655a988416SJim Ingham 
6665a988416SJim Ingham     // Comment out this option for the moment, as we don't actually use it, but will in the future.
6675a988416SJim Ingham     // This way users won't see it, but the infrastructure is left in place.
668e2607b50SVirgile Bello     //    { 0, false, "column",     'C', OptionParser::eRequiredArgument, NULL, "<column>",
6695a988416SJim Ingham     //    "Set the breakpoint by source location at this particular column."},
6705a988416SJim Ingham 
671*d37221dcSZachary Turner     { LLDB_OPT_SET_2, true, "address", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression,
6725a988416SJim Ingham         "Set the breakpoint by address, at the specified address."},
6735a988416SJim Ingham 
674*d37221dcSZachary Turner     { LLDB_OPT_SET_3, true, "name", 'n', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
675551262d7SJim Ingham         "Set the breakpoint by function name.  Can be repeated multiple times to make one breakpoint for multiple names" },
6765a988416SJim Ingham 
677*d37221dcSZachary Turner     { LLDB_OPT_SET_4, true, "fullname", 'F', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFullName,
6785a988416SJim Ingham         "Set the breakpoint by fully qualified function names. For C++ this means namespaces and all arguments, and "
6795a988416SJim Ingham         "for Objective C this means a full function prototype with class and selector.   "
6805a988416SJim Ingham         "Can be repeated multiple times to make one breakpoint for multiple names." },
6815a988416SJim Ingham 
682*d37221dcSZachary Turner     { LLDB_OPT_SET_5, true, "selector", 'S', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeSelector,
6835a988416SJim Ingham         "Set the breakpoint by ObjC selector name. Can be repeated multiple times to make one breakpoint for multiple Selectors." },
6845a988416SJim Ingham 
685*d37221dcSZachary Turner     { LLDB_OPT_SET_6, true, "method", 'M', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeMethod,
6865a988416SJim Ingham         "Set the breakpoint by C++ method names.  Can be repeated multiple times to make one breakpoint for multiple methods." },
6875a988416SJim Ingham 
688*d37221dcSZachary Turner     { LLDB_OPT_SET_7, true, "func-regex", 'r', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeRegularExpression,
6895a988416SJim Ingham         "Set the breakpoint by function name, evaluating a regular-expression to find the function name(s)." },
6905a988416SJim Ingham 
691*d37221dcSZachary Turner     { LLDB_OPT_SET_8, true, "basename", 'b', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
6925a988416SJim Ingham         "Set the breakpoint by function basename (C++ namespaces and arguments will be ignored). "
6935a988416SJim Ingham         "Can be repeated multiple times to make one breakpoint for multiple symbols." },
6945a988416SJim Ingham 
695*d37221dcSZachary Turner     { LLDB_OPT_SET_9, true, "source-pattern-regexp", 'p', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeRegularExpression,
696e96ade8bSJim Ingham         "Set the breakpoint by specifying a regular expression which is matched against the source text in a source file or files "
697e96ade8bSJim Ingham         "specified with the -f option.  The -f option can be specified more than once.  "
698e96ade8bSJim Ingham         "If no source files are specified, uses the current \"default source file\"" },
6995a988416SJim Ingham 
700*d37221dcSZachary Turner     { LLDB_OPT_SET_10, true, "language-exception", 'E', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage,
7015a988416SJim Ingham         "Set the breakpoint on exceptions thrown by the specified language (without options, on throw but not catch.)" },
7025a988416SJim Ingham 
703*d37221dcSZachary Turner     { LLDB_OPT_SET_10, false, "on-throw", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,
7045a988416SJim Ingham         "Set the breakpoint on exception throW." },
7055a988416SJim Ingham 
706*d37221dcSZachary Turner     { LLDB_OPT_SET_10, false, "on-catch", 'h', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,
7075a988416SJim Ingham         "Set the breakpoint on exception catcH." },
7085a988416SJim Ingham 
709*d37221dcSZachary Turner     { LLDB_OPT_SKIP_PROLOGUE, false, "skip-prologue", 'K', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,
7105a988416SJim Ingham         "sKip the prologue if the breakpoint is at the beginning of a function.  If not set the target.skip-prologue setting is used." },
7115a988416SJim Ingham 
712*d37221dcSZachary Turner     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
7135a988416SJim Ingham };
7145a988416SJim Ingham 
7155a988416SJim Ingham //-------------------------------------------------------------------------
7165a988416SJim Ingham // CommandObjectBreakpointModify
7175a988416SJim Ingham //-------------------------------------------------------------------------
7185a988416SJim Ingham #pragma mark Modify
7195a988416SJim Ingham 
7205a988416SJim Ingham class CommandObjectBreakpointModify : public CommandObjectParsed
7215a988416SJim Ingham {
7225a988416SJim Ingham public:
7235a988416SJim Ingham 
7245a988416SJim Ingham     CommandObjectBreakpointModify (CommandInterpreter &interpreter) :
7255a988416SJim Ingham         CommandObjectParsed (interpreter,
7265a988416SJim Ingham                              "breakpoint modify",
7275a988416SJim Ingham                              "Modify the options on a breakpoint or set of breakpoints in the executable.  "
7285a988416SJim Ingham                              "If no breakpoint is specified, acts on the last created breakpoint.  "
7295a988416SJim Ingham                              "With the exception of -e, -d and -i, passing an empty argument clears the modification.",
7305a988416SJim Ingham                              NULL),
7315a988416SJim Ingham         m_options (interpreter)
7325a988416SJim Ingham     {
7335a988416SJim Ingham         CommandArgumentEntry arg;
7345a988416SJim Ingham         CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
7355a988416SJim Ingham         // Add the entry for the first argument for this command to the object's arguments vector.
7365a988416SJim Ingham         m_arguments.push_back (arg);
7375a988416SJim Ingham     }
7385a988416SJim Ingham 
7395a988416SJim Ingham 
7405a988416SJim Ingham     virtual
7415a988416SJim Ingham     ~CommandObjectBreakpointModify () {}
7425a988416SJim Ingham 
7435a988416SJim Ingham     virtual Options *
7445a988416SJim Ingham     GetOptions ()
7455a988416SJim Ingham     {
7465a988416SJim Ingham         return &m_options;
7475a988416SJim Ingham     }
7485a988416SJim Ingham 
7495a988416SJim Ingham     class CommandOptions : public Options
7505a988416SJim Ingham     {
7515a988416SJim Ingham     public:
7525a988416SJim Ingham 
7535a988416SJim Ingham         CommandOptions (CommandInterpreter &interpreter) :
7545a988416SJim Ingham             Options (interpreter),
7555a988416SJim Ingham             m_ignore_count (0),
7565a988416SJim Ingham             m_thread_id(LLDB_INVALID_THREAD_ID),
7575a988416SJim Ingham             m_thread_id_passed(false),
7585a988416SJim Ingham             m_thread_index (UINT32_MAX),
7595a988416SJim Ingham             m_thread_index_passed(false),
7605a988416SJim Ingham             m_thread_name(),
7615a988416SJim Ingham             m_queue_name(),
7625a988416SJim Ingham             m_condition (),
763ca36cd16SJim Ingham             m_one_shot (false),
7645a988416SJim Ingham             m_enable_passed (false),
7655a988416SJim Ingham             m_enable_value (false),
7665a988416SJim Ingham             m_name_passed (false),
7675a988416SJim Ingham             m_queue_passed (false),
768ca36cd16SJim Ingham             m_condition_passed (false),
769ca36cd16SJim Ingham             m_one_shot_passed (false)
7705a988416SJim Ingham         {
7715a988416SJim Ingham         }
7725a988416SJim Ingham 
7735a988416SJim Ingham         virtual
7745a988416SJim Ingham         ~CommandOptions () {}
7755a988416SJim Ingham 
7765a988416SJim Ingham         virtual Error
7775a988416SJim Ingham         SetOptionValue (uint32_t option_idx, const char *option_arg)
7785a988416SJim Ingham         {
7795a988416SJim Ingham             Error error;
7803bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
7815a988416SJim Ingham 
7825a988416SJim Ingham             switch (short_option)
7835a988416SJim Ingham             {
7845a988416SJim Ingham                 case 'c':
7855a988416SJim Ingham                     if (option_arg != NULL)
7865a988416SJim Ingham                         m_condition.assign (option_arg);
7875a988416SJim Ingham                     else
7885a988416SJim Ingham                         m_condition.clear();
7895a988416SJim Ingham                     m_condition_passed = true;
7905a988416SJim Ingham                     break;
7915a988416SJim Ingham                 case 'd':
7925a988416SJim Ingham                     m_enable_passed = true;
7935a988416SJim Ingham                     m_enable_value = false;
7945a988416SJim Ingham                     break;
7955a988416SJim Ingham                 case 'e':
7965a988416SJim Ingham                     m_enable_passed = true;
7975a988416SJim Ingham                     m_enable_value = true;
7985a988416SJim Ingham                     break;
7995a988416SJim Ingham                 case 'i':
8005a988416SJim Ingham                 {
8015a988416SJim Ingham                     m_ignore_count = Args::StringToUInt32(option_arg, UINT32_MAX, 0);
8025a988416SJim Ingham                     if (m_ignore_count == UINT32_MAX)
8035a988416SJim Ingham                        error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
8045a988416SJim Ingham                 }
8055a988416SJim Ingham                 break;
806ca36cd16SJim Ingham                 case 'o':
807ca36cd16SJim Ingham                 {
808ca36cd16SJim Ingham                     bool value, success;
809ca36cd16SJim Ingham                     value = Args::StringToBoolean(option_arg, false, &success);
810ca36cd16SJim Ingham                     if (success)
811ca36cd16SJim Ingham                     {
812ca36cd16SJim Ingham                         m_one_shot_passed = true;
813ca36cd16SJim Ingham                         m_one_shot = value;
814ca36cd16SJim Ingham                     }
815ca36cd16SJim Ingham                     else
816ca36cd16SJim Ingham                         error.SetErrorStringWithFormat("invalid boolean value '%s' passed for -o option", option_arg);
817ca36cd16SJim Ingham                 }
818ca36cd16SJim Ingham                 break;
8195a988416SJim Ingham                 case 't' :
8205a988416SJim Ingham                 {
8215a988416SJim Ingham                     if (option_arg[0] == '\0')
8225a988416SJim Ingham                     {
8235a988416SJim Ingham                         m_thread_id = LLDB_INVALID_THREAD_ID;
8245a988416SJim Ingham                         m_thread_id_passed = true;
8255a988416SJim Ingham                     }
8265a988416SJim Ingham                     else
8275a988416SJim Ingham                     {
8285a988416SJim Ingham                         m_thread_id = Args::StringToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
8295a988416SJim Ingham                         if (m_thread_id == LLDB_INVALID_THREAD_ID)
8305a988416SJim Ingham                            error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
8315a988416SJim Ingham                         else
8325a988416SJim Ingham                             m_thread_id_passed = true;
8335a988416SJim Ingham                     }
8345a988416SJim Ingham                 }
8355a988416SJim Ingham                 break;
8365a988416SJim Ingham                 case 'T':
8375a988416SJim Ingham                     if (option_arg != NULL)
8385a988416SJim Ingham                         m_thread_name.assign (option_arg);
8395a988416SJim Ingham                     else
8405a988416SJim Ingham                         m_thread_name.clear();
8415a988416SJim Ingham                     m_name_passed = true;
8425a988416SJim Ingham                     break;
8435a988416SJim Ingham                 case 'q':
8445a988416SJim Ingham                     if (option_arg != NULL)
8455a988416SJim Ingham                         m_queue_name.assign (option_arg);
8465a988416SJim Ingham                     else
8475a988416SJim Ingham                         m_queue_name.clear();
8485a988416SJim Ingham                     m_queue_passed = true;
8495a988416SJim Ingham                     break;
8505a988416SJim Ingham                 case 'x':
8515a988416SJim Ingham                 {
8525a988416SJim Ingham                     if (option_arg[0] == '\n')
8535a988416SJim Ingham                     {
8545a988416SJim Ingham                         m_thread_index = UINT32_MAX;
8555a988416SJim Ingham                         m_thread_index_passed = true;
8565a988416SJim Ingham                     }
8575a988416SJim Ingham                     else
8585a988416SJim Ingham                     {
8595a988416SJim Ingham                         m_thread_index = Args::StringToUInt32 (option_arg, UINT32_MAX, 0);
8605a988416SJim Ingham                         if (m_thread_id == UINT32_MAX)
8615a988416SJim Ingham                            error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
8625a988416SJim Ingham                         else
8635a988416SJim Ingham                             m_thread_index_passed = true;
8645a988416SJim Ingham                     }
8655a988416SJim Ingham                 }
8665a988416SJim Ingham                 break;
8675a988416SJim Ingham                 default:
8685a988416SJim Ingham                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
8695a988416SJim Ingham                     break;
8705a988416SJim Ingham             }
8715a988416SJim Ingham 
8725a988416SJim Ingham             return error;
8735a988416SJim Ingham         }
8745a988416SJim Ingham         void
8755a988416SJim Ingham         OptionParsingStarting ()
8765a988416SJim Ingham         {
8775a988416SJim Ingham             m_ignore_count = 0;
8785a988416SJim Ingham             m_thread_id = LLDB_INVALID_THREAD_ID;
8795a988416SJim Ingham             m_thread_id_passed = false;
8805a988416SJim Ingham             m_thread_index = UINT32_MAX;
8815a988416SJim Ingham             m_thread_index_passed = false;
8825a988416SJim Ingham             m_thread_name.clear();
8835a988416SJim Ingham             m_queue_name.clear();
8845a988416SJim Ingham             m_condition.clear();
885ca36cd16SJim Ingham             m_one_shot = false;
8865a988416SJim Ingham             m_enable_passed = false;
8875a988416SJim Ingham             m_queue_passed = false;
8885a988416SJim Ingham             m_name_passed = false;
8895a988416SJim Ingham             m_condition_passed = false;
890ca36cd16SJim Ingham             m_one_shot_passed = false;
8915a988416SJim Ingham         }
8925a988416SJim Ingham 
8935a988416SJim Ingham         const OptionDefinition*
8945a988416SJim Ingham         GetDefinitions ()
8955a988416SJim Ingham         {
8965a988416SJim Ingham             return g_option_table;
8975a988416SJim Ingham         }
8985a988416SJim Ingham 
8995a988416SJim Ingham 
9005a988416SJim Ingham         // Options table: Required for subclasses of Options.
9015a988416SJim Ingham 
9025a988416SJim Ingham         static OptionDefinition g_option_table[];
9035a988416SJim Ingham 
9045a988416SJim Ingham         // Instance variables to hold the values for command options.
9055a988416SJim Ingham 
9065a988416SJim Ingham         uint32_t m_ignore_count;
9075a988416SJim Ingham         lldb::tid_t m_thread_id;
9085a988416SJim Ingham         bool m_thread_id_passed;
9095a988416SJim Ingham         uint32_t m_thread_index;
9105a988416SJim Ingham         bool m_thread_index_passed;
9115a988416SJim Ingham         std::string m_thread_name;
9125a988416SJim Ingham         std::string m_queue_name;
9135a988416SJim Ingham         std::string m_condition;
914ca36cd16SJim Ingham         bool m_one_shot;
9155a988416SJim Ingham         bool m_enable_passed;
9165a988416SJim Ingham         bool m_enable_value;
9175a988416SJim Ingham         bool m_name_passed;
9185a988416SJim Ingham         bool m_queue_passed;
9195a988416SJim Ingham         bool m_condition_passed;
920ca36cd16SJim Ingham         bool m_one_shot_passed;
9215a988416SJim Ingham 
9225a988416SJim Ingham     };
9235a988416SJim Ingham 
9245a988416SJim Ingham protected:
9255a988416SJim Ingham     virtual bool
9265a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
9275a988416SJim Ingham     {
9285a988416SJim Ingham         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
9295a988416SJim Ingham         if (target == NULL)
9305a988416SJim Ingham         {
9315a988416SJim Ingham             result.AppendError ("Invalid target.  No existing target or breakpoints.");
9325a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
9335a988416SJim Ingham             return false;
9345a988416SJim Ingham         }
9355a988416SJim Ingham 
9365a988416SJim Ingham         Mutex::Locker locker;
9375a988416SJim Ingham         target->GetBreakpointList().GetListMutex(locker);
9385a988416SJim Ingham 
9395a988416SJim Ingham         BreakpointIDList valid_bp_ids;
9405a988416SJim Ingham 
9415a988416SJim Ingham         CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
9425a988416SJim Ingham 
9435a988416SJim Ingham         if (result.Succeeded())
9445a988416SJim Ingham         {
9455a988416SJim Ingham             const size_t count = valid_bp_ids.GetSize();
9465a988416SJim Ingham             for (size_t i = 0; i < count; ++i)
9475a988416SJim Ingham             {
9485a988416SJim Ingham                 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
9495a988416SJim Ingham 
9505a988416SJim Ingham                 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
9515a988416SJim Ingham                 {
9525a988416SJim Ingham                     Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
9535a988416SJim Ingham                     if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
9545a988416SJim Ingham                     {
9555a988416SJim Ingham                         BreakpointLocation *location = bp->FindLocationByID (cur_bp_id.GetLocationID()).get();
9565a988416SJim Ingham                         if (location)
9575a988416SJim Ingham                         {
9585a988416SJim Ingham                             if (m_options.m_thread_id_passed)
9595a988416SJim Ingham                                 location->SetThreadID (m_options.m_thread_id);
9605a988416SJim Ingham 
9615a988416SJim Ingham                             if (m_options.m_thread_index_passed)
9625a988416SJim Ingham                                 location->SetThreadIndex(m_options.m_thread_index);
9635a988416SJim Ingham 
9645a988416SJim Ingham                             if (m_options.m_name_passed)
9655a988416SJim Ingham                                 location->SetThreadName(m_options.m_thread_name.c_str());
9665a988416SJim Ingham 
9675a988416SJim Ingham                             if (m_options.m_queue_passed)
9685a988416SJim Ingham                                 location->SetQueueName(m_options.m_queue_name.c_str());
9695a988416SJim Ingham 
9705a988416SJim Ingham                             if (m_options.m_ignore_count != 0)
9715a988416SJim Ingham                                 location->SetIgnoreCount(m_options.m_ignore_count);
9725a988416SJim Ingham 
9735a988416SJim Ingham                             if (m_options.m_enable_passed)
9745a988416SJim Ingham                                 location->SetEnabled (m_options.m_enable_value);
9755a988416SJim Ingham 
9765a988416SJim Ingham                             if (m_options.m_condition_passed)
9775a988416SJim Ingham                                 location->SetCondition (m_options.m_condition.c_str());
9785a988416SJim Ingham                         }
9795a988416SJim Ingham                     }
9805a988416SJim Ingham                     else
9815a988416SJim Ingham                     {
9825a988416SJim Ingham                         if (m_options.m_thread_id_passed)
9835a988416SJim Ingham                             bp->SetThreadID (m_options.m_thread_id);
9845a988416SJim Ingham 
9855a988416SJim Ingham                         if (m_options.m_thread_index_passed)
9865a988416SJim Ingham                             bp->SetThreadIndex(m_options.m_thread_index);
9875a988416SJim Ingham 
9885a988416SJim Ingham                         if (m_options.m_name_passed)
9895a988416SJim Ingham                             bp->SetThreadName(m_options.m_thread_name.c_str());
9905a988416SJim Ingham 
9915a988416SJim Ingham                         if (m_options.m_queue_passed)
9925a988416SJim Ingham                             bp->SetQueueName(m_options.m_queue_name.c_str());
9935a988416SJim Ingham 
9945a988416SJim Ingham                         if (m_options.m_ignore_count != 0)
9955a988416SJim Ingham                             bp->SetIgnoreCount(m_options.m_ignore_count);
9965a988416SJim Ingham 
9975a988416SJim Ingham                         if (m_options.m_enable_passed)
9985a988416SJim Ingham                             bp->SetEnabled (m_options.m_enable_value);
9995a988416SJim Ingham 
10005a988416SJim Ingham                         if (m_options.m_condition_passed)
10015a988416SJim Ingham                             bp->SetCondition (m_options.m_condition.c_str());
10025a988416SJim Ingham                     }
10035a988416SJim Ingham                 }
10045a988416SJim Ingham             }
10055a988416SJim Ingham         }
10065a988416SJim Ingham 
10075a988416SJim Ingham         return result.Succeeded();
10085a988416SJim Ingham     }
10095a988416SJim Ingham 
10105a988416SJim Ingham private:
10115a988416SJim Ingham     CommandOptions m_options;
10125a988416SJim Ingham };
10135a988416SJim Ingham 
10145a988416SJim Ingham #pragma mark Modify::CommandOptions
10155a988416SJim Ingham OptionDefinition
10165a988416SJim Ingham CommandObjectBreakpointModify::CommandOptions::g_option_table[] =
10175a988416SJim Ingham {
1018*d37221dcSZachary 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." },
1019*d37221dcSZachary 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." },
1020*d37221dcSZachary 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."},
1021*d37221dcSZachary 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."},
1022*d37221dcSZachary 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."},
1023*d37221dcSZachary 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."},
1024*d37221dcSZachary 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."},
1025*d37221dcSZachary Turner { LLDB_OPT_SET_1,   false, "enable",       'e', OptionParser::eNoArgument,       NULL, NULL, 0, eArgTypeNone, "Enable the breakpoint."},
1026*d37221dcSZachary Turner { LLDB_OPT_SET_2,   false, "disable",      'd', OptionParser::eNoArgument,       NULL, NULL, 0, eArgTypeNone, "Disable the breakpoint."},
1027*d37221dcSZachary Turner { 0,                false, NULL,            0 , 0,                 NULL, NULL, 0, eArgTypeNone, NULL }
10285a988416SJim Ingham };
10295a988416SJim Ingham 
10305a988416SJim Ingham //-------------------------------------------------------------------------
10315a988416SJim Ingham // CommandObjectBreakpointEnable
10325a988416SJim Ingham //-------------------------------------------------------------------------
10335a988416SJim Ingham #pragma mark Enable
10345a988416SJim Ingham 
10355a988416SJim Ingham class CommandObjectBreakpointEnable : public CommandObjectParsed
10365a988416SJim Ingham {
10375a988416SJim Ingham public:
10385a988416SJim Ingham     CommandObjectBreakpointEnable (CommandInterpreter &interpreter) :
10395a988416SJim Ingham         CommandObjectParsed (interpreter,
10405a988416SJim Ingham                              "enable",
10415a988416SJim Ingham                              "Enable the specified disabled breakpoint(s). If no breakpoints are specified, enable all of them.",
10425a988416SJim Ingham                              NULL)
10435a988416SJim Ingham     {
10445a988416SJim Ingham         CommandArgumentEntry arg;
10455a988416SJim Ingham         CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
10465a988416SJim Ingham         // Add the entry for the first argument for this command to the object's arguments vector.
10475a988416SJim Ingham         m_arguments.push_back (arg);
10485a988416SJim Ingham     }
10495a988416SJim Ingham 
10505a988416SJim Ingham 
10515a988416SJim Ingham     virtual
10525a988416SJim Ingham     ~CommandObjectBreakpointEnable () {}
10535a988416SJim Ingham 
10545a988416SJim Ingham protected:
10555a988416SJim Ingham     virtual bool
10565a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
10575a988416SJim Ingham     {
10585a988416SJim Ingham         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
10595a988416SJim Ingham         if (target == NULL)
10605a988416SJim Ingham         {
10615a988416SJim Ingham             result.AppendError ("Invalid target.  No existing target or breakpoints.");
10625a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
10635a988416SJim Ingham             return false;
10645a988416SJim Ingham         }
10655a988416SJim Ingham 
10665a988416SJim Ingham         Mutex::Locker locker;
10675a988416SJim Ingham         target->GetBreakpointList().GetListMutex(locker);
10685a988416SJim Ingham 
10695a988416SJim Ingham         const BreakpointList &breakpoints = target->GetBreakpointList();
10705a988416SJim Ingham 
10715a988416SJim Ingham         size_t num_breakpoints = breakpoints.GetSize();
10725a988416SJim Ingham 
10735a988416SJim Ingham         if (num_breakpoints == 0)
10745a988416SJim Ingham         {
10755a988416SJim Ingham             result.AppendError ("No breakpoints exist to be enabled.");
10765a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
10775a988416SJim Ingham             return false;
10785a988416SJim Ingham         }
10795a988416SJim Ingham 
10805a988416SJim Ingham         if (command.GetArgumentCount() == 0)
10815a988416SJim Ingham         {
10825a988416SJim Ingham             // No breakpoint selected; enable all currently set breakpoints.
10835a988416SJim Ingham             target->EnableAllBreakpoints ();
10846fea17e8SGreg Clayton             result.AppendMessageWithFormat ("All breakpoints enabled. (%" PRIu64 " breakpoints)\n", (uint64_t)num_breakpoints);
10855a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
10865a988416SJim Ingham         }
10875a988416SJim Ingham         else
10885a988416SJim Ingham         {
10895a988416SJim Ingham             // Particular breakpoint selected; enable that breakpoint.
10905a988416SJim Ingham             BreakpointIDList valid_bp_ids;
10915a988416SJim Ingham             CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
10925a988416SJim Ingham 
10935a988416SJim Ingham             if (result.Succeeded())
10945a988416SJim Ingham             {
10955a988416SJim Ingham                 int enable_count = 0;
10965a988416SJim Ingham                 int loc_count = 0;
10975a988416SJim Ingham                 const size_t count = valid_bp_ids.GetSize();
10985a988416SJim Ingham                 for (size_t i = 0; i < count; ++i)
10995a988416SJim Ingham                 {
11005a988416SJim Ingham                     BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
11015a988416SJim Ingham 
11025a988416SJim Ingham                     if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
11035a988416SJim Ingham                     {
11045a988416SJim Ingham                         Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
11055a988416SJim Ingham                         if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
11065a988416SJim Ingham                         {
11075a988416SJim Ingham                             BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
11085a988416SJim Ingham                             if (location)
11095a988416SJim Ingham                             {
11105a988416SJim Ingham                                 location->SetEnabled (true);
11115a988416SJim Ingham                                 ++loc_count;
11125a988416SJim Ingham                             }
11135a988416SJim Ingham                         }
11145a988416SJim Ingham                         else
11155a988416SJim Ingham                         {
11165a988416SJim Ingham                             breakpoint->SetEnabled (true);
11175a988416SJim Ingham                             ++enable_count;
11185a988416SJim Ingham                         }
11195a988416SJim Ingham                     }
11205a988416SJim Ingham                 }
11215a988416SJim Ingham                 result.AppendMessageWithFormat ("%d breakpoints enabled.\n", enable_count + loc_count);
11225a988416SJim Ingham                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
11235a988416SJim Ingham             }
11245a988416SJim Ingham         }
11255a988416SJim Ingham 
11265a988416SJim Ingham         return result.Succeeded();
11275a988416SJim Ingham     }
11285a988416SJim Ingham };
11295a988416SJim Ingham 
11305a988416SJim Ingham //-------------------------------------------------------------------------
11315a988416SJim Ingham // CommandObjectBreakpointDisable
11325a988416SJim Ingham //-------------------------------------------------------------------------
11335a988416SJim Ingham #pragma mark Disable
11345a988416SJim Ingham 
11355a988416SJim Ingham class CommandObjectBreakpointDisable : public CommandObjectParsed
11365a988416SJim Ingham {
11375a988416SJim Ingham public:
11385a988416SJim Ingham     CommandObjectBreakpointDisable (CommandInterpreter &interpreter) :
11395a988416SJim Ingham         CommandObjectParsed (interpreter,
11405a988416SJim Ingham                              "breakpoint disable",
11415a988416SJim Ingham                              "Disable the specified breakpoint(s) without removing it/them.  If no breakpoints are specified, disable them all.",
11425a988416SJim Ingham                              NULL)
11435a988416SJim Ingham     {
1144b0fac509SJim Ingham         SetHelpLong(
1145b0fac509SJim Ingham "Disable the specified breakpoint(s) without removing it/them.  \n\
1146b0fac509SJim Ingham If no breakpoints are specified, disable them all.\n\
1147b0fac509SJim Ingham \n\
1148b0fac509SJim Ingham Note: disabling a breakpoint will cause none of its locations to be hit\n\
1149b0fac509SJim Ingham regardless of whether they are enabled or disabled.  So the sequence: \n\
1150b0fac509SJim Ingham \n\
1151b0fac509SJim Ingham     (lldb) break disable 1\n\
1152b0fac509SJim Ingham     (lldb) break enable 1.1\n\
1153b0fac509SJim Ingham \n\
1154b0fac509SJim Ingham will NOT cause location 1.1 to get hit.  To achieve that, do:\n\
1155b0fac509SJim Ingham \n\
1156b0fac509SJim Ingham     (lldb) break disable 1.*\n\
1157b0fac509SJim Ingham     (lldb) break enable 1.1\n\
1158b0fac509SJim Ingham \n\
1159b0fac509SJim Ingham The first command disables all the locations of breakpoint 1, \n\
1160b0fac509SJim Ingham the second re-enables the first location."
1161b0fac509SJim Ingham                     );
1162b0fac509SJim Ingham 
11635a988416SJim Ingham         CommandArgumentEntry arg;
11645a988416SJim Ingham         CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
11655a988416SJim Ingham         // Add the entry for the first argument for this command to the object's arguments vector.
11665a988416SJim Ingham         m_arguments.push_back (arg);
1167b0fac509SJim Ingham 
11685a988416SJim Ingham     }
11695a988416SJim Ingham 
11705a988416SJim Ingham 
11715a988416SJim Ingham     virtual
11725a988416SJim Ingham     ~CommandObjectBreakpointDisable () {}
11735a988416SJim Ingham 
11745a988416SJim Ingham protected:
11755a988416SJim Ingham     virtual bool
11765a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
11775a988416SJim Ingham     {
11785a988416SJim Ingham         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
11795a988416SJim Ingham         if (target == NULL)
11805a988416SJim Ingham         {
11815a988416SJim Ingham             result.AppendError ("Invalid target.  No existing target or breakpoints.");
11825a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
11835a988416SJim Ingham             return false;
11845a988416SJim Ingham         }
11855a988416SJim Ingham 
11865a988416SJim Ingham         Mutex::Locker locker;
11875a988416SJim Ingham         target->GetBreakpointList().GetListMutex(locker);
11885a988416SJim Ingham 
11895a988416SJim Ingham         const BreakpointList &breakpoints = target->GetBreakpointList();
11905a988416SJim Ingham         size_t num_breakpoints = breakpoints.GetSize();
11915a988416SJim Ingham 
11925a988416SJim Ingham         if (num_breakpoints == 0)
11935a988416SJim Ingham         {
11945a988416SJim Ingham             result.AppendError ("No breakpoints exist to be disabled.");
11955a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
11965a988416SJim Ingham             return false;
11975a988416SJim Ingham         }
11985a988416SJim Ingham 
11995a988416SJim Ingham         if (command.GetArgumentCount() == 0)
12005a988416SJim Ingham         {
12015a988416SJim Ingham             // No breakpoint selected; disable all currently set breakpoints.
12025a988416SJim Ingham             target->DisableAllBreakpoints ();
12036fea17e8SGreg Clayton             result.AppendMessageWithFormat ("All breakpoints disabled. (%" PRIu64 " breakpoints)\n", (uint64_t)num_breakpoints);
12045a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
12055a988416SJim Ingham         }
12065a988416SJim Ingham         else
12075a988416SJim Ingham         {
12085a988416SJim Ingham             // Particular breakpoint selected; disable that breakpoint.
12095a988416SJim Ingham             BreakpointIDList valid_bp_ids;
12105a988416SJim Ingham 
12115a988416SJim Ingham             CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
12125a988416SJim Ingham 
12135a988416SJim Ingham             if (result.Succeeded())
12145a988416SJim Ingham             {
12155a988416SJim Ingham                 int disable_count = 0;
12165a988416SJim Ingham                 int loc_count = 0;
12175a988416SJim Ingham                 const size_t count = valid_bp_ids.GetSize();
12185a988416SJim Ingham                 for (size_t i = 0; i < count; ++i)
12195a988416SJim Ingham                 {
12205a988416SJim Ingham                     BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
12215a988416SJim Ingham 
12225a988416SJim Ingham                     if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
12235a988416SJim Ingham                     {
12245a988416SJim Ingham                         Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
12255a988416SJim Ingham                         if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
12265a988416SJim Ingham                         {
12275a988416SJim Ingham                             BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
12285a988416SJim Ingham                             if (location)
12295a988416SJim Ingham                             {
12305a988416SJim Ingham                                 location->SetEnabled (false);
12315a988416SJim Ingham                                 ++loc_count;
12325a988416SJim Ingham                             }
12335a988416SJim Ingham                         }
12345a988416SJim Ingham                         else
12355a988416SJim Ingham                         {
12365a988416SJim Ingham                             breakpoint->SetEnabled (false);
12375a988416SJim Ingham                             ++disable_count;
12385a988416SJim Ingham                         }
12395a988416SJim Ingham                     }
12405a988416SJim Ingham                 }
12415a988416SJim Ingham                 result.AppendMessageWithFormat ("%d breakpoints disabled.\n", disable_count + loc_count);
12425a988416SJim Ingham                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
12435a988416SJim Ingham             }
12445a988416SJim Ingham         }
12455a988416SJim Ingham 
12465a988416SJim Ingham         return result.Succeeded();
12475a988416SJim Ingham     }
12485a988416SJim Ingham 
12495a988416SJim Ingham };
12505a988416SJim Ingham 
12515a988416SJim Ingham //-------------------------------------------------------------------------
12525a988416SJim Ingham // CommandObjectBreakpointList
12535a988416SJim Ingham //-------------------------------------------------------------------------
12545a988416SJim Ingham #pragma mark List
12555a988416SJim Ingham 
12565a988416SJim Ingham class CommandObjectBreakpointList : public CommandObjectParsed
12575a988416SJim Ingham {
12585a988416SJim Ingham public:
12595a988416SJim Ingham     CommandObjectBreakpointList (CommandInterpreter &interpreter) :
12605a988416SJim Ingham         CommandObjectParsed (interpreter,
12615a988416SJim Ingham                              "breakpoint list",
12625a988416SJim Ingham                              "List some or all breakpoints at configurable levels of detail.",
12635a988416SJim Ingham                              NULL),
12645a988416SJim Ingham         m_options (interpreter)
12655a988416SJim Ingham     {
12665a988416SJim Ingham         CommandArgumentEntry arg;
12675a988416SJim Ingham         CommandArgumentData bp_id_arg;
12685a988416SJim Ingham 
12695a988416SJim Ingham         // Define the first (and only) variant of this arg.
12705a988416SJim Ingham         bp_id_arg.arg_type = eArgTypeBreakpointID;
12715a988416SJim Ingham         bp_id_arg.arg_repetition = eArgRepeatOptional;
12725a988416SJim Ingham 
12735a988416SJim Ingham         // There is only one variant this argument could be; put it into the argument entry.
12745a988416SJim Ingham         arg.push_back (bp_id_arg);
12755a988416SJim Ingham 
12765a988416SJim Ingham         // Push the data for the first argument into the m_arguments vector.
12775a988416SJim Ingham         m_arguments.push_back (arg);
12785a988416SJim Ingham     }
12795a988416SJim Ingham 
12805a988416SJim Ingham 
12815a988416SJim Ingham     virtual
12825a988416SJim Ingham     ~CommandObjectBreakpointList () {}
12835a988416SJim Ingham 
12845a988416SJim Ingham     virtual Options *
12855a988416SJim Ingham     GetOptions ()
12865a988416SJim Ingham     {
12875a988416SJim Ingham         return &m_options;
12885a988416SJim Ingham     }
12895a988416SJim Ingham 
12905a988416SJim Ingham     class CommandOptions : public Options
12915a988416SJim Ingham     {
12925a988416SJim Ingham     public:
12935a988416SJim Ingham 
12945a988416SJim Ingham         CommandOptions (CommandInterpreter &interpreter) :
12955a988416SJim Ingham             Options (interpreter),
12965a988416SJim Ingham             m_level (lldb::eDescriptionLevelBrief)  // Breakpoint List defaults to brief descriptions
12975a988416SJim Ingham         {
12985a988416SJim Ingham         }
12995a988416SJim Ingham 
13005a988416SJim Ingham         virtual
13015a988416SJim Ingham         ~CommandOptions () {}
13025a988416SJim Ingham 
13035a988416SJim Ingham         virtual Error
13045a988416SJim Ingham         SetOptionValue (uint32_t option_idx, const char *option_arg)
13055a988416SJim Ingham         {
13065a988416SJim Ingham             Error error;
13073bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
13085a988416SJim Ingham 
13095a988416SJim Ingham             switch (short_option)
13105a988416SJim Ingham             {
13115a988416SJim Ingham                 case 'b':
13125a988416SJim Ingham                     m_level = lldb::eDescriptionLevelBrief;
13135a988416SJim Ingham                     break;
13145a988416SJim Ingham                 case 'f':
13155a988416SJim Ingham                     m_level = lldb::eDescriptionLevelFull;
13165a988416SJim Ingham                     break;
13175a988416SJim Ingham                 case 'v':
13185a988416SJim Ingham                     m_level = lldb::eDescriptionLevelVerbose;
13195a988416SJim Ingham                     break;
13205a988416SJim Ingham                 case 'i':
13215a988416SJim Ingham                     m_internal = true;
13225a988416SJim Ingham                     break;
13235a988416SJim Ingham                 default:
13245a988416SJim Ingham                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
13255a988416SJim Ingham                     break;
13265a988416SJim Ingham             }
13275a988416SJim Ingham 
13285a988416SJim Ingham             return error;
13295a988416SJim Ingham         }
13305a988416SJim Ingham 
13315a988416SJim Ingham         void
13325a988416SJim Ingham         OptionParsingStarting ()
13335a988416SJim Ingham         {
13345a988416SJim Ingham             m_level = lldb::eDescriptionLevelFull;
13355a988416SJim Ingham             m_internal = false;
13365a988416SJim Ingham         }
13375a988416SJim Ingham 
13385a988416SJim Ingham         const OptionDefinition *
13395a988416SJim Ingham         GetDefinitions ()
13405a988416SJim Ingham         {
13415a988416SJim Ingham             return g_option_table;
13425a988416SJim Ingham         }
13435a988416SJim Ingham 
13445a988416SJim Ingham         // Options table: Required for subclasses of Options.
13455a988416SJim Ingham 
13465a988416SJim Ingham         static OptionDefinition g_option_table[];
13475a988416SJim Ingham 
13485a988416SJim Ingham         // Instance variables to hold the values for command options.
13495a988416SJim Ingham 
13505a988416SJim Ingham         lldb::DescriptionLevel m_level;
13515a988416SJim Ingham 
13525a988416SJim Ingham         bool m_internal;
13535a988416SJim Ingham     };
13545a988416SJim Ingham 
13555a988416SJim Ingham protected:
13565a988416SJim Ingham     virtual bool
13575a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
13585a988416SJim Ingham     {
13595a988416SJim Ingham         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
13605a988416SJim Ingham         if (target == NULL)
13615a988416SJim Ingham         {
13625a988416SJim Ingham             result.AppendError ("Invalid target. No current target or breakpoints.");
13635a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
13645a988416SJim Ingham             return true;
13655a988416SJim Ingham         }
13665a988416SJim Ingham 
13675a988416SJim Ingham         const BreakpointList &breakpoints = target->GetBreakpointList(m_options.m_internal);
13685a988416SJim Ingham         Mutex::Locker locker;
13695a988416SJim Ingham         target->GetBreakpointList(m_options.m_internal).GetListMutex(locker);
13705a988416SJim Ingham 
13715a988416SJim Ingham         size_t num_breakpoints = breakpoints.GetSize();
13725a988416SJim Ingham 
13735a988416SJim Ingham         if (num_breakpoints == 0)
13745a988416SJim Ingham         {
13755a988416SJim Ingham             result.AppendMessage ("No breakpoints currently set.");
13765a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
13775a988416SJim Ingham             return true;
13785a988416SJim Ingham         }
13795a988416SJim Ingham 
13805a988416SJim Ingham         Stream &output_stream = result.GetOutputStream();
13815a988416SJim Ingham 
13825a988416SJim Ingham         if (command.GetArgumentCount() == 0)
13835a988416SJim Ingham         {
13845a988416SJim Ingham             // No breakpoint selected; show info about all currently set breakpoints.
13855a988416SJim Ingham             result.AppendMessage ("Current breakpoints:");
13865a988416SJim Ingham             for (size_t i = 0; i < num_breakpoints; ++i)
13875a988416SJim Ingham             {
13885a988416SJim Ingham                 Breakpoint *breakpoint = breakpoints.GetBreakpointAtIndex (i).get();
13895a988416SJim Ingham                 AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
13905a988416SJim Ingham             }
13915a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
13925a988416SJim Ingham         }
13935a988416SJim Ingham         else
13945a988416SJim Ingham         {
13955a988416SJim Ingham             // Particular breakpoints selected; show info about that breakpoint.
13965a988416SJim Ingham             BreakpointIDList valid_bp_ids;
13975a988416SJim Ingham             CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
13985a988416SJim Ingham 
13995a988416SJim Ingham             if (result.Succeeded())
14005a988416SJim Ingham             {
14015a988416SJim Ingham                 for (size_t i = 0; i < valid_bp_ids.GetSize(); ++i)
14025a988416SJim Ingham                 {
14035a988416SJim Ingham                     BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
14045a988416SJim Ingham                     Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
14055a988416SJim Ingham                     AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
14065a988416SJim Ingham                 }
14075a988416SJim Ingham                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
14085a988416SJim Ingham             }
14095a988416SJim Ingham             else
14105a988416SJim Ingham             {
14115a988416SJim Ingham                 result.AppendError ("Invalid breakpoint id.");
14125a988416SJim Ingham                 result.SetStatus (eReturnStatusFailed);
14135a988416SJim Ingham             }
14145a988416SJim Ingham         }
14155a988416SJim Ingham 
14165a988416SJim Ingham         return result.Succeeded();
14175a988416SJim Ingham     }
14185a988416SJim Ingham 
14195a988416SJim Ingham private:
14205a988416SJim Ingham     CommandOptions m_options;
14215a988416SJim Ingham };
14225a988416SJim Ingham 
14235a988416SJim Ingham #pragma mark List::CommandOptions
14245a988416SJim Ingham OptionDefinition
14255a988416SJim Ingham CommandObjectBreakpointList::CommandOptions::g_option_table[] =
14265a988416SJim Ingham {
1427*d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "internal", 'i', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
14285a988416SJim Ingham         "Show debugger internal breakpoints" },
14295a988416SJim Ingham 
1430*d37221dcSZachary Turner     { LLDB_OPT_SET_1, false, "brief",    'b', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
14315a988416SJim Ingham         "Give a brief description of the breakpoint (no location info)."},
14325a988416SJim Ingham 
14335a988416SJim Ingham     // FIXME: We need to add an "internal" command, and then add this sort of thing to it.
14345a988416SJim Ingham     // But I need to see it for now, and don't want to wait.
1435*d37221dcSZachary Turner     { LLDB_OPT_SET_2, false, "full",    'f', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
14365a988416SJim Ingham         "Give a full description of the breakpoint and its locations."},
14375a988416SJim Ingham 
1438*d37221dcSZachary Turner     { LLDB_OPT_SET_3, false, "verbose", 'v', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
14395a988416SJim Ingham         "Explain everything we know about the breakpoint (for debugging debugger bugs)." },
14405a988416SJim Ingham 
1441*d37221dcSZachary Turner     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
14425a988416SJim Ingham };
14435a988416SJim Ingham 
14445a988416SJim Ingham //-------------------------------------------------------------------------
14455a988416SJim Ingham // CommandObjectBreakpointClear
14465a988416SJim Ingham //-------------------------------------------------------------------------
14475a988416SJim Ingham #pragma mark Clear
14485a988416SJim Ingham 
14495a988416SJim Ingham class CommandObjectBreakpointClear : public CommandObjectParsed
14505a988416SJim Ingham {
14515a988416SJim Ingham public:
14525a988416SJim Ingham 
14535a988416SJim Ingham     typedef enum BreakpointClearType
14545a988416SJim Ingham     {
14555a988416SJim Ingham         eClearTypeInvalid,
14565a988416SJim Ingham         eClearTypeFileAndLine
14575a988416SJim Ingham     } BreakpointClearType;
14585a988416SJim Ingham 
14595a988416SJim Ingham     CommandObjectBreakpointClear (CommandInterpreter &interpreter) :
14605a988416SJim Ingham         CommandObjectParsed (interpreter,
14615a988416SJim Ingham                              "breakpoint clear",
14625a988416SJim Ingham                              "Clears a breakpoint or set of breakpoints in the executable.",
14635a988416SJim Ingham                              "breakpoint clear <cmd-options>"),
14645a988416SJim Ingham         m_options (interpreter)
14655a988416SJim Ingham     {
14665a988416SJim Ingham     }
14675a988416SJim Ingham 
14685a988416SJim Ingham     virtual
14695a988416SJim Ingham     ~CommandObjectBreakpointClear () {}
14705a988416SJim Ingham 
14715a988416SJim Ingham     virtual Options *
14725a988416SJim Ingham     GetOptions ()
14735a988416SJim Ingham     {
14745a988416SJim Ingham         return &m_options;
14755a988416SJim Ingham     }
14765a988416SJim Ingham 
14775a988416SJim Ingham     class CommandOptions : public Options
14785a988416SJim Ingham     {
14795a988416SJim Ingham     public:
14805a988416SJim Ingham 
14815a988416SJim Ingham         CommandOptions (CommandInterpreter &interpreter) :
14825a988416SJim Ingham             Options (interpreter),
14835a988416SJim Ingham             m_filename (),
14845a988416SJim Ingham             m_line_num (0)
14855a988416SJim Ingham         {
14865a988416SJim Ingham         }
14875a988416SJim Ingham 
14885a988416SJim Ingham         virtual
14895a988416SJim Ingham         ~CommandOptions () {}
14905a988416SJim Ingham 
14915a988416SJim Ingham         virtual Error
14925a988416SJim Ingham         SetOptionValue (uint32_t option_idx, const char *option_arg)
14935a988416SJim Ingham         {
14945a988416SJim Ingham             Error error;
14953bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
14965a988416SJim Ingham 
14975a988416SJim Ingham             switch (short_option)
14985a988416SJim Ingham             {
14995a988416SJim Ingham                 case 'f':
15005a988416SJim Ingham                     m_filename.assign (option_arg);
15015a988416SJim Ingham                     break;
15025a988416SJim Ingham 
15035a988416SJim Ingham                 case 'l':
15045a988416SJim Ingham                     m_line_num = Args::StringToUInt32 (option_arg, 0);
15055a988416SJim Ingham                     break;
15065a988416SJim Ingham 
15075a988416SJim Ingham                 default:
15085a988416SJim Ingham                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
15095a988416SJim Ingham                     break;
15105a988416SJim Ingham             }
15115a988416SJim Ingham 
15125a988416SJim Ingham             return error;
15135a988416SJim Ingham         }
15145a988416SJim Ingham 
15155a988416SJim Ingham         void
15165a988416SJim Ingham         OptionParsingStarting ()
15175a988416SJim Ingham         {
15185a988416SJim Ingham             m_filename.clear();
15195a988416SJim Ingham             m_line_num = 0;
15205a988416SJim Ingham         }
15215a988416SJim Ingham 
15225a988416SJim Ingham         const OptionDefinition*
15235a988416SJim Ingham         GetDefinitions ()
15245a988416SJim Ingham         {
15255a988416SJim Ingham             return g_option_table;
15265a988416SJim Ingham         }
15275a988416SJim Ingham 
15285a988416SJim Ingham         // Options table: Required for subclasses of Options.
15295a988416SJim Ingham 
15305a988416SJim Ingham         static OptionDefinition g_option_table[];
15315a988416SJim Ingham 
15325a988416SJim Ingham         // Instance variables to hold the values for command options.
15335a988416SJim Ingham 
15345a988416SJim Ingham         std::string m_filename;
15355a988416SJim Ingham         uint32_t m_line_num;
15365a988416SJim Ingham 
15375a988416SJim Ingham     };
15385a988416SJim Ingham 
15395a988416SJim Ingham protected:
15405a988416SJim Ingham     virtual bool
15415a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
15425a988416SJim Ingham     {
15435a988416SJim Ingham         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
15445a988416SJim Ingham         if (target == NULL)
15455a988416SJim Ingham         {
15465a988416SJim Ingham             result.AppendError ("Invalid target. No existing target or breakpoints.");
15475a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
15485a988416SJim Ingham             return false;
15495a988416SJim Ingham         }
15505a988416SJim Ingham 
15515a988416SJim Ingham         // The following are the various types of breakpoints that could be cleared:
15525a988416SJim Ingham         //   1). -f -l (clearing breakpoint by source location)
15535a988416SJim Ingham 
15545a988416SJim Ingham         BreakpointClearType break_type = eClearTypeInvalid;
15555a988416SJim Ingham 
15565a988416SJim Ingham         if (m_options.m_line_num != 0)
15575a988416SJim Ingham             break_type = eClearTypeFileAndLine;
15585a988416SJim Ingham 
15595a988416SJim Ingham         Mutex::Locker locker;
15605a988416SJim Ingham         target->GetBreakpointList().GetListMutex(locker);
15615a988416SJim Ingham 
15625a988416SJim Ingham         BreakpointList &breakpoints = target->GetBreakpointList();
15635a988416SJim Ingham         size_t num_breakpoints = breakpoints.GetSize();
15645a988416SJim Ingham 
15655a988416SJim Ingham         // Early return if there's no breakpoint at all.
15665a988416SJim Ingham         if (num_breakpoints == 0)
15675a988416SJim Ingham         {
15685a988416SJim Ingham             result.AppendError ("Breakpoint clear: No breakpoint cleared.");
15695a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
15705a988416SJim Ingham             return result.Succeeded();
15715a988416SJim Ingham         }
15725a988416SJim Ingham 
15735a988416SJim Ingham         // Find matching breakpoints and delete them.
15745a988416SJim Ingham 
15755a988416SJim Ingham         // First create a copy of all the IDs.
15765a988416SJim Ingham         std::vector<break_id_t> BreakIDs;
15775a988416SJim Ingham         for (size_t i = 0; i < num_breakpoints; ++i)
15785a988416SJim Ingham             BreakIDs.push_back(breakpoints.GetBreakpointAtIndex(i).get()->GetID());
15795a988416SJim Ingham 
15805a988416SJim Ingham         int num_cleared = 0;
15815a988416SJim Ingham         StreamString ss;
15825a988416SJim Ingham         switch (break_type)
15835a988416SJim Ingham         {
15845a988416SJim Ingham             case eClearTypeFileAndLine: // Breakpoint by source position
15855a988416SJim Ingham                 {
15865a988416SJim Ingham                     const ConstString filename(m_options.m_filename.c_str());
15875a988416SJim Ingham                     BreakpointLocationCollection loc_coll;
15885a988416SJim Ingham 
15895a988416SJim Ingham                     for (size_t i = 0; i < num_breakpoints; ++i)
15905a988416SJim Ingham                     {
15915a988416SJim Ingham                         Breakpoint *bp = breakpoints.FindBreakpointByID(BreakIDs[i]).get();
15925a988416SJim Ingham 
15935a988416SJim Ingham                         if (bp->GetMatchingFileLine(filename, m_options.m_line_num, loc_coll))
15945a988416SJim Ingham                         {
15955a988416SJim Ingham                             // If the collection size is 0, it's a full match and we can just remove the breakpoint.
15965a988416SJim Ingham                             if (loc_coll.GetSize() == 0)
15975a988416SJim Ingham                             {
15985a988416SJim Ingham                                 bp->GetDescription(&ss, lldb::eDescriptionLevelBrief);
15995a988416SJim Ingham                                 ss.EOL();
16005a988416SJim Ingham                                 target->RemoveBreakpointByID (bp->GetID());
16015a988416SJim Ingham                                 ++num_cleared;
16025a988416SJim Ingham                             }
16035a988416SJim Ingham                         }
16045a988416SJim Ingham                     }
16055a988416SJim Ingham                 }
16065a988416SJim Ingham                 break;
16075a988416SJim Ingham 
16085a988416SJim Ingham             default:
16095a988416SJim Ingham                 break;
16105a988416SJim Ingham         }
16115a988416SJim Ingham 
16125a988416SJim Ingham         if (num_cleared > 0)
16135a988416SJim Ingham         {
16145a988416SJim Ingham             Stream &output_stream = result.GetOutputStream();
16155a988416SJim Ingham             output_stream.Printf ("%d breakpoints cleared:\n", num_cleared);
16165a988416SJim Ingham             output_stream << ss.GetData();
16175a988416SJim Ingham             output_stream.EOL();
16185a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
16195a988416SJim Ingham         }
16205a988416SJim Ingham         else
16215a988416SJim Ingham         {
16225a988416SJim Ingham             result.AppendError ("Breakpoint clear: No breakpoint cleared.");
16235a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
16245a988416SJim Ingham         }
16255a988416SJim Ingham 
16265a988416SJim Ingham         return result.Succeeded();
16275a988416SJim Ingham     }
16285a988416SJim Ingham 
16295a988416SJim Ingham private:
16305a988416SJim Ingham     CommandOptions m_options;
16315a988416SJim Ingham };
16325a988416SJim Ingham 
16335a988416SJim Ingham #pragma mark Clear::CommandOptions
16345a988416SJim Ingham 
16355a988416SJim Ingham OptionDefinition
16365a988416SJim Ingham CommandObjectBreakpointClear::CommandOptions::g_option_table[] =
16375a988416SJim Ingham {
1638*d37221dcSZachary Turner     { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
16395a988416SJim Ingham         "Specify the breakpoint by source location in this particular file."},
16405a988416SJim Ingham 
1641*d37221dcSZachary Turner     { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum,
16425a988416SJim Ingham         "Specify the breakpoint by source location at this particular line."},
16435a988416SJim Ingham 
1644*d37221dcSZachary Turner     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
16455a988416SJim Ingham };
16465a988416SJim Ingham 
16475a988416SJim Ingham //-------------------------------------------------------------------------
16485a988416SJim Ingham // CommandObjectBreakpointDelete
16495a988416SJim Ingham //-------------------------------------------------------------------------
16505a988416SJim Ingham #pragma mark Delete
16515a988416SJim Ingham 
16525a988416SJim Ingham class CommandObjectBreakpointDelete : public CommandObjectParsed
16535a988416SJim Ingham {
16545a988416SJim Ingham public:
16555a988416SJim Ingham     CommandObjectBreakpointDelete (CommandInterpreter &interpreter) :
16565a988416SJim Ingham         CommandObjectParsed (interpreter,
16575a988416SJim Ingham                              "breakpoint delete",
16585a988416SJim Ingham                              "Delete the specified breakpoint(s).  If no breakpoints are specified, delete them all.",
16595a988416SJim Ingham                              NULL)
16605a988416SJim Ingham     {
16615a988416SJim Ingham         CommandArgumentEntry arg;
16625a988416SJim Ingham         CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
16635a988416SJim Ingham         // Add the entry for the first argument for this command to the object's arguments vector.
16645a988416SJim Ingham         m_arguments.push_back (arg);
16655a988416SJim Ingham     }
16665a988416SJim Ingham 
16675a988416SJim Ingham     virtual
16685a988416SJim Ingham     ~CommandObjectBreakpointDelete () {}
16695a988416SJim Ingham 
16705a988416SJim Ingham protected:
16715a988416SJim Ingham     virtual bool
16725a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
16735a988416SJim Ingham     {
16745a988416SJim Ingham         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
16755a988416SJim Ingham         if (target == NULL)
16765a988416SJim Ingham         {
16775a988416SJim Ingham             result.AppendError ("Invalid target. No existing target or breakpoints.");
16785a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
16795a988416SJim Ingham             return false;
16805a988416SJim Ingham         }
16815a988416SJim Ingham 
16825a988416SJim Ingham         Mutex::Locker locker;
16835a988416SJim Ingham         target->GetBreakpointList().GetListMutex(locker);
16845a988416SJim Ingham 
16855a988416SJim Ingham         const BreakpointList &breakpoints = target->GetBreakpointList();
16865a988416SJim Ingham 
16875a988416SJim Ingham         size_t num_breakpoints = breakpoints.GetSize();
16885a988416SJim Ingham 
16895a988416SJim Ingham         if (num_breakpoints == 0)
16905a988416SJim Ingham         {
16915a988416SJim Ingham             result.AppendError ("No breakpoints exist to be deleted.");
16925a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
16935a988416SJim Ingham             return false;
16945a988416SJim Ingham         }
16955a988416SJim Ingham 
16965a988416SJim Ingham         if (command.GetArgumentCount() == 0)
16975a988416SJim Ingham         {
16985a988416SJim Ingham             if (!m_interpreter.Confirm ("About to delete all breakpoints, do you want to do that?", true))
16995a988416SJim Ingham             {
17005a988416SJim Ingham                 result.AppendMessage("Operation cancelled...");
17015a988416SJim Ingham             }
17025a988416SJim Ingham             else
17035a988416SJim Ingham             {
17045a988416SJim Ingham                 target->RemoveAllBreakpoints ();
17056fea17e8SGreg Clayton                 result.AppendMessageWithFormat ("All breakpoints removed. (%" PRIu64 " breakpoint%s)\n", (uint64_t)num_breakpoints, num_breakpoints > 1 ? "s" : "");
17065a988416SJim Ingham             }
17075a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
17085a988416SJim Ingham         }
17095a988416SJim Ingham         else
17105a988416SJim Ingham         {
17115a988416SJim Ingham             // Particular breakpoint selected; disable that breakpoint.
17125a988416SJim Ingham             BreakpointIDList valid_bp_ids;
17135a988416SJim Ingham             CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
17145a988416SJim Ingham 
17155a988416SJim Ingham             if (result.Succeeded())
17165a988416SJim Ingham             {
17175a988416SJim Ingham                 int delete_count = 0;
17185a988416SJim Ingham                 int disable_count = 0;
17195a988416SJim Ingham                 const size_t count = valid_bp_ids.GetSize();
17205a988416SJim Ingham                 for (size_t i = 0; i < count; ++i)
17215a988416SJim Ingham                 {
17225a988416SJim Ingham                     BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
17235a988416SJim Ingham 
17245a988416SJim Ingham                     if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
17255a988416SJim Ingham                     {
17265a988416SJim Ingham                         if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
17275a988416SJim Ingham                         {
17285a988416SJim Ingham                             Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
17295a988416SJim Ingham                             BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
17305a988416SJim Ingham                             // It makes no sense to try to delete individual locations, so we disable them instead.
17315a988416SJim Ingham                             if (location)
17325a988416SJim Ingham                             {
17335a988416SJim Ingham                                 location->SetEnabled (false);
17345a988416SJim Ingham                                 ++disable_count;
17355a988416SJim Ingham                             }
17365a988416SJim Ingham                         }
17375a988416SJim Ingham                         else
17385a988416SJim Ingham                         {
17395a988416SJim Ingham                             target->RemoveBreakpointByID (cur_bp_id.GetBreakpointID());
17405a988416SJim Ingham                             ++delete_count;
17415a988416SJim Ingham                         }
17425a988416SJim Ingham                     }
17435a988416SJim Ingham                 }
17445a988416SJim Ingham                 result.AppendMessageWithFormat ("%d breakpoints deleted; %d breakpoint locations disabled.\n",
17455a988416SJim Ingham                                                delete_count, disable_count);
17465a988416SJim Ingham                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
17475a988416SJim Ingham             }
17485a988416SJim Ingham         }
17495a988416SJim Ingham         return result.Succeeded();
17505a988416SJim Ingham     }
17515a988416SJim Ingham };
17525a988416SJim Ingham 
175330fdc8d8SChris Lattner //-------------------------------------------------------------------------
175430fdc8d8SChris Lattner // CommandObjectMultiwordBreakpoint
175530fdc8d8SChris Lattner //-------------------------------------------------------------------------
1756ae1c4cf5SJim Ingham #pragma mark MultiwordBreakpoint
175730fdc8d8SChris Lattner 
17586611103cSGreg Clayton CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint (CommandInterpreter &interpreter) :
1759a7015092SGreg Clayton     CommandObjectMultiword (interpreter,
1760a7015092SGreg Clayton                             "breakpoint",
176146fbc60fSJim Ingham                             "A set of commands for operating on breakpoints. Also see _regexp-break.",
176230fdc8d8SChris Lattner                             "breakpoint <command> [<command-options>]")
176330fdc8d8SChris Lattner {
1764a7015092SGreg Clayton     CommandObjectSP list_command_object (new CommandObjectBreakpointList (interpreter));
1765a7015092SGreg Clayton     CommandObjectSP enable_command_object (new CommandObjectBreakpointEnable (interpreter));
1766a7015092SGreg Clayton     CommandObjectSP disable_command_object (new CommandObjectBreakpointDisable (interpreter));
1767b7234e40SJohnny Chen     CommandObjectSP clear_command_object (new CommandObjectBreakpointClear (interpreter));
1768b7234e40SJohnny Chen     CommandObjectSP delete_command_object (new CommandObjectBreakpointDelete (interpreter));
1769a7015092SGreg Clayton     CommandObjectSP set_command_object (new CommandObjectBreakpointSet (interpreter));
177030fdc8d8SChris Lattner     CommandObjectSP command_command_object (new CommandObjectBreakpointCommand (interpreter));
1771a7015092SGreg Clayton     CommandObjectSP modify_command_object (new CommandObjectBreakpointModify(interpreter));
177230fdc8d8SChris Lattner 
1773b7234e40SJohnny Chen     list_command_object->SetCommandName ("breakpoint list");
177430fdc8d8SChris Lattner     enable_command_object->SetCommandName("breakpoint enable");
177530fdc8d8SChris Lattner     disable_command_object->SetCommandName("breakpoint disable");
1776b7234e40SJohnny Chen     clear_command_object->SetCommandName("breakpoint clear");
1777b7234e40SJohnny Chen     delete_command_object->SetCommandName("breakpoint delete");
1778ae1c4cf5SJim Ingham     set_command_object->SetCommandName("breakpoint set");
1779b7234e40SJohnny Chen     command_command_object->SetCommandName ("breakpoint command");
1780b7234e40SJohnny Chen     modify_command_object->SetCommandName ("breakpoint modify");
178130fdc8d8SChris Lattner 
178223f59509SGreg Clayton     LoadSubCommand ("list",       list_command_object);
178323f59509SGreg Clayton     LoadSubCommand ("enable",     enable_command_object);
178423f59509SGreg Clayton     LoadSubCommand ("disable",    disable_command_object);
178523f59509SGreg Clayton     LoadSubCommand ("clear",      clear_command_object);
178623f59509SGreg Clayton     LoadSubCommand ("delete",     delete_command_object);
178723f59509SGreg Clayton     LoadSubCommand ("set",        set_command_object);
178823f59509SGreg Clayton     LoadSubCommand ("command",    command_command_object);
178923f59509SGreg Clayton     LoadSubCommand ("modify",     modify_command_object);
179030fdc8d8SChris Lattner }
179130fdc8d8SChris Lattner 
179230fdc8d8SChris Lattner CommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint ()
179330fdc8d8SChris Lattner {
179430fdc8d8SChris Lattner }
179530fdc8d8SChris Lattner 
179630fdc8d8SChris Lattner void
179730fdc8d8SChris Lattner CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (Args &args, Target *target, CommandReturnObject &result,
179830fdc8d8SChris Lattner                                                          BreakpointIDList *valid_ids)
179930fdc8d8SChris Lattner {
180030fdc8d8SChris Lattner     // args can be strings representing 1). integers (for breakpoint ids)
180130fdc8d8SChris Lattner     //                                  2). the full breakpoint & location canonical representation
180230fdc8d8SChris Lattner     //                                  3). the word "to" or a hyphen, representing a range (in which case there
180330fdc8d8SChris Lattner     //                                      had *better* be an entry both before & after of one of the first two types.
180436f3b369SJim Ingham     // If args is empty, we will use the last created breakpoint (if there is one.)
180530fdc8d8SChris Lattner 
180630fdc8d8SChris Lattner     Args temp_args;
180730fdc8d8SChris Lattner 
180836f3b369SJim Ingham     if (args.GetArgumentCount() == 0)
180936f3b369SJim Ingham     {
18104d122c40SGreg Clayton         if (target->GetLastCreatedBreakpoint())
181136f3b369SJim Ingham         {
181236f3b369SJim Ingham             valid_ids->AddBreakpointID (BreakpointID(target->GetLastCreatedBreakpoint()->GetID(), LLDB_INVALID_BREAK_ID));
181336f3b369SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
181436f3b369SJim Ingham         }
181536f3b369SJim Ingham         else
181636f3b369SJim Ingham         {
181736f3b369SJim Ingham             result.AppendError("No breakpoint specified and no last created breakpoint.");
181836f3b369SJim Ingham             result.SetStatus (eReturnStatusFailed);
181936f3b369SJim Ingham         }
182036f3b369SJim Ingham         return;
182136f3b369SJim Ingham     }
182236f3b369SJim Ingham 
182330fdc8d8SChris Lattner     // Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff directly from the old ARGS to
182430fdc8d8SChris Lattner     // the new TEMP_ARGS.  Do not copy breakpoint id range strings over; instead generate a list of strings for
182530fdc8d8SChris Lattner     // all the breakpoint ids in the range, and shove all of those breakpoint id strings into TEMP_ARGS.
182630fdc8d8SChris Lattner 
182730fdc8d8SChris Lattner     BreakpointIDList::FindAndReplaceIDRanges (args, target, result, temp_args);
182830fdc8d8SChris Lattner 
182930fdc8d8SChris Lattner     // NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual BreakpointIDList:
183030fdc8d8SChris Lattner 
1831c982c768SGreg Clayton     valid_ids->InsertStringArray (temp_args.GetConstArgumentVector(), temp_args.GetArgumentCount(), result);
183230fdc8d8SChris Lattner 
183330fdc8d8SChris Lattner     // At this point,  all of the breakpoint ids that the user passed in have been converted to breakpoint IDs
183430fdc8d8SChris Lattner     // and put into valid_ids.
183530fdc8d8SChris Lattner 
183630fdc8d8SChris Lattner     if (result.Succeeded())
183730fdc8d8SChris Lattner     {
183830fdc8d8SChris Lattner         // Now that we've converted everything from args into a list of breakpoint ids, go through our tentative list
183930fdc8d8SChris Lattner         // of breakpoint id's and verify that they correspond to valid/currently set breakpoints.
184030fdc8d8SChris Lattner 
1841c982c768SGreg Clayton         const size_t count = valid_ids->GetSize();
1842c982c768SGreg Clayton         for (size_t i = 0; i < count; ++i)
184330fdc8d8SChris Lattner         {
184430fdc8d8SChris Lattner             BreakpointID cur_bp_id = valid_ids->GetBreakpointIDAtIndex (i);
184530fdc8d8SChris Lattner             Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
184630fdc8d8SChris Lattner             if (breakpoint != NULL)
184730fdc8d8SChris Lattner             {
1848c7bece56SGreg Clayton                 const size_t num_locations = breakpoint->GetNumLocations();
18493985c8c6SSaleem Abdulrasool                 if (static_cast<size_t>(cur_bp_id.GetLocationID()) > num_locations)
185030fdc8d8SChris Lattner                 {
185130fdc8d8SChris Lattner                     StreamString id_str;
1852c982c768SGreg Clayton                     BreakpointID::GetCanonicalReference (&id_str,
1853c982c768SGreg Clayton                                                          cur_bp_id.GetBreakpointID(),
185430fdc8d8SChris Lattner                                                          cur_bp_id.GetLocationID());
1855c982c768SGreg Clayton                     i = valid_ids->GetSize() + 1;
185630fdc8d8SChris Lattner                     result.AppendErrorWithFormat ("'%s' is not a currently valid breakpoint/location id.\n",
185730fdc8d8SChris Lattner                                                  id_str.GetData());
185830fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusFailed);
185930fdc8d8SChris Lattner                 }
186030fdc8d8SChris Lattner             }
186130fdc8d8SChris Lattner             else
186230fdc8d8SChris Lattner             {
1863c982c768SGreg Clayton                 i = valid_ids->GetSize() + 1;
186430fdc8d8SChris Lattner                 result.AppendErrorWithFormat ("'%d' is not a currently valid breakpoint id.\n", cur_bp_id.GetBreakpointID());
186530fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
186630fdc8d8SChris Lattner             }
186730fdc8d8SChris Lattner         }
186830fdc8d8SChris Lattner     }
186930fdc8d8SChris Lattner }
1870