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"
2930fdc8d8SChris Lattner #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),
109a8558b62SJim Ingham             m_language (eLanguageTypeUnknown),
110ca36cd16SJim Ingham             m_skip_prologue (eLazyBoolCalculate),
111ca36cd16SJim Ingham             m_one_shot (false)
11230fdc8d8SChris Lattner         {
11330fdc8d8SChris Lattner         }
11430fdc8d8SChris Lattner 
11530fdc8d8SChris Lattner 
1165a988416SJim Ingham         virtual
1175a988416SJim Ingham         ~CommandOptions () {}
11887df91b8SJim Ingham 
1195a988416SJim Ingham         virtual Error
1205a988416SJim Ingham         SetOptionValue (uint32_t option_idx, const char *option_arg)
12130fdc8d8SChris Lattner         {
12230fdc8d8SChris Lattner             Error error;
1233bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
12430fdc8d8SChris Lattner 
12530fdc8d8SChris Lattner             switch (short_option)
12630fdc8d8SChris Lattner             {
12730fdc8d8SChris Lattner                 case 'a':
128b9d5df58SGreg Clayton                     {
129b9d5df58SGreg Clayton                         ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
130b9d5df58SGreg Clayton                         m_load_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
131b9d5df58SGreg Clayton                     }
13230fdc8d8SChris Lattner                     break;
13330fdc8d8SChris Lattner 
134ca36cd16SJim Ingham                 case 'b':
135ca36cd16SJim Ingham                     m_func_names.push_back (option_arg);
136ca36cd16SJim Ingham                     m_func_name_type_mask |= eFunctionNameTypeBase;
137ca36cd16SJim Ingham                     break;
138ca36cd16SJim Ingham 
1397d49c9c8SJohnny Chen                 case 'C':
14030fdc8d8SChris Lattner                     m_column = Args::StringToUInt32 (option_arg, 0);
14130fdc8d8SChris Lattner                     break;
1420c5cd90dSGreg Clayton 
1437d49c9c8SJohnny Chen                 case 'c':
1447d49c9c8SJohnny Chen                     m_condition.assign(option_arg);
1457d49c9c8SJohnny Chen                     break;
1467d49c9c8SJohnny Chen 
147fab10e89SJim Ingham                 case 'E':
148fab10e89SJim Ingham                 {
149fab10e89SJim Ingham                     LanguageType language = LanguageRuntime::GetLanguageTypeFromString (option_arg);
150fab10e89SJim Ingham 
151fab10e89SJim Ingham                     switch (language)
152fab10e89SJim Ingham                     {
153fab10e89SJim Ingham                         case eLanguageTypeC89:
154fab10e89SJim Ingham                         case eLanguageTypeC:
155fab10e89SJim Ingham                         case eLanguageTypeC99:
156fab10e89SJim Ingham                             m_language = eLanguageTypeC;
157fab10e89SJim Ingham                             break;
158fab10e89SJim Ingham                         case eLanguageTypeC_plus_plus:
159fab10e89SJim Ingham                             m_language = eLanguageTypeC_plus_plus;
160fab10e89SJim Ingham                             break;
161fab10e89SJim Ingham                         case eLanguageTypeObjC:
162fab10e89SJim Ingham                             m_language = eLanguageTypeObjC;
163fab10e89SJim Ingham                             break;
164fab10e89SJim Ingham                         case eLanguageTypeObjC_plus_plus:
165fab10e89SJim Ingham                             error.SetErrorStringWithFormat ("Set exception breakpoints separately for c++ and objective-c");
166fab10e89SJim Ingham                             break;
167fab10e89SJim Ingham                         case eLanguageTypeUnknown:
168fab10e89SJim Ingham                             error.SetErrorStringWithFormat ("Unknown language type: '%s' for exception breakpoint", option_arg);
169fab10e89SJim Ingham                             break;
170fab10e89SJim Ingham                         default:
171fab10e89SJim Ingham                             error.SetErrorStringWithFormat ("Unsupported language type: '%s' for exception breakpoint", option_arg);
172fab10e89SJim Ingham                     }
173fab10e89SJim Ingham                 }
174fab10e89SJim Ingham                 break;
175ca36cd16SJim Ingham 
176ca36cd16SJim Ingham                 case 'f':
177ca36cd16SJim Ingham                     m_filenames.AppendIfUnique (FileSpec(option_arg, false));
178fab10e89SJim Ingham                     break;
179ca36cd16SJim Ingham 
180ca36cd16SJim Ingham                 case 'F':
181ca36cd16SJim Ingham                     m_func_names.push_back (option_arg);
182ca36cd16SJim Ingham                     m_func_name_type_mask |= eFunctionNameTypeFull;
183ca36cd16SJim Ingham                     break;
184ca36cd16SJim Ingham 
185fab10e89SJim Ingham                 case 'h':
186fab10e89SJim Ingham                 {
187fab10e89SJim Ingham                     bool success;
188fab10e89SJim Ingham                     m_catch_bp = Args::StringToBoolean (option_arg, true, &success);
189fab10e89SJim Ingham                     if (!success)
190fab10e89SJim Ingham                         error.SetErrorStringWithFormat ("Invalid boolean value for on-catch option: '%s'", option_arg);
191fab10e89SJim Ingham                 }
192168d469aSJim Ingham                 break;
193ca36cd16SJim Ingham                 case 'i':
194ca36cd16SJim Ingham                 {
195ca36cd16SJim Ingham                     m_ignore_count = Args::StringToUInt32(option_arg, UINT32_MAX, 0);
196ca36cd16SJim Ingham                     if (m_ignore_count == UINT32_MAX)
197ca36cd16SJim Ingham                        error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
198ca36cd16SJim Ingham                     break;
199ca36cd16SJim Ingham                 }
200ca36cd16SJim Ingham 
201a8558b62SJim Ingham                 case 'K':
202a8558b62SJim Ingham                 {
203a8558b62SJim Ingham                     bool success;
204a8558b62SJim Ingham                     bool value;
205a8558b62SJim Ingham                     value = Args::StringToBoolean (option_arg, true, &success);
206a8558b62SJim Ingham                     if (value)
207a8558b62SJim Ingham                         m_skip_prologue = eLazyBoolYes;
208a8558b62SJim Ingham                     else
209a8558b62SJim Ingham                         m_skip_prologue = eLazyBoolNo;
210a8558b62SJim Ingham 
211a8558b62SJim Ingham                     if (!success)
212a8558b62SJim Ingham                         error.SetErrorStringWithFormat ("Invalid boolean value for skip prologue option: '%s'", option_arg);
213a8558b62SJim Ingham                 }
214fab10e89SJim Ingham                 break;
215ca36cd16SJim Ingham 
216ca36cd16SJim Ingham                 case 'l':
217ca36cd16SJim Ingham                     m_line_num = Args::StringToUInt32 (option_arg, 0);
218ca36cd16SJim Ingham                     break;
219ca36cd16SJim Ingham 
220ca36cd16SJim Ingham                 case 'M':
221ca36cd16SJim Ingham                     m_func_names.push_back (option_arg);
222ca36cd16SJim Ingham                     m_func_name_type_mask |= eFunctionNameTypeMethod;
223ca36cd16SJim Ingham                     break;
224ca36cd16SJim Ingham 
225ca36cd16SJim Ingham                 case 'n':
226ca36cd16SJim Ingham                     m_func_names.push_back (option_arg);
227ca36cd16SJim Ingham                     m_func_name_type_mask |= eFunctionNameTypeAuto;
228ca36cd16SJim Ingham                     break;
229ca36cd16SJim Ingham 
230ca36cd16SJim Ingham                 case 'o':
231ca36cd16SJim Ingham                     m_one_shot = true;
232ca36cd16SJim Ingham                     break;
233ca36cd16SJim Ingham 
234ca36cd16SJim Ingham                 case 'p':
235ca36cd16SJim Ingham                     m_source_text_regexp.assign (option_arg);
236ca36cd16SJim Ingham                     break;
237ca36cd16SJim Ingham 
238ca36cd16SJim Ingham                 case 'q':
239ca36cd16SJim Ingham                     m_queue_name.assign (option_arg);
240ca36cd16SJim Ingham                     break;
241ca36cd16SJim Ingham 
242ca36cd16SJim Ingham                 case 'r':
243ca36cd16SJim Ingham                     m_func_regexp.assign (option_arg);
244ca36cd16SJim Ingham                     break;
245ca36cd16SJim Ingham 
246ca36cd16SJim Ingham                 case 's':
247ca36cd16SJim Ingham                 {
248ca36cd16SJim Ingham                     m_modules.AppendIfUnique (FileSpec (option_arg, false));
249ca36cd16SJim Ingham                     break;
250ca36cd16SJim Ingham                 }
251ca36cd16SJim Ingham 
252ca36cd16SJim Ingham                 case 'S':
253ca36cd16SJim Ingham                     m_func_names.push_back (option_arg);
254ca36cd16SJim Ingham                     m_func_name_type_mask |= eFunctionNameTypeSelector;
255ca36cd16SJim Ingham                     break;
256ca36cd16SJim Ingham 
257ca36cd16SJim Ingham                 case 't' :
258ca36cd16SJim Ingham                 {
259ca36cd16SJim Ingham                     m_thread_id = Args::StringToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
260ca36cd16SJim Ingham                     if (m_thread_id == LLDB_INVALID_THREAD_ID)
261ca36cd16SJim Ingham                        error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
262ca36cd16SJim Ingham                 }
263ca36cd16SJim Ingham                 break;
264ca36cd16SJim Ingham 
265ca36cd16SJim Ingham                 case 'T':
266ca36cd16SJim Ingham                     m_thread_name.assign (option_arg);
267ca36cd16SJim Ingham                     break;
268ca36cd16SJim Ingham 
269ca36cd16SJim Ingham                 case 'w':
270ca36cd16SJim Ingham                 {
271ca36cd16SJim Ingham                     bool success;
272ca36cd16SJim Ingham                     m_throw_bp = Args::StringToBoolean (option_arg, true, &success);
273ca36cd16SJim Ingham                     if (!success)
274ca36cd16SJim Ingham                         error.SetErrorStringWithFormat ("Invalid boolean value for on-throw option: '%s'", option_arg);
275ca36cd16SJim Ingham                 }
276ca36cd16SJim Ingham                 break;
277ca36cd16SJim Ingham 
278ca36cd16SJim Ingham                 case 'x':
279ca36cd16SJim Ingham                 {
280ca36cd16SJim Ingham                     m_thread_index = Args::StringToUInt32(option_arg, UINT32_MAX, 0);
281ca36cd16SJim Ingham                     if (m_thread_id == UINT32_MAX)
282ca36cd16SJim Ingham                        error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
283ca36cd16SJim Ingham 
284ca36cd16SJim Ingham                 }
285ca36cd16SJim Ingham                 break;
286ca36cd16SJim Ingham 
28730fdc8d8SChris Lattner                 default:
28886edbf41SGreg Clayton                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
28930fdc8d8SChris Lattner                     break;
29030fdc8d8SChris Lattner             }
29130fdc8d8SChris Lattner 
29230fdc8d8SChris Lattner             return error;
29330fdc8d8SChris Lattner         }
29430fdc8d8SChris Lattner         void
2955a988416SJim Ingham         OptionParsingStarting ()
29630fdc8d8SChris Lattner         {
2977d49c9c8SJohnny Chen             m_condition.clear();
29887df91b8SJim Ingham             m_filenames.Clear();
29930fdc8d8SChris Lattner             m_line_num = 0;
30030fdc8d8SChris Lattner             m_column = 0;
301fab10e89SJim Ingham             m_func_names.clear();
3021f746071SGreg Clayton             m_func_name_type_mask = eFunctionNameTypeNone;
30330fdc8d8SChris Lattner             m_func_regexp.clear();
3041f746071SGreg Clayton             m_source_text_regexp.clear();
30587df91b8SJim Ingham             m_modules.Clear();
3061f746071SGreg Clayton             m_load_addr = LLDB_INVALID_ADDRESS;
307c982c768SGreg Clayton             m_ignore_count = 0;
3081b54c88cSJim Ingham             m_thread_id = LLDB_INVALID_THREAD_ID;
309c982c768SGreg Clayton             m_thread_index = UINT32_MAX;
3101b54c88cSJim Ingham             m_thread_name.clear();
3111b54c88cSJim Ingham             m_queue_name.clear();
312fab10e89SJim Ingham             m_catch_bp = false;
313fab10e89SJim Ingham             m_throw_bp = true;
3141f746071SGreg Clayton             m_language = eLanguageTypeUnknown;
315a8558b62SJim Ingham             m_skip_prologue = eLazyBoolCalculate;
316ca36cd16SJim Ingham             m_one_shot = false;
31730fdc8d8SChris Lattner         }
31830fdc8d8SChris Lattner 
3195a988416SJim Ingham         const OptionDefinition*
3205a988416SJim Ingham         GetDefinitions ()
32130fdc8d8SChris Lattner         {
3225a988416SJim Ingham             return g_option_table;
32330fdc8d8SChris Lattner         }
32430fdc8d8SChris Lattner 
3255a988416SJim Ingham         // Options table: Required for subclasses of Options.
32630fdc8d8SChris Lattner 
3275a988416SJim Ingham         static OptionDefinition g_option_table[];
32830fdc8d8SChris Lattner 
3295a988416SJim Ingham         // Instance variables to hold the values for command options.
330969795f1SJim Ingham 
3315a988416SJim Ingham         std::string m_condition;
3325a988416SJim Ingham         FileSpecList m_filenames;
3335a988416SJim Ingham         uint32_t m_line_num;
3345a988416SJim Ingham         uint32_t m_column;
3355a988416SJim Ingham         std::vector<std::string> m_func_names;
3365a988416SJim Ingham         uint32_t m_func_name_type_mask;
3375a988416SJim Ingham         std::string m_func_regexp;
3385a988416SJim Ingham         std::string m_source_text_regexp;
3395a988416SJim Ingham         FileSpecList m_modules;
3405a988416SJim Ingham         lldb::addr_t m_load_addr;
3415a988416SJim Ingham         uint32_t m_ignore_count;
3425a988416SJim Ingham         lldb::tid_t m_thread_id;
3435a988416SJim Ingham         uint32_t m_thread_index;
3445a988416SJim Ingham         std::string m_thread_name;
3455a988416SJim Ingham         std::string m_queue_name;
3465a988416SJim Ingham         bool m_catch_bp;
3475a988416SJim Ingham         bool m_throw_bp;
3485a988416SJim Ingham         lldb::LanguageType m_language;
3495a988416SJim Ingham         LazyBool m_skip_prologue;
350ca36cd16SJim Ingham         bool m_one_shot;
3515a988416SJim Ingham 
3525a988416SJim Ingham     };
3535a988416SJim Ingham 
3545a988416SJim Ingham protected:
3555a988416SJim Ingham     virtual bool
3565a988416SJim Ingham     DoExecute (Args& command,
3575a988416SJim Ingham              CommandReturnObject &result)
35830fdc8d8SChris Lattner     {
359a7015092SGreg Clayton         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
36030fdc8d8SChris Lattner         if (target == NULL)
36130fdc8d8SChris Lattner         {
362effe5c95SGreg Clayton             result.AppendError ("Invalid target.  Must set target before setting breakpoints (see 'target create' command).");
36330fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
36430fdc8d8SChris Lattner             return false;
36530fdc8d8SChris Lattner         }
36630fdc8d8SChris Lattner 
36730fdc8d8SChris Lattner         // The following are the various types of breakpoints that could be set:
36830fdc8d8SChris Lattner         //   1).  -f -l -p  [-s -g]   (setting breakpoint by source location)
36930fdc8d8SChris Lattner         //   2).  -a  [-s -g]         (setting breakpoint by address)
37030fdc8d8SChris Lattner         //   3).  -n  [-s -g]         (setting breakpoint by function name)
37130fdc8d8SChris Lattner         //   4).  -r  [-s -g]         (setting breakpoint by function name regular expression)
372969795f1SJim Ingham         //   5).  -p -f               (setting a breakpoint by comparing a reg-exp to source text)
373fab10e89SJim Ingham         //   6).  -E [-w -h]          (setting a breakpoint for exceptions for a given language.)
37430fdc8d8SChris Lattner 
37530fdc8d8SChris Lattner         BreakpointSetType break_type = eSetTypeInvalid;
37630fdc8d8SChris Lattner 
37730fdc8d8SChris Lattner         if (m_options.m_line_num != 0)
37830fdc8d8SChris Lattner             break_type = eSetTypeFileAndLine;
37930fdc8d8SChris Lattner         else if (m_options.m_load_addr != LLDB_INVALID_ADDRESS)
38030fdc8d8SChris Lattner             break_type = eSetTypeAddress;
381fab10e89SJim Ingham         else if (!m_options.m_func_names.empty())
38230fdc8d8SChris Lattner             break_type = eSetTypeFunctionName;
38330fdc8d8SChris Lattner         else if  (!m_options.m_func_regexp.empty())
38430fdc8d8SChris Lattner             break_type = eSetTypeFunctionRegexp;
385969795f1SJim Ingham         else if (!m_options.m_source_text_regexp.empty())
386969795f1SJim Ingham             break_type = eSetTypeSourceRegexp;
387fab10e89SJim Ingham         else if (m_options.m_language != eLanguageTypeUnknown)
388fab10e89SJim Ingham             break_type = eSetTypeException;
38930fdc8d8SChris Lattner 
39030fdc8d8SChris Lattner         Breakpoint *bp = NULL;
391274060b6SGreg Clayton         FileSpec module_spec;
392a8558b62SJim Ingham         const bool internal = false;
393a8558b62SJim Ingham 
39430fdc8d8SChris Lattner         switch (break_type)
39530fdc8d8SChris Lattner         {
39630fdc8d8SChris Lattner             case eSetTypeFileAndLine: // Breakpoint by source position
39730fdc8d8SChris Lattner                 {
39830fdc8d8SChris Lattner                     FileSpec file;
399c7bece56SGreg Clayton                     const size_t num_files = m_options.m_filenames.GetSize();
40087df91b8SJim Ingham                     if (num_files == 0)
40187df91b8SJim Ingham                     {
40287df91b8SJim Ingham                         if (!GetDefaultFile (target, file, result))
40387df91b8SJim Ingham                         {
40487df91b8SJim Ingham                             result.AppendError("No file supplied and no default file available.");
40587df91b8SJim Ingham                             result.SetStatus (eReturnStatusFailed);
40687df91b8SJim Ingham                             return false;
40787df91b8SJim Ingham                         }
40887df91b8SJim Ingham                     }
40987df91b8SJim Ingham                     else if (num_files > 1)
41087df91b8SJim Ingham                     {
41187df91b8SJim Ingham                         result.AppendError("Only one file at a time is allowed for file and line breakpoints.");
41287df91b8SJim Ingham                         result.SetStatus (eReturnStatusFailed);
41387df91b8SJim Ingham                         return false;
41487df91b8SJim Ingham                     }
41587df91b8SJim Ingham                     else
41687df91b8SJim Ingham                         file = m_options.m_filenames.GetFileSpecAtIndex(0);
41730fdc8d8SChris Lattner 
4181f746071SGreg Clayton                     // Only check for inline functions if
4191f746071SGreg Clayton                     LazyBool check_inlines = eLazyBoolCalculate;
4201f746071SGreg Clayton 
42187df91b8SJim Ingham                     bp = target->CreateBreakpoint (&(m_options.m_modules),
42230fdc8d8SChris Lattner                                                    file,
42330fdc8d8SChris Lattner                                                    m_options.m_line_num,
4241f746071SGreg Clayton                                                    check_inlines,
425a8558b62SJim Ingham                                                    m_options.m_skip_prologue,
426a8558b62SJim Ingham                                                    internal).get();
42730fdc8d8SChris Lattner                 }
42830fdc8d8SChris Lattner                 break;
4296eee5aa0SGreg Clayton 
43030fdc8d8SChris Lattner             case eSetTypeAddress: // Breakpoint by address
43130fdc8d8SChris Lattner                 bp = target->CreateBreakpoint (m_options.m_load_addr, false).get();
43230fdc8d8SChris Lattner                 break;
4330c5cd90dSGreg Clayton 
43430fdc8d8SChris Lattner             case eSetTypeFunctionName: // Breakpoint by function name
4350c5cd90dSGreg Clayton                 {
4360c5cd90dSGreg Clayton                     uint32_t name_type_mask = m_options.m_func_name_type_mask;
4370c5cd90dSGreg Clayton 
4380c5cd90dSGreg Clayton                     if (name_type_mask == 0)
439e02b8504SGreg Clayton                         name_type_mask = eFunctionNameTypeAuto;
4400c5cd90dSGreg Clayton 
44187df91b8SJim Ingham                     bp = target->CreateBreakpoint (&(m_options.m_modules),
44287df91b8SJim Ingham                                                    &(m_options.m_filenames),
443fab10e89SJim Ingham                                                    m_options.m_func_names,
444274060b6SGreg Clayton                                                    name_type_mask,
445a8558b62SJim Ingham                                                    m_options.m_skip_prologue,
446a8558b62SJim Ingham                                                    internal).get();
4470c5cd90dSGreg Clayton                 }
44830fdc8d8SChris Lattner                 break;
4490c5cd90dSGreg Clayton 
45030fdc8d8SChris Lattner             case eSetTypeFunctionRegexp: // Breakpoint by regular expression function name
45130fdc8d8SChris Lattner                 {
45230fdc8d8SChris Lattner                     RegularExpression regexp(m_options.m_func_regexp.c_str());
453969795f1SJim Ingham                     if (!regexp.IsValid())
45430fdc8d8SChris Lattner                     {
455969795f1SJim Ingham                         char err_str[1024];
456969795f1SJim Ingham                         regexp.GetErrorAsCString(err_str, sizeof(err_str));
457969795f1SJim Ingham                         result.AppendErrorWithFormat("Function name regular expression could not be compiled: \"%s\"",
458969795f1SJim Ingham                                                      err_str);
45930fdc8d8SChris Lattner                         result.SetStatus (eReturnStatusFailed);
460969795f1SJim Ingham                         return false;
46130fdc8d8SChris Lattner                     }
46287df91b8SJim Ingham 
463a8558b62SJim Ingham                     bp = target->CreateFuncRegexBreakpoint (&(m_options.m_modules),
464a8558b62SJim Ingham                                                             &(m_options.m_filenames),
465a8558b62SJim Ingham                                                             regexp,
466a8558b62SJim Ingham                                                             m_options.m_skip_prologue,
467a8558b62SJim Ingham                                                             internal).get();
46830fdc8d8SChris Lattner                 }
46930fdc8d8SChris Lattner                 break;
470969795f1SJim Ingham             case eSetTypeSourceRegexp: // Breakpoint by regexp on source text.
471969795f1SJim Ingham                 {
472c7bece56SGreg Clayton                     const size_t num_files = m_options.m_filenames.GetSize();
47387df91b8SJim Ingham 
47487df91b8SJim Ingham                     if (num_files == 0)
47587df91b8SJim Ingham                     {
476969795f1SJim Ingham                         FileSpec file;
47787df91b8SJim Ingham                         if (!GetDefaultFile (target, file, result))
47887df91b8SJim Ingham                         {
47987df91b8SJim Ingham                             result.AppendError ("No files provided and could not find default file.");
48087df91b8SJim Ingham                             result.SetStatus (eReturnStatusFailed);
48187df91b8SJim Ingham                             return false;
48287df91b8SJim Ingham                         }
48387df91b8SJim Ingham                         else
48487df91b8SJim Ingham                         {
48587df91b8SJim Ingham                             m_options.m_filenames.Append (file);
48687df91b8SJim Ingham                         }
48787df91b8SJim Ingham                     }
4880c5cd90dSGreg Clayton 
489969795f1SJim Ingham                     RegularExpression regexp(m_options.m_source_text_regexp.c_str());
490969795f1SJim Ingham                     if (!regexp.IsValid())
491969795f1SJim Ingham                     {
492969795f1SJim Ingham                         char err_str[1024];
493969795f1SJim Ingham                         regexp.GetErrorAsCString(err_str, sizeof(err_str));
494969795f1SJim Ingham                         result.AppendErrorWithFormat("Source text regular expression could not be compiled: \"%s\"",
495969795f1SJim Ingham                                                      err_str);
496969795f1SJim Ingham                         result.SetStatus (eReturnStatusFailed);
497969795f1SJim Ingham                         return false;
498969795f1SJim Ingham                     }
49987df91b8SJim Ingham                     bp = target->CreateSourceRegexBreakpoint (&(m_options.m_modules), &(m_options.m_filenames), regexp).get();
500969795f1SJim Ingham                 }
501969795f1SJim Ingham                 break;
502fab10e89SJim Ingham             case eSetTypeException:
503fab10e89SJim Ingham                 {
504fab10e89SJim Ingham                     bp = target->CreateExceptionBreakpoint (m_options.m_language, m_options.m_catch_bp, m_options.m_throw_bp).get();
505fab10e89SJim Ingham                 }
506fab10e89SJim Ingham                 break;
50730fdc8d8SChris Lattner             default:
50830fdc8d8SChris Lattner                 break;
50930fdc8d8SChris Lattner         }
51030fdc8d8SChris Lattner 
5111b54c88cSJim Ingham         // Now set the various options that were passed in:
5121b54c88cSJim Ingham         if (bp)
5131b54c88cSJim Ingham         {
5141b54c88cSJim Ingham             if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
5151b54c88cSJim Ingham                 bp->SetThreadID (m_options.m_thread_id);
5161b54c88cSJim Ingham 
517c982c768SGreg Clayton             if (m_options.m_thread_index != UINT32_MAX)
5181b54c88cSJim Ingham                 bp->GetOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index);
5191b54c88cSJim Ingham 
5201b54c88cSJim Ingham             if (!m_options.m_thread_name.empty())
5211b54c88cSJim Ingham                 bp->GetOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str());
5221b54c88cSJim Ingham 
5231b54c88cSJim Ingham             if (!m_options.m_queue_name.empty())
5241b54c88cSJim Ingham                 bp->GetOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str());
5251b54c88cSJim Ingham 
526c982c768SGreg Clayton             if (m_options.m_ignore_count != 0)
5271b54c88cSJim Ingham                 bp->GetOptions()->SetIgnoreCount(m_options.m_ignore_count);
5287d49c9c8SJohnny Chen 
5297d49c9c8SJohnny Chen             if (!m_options.m_condition.empty())
5307d49c9c8SJohnny Chen                 bp->GetOptions()->SetCondition(m_options.m_condition.c_str());
531ca36cd16SJim Ingham 
532ca36cd16SJim Ingham             bp->SetOneShot (m_options.m_one_shot);
5331b54c88cSJim Ingham         }
5341b54c88cSJim Ingham 
535969795f1SJim Ingham         if (bp)
53630fdc8d8SChris Lattner         {
53785e8b814SJim Ingham             Stream &output_stream = result.GetOutputStream();
5381391cc7dSJim Ingham             const bool show_locations = false;
5391391cc7dSJim Ingham             bp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial, show_locations);
540fab10e89SJim Ingham             // Don't print out this warning for exception breakpoints.  They can get set before the target
541fab10e89SJim Ingham             // is set, but we won't know how to actually set the breakpoint till we run.
542fab10e89SJim Ingham             if (bp->GetNumLocations() == 0 && break_type != eSetTypeException)
543be484f41SCaroline Tice                 output_stream.Printf ("WARNING:  Unable to resolve breakpoint to any actual locations.\n");
54430fdc8d8SChris Lattner             result.SetStatus (eReturnStatusSuccessFinishResult);
54530fdc8d8SChris Lattner         }
54630fdc8d8SChris Lattner         else if (!bp)
54730fdc8d8SChris Lattner         {
54830fdc8d8SChris Lattner             result.AppendError ("Breakpoint creation failed: No breakpoint created.");
54930fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
55030fdc8d8SChris Lattner         }
55130fdc8d8SChris Lattner 
55230fdc8d8SChris Lattner         return result.Succeeded();
55330fdc8d8SChris Lattner     }
55430fdc8d8SChris Lattner 
5555a988416SJim Ingham private:
5565a988416SJim Ingham     bool
5575a988416SJim Ingham     GetDefaultFile (Target *target, FileSpec &file, CommandReturnObject &result)
5585a988416SJim Ingham     {
5595a988416SJim Ingham         uint32_t default_line;
5605a988416SJim Ingham         // First use the Source Manager's default file.
5615a988416SJim Ingham         // Then use the current stack frame's file.
5625a988416SJim Ingham         if (!target->GetSourceManager().GetDefaultFileAndLine(file, default_line))
5635a988416SJim Ingham         {
564f9fc609fSGreg Clayton             StackFrame *cur_frame = m_exe_ctx.GetFramePtr();
5655a988416SJim Ingham             if (cur_frame == NULL)
5665a988416SJim Ingham             {
5675a988416SJim Ingham                 result.AppendError ("No selected frame to use to find the default file.");
5685a988416SJim Ingham                 result.SetStatus (eReturnStatusFailed);
5695a988416SJim Ingham                 return false;
5705a988416SJim Ingham             }
5715a988416SJim Ingham             else if (!cur_frame->HasDebugInformation())
5725a988416SJim Ingham             {
5735a988416SJim Ingham                 result.AppendError ("Cannot use the selected frame to find the default file, it has no debug info.");
5745a988416SJim Ingham                 result.SetStatus (eReturnStatusFailed);
5755a988416SJim Ingham                 return false;
5765a988416SJim Ingham             }
5775a988416SJim Ingham             else
5785a988416SJim Ingham             {
5795a988416SJim Ingham                 const SymbolContext &sc = cur_frame->GetSymbolContext (eSymbolContextLineEntry);
5805a988416SJim Ingham                 if (sc.line_entry.file)
5815a988416SJim Ingham                 {
5825a988416SJim Ingham                     file = sc.line_entry.file;
5835a988416SJim Ingham                 }
5845a988416SJim Ingham                 else
5855a988416SJim Ingham                 {
5865a988416SJim Ingham                     result.AppendError ("Can't find the file for the selected frame to use as the default file.");
5875a988416SJim Ingham                     result.SetStatus (eReturnStatusFailed);
5885a988416SJim Ingham                     return false;
5895a988416SJim Ingham                 }
5905a988416SJim Ingham             }
5915a988416SJim Ingham         }
5925a988416SJim Ingham         return true;
5935a988416SJim Ingham     }
5945a988416SJim Ingham 
5955a988416SJim Ingham     CommandOptions m_options;
5965a988416SJim Ingham };
5975a988416SJim Ingham // If an additional option set beyond LLDB_OPTION_SET_10 is added, make sure to
5985a988416SJim Ingham // update the numbers passed to LLDB_OPT_SET_FROM_TO(...) appropriately.
5995a988416SJim Ingham #define LLDB_OPT_FILE ( LLDB_OPT_SET_FROM_TO(1, 9) & ~LLDB_OPT_SET_2 )
6005a988416SJim Ingham #define LLDB_OPT_NOT_10 ( LLDB_OPT_SET_FROM_TO(1, 10) & ~LLDB_OPT_SET_10 )
6015a988416SJim Ingham #define LLDB_OPT_SKIP_PROLOGUE ( LLDB_OPT_SET_1 | LLDB_OPT_SET_FROM_TO(3,8) )
6025a988416SJim Ingham 
6035a988416SJim Ingham OptionDefinition
6045a988416SJim Ingham CommandObjectBreakpointSet::CommandOptions::g_option_table[] =
6055a988416SJim Ingham {
6065a988416SJim Ingham     { LLDB_OPT_NOT_10, false, "shlib", 's', required_argument, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName,
6075a988416SJim Ingham         "Set the breakpoint only in this shared library.  "
6085a988416SJim Ingham         "Can repeat this option multiple times to specify multiple shared libraries."},
6095a988416SJim Ingham 
6105a988416SJim Ingham     { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', required_argument,   NULL, 0, eArgTypeCount,
6115a988416SJim Ingham         "Set the number of times this breakpoint is skipped before stopping." },
6125a988416SJim Ingham 
613ca36cd16SJim Ingham     { LLDB_OPT_SET_ALL, false, "one-shot", 'o', no_argument,   NULL, 0, eArgTypeNone,
614b2b256afSJim Ingham         "The breakpoint is deleted the first time it causes a stop." },
615ca36cd16SJim Ingham 
6165a988416SJim Ingham     { LLDB_OPT_SET_ALL, false, "condition",    'c', required_argument, NULL, 0, eArgTypeExpression,
6175a988416SJim Ingham         "The breakpoint stops only if this condition expression evaluates to true."},
6185a988416SJim Ingham 
6195a988416SJim Ingham     { LLDB_OPT_SET_ALL, false, "thread-index", 'x', required_argument, NULL, 0, eArgTypeThreadIndex,
620a89be91fSJim Ingham         "The breakpoint stops only for the thread whose indeX matches this argument."},
6215a988416SJim Ingham 
6225a988416SJim Ingham     { LLDB_OPT_SET_ALL, false, "thread-id", 't', required_argument, NULL, 0, eArgTypeThreadID,
6235a988416SJim Ingham         "The breakpoint stops only for the thread whose TID matches this argument."},
6245a988416SJim Ingham 
6255a988416SJim Ingham     { LLDB_OPT_SET_ALL, false, "thread-name", 'T', required_argument, NULL, 0, eArgTypeThreadName,
6265a988416SJim Ingham         "The breakpoint stops only for the thread whose thread name matches this argument."},
6275a988416SJim Ingham 
6285a988416SJim Ingham     { LLDB_OPT_SET_ALL, false, "queue-name", 'q', required_argument, NULL, 0, eArgTypeQueueName,
6295a988416SJim Ingham         "The breakpoint stops only for threads in the queue whose name is given by this argument."},
6305a988416SJim Ingham 
6315a988416SJim Ingham     { LLDB_OPT_FILE, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
632289aca64SJim Ingham         "Specifies the source file in which to set this breakpoint.  "
633289aca64SJim Ingham         "Note, by default lldb only looks for files that are #included if they use the standard include file extensions.  "
6346394479eSJim Ingham         "To set breakpoints on .c/.cpp/.m/.mm files that are #included, set target.inline-breakpoint-strategy"
635289aca64SJim Ingham         " to \"always\"."},
6365a988416SJim Ingham 
6375a988416SJim Ingham     { LLDB_OPT_SET_1, true, "line", 'l', required_argument, NULL, 0, eArgTypeLineNum,
6385a988416SJim Ingham         "Specifies the line number on which to set this breakpoint."},
6395a988416SJim Ingham 
6405a988416SJim Ingham     // Comment out this option for the moment, as we don't actually use it, but will in the future.
6415a988416SJim Ingham     // This way users won't see it, but the infrastructure is left in place.
6425a988416SJim Ingham     //    { 0, false, "column",     'C', required_argument, NULL, "<column>",
6435a988416SJim Ingham     //    "Set the breakpoint by source location at this particular column."},
6445a988416SJim Ingham 
645b84a9dbfSEnrico Granata     { LLDB_OPT_SET_2, true, "address", 'a', required_argument, NULL, 0, eArgTypeAddressOrExpression,
6465a988416SJim Ingham         "Set the breakpoint by address, at the specified address."},
6475a988416SJim Ingham 
6485a988416SJim Ingham     { LLDB_OPT_SET_3, true, "name", 'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
649551262d7SJim Ingham         "Set the breakpoint by function name.  Can be repeated multiple times to make one breakpoint for multiple names" },
6505a988416SJim Ingham 
6515a988416SJim Ingham     { LLDB_OPT_SET_4, true, "fullname", 'F', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFullName,
6525a988416SJim Ingham         "Set the breakpoint by fully qualified function names. For C++ this means namespaces and all arguments, and "
6535a988416SJim Ingham         "for Objective C this means a full function prototype with class and selector.   "
6545a988416SJim Ingham         "Can be repeated multiple times to make one breakpoint for multiple names." },
6555a988416SJim Ingham 
6565a988416SJim Ingham     { LLDB_OPT_SET_5, true, "selector", 'S', required_argument, NULL, 0, eArgTypeSelector,
6575a988416SJim Ingham         "Set the breakpoint by ObjC selector name. Can be repeated multiple times to make one breakpoint for multiple Selectors." },
6585a988416SJim Ingham 
6595a988416SJim Ingham     { LLDB_OPT_SET_6, true, "method", 'M', required_argument, NULL, 0, eArgTypeMethod,
6605a988416SJim Ingham         "Set the breakpoint by C++ method names.  Can be repeated multiple times to make one breakpoint for multiple methods." },
6615a988416SJim Ingham 
6625a988416SJim Ingham     { LLDB_OPT_SET_7, true, "func-regex", 'r', required_argument, NULL, 0, eArgTypeRegularExpression,
6635a988416SJim Ingham         "Set the breakpoint by function name, evaluating a regular-expression to find the function name(s)." },
6645a988416SJim Ingham 
6655a988416SJim Ingham     { LLDB_OPT_SET_8, true, "basename", 'b', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
6665a988416SJim Ingham         "Set the breakpoint by function basename (C++ namespaces and arguments will be ignored). "
6675a988416SJim Ingham         "Can be repeated multiple times to make one breakpoint for multiple symbols." },
6685a988416SJim Ingham 
6695a988416SJim Ingham     { LLDB_OPT_SET_9, true, "source-pattern-regexp", 'p', required_argument, NULL, 0, eArgTypeRegularExpression,
670*e96ade8bSJim Ingham         "Set the breakpoint by specifying a regular expression which is matched against the source text in a source file or files "
671*e96ade8bSJim Ingham         "specified with the -f option.  The -f option can be specified more than once.  "
672*e96ade8bSJim Ingham         "If no source files are specified, uses the current \"default source file\"" },
6735a988416SJim Ingham 
6745a988416SJim Ingham     { LLDB_OPT_SET_10, true, "language-exception", 'E', required_argument, NULL, 0, eArgTypeLanguage,
6755a988416SJim Ingham         "Set the breakpoint on exceptions thrown by the specified language (without options, on throw but not catch.)" },
6765a988416SJim Ingham 
6775a988416SJim Ingham     { LLDB_OPT_SET_10, false, "on-throw", 'w', required_argument, NULL, 0, eArgTypeBoolean,
6785a988416SJim Ingham         "Set the breakpoint on exception throW." },
6795a988416SJim Ingham 
6805a988416SJim Ingham     { LLDB_OPT_SET_10, false, "on-catch", 'h', required_argument, NULL, 0, eArgTypeBoolean,
6815a988416SJim Ingham         "Set the breakpoint on exception catcH." },
6825a988416SJim Ingham 
6835a988416SJim Ingham     { LLDB_OPT_SKIP_PROLOGUE, false, "skip-prologue", 'K', required_argument, NULL, 0, eArgTypeBoolean,
6845a988416SJim Ingham         "sKip the prologue if the breakpoint is at the beginning of a function.  If not set the target.skip-prologue setting is used." },
6855a988416SJim Ingham 
6865a988416SJim Ingham     { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
6875a988416SJim Ingham };
6885a988416SJim Ingham 
6895a988416SJim Ingham //-------------------------------------------------------------------------
6905a988416SJim Ingham // CommandObjectBreakpointModify
6915a988416SJim Ingham //-------------------------------------------------------------------------
6925a988416SJim Ingham #pragma mark Modify
6935a988416SJim Ingham 
6945a988416SJim Ingham class CommandObjectBreakpointModify : public CommandObjectParsed
6955a988416SJim Ingham {
6965a988416SJim Ingham public:
6975a988416SJim Ingham 
6985a988416SJim Ingham     CommandObjectBreakpointModify (CommandInterpreter &interpreter) :
6995a988416SJim Ingham         CommandObjectParsed (interpreter,
7005a988416SJim Ingham                              "breakpoint modify",
7015a988416SJim Ingham                              "Modify the options on a breakpoint or set of breakpoints in the executable.  "
7025a988416SJim Ingham                              "If no breakpoint is specified, acts on the last created breakpoint.  "
7035a988416SJim Ingham                              "With the exception of -e, -d and -i, passing an empty argument clears the modification.",
7045a988416SJim Ingham                              NULL),
7055a988416SJim Ingham         m_options (interpreter)
7065a988416SJim Ingham     {
7075a988416SJim Ingham         CommandArgumentEntry arg;
7085a988416SJim Ingham         CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
7095a988416SJim Ingham         // Add the entry for the first argument for this command to the object's arguments vector.
7105a988416SJim Ingham         m_arguments.push_back (arg);
7115a988416SJim Ingham     }
7125a988416SJim Ingham 
7135a988416SJim Ingham 
7145a988416SJim Ingham     virtual
7155a988416SJim Ingham     ~CommandObjectBreakpointModify () {}
7165a988416SJim Ingham 
7175a988416SJim Ingham     virtual Options *
7185a988416SJim Ingham     GetOptions ()
7195a988416SJim Ingham     {
7205a988416SJim Ingham         return &m_options;
7215a988416SJim Ingham     }
7225a988416SJim Ingham 
7235a988416SJim Ingham     class CommandOptions : public Options
7245a988416SJim Ingham     {
7255a988416SJim Ingham     public:
7265a988416SJim Ingham 
7275a988416SJim Ingham         CommandOptions (CommandInterpreter &interpreter) :
7285a988416SJim Ingham             Options (interpreter),
7295a988416SJim Ingham             m_ignore_count (0),
7305a988416SJim Ingham             m_thread_id(LLDB_INVALID_THREAD_ID),
7315a988416SJim Ingham             m_thread_id_passed(false),
7325a988416SJim Ingham             m_thread_index (UINT32_MAX),
7335a988416SJim Ingham             m_thread_index_passed(false),
7345a988416SJim Ingham             m_thread_name(),
7355a988416SJim Ingham             m_queue_name(),
7365a988416SJim Ingham             m_condition (),
737ca36cd16SJim Ingham             m_one_shot (false),
7385a988416SJim Ingham             m_enable_passed (false),
7395a988416SJim Ingham             m_enable_value (false),
7405a988416SJim Ingham             m_name_passed (false),
7415a988416SJim Ingham             m_queue_passed (false),
742ca36cd16SJim Ingham             m_condition_passed (false),
743ca36cd16SJim Ingham             m_one_shot_passed (false)
7445a988416SJim Ingham         {
7455a988416SJim Ingham         }
7465a988416SJim Ingham 
7475a988416SJim Ingham         virtual
7485a988416SJim Ingham         ~CommandOptions () {}
7495a988416SJim Ingham 
7505a988416SJim Ingham         virtual Error
7515a988416SJim Ingham         SetOptionValue (uint32_t option_idx, const char *option_arg)
7525a988416SJim Ingham         {
7535a988416SJim Ingham             Error error;
7543bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
7555a988416SJim Ingham 
7565a988416SJim Ingham             switch (short_option)
7575a988416SJim Ingham             {
7585a988416SJim Ingham                 case 'c':
7595a988416SJim Ingham                     if (option_arg != NULL)
7605a988416SJim Ingham                         m_condition.assign (option_arg);
7615a988416SJim Ingham                     else
7625a988416SJim Ingham                         m_condition.clear();
7635a988416SJim Ingham                     m_condition_passed = true;
7645a988416SJim Ingham                     break;
7655a988416SJim Ingham                 case 'd':
7665a988416SJim Ingham                     m_enable_passed = true;
7675a988416SJim Ingham                     m_enable_value = false;
7685a988416SJim Ingham                     break;
7695a988416SJim Ingham                 case 'e':
7705a988416SJim Ingham                     m_enable_passed = true;
7715a988416SJim Ingham                     m_enable_value = true;
7725a988416SJim Ingham                     break;
7735a988416SJim Ingham                 case 'i':
7745a988416SJim Ingham                 {
7755a988416SJim Ingham                     m_ignore_count = Args::StringToUInt32(option_arg, UINT32_MAX, 0);
7765a988416SJim Ingham                     if (m_ignore_count == UINT32_MAX)
7775a988416SJim Ingham                        error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
7785a988416SJim Ingham                 }
7795a988416SJim Ingham                 break;
780ca36cd16SJim Ingham                 case 'o':
781ca36cd16SJim Ingham                 {
782ca36cd16SJim Ingham                     bool value, success;
783ca36cd16SJim Ingham                     value = Args::StringToBoolean(option_arg, false, &success);
784ca36cd16SJim Ingham                     if (success)
785ca36cd16SJim Ingham                     {
786ca36cd16SJim Ingham                         m_one_shot_passed = true;
787ca36cd16SJim Ingham                         m_one_shot = value;
788ca36cd16SJim Ingham                     }
789ca36cd16SJim Ingham                     else
790ca36cd16SJim Ingham                         error.SetErrorStringWithFormat("invalid boolean value '%s' passed for -o option", option_arg);
791ca36cd16SJim Ingham                 }
792ca36cd16SJim Ingham                 break;
7935a988416SJim Ingham                 case 't' :
7945a988416SJim Ingham                 {
7955a988416SJim Ingham                     if (option_arg[0] == '\0')
7965a988416SJim Ingham                     {
7975a988416SJim Ingham                         m_thread_id = LLDB_INVALID_THREAD_ID;
7985a988416SJim Ingham                         m_thread_id_passed = true;
7995a988416SJim Ingham                     }
8005a988416SJim Ingham                     else
8015a988416SJim Ingham                     {
8025a988416SJim Ingham                         m_thread_id = Args::StringToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
8035a988416SJim Ingham                         if (m_thread_id == LLDB_INVALID_THREAD_ID)
8045a988416SJim Ingham                            error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
8055a988416SJim Ingham                         else
8065a988416SJim Ingham                             m_thread_id_passed = true;
8075a988416SJim Ingham                     }
8085a988416SJim Ingham                 }
8095a988416SJim Ingham                 break;
8105a988416SJim Ingham                 case 'T':
8115a988416SJim Ingham                     if (option_arg != NULL)
8125a988416SJim Ingham                         m_thread_name.assign (option_arg);
8135a988416SJim Ingham                     else
8145a988416SJim Ingham                         m_thread_name.clear();
8155a988416SJim Ingham                     m_name_passed = true;
8165a988416SJim Ingham                     break;
8175a988416SJim Ingham                 case 'q':
8185a988416SJim Ingham                     if (option_arg != NULL)
8195a988416SJim Ingham                         m_queue_name.assign (option_arg);
8205a988416SJim Ingham                     else
8215a988416SJim Ingham                         m_queue_name.clear();
8225a988416SJim Ingham                     m_queue_passed = true;
8235a988416SJim Ingham                     break;
8245a988416SJim Ingham                 case 'x':
8255a988416SJim Ingham                 {
8265a988416SJim Ingham                     if (option_arg[0] == '\n')
8275a988416SJim Ingham                     {
8285a988416SJim Ingham                         m_thread_index = UINT32_MAX;
8295a988416SJim Ingham                         m_thread_index_passed = true;
8305a988416SJim Ingham                     }
8315a988416SJim Ingham                     else
8325a988416SJim Ingham                     {
8335a988416SJim Ingham                         m_thread_index = Args::StringToUInt32 (option_arg, UINT32_MAX, 0);
8345a988416SJim Ingham                         if (m_thread_id == UINT32_MAX)
8355a988416SJim Ingham                            error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
8365a988416SJim Ingham                         else
8375a988416SJim Ingham                             m_thread_index_passed = true;
8385a988416SJim Ingham                     }
8395a988416SJim Ingham                 }
8405a988416SJim Ingham                 break;
8415a988416SJim Ingham                 default:
8425a988416SJim Ingham                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
8435a988416SJim Ingham                     break;
8445a988416SJim Ingham             }
8455a988416SJim Ingham 
8465a988416SJim Ingham             return error;
8475a988416SJim Ingham         }
8485a988416SJim Ingham         void
8495a988416SJim Ingham         OptionParsingStarting ()
8505a988416SJim Ingham         {
8515a988416SJim Ingham             m_ignore_count = 0;
8525a988416SJim Ingham             m_thread_id = LLDB_INVALID_THREAD_ID;
8535a988416SJim Ingham             m_thread_id_passed = false;
8545a988416SJim Ingham             m_thread_index = UINT32_MAX;
8555a988416SJim Ingham             m_thread_index_passed = false;
8565a988416SJim Ingham             m_thread_name.clear();
8575a988416SJim Ingham             m_queue_name.clear();
8585a988416SJim Ingham             m_condition.clear();
859ca36cd16SJim Ingham             m_one_shot = false;
8605a988416SJim Ingham             m_enable_passed = false;
8615a988416SJim Ingham             m_queue_passed = false;
8625a988416SJim Ingham             m_name_passed = false;
8635a988416SJim Ingham             m_condition_passed = false;
864ca36cd16SJim Ingham             m_one_shot_passed = false;
8655a988416SJim Ingham         }
8665a988416SJim Ingham 
8675a988416SJim Ingham         const OptionDefinition*
8685a988416SJim Ingham         GetDefinitions ()
8695a988416SJim Ingham         {
8705a988416SJim Ingham             return g_option_table;
8715a988416SJim Ingham         }
8725a988416SJim Ingham 
8735a988416SJim Ingham 
8745a988416SJim Ingham         // Options table: Required for subclasses of Options.
8755a988416SJim Ingham 
8765a988416SJim Ingham         static OptionDefinition g_option_table[];
8775a988416SJim Ingham 
8785a988416SJim Ingham         // Instance variables to hold the values for command options.
8795a988416SJim Ingham 
8805a988416SJim Ingham         uint32_t m_ignore_count;
8815a988416SJim Ingham         lldb::tid_t m_thread_id;
8825a988416SJim Ingham         bool m_thread_id_passed;
8835a988416SJim Ingham         uint32_t m_thread_index;
8845a988416SJim Ingham         bool m_thread_index_passed;
8855a988416SJim Ingham         std::string m_thread_name;
8865a988416SJim Ingham         std::string m_queue_name;
8875a988416SJim Ingham         std::string m_condition;
888ca36cd16SJim Ingham         bool m_one_shot;
8895a988416SJim Ingham         bool m_enable_passed;
8905a988416SJim Ingham         bool m_enable_value;
8915a988416SJim Ingham         bool m_name_passed;
8925a988416SJim Ingham         bool m_queue_passed;
8935a988416SJim Ingham         bool m_condition_passed;
894ca36cd16SJim Ingham         bool m_one_shot_passed;
8955a988416SJim Ingham 
8965a988416SJim Ingham     };
8975a988416SJim Ingham 
8985a988416SJim Ingham protected:
8995a988416SJim Ingham     virtual bool
9005a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
9015a988416SJim Ingham     {
9025a988416SJim Ingham         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
9035a988416SJim Ingham         if (target == NULL)
9045a988416SJim Ingham         {
9055a988416SJim Ingham             result.AppendError ("Invalid target.  No existing target or breakpoints.");
9065a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
9075a988416SJim Ingham             return false;
9085a988416SJim Ingham         }
9095a988416SJim Ingham 
9105a988416SJim Ingham         Mutex::Locker locker;
9115a988416SJim Ingham         target->GetBreakpointList().GetListMutex(locker);
9125a988416SJim Ingham 
9135a988416SJim Ingham         BreakpointIDList valid_bp_ids;
9145a988416SJim Ingham 
9155a988416SJim Ingham         CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
9165a988416SJim Ingham 
9175a988416SJim Ingham         if (result.Succeeded())
9185a988416SJim Ingham         {
9195a988416SJim Ingham             const size_t count = valid_bp_ids.GetSize();
9205a988416SJim Ingham             for (size_t i = 0; i < count; ++i)
9215a988416SJim Ingham             {
9225a988416SJim Ingham                 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
9235a988416SJim Ingham 
9245a988416SJim Ingham                 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
9255a988416SJim Ingham                 {
9265a988416SJim Ingham                     Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
9275a988416SJim Ingham                     if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
9285a988416SJim Ingham                     {
9295a988416SJim Ingham                         BreakpointLocation *location = bp->FindLocationByID (cur_bp_id.GetLocationID()).get();
9305a988416SJim Ingham                         if (location)
9315a988416SJim Ingham                         {
9325a988416SJim Ingham                             if (m_options.m_thread_id_passed)
9335a988416SJim Ingham                                 location->SetThreadID (m_options.m_thread_id);
9345a988416SJim Ingham 
9355a988416SJim Ingham                             if (m_options.m_thread_index_passed)
9365a988416SJim Ingham                                 location->SetThreadIndex(m_options.m_thread_index);
9375a988416SJim Ingham 
9385a988416SJim Ingham                             if (m_options.m_name_passed)
9395a988416SJim Ingham                                 location->SetThreadName(m_options.m_thread_name.c_str());
9405a988416SJim Ingham 
9415a988416SJim Ingham                             if (m_options.m_queue_passed)
9425a988416SJim Ingham                                 location->SetQueueName(m_options.m_queue_name.c_str());
9435a988416SJim Ingham 
9445a988416SJim Ingham                             if (m_options.m_ignore_count != 0)
9455a988416SJim Ingham                                 location->SetIgnoreCount(m_options.m_ignore_count);
9465a988416SJim Ingham 
9475a988416SJim Ingham                             if (m_options.m_enable_passed)
9485a988416SJim Ingham                                 location->SetEnabled (m_options.m_enable_value);
9495a988416SJim Ingham 
9505a988416SJim Ingham                             if (m_options.m_condition_passed)
9515a988416SJim Ingham                                 location->SetCondition (m_options.m_condition.c_str());
9525a988416SJim Ingham                         }
9535a988416SJim Ingham                     }
9545a988416SJim Ingham                     else
9555a988416SJim Ingham                     {
9565a988416SJim Ingham                         if (m_options.m_thread_id_passed)
9575a988416SJim Ingham                             bp->SetThreadID (m_options.m_thread_id);
9585a988416SJim Ingham 
9595a988416SJim Ingham                         if (m_options.m_thread_index_passed)
9605a988416SJim Ingham                             bp->SetThreadIndex(m_options.m_thread_index);
9615a988416SJim Ingham 
9625a988416SJim Ingham                         if (m_options.m_name_passed)
9635a988416SJim Ingham                             bp->SetThreadName(m_options.m_thread_name.c_str());
9645a988416SJim Ingham 
9655a988416SJim Ingham                         if (m_options.m_queue_passed)
9665a988416SJim Ingham                             bp->SetQueueName(m_options.m_queue_name.c_str());
9675a988416SJim Ingham 
9685a988416SJim Ingham                         if (m_options.m_ignore_count != 0)
9695a988416SJim Ingham                             bp->SetIgnoreCount(m_options.m_ignore_count);
9705a988416SJim Ingham 
9715a988416SJim Ingham                         if (m_options.m_enable_passed)
9725a988416SJim Ingham                             bp->SetEnabled (m_options.m_enable_value);
9735a988416SJim Ingham 
9745a988416SJim Ingham                         if (m_options.m_condition_passed)
9755a988416SJim Ingham                             bp->SetCondition (m_options.m_condition.c_str());
9765a988416SJim Ingham                     }
9775a988416SJim Ingham                 }
9785a988416SJim Ingham             }
9795a988416SJim Ingham         }
9805a988416SJim Ingham 
9815a988416SJim Ingham         return result.Succeeded();
9825a988416SJim Ingham     }
9835a988416SJim Ingham 
9845a988416SJim Ingham private:
9855a988416SJim Ingham     CommandOptions m_options;
9865a988416SJim Ingham };
9875a988416SJim Ingham 
9885a988416SJim Ingham #pragma mark Modify::CommandOptions
9895a988416SJim Ingham OptionDefinition
9905a988416SJim Ingham CommandObjectBreakpointModify::CommandOptions::g_option_table[] =
9915a988416SJim Ingham {
9925a988416SJim Ingham { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', required_argument, NULL, 0, eArgTypeCount, "Set the number of times this breakpoint is skipped before stopping." },
993ca36cd16SJim Ingham { LLDB_OPT_SET_ALL, false, "one-shot",     'o', required_argument, NULL, 0, eArgTypeBoolean, "The breakpoint is deleted the first time it stop causes a stop." },
994bce7c77dSSean Callanan { LLDB_OPT_SET_ALL, false, "thread-index", 'x', required_argument, NULL, 0, eArgTypeThreadIndex, "The breakpoint stops only for the thread whose index matches this argument."},
9955a988416SJim Ingham { LLDB_OPT_SET_ALL, false, "thread-id",    't', required_argument, NULL, 0, eArgTypeThreadID, "The breakpoint stops only for the thread whose TID matches this argument."},
9965a988416SJim Ingham { LLDB_OPT_SET_ALL, false, "thread-name",  'T', required_argument, NULL, 0, eArgTypeThreadName, "The breakpoint stops only for the thread whose thread name matches this argument."},
9975a988416SJim Ingham { LLDB_OPT_SET_ALL, false, "queue-name",   'q', required_argument, NULL, 0, eArgTypeQueueName, "The breakpoint stops only for threads in the queue whose name is given by this argument."},
9985a988416SJim Ingham { LLDB_OPT_SET_ALL, false, "condition",    'c', required_argument, NULL, 0, eArgTypeExpression, "The breakpoint stops only if this condition expression evaluates to true."},
9995a988416SJim Ingham { LLDB_OPT_SET_1,   false, "enable",       'e', no_argument,       NULL, 0, eArgTypeNone, "Enable the breakpoint."},
10005a988416SJim Ingham { LLDB_OPT_SET_2,   false, "disable",      'd', no_argument,       NULL, 0, eArgTypeNone, "Disable the breakpoint."},
10015a988416SJim Ingham { 0,                false, NULL,            0 , 0,                 NULL, 0, eArgTypeNone, NULL }
10025a988416SJim Ingham };
10035a988416SJim Ingham 
10045a988416SJim Ingham //-------------------------------------------------------------------------
10055a988416SJim Ingham // CommandObjectBreakpointEnable
10065a988416SJim Ingham //-------------------------------------------------------------------------
10075a988416SJim Ingham #pragma mark Enable
10085a988416SJim Ingham 
10095a988416SJim Ingham class CommandObjectBreakpointEnable : public CommandObjectParsed
10105a988416SJim Ingham {
10115a988416SJim Ingham public:
10125a988416SJim Ingham     CommandObjectBreakpointEnable (CommandInterpreter &interpreter) :
10135a988416SJim Ingham         CommandObjectParsed (interpreter,
10145a988416SJim Ingham                              "enable",
10155a988416SJim Ingham                              "Enable the specified disabled breakpoint(s). If no breakpoints are specified, enable all of them.",
10165a988416SJim Ingham                              NULL)
10175a988416SJim Ingham     {
10185a988416SJim Ingham         CommandArgumentEntry arg;
10195a988416SJim Ingham         CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
10205a988416SJim Ingham         // Add the entry for the first argument for this command to the object's arguments vector.
10215a988416SJim Ingham         m_arguments.push_back (arg);
10225a988416SJim Ingham     }
10235a988416SJim Ingham 
10245a988416SJim Ingham 
10255a988416SJim Ingham     virtual
10265a988416SJim Ingham     ~CommandObjectBreakpointEnable () {}
10275a988416SJim Ingham 
10285a988416SJim Ingham protected:
10295a988416SJim Ingham     virtual bool
10305a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
10315a988416SJim Ingham     {
10325a988416SJim Ingham         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
10335a988416SJim Ingham         if (target == NULL)
10345a988416SJim Ingham         {
10355a988416SJim Ingham             result.AppendError ("Invalid target.  No existing target or breakpoints.");
10365a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
10375a988416SJim Ingham             return false;
10385a988416SJim Ingham         }
10395a988416SJim Ingham 
10405a988416SJim Ingham         Mutex::Locker locker;
10415a988416SJim Ingham         target->GetBreakpointList().GetListMutex(locker);
10425a988416SJim Ingham 
10435a988416SJim Ingham         const BreakpointList &breakpoints = target->GetBreakpointList();
10445a988416SJim Ingham 
10455a988416SJim Ingham         size_t num_breakpoints = breakpoints.GetSize();
10465a988416SJim Ingham 
10475a988416SJim Ingham         if (num_breakpoints == 0)
10485a988416SJim Ingham         {
10495a988416SJim Ingham             result.AppendError ("No breakpoints exist to be enabled.");
10505a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
10515a988416SJim Ingham             return false;
10525a988416SJim Ingham         }
10535a988416SJim Ingham 
10545a988416SJim Ingham         if (command.GetArgumentCount() == 0)
10555a988416SJim Ingham         {
10565a988416SJim Ingham             // No breakpoint selected; enable all currently set breakpoints.
10575a988416SJim Ingham             target->EnableAllBreakpoints ();
10585a988416SJim Ingham             result.AppendMessageWithFormat ("All breakpoints enabled. (%lu breakpoints)\n", num_breakpoints);
10595a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
10605a988416SJim Ingham         }
10615a988416SJim Ingham         else
10625a988416SJim Ingham         {
10635a988416SJim Ingham             // Particular breakpoint selected; enable that breakpoint.
10645a988416SJim Ingham             BreakpointIDList valid_bp_ids;
10655a988416SJim Ingham             CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
10665a988416SJim Ingham 
10675a988416SJim Ingham             if (result.Succeeded())
10685a988416SJim Ingham             {
10695a988416SJim Ingham                 int enable_count = 0;
10705a988416SJim Ingham                 int loc_count = 0;
10715a988416SJim Ingham                 const size_t count = valid_bp_ids.GetSize();
10725a988416SJim Ingham                 for (size_t i = 0; i < count; ++i)
10735a988416SJim Ingham                 {
10745a988416SJim Ingham                     BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
10755a988416SJim Ingham 
10765a988416SJim Ingham                     if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
10775a988416SJim Ingham                     {
10785a988416SJim Ingham                         Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
10795a988416SJim Ingham                         if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
10805a988416SJim Ingham                         {
10815a988416SJim Ingham                             BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
10825a988416SJim Ingham                             if (location)
10835a988416SJim Ingham                             {
10845a988416SJim Ingham                                 location->SetEnabled (true);
10855a988416SJim Ingham                                 ++loc_count;
10865a988416SJim Ingham                             }
10875a988416SJim Ingham                         }
10885a988416SJim Ingham                         else
10895a988416SJim Ingham                         {
10905a988416SJim Ingham                             breakpoint->SetEnabled (true);
10915a988416SJim Ingham                             ++enable_count;
10925a988416SJim Ingham                         }
10935a988416SJim Ingham                     }
10945a988416SJim Ingham                 }
10955a988416SJim Ingham                 result.AppendMessageWithFormat ("%d breakpoints enabled.\n", enable_count + loc_count);
10965a988416SJim Ingham                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
10975a988416SJim Ingham             }
10985a988416SJim Ingham         }
10995a988416SJim Ingham 
11005a988416SJim Ingham         return result.Succeeded();
11015a988416SJim Ingham     }
11025a988416SJim Ingham };
11035a988416SJim Ingham 
11045a988416SJim Ingham //-------------------------------------------------------------------------
11055a988416SJim Ingham // CommandObjectBreakpointDisable
11065a988416SJim Ingham //-------------------------------------------------------------------------
11075a988416SJim Ingham #pragma mark Disable
11085a988416SJim Ingham 
11095a988416SJim Ingham class CommandObjectBreakpointDisable : public CommandObjectParsed
11105a988416SJim Ingham {
11115a988416SJim Ingham public:
11125a988416SJim Ingham     CommandObjectBreakpointDisable (CommandInterpreter &interpreter) :
11135a988416SJim Ingham         CommandObjectParsed (interpreter,
11145a988416SJim Ingham                              "breakpoint disable",
11155a988416SJim Ingham                              "Disable the specified breakpoint(s) without removing it/them.  If no breakpoints are specified, disable them all.",
11165a988416SJim Ingham                              NULL)
11175a988416SJim Ingham     {
1118b0fac509SJim Ingham         SetHelpLong(
1119b0fac509SJim Ingham "Disable the specified breakpoint(s) without removing it/them.  \n\
1120b0fac509SJim Ingham If no breakpoints are specified, disable them all.\n\
1121b0fac509SJim Ingham \n\
1122b0fac509SJim Ingham Note: disabling a breakpoint will cause none of its locations to be hit\n\
1123b0fac509SJim Ingham regardless of whether they are enabled or disabled.  So the sequence: \n\
1124b0fac509SJim Ingham \n\
1125b0fac509SJim Ingham     (lldb) break disable 1\n\
1126b0fac509SJim Ingham     (lldb) break enable 1.1\n\
1127b0fac509SJim Ingham \n\
1128b0fac509SJim Ingham will NOT cause location 1.1 to get hit.  To achieve that, do:\n\
1129b0fac509SJim Ingham \n\
1130b0fac509SJim Ingham     (lldb) break disable 1.*\n\
1131b0fac509SJim Ingham     (lldb) break enable 1.1\n\
1132b0fac509SJim Ingham \n\
1133b0fac509SJim Ingham The first command disables all the locations of breakpoint 1, \n\
1134b0fac509SJim Ingham the second re-enables the first location."
1135b0fac509SJim Ingham                     );
1136b0fac509SJim Ingham 
11375a988416SJim Ingham         CommandArgumentEntry arg;
11385a988416SJim Ingham         CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
11395a988416SJim Ingham         // Add the entry for the first argument for this command to the object's arguments vector.
11405a988416SJim Ingham         m_arguments.push_back (arg);
1141b0fac509SJim Ingham 
11425a988416SJim Ingham     }
11435a988416SJim Ingham 
11445a988416SJim Ingham 
11455a988416SJim Ingham     virtual
11465a988416SJim Ingham     ~CommandObjectBreakpointDisable () {}
11475a988416SJim Ingham 
11485a988416SJim Ingham protected:
11495a988416SJim Ingham     virtual bool
11505a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
11515a988416SJim Ingham     {
11525a988416SJim Ingham         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
11535a988416SJim Ingham         if (target == NULL)
11545a988416SJim Ingham         {
11555a988416SJim Ingham             result.AppendError ("Invalid target.  No existing target or breakpoints.");
11565a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
11575a988416SJim Ingham             return false;
11585a988416SJim Ingham         }
11595a988416SJim Ingham 
11605a988416SJim Ingham         Mutex::Locker locker;
11615a988416SJim Ingham         target->GetBreakpointList().GetListMutex(locker);
11625a988416SJim Ingham 
11635a988416SJim Ingham         const BreakpointList &breakpoints = target->GetBreakpointList();
11645a988416SJim Ingham         size_t num_breakpoints = breakpoints.GetSize();
11655a988416SJim Ingham 
11665a988416SJim Ingham         if (num_breakpoints == 0)
11675a988416SJim Ingham         {
11685a988416SJim Ingham             result.AppendError ("No breakpoints exist to be disabled.");
11695a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
11705a988416SJim Ingham             return false;
11715a988416SJim Ingham         }
11725a988416SJim Ingham 
11735a988416SJim Ingham         if (command.GetArgumentCount() == 0)
11745a988416SJim Ingham         {
11755a988416SJim Ingham             // No breakpoint selected; disable all currently set breakpoints.
11765a988416SJim Ingham             target->DisableAllBreakpoints ();
11775a988416SJim Ingham             result.AppendMessageWithFormat ("All breakpoints disabled. (%lu breakpoints)\n", num_breakpoints);
11785a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
11795a988416SJim Ingham         }
11805a988416SJim Ingham         else
11815a988416SJim Ingham         {
11825a988416SJim Ingham             // Particular breakpoint selected; disable that breakpoint.
11835a988416SJim Ingham             BreakpointIDList valid_bp_ids;
11845a988416SJim Ingham 
11855a988416SJim Ingham             CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
11865a988416SJim Ingham 
11875a988416SJim Ingham             if (result.Succeeded())
11885a988416SJim Ingham             {
11895a988416SJim Ingham                 int disable_count = 0;
11905a988416SJim Ingham                 int loc_count = 0;
11915a988416SJim Ingham                 const size_t count = valid_bp_ids.GetSize();
11925a988416SJim Ingham                 for (size_t i = 0; i < count; ++i)
11935a988416SJim Ingham                 {
11945a988416SJim Ingham                     BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
11955a988416SJim Ingham 
11965a988416SJim Ingham                     if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
11975a988416SJim Ingham                     {
11985a988416SJim Ingham                         Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
11995a988416SJim Ingham                         if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
12005a988416SJim Ingham                         {
12015a988416SJim Ingham                             BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
12025a988416SJim Ingham                             if (location)
12035a988416SJim Ingham                             {
12045a988416SJim Ingham                                 location->SetEnabled (false);
12055a988416SJim Ingham                                 ++loc_count;
12065a988416SJim Ingham                             }
12075a988416SJim Ingham                         }
12085a988416SJim Ingham                         else
12095a988416SJim Ingham                         {
12105a988416SJim Ingham                             breakpoint->SetEnabled (false);
12115a988416SJim Ingham                             ++disable_count;
12125a988416SJim Ingham                         }
12135a988416SJim Ingham                     }
12145a988416SJim Ingham                 }
12155a988416SJim Ingham                 result.AppendMessageWithFormat ("%d breakpoints disabled.\n", disable_count + loc_count);
12165a988416SJim Ingham                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
12175a988416SJim Ingham             }
12185a988416SJim Ingham         }
12195a988416SJim Ingham 
12205a988416SJim Ingham         return result.Succeeded();
12215a988416SJim Ingham     }
12225a988416SJim Ingham 
12235a988416SJim Ingham };
12245a988416SJim Ingham 
12255a988416SJim Ingham //-------------------------------------------------------------------------
12265a988416SJim Ingham // CommandObjectBreakpointList
12275a988416SJim Ingham //-------------------------------------------------------------------------
12285a988416SJim Ingham #pragma mark List
12295a988416SJim Ingham 
12305a988416SJim Ingham class CommandObjectBreakpointList : public CommandObjectParsed
12315a988416SJim Ingham {
12325a988416SJim Ingham public:
12335a988416SJim Ingham     CommandObjectBreakpointList (CommandInterpreter &interpreter) :
12345a988416SJim Ingham         CommandObjectParsed (interpreter,
12355a988416SJim Ingham                              "breakpoint list",
12365a988416SJim Ingham                              "List some or all breakpoints at configurable levels of detail.",
12375a988416SJim Ingham                              NULL),
12385a988416SJim Ingham         m_options (interpreter)
12395a988416SJim Ingham     {
12405a988416SJim Ingham         CommandArgumentEntry arg;
12415a988416SJim Ingham         CommandArgumentData bp_id_arg;
12425a988416SJim Ingham 
12435a988416SJim Ingham         // Define the first (and only) variant of this arg.
12445a988416SJim Ingham         bp_id_arg.arg_type = eArgTypeBreakpointID;
12455a988416SJim Ingham         bp_id_arg.arg_repetition = eArgRepeatOptional;
12465a988416SJim Ingham 
12475a988416SJim Ingham         // There is only one variant this argument could be; put it into the argument entry.
12485a988416SJim Ingham         arg.push_back (bp_id_arg);
12495a988416SJim Ingham 
12505a988416SJim Ingham         // Push the data for the first argument into the m_arguments vector.
12515a988416SJim Ingham         m_arguments.push_back (arg);
12525a988416SJim Ingham     }
12535a988416SJim Ingham 
12545a988416SJim Ingham 
12555a988416SJim Ingham     virtual
12565a988416SJim Ingham     ~CommandObjectBreakpointList () {}
12575a988416SJim Ingham 
12585a988416SJim Ingham     virtual Options *
12595a988416SJim Ingham     GetOptions ()
12605a988416SJim Ingham     {
12615a988416SJim Ingham         return &m_options;
12625a988416SJim Ingham     }
12635a988416SJim Ingham 
12645a988416SJim Ingham     class CommandOptions : public Options
12655a988416SJim Ingham     {
12665a988416SJim Ingham     public:
12675a988416SJim Ingham 
12685a988416SJim Ingham         CommandOptions (CommandInterpreter &interpreter) :
12695a988416SJim Ingham             Options (interpreter),
12705a988416SJim Ingham             m_level (lldb::eDescriptionLevelBrief)  // Breakpoint List defaults to brief descriptions
12715a988416SJim Ingham         {
12725a988416SJim Ingham         }
12735a988416SJim Ingham 
12745a988416SJim Ingham         virtual
12755a988416SJim Ingham         ~CommandOptions () {}
12765a988416SJim Ingham 
12775a988416SJim Ingham         virtual Error
12785a988416SJim Ingham         SetOptionValue (uint32_t option_idx, const char *option_arg)
12795a988416SJim Ingham         {
12805a988416SJim Ingham             Error error;
12813bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
12825a988416SJim Ingham 
12835a988416SJim Ingham             switch (short_option)
12845a988416SJim Ingham             {
12855a988416SJim Ingham                 case 'b':
12865a988416SJim Ingham                     m_level = lldb::eDescriptionLevelBrief;
12875a988416SJim Ingham                     break;
12885a988416SJim Ingham                 case 'f':
12895a988416SJim Ingham                     m_level = lldb::eDescriptionLevelFull;
12905a988416SJim Ingham                     break;
12915a988416SJim Ingham                 case 'v':
12925a988416SJim Ingham                     m_level = lldb::eDescriptionLevelVerbose;
12935a988416SJim Ingham                     break;
12945a988416SJim Ingham                 case 'i':
12955a988416SJim Ingham                     m_internal = true;
12965a988416SJim Ingham                     break;
12975a988416SJim Ingham                 default:
12985a988416SJim Ingham                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
12995a988416SJim Ingham                     break;
13005a988416SJim Ingham             }
13015a988416SJim Ingham 
13025a988416SJim Ingham             return error;
13035a988416SJim Ingham         }
13045a988416SJim Ingham 
13055a988416SJim Ingham         void
13065a988416SJim Ingham         OptionParsingStarting ()
13075a988416SJim Ingham         {
13085a988416SJim Ingham             m_level = lldb::eDescriptionLevelFull;
13095a988416SJim Ingham             m_internal = false;
13105a988416SJim Ingham         }
13115a988416SJim Ingham 
13125a988416SJim Ingham         const OptionDefinition *
13135a988416SJim Ingham         GetDefinitions ()
13145a988416SJim Ingham         {
13155a988416SJim Ingham             return g_option_table;
13165a988416SJim Ingham         }
13175a988416SJim Ingham 
13185a988416SJim Ingham         // Options table: Required for subclasses of Options.
13195a988416SJim Ingham 
13205a988416SJim Ingham         static OptionDefinition g_option_table[];
13215a988416SJim Ingham 
13225a988416SJim Ingham         // Instance variables to hold the values for command options.
13235a988416SJim Ingham 
13245a988416SJim Ingham         lldb::DescriptionLevel m_level;
13255a988416SJim Ingham 
13265a988416SJim Ingham         bool m_internal;
13275a988416SJim Ingham     };
13285a988416SJim Ingham 
13295a988416SJim Ingham protected:
13305a988416SJim Ingham     virtual bool
13315a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
13325a988416SJim Ingham     {
13335a988416SJim Ingham         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
13345a988416SJim Ingham         if (target == NULL)
13355a988416SJim Ingham         {
13365a988416SJim Ingham             result.AppendError ("Invalid target. No current target or breakpoints.");
13375a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
13385a988416SJim Ingham             return true;
13395a988416SJim Ingham         }
13405a988416SJim Ingham 
13415a988416SJim Ingham         const BreakpointList &breakpoints = target->GetBreakpointList(m_options.m_internal);
13425a988416SJim Ingham         Mutex::Locker locker;
13435a988416SJim Ingham         target->GetBreakpointList(m_options.m_internal).GetListMutex(locker);
13445a988416SJim Ingham 
13455a988416SJim Ingham         size_t num_breakpoints = breakpoints.GetSize();
13465a988416SJim Ingham 
13475a988416SJim Ingham         if (num_breakpoints == 0)
13485a988416SJim Ingham         {
13495a988416SJim Ingham             result.AppendMessage ("No breakpoints currently set.");
13505a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
13515a988416SJim Ingham             return true;
13525a988416SJim Ingham         }
13535a988416SJim Ingham 
13545a988416SJim Ingham         Stream &output_stream = result.GetOutputStream();
13555a988416SJim Ingham 
13565a988416SJim Ingham         if (command.GetArgumentCount() == 0)
13575a988416SJim Ingham         {
13585a988416SJim Ingham             // No breakpoint selected; show info about all currently set breakpoints.
13595a988416SJim Ingham             result.AppendMessage ("Current breakpoints:");
13605a988416SJim Ingham             for (size_t i = 0; i < num_breakpoints; ++i)
13615a988416SJim Ingham             {
13625a988416SJim Ingham                 Breakpoint *breakpoint = breakpoints.GetBreakpointAtIndex (i).get();
13635a988416SJim Ingham                 AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
13645a988416SJim Ingham             }
13655a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
13665a988416SJim Ingham         }
13675a988416SJim Ingham         else
13685a988416SJim Ingham         {
13695a988416SJim Ingham             // Particular breakpoints selected; show info about that breakpoint.
13705a988416SJim Ingham             BreakpointIDList valid_bp_ids;
13715a988416SJim Ingham             CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
13725a988416SJim Ingham 
13735a988416SJim Ingham             if (result.Succeeded())
13745a988416SJim Ingham             {
13755a988416SJim Ingham                 for (size_t i = 0; i < valid_bp_ids.GetSize(); ++i)
13765a988416SJim Ingham                 {
13775a988416SJim Ingham                     BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
13785a988416SJim Ingham                     Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
13795a988416SJim Ingham                     AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
13805a988416SJim Ingham                 }
13815a988416SJim Ingham                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
13825a988416SJim Ingham             }
13835a988416SJim Ingham             else
13845a988416SJim Ingham             {
13855a988416SJim Ingham                 result.AppendError ("Invalid breakpoint id.");
13865a988416SJim Ingham                 result.SetStatus (eReturnStatusFailed);
13875a988416SJim Ingham             }
13885a988416SJim Ingham         }
13895a988416SJim Ingham 
13905a988416SJim Ingham         return result.Succeeded();
13915a988416SJim Ingham     }
13925a988416SJim Ingham 
13935a988416SJim Ingham private:
13945a988416SJim Ingham     CommandOptions m_options;
13955a988416SJim Ingham };
13965a988416SJim Ingham 
13975a988416SJim Ingham #pragma mark List::CommandOptions
13985a988416SJim Ingham OptionDefinition
13995a988416SJim Ingham CommandObjectBreakpointList::CommandOptions::g_option_table[] =
14005a988416SJim Ingham {
14015a988416SJim Ingham     { LLDB_OPT_SET_ALL, false, "internal", 'i', no_argument, NULL, 0, eArgTypeNone,
14025a988416SJim Ingham         "Show debugger internal breakpoints" },
14035a988416SJim Ingham 
14045a988416SJim Ingham     { LLDB_OPT_SET_1, false, "brief",    'b', no_argument, NULL, 0, eArgTypeNone,
14055a988416SJim Ingham         "Give a brief description of the breakpoint (no location info)."},
14065a988416SJim Ingham 
14075a988416SJim Ingham     // FIXME: We need to add an "internal" command, and then add this sort of thing to it.
14085a988416SJim Ingham     // But I need to see it for now, and don't want to wait.
14095a988416SJim Ingham     { LLDB_OPT_SET_2, false, "full",    'f', no_argument, NULL, 0, eArgTypeNone,
14105a988416SJim Ingham         "Give a full description of the breakpoint and its locations."},
14115a988416SJim Ingham 
14125a988416SJim Ingham     { LLDB_OPT_SET_3, false, "verbose", 'v', no_argument, NULL, 0, eArgTypeNone,
14135a988416SJim Ingham         "Explain everything we know about the breakpoint (for debugging debugger bugs)." },
14145a988416SJim Ingham 
14155a988416SJim Ingham     { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
14165a988416SJim Ingham };
14175a988416SJim Ingham 
14185a988416SJim Ingham //-------------------------------------------------------------------------
14195a988416SJim Ingham // CommandObjectBreakpointClear
14205a988416SJim Ingham //-------------------------------------------------------------------------
14215a988416SJim Ingham #pragma mark Clear
14225a988416SJim Ingham 
14235a988416SJim Ingham class CommandObjectBreakpointClear : public CommandObjectParsed
14245a988416SJim Ingham {
14255a988416SJim Ingham public:
14265a988416SJim Ingham 
14275a988416SJim Ingham     typedef enum BreakpointClearType
14285a988416SJim Ingham     {
14295a988416SJim Ingham         eClearTypeInvalid,
14305a988416SJim Ingham         eClearTypeFileAndLine
14315a988416SJim Ingham     } BreakpointClearType;
14325a988416SJim Ingham 
14335a988416SJim Ingham     CommandObjectBreakpointClear (CommandInterpreter &interpreter) :
14345a988416SJim Ingham         CommandObjectParsed (interpreter,
14355a988416SJim Ingham                              "breakpoint clear",
14365a988416SJim Ingham                              "Clears a breakpoint or set of breakpoints in the executable.",
14375a988416SJim Ingham                              "breakpoint clear <cmd-options>"),
14385a988416SJim Ingham         m_options (interpreter)
14395a988416SJim Ingham     {
14405a988416SJim Ingham     }
14415a988416SJim Ingham 
14425a988416SJim Ingham     virtual
14435a988416SJim Ingham     ~CommandObjectBreakpointClear () {}
14445a988416SJim Ingham 
14455a988416SJim Ingham     virtual Options *
14465a988416SJim Ingham     GetOptions ()
14475a988416SJim Ingham     {
14485a988416SJim Ingham         return &m_options;
14495a988416SJim Ingham     }
14505a988416SJim Ingham 
14515a988416SJim Ingham     class CommandOptions : public Options
14525a988416SJim Ingham     {
14535a988416SJim Ingham     public:
14545a988416SJim Ingham 
14555a988416SJim Ingham         CommandOptions (CommandInterpreter &interpreter) :
14565a988416SJim Ingham             Options (interpreter),
14575a988416SJim Ingham             m_filename (),
14585a988416SJim Ingham             m_line_num (0)
14595a988416SJim Ingham         {
14605a988416SJim Ingham         }
14615a988416SJim Ingham 
14625a988416SJim Ingham         virtual
14635a988416SJim Ingham         ~CommandOptions () {}
14645a988416SJim Ingham 
14655a988416SJim Ingham         virtual Error
14665a988416SJim Ingham         SetOptionValue (uint32_t option_idx, const char *option_arg)
14675a988416SJim Ingham         {
14685a988416SJim Ingham             Error error;
14693bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
14705a988416SJim Ingham 
14715a988416SJim Ingham             switch (short_option)
14725a988416SJim Ingham             {
14735a988416SJim Ingham                 case 'f':
14745a988416SJim Ingham                     m_filename.assign (option_arg);
14755a988416SJim Ingham                     break;
14765a988416SJim Ingham 
14775a988416SJim Ingham                 case 'l':
14785a988416SJim Ingham                     m_line_num = Args::StringToUInt32 (option_arg, 0);
14795a988416SJim Ingham                     break;
14805a988416SJim Ingham 
14815a988416SJim Ingham                 default:
14825a988416SJim Ingham                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
14835a988416SJim Ingham                     break;
14845a988416SJim Ingham             }
14855a988416SJim Ingham 
14865a988416SJim Ingham             return error;
14875a988416SJim Ingham         }
14885a988416SJim Ingham 
14895a988416SJim Ingham         void
14905a988416SJim Ingham         OptionParsingStarting ()
14915a988416SJim Ingham         {
14925a988416SJim Ingham             m_filename.clear();
14935a988416SJim Ingham             m_line_num = 0;
14945a988416SJim Ingham         }
14955a988416SJim Ingham 
14965a988416SJim Ingham         const OptionDefinition*
14975a988416SJim Ingham         GetDefinitions ()
14985a988416SJim Ingham         {
14995a988416SJim Ingham             return g_option_table;
15005a988416SJim Ingham         }
15015a988416SJim Ingham 
15025a988416SJim Ingham         // Options table: Required for subclasses of Options.
15035a988416SJim Ingham 
15045a988416SJim Ingham         static OptionDefinition g_option_table[];
15055a988416SJim Ingham 
15065a988416SJim Ingham         // Instance variables to hold the values for command options.
15075a988416SJim Ingham 
15085a988416SJim Ingham         std::string m_filename;
15095a988416SJim Ingham         uint32_t m_line_num;
15105a988416SJim Ingham 
15115a988416SJim Ingham     };
15125a988416SJim Ingham 
15135a988416SJim Ingham protected:
15145a988416SJim Ingham     virtual bool
15155a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
15165a988416SJim Ingham     {
15175a988416SJim Ingham         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
15185a988416SJim Ingham         if (target == NULL)
15195a988416SJim Ingham         {
15205a988416SJim Ingham             result.AppendError ("Invalid target. No existing target or breakpoints.");
15215a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
15225a988416SJim Ingham             return false;
15235a988416SJim Ingham         }
15245a988416SJim Ingham 
15255a988416SJim Ingham         // The following are the various types of breakpoints that could be cleared:
15265a988416SJim Ingham         //   1). -f -l (clearing breakpoint by source location)
15275a988416SJim Ingham 
15285a988416SJim Ingham         BreakpointClearType break_type = eClearTypeInvalid;
15295a988416SJim Ingham 
15305a988416SJim Ingham         if (m_options.m_line_num != 0)
15315a988416SJim Ingham             break_type = eClearTypeFileAndLine;
15325a988416SJim Ingham 
15335a988416SJim Ingham         Mutex::Locker locker;
15345a988416SJim Ingham         target->GetBreakpointList().GetListMutex(locker);
15355a988416SJim Ingham 
15365a988416SJim Ingham         BreakpointList &breakpoints = target->GetBreakpointList();
15375a988416SJim Ingham         size_t num_breakpoints = breakpoints.GetSize();
15385a988416SJim Ingham 
15395a988416SJim Ingham         // Early return if there's no breakpoint at all.
15405a988416SJim Ingham         if (num_breakpoints == 0)
15415a988416SJim Ingham         {
15425a988416SJim Ingham             result.AppendError ("Breakpoint clear: No breakpoint cleared.");
15435a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
15445a988416SJim Ingham             return result.Succeeded();
15455a988416SJim Ingham         }
15465a988416SJim Ingham 
15475a988416SJim Ingham         // Find matching breakpoints and delete them.
15485a988416SJim Ingham 
15495a988416SJim Ingham         // First create a copy of all the IDs.
15505a988416SJim Ingham         std::vector<break_id_t> BreakIDs;
15515a988416SJim Ingham         for (size_t i = 0; i < num_breakpoints; ++i)
15525a988416SJim Ingham             BreakIDs.push_back(breakpoints.GetBreakpointAtIndex(i).get()->GetID());
15535a988416SJim Ingham 
15545a988416SJim Ingham         int num_cleared = 0;
15555a988416SJim Ingham         StreamString ss;
15565a988416SJim Ingham         switch (break_type)
15575a988416SJim Ingham         {
15585a988416SJim Ingham             case eClearTypeFileAndLine: // Breakpoint by source position
15595a988416SJim Ingham                 {
15605a988416SJim Ingham                     const ConstString filename(m_options.m_filename.c_str());
15615a988416SJim Ingham                     BreakpointLocationCollection loc_coll;
15625a988416SJim Ingham 
15635a988416SJim Ingham                     for (size_t i = 0; i < num_breakpoints; ++i)
15645a988416SJim Ingham                     {
15655a988416SJim Ingham                         Breakpoint *bp = breakpoints.FindBreakpointByID(BreakIDs[i]).get();
15665a988416SJim Ingham 
15675a988416SJim Ingham                         if (bp->GetMatchingFileLine(filename, m_options.m_line_num, loc_coll))
15685a988416SJim Ingham                         {
15695a988416SJim Ingham                             // If the collection size is 0, it's a full match and we can just remove the breakpoint.
15705a988416SJim Ingham                             if (loc_coll.GetSize() == 0)
15715a988416SJim Ingham                             {
15725a988416SJim Ingham                                 bp->GetDescription(&ss, lldb::eDescriptionLevelBrief);
15735a988416SJim Ingham                                 ss.EOL();
15745a988416SJim Ingham                                 target->RemoveBreakpointByID (bp->GetID());
15755a988416SJim Ingham                                 ++num_cleared;
15765a988416SJim Ingham                             }
15775a988416SJim Ingham                         }
15785a988416SJim Ingham                     }
15795a988416SJim Ingham                 }
15805a988416SJim Ingham                 break;
15815a988416SJim Ingham 
15825a988416SJim Ingham             default:
15835a988416SJim Ingham                 break;
15845a988416SJim Ingham         }
15855a988416SJim Ingham 
15865a988416SJim Ingham         if (num_cleared > 0)
15875a988416SJim Ingham         {
15885a988416SJim Ingham             Stream &output_stream = result.GetOutputStream();
15895a988416SJim Ingham             output_stream.Printf ("%d breakpoints cleared:\n", num_cleared);
15905a988416SJim Ingham             output_stream << ss.GetData();
15915a988416SJim Ingham             output_stream.EOL();
15925a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
15935a988416SJim Ingham         }
15945a988416SJim Ingham         else
15955a988416SJim Ingham         {
15965a988416SJim Ingham             result.AppendError ("Breakpoint clear: No breakpoint cleared.");
15975a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
15985a988416SJim Ingham         }
15995a988416SJim Ingham 
16005a988416SJim Ingham         return result.Succeeded();
16015a988416SJim Ingham     }
16025a988416SJim Ingham 
16035a988416SJim Ingham private:
16045a988416SJim Ingham     CommandOptions m_options;
16055a988416SJim Ingham };
16065a988416SJim Ingham 
16075a988416SJim Ingham #pragma mark Clear::CommandOptions
16085a988416SJim Ingham 
16095a988416SJim Ingham OptionDefinition
16105a988416SJim Ingham CommandObjectBreakpointClear::CommandOptions::g_option_table[] =
16115a988416SJim Ingham {
16125a988416SJim Ingham     { LLDB_OPT_SET_1, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
16135a988416SJim Ingham         "Specify the breakpoint by source location in this particular file."},
16145a988416SJim Ingham 
16155a988416SJim Ingham     { LLDB_OPT_SET_1, true, "line", 'l', required_argument, NULL, 0, eArgTypeLineNum,
16165a988416SJim Ingham         "Specify the breakpoint by source location at this particular line."},
16175a988416SJim Ingham 
16185a988416SJim Ingham     { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
16195a988416SJim Ingham };
16205a988416SJim Ingham 
16215a988416SJim Ingham //-------------------------------------------------------------------------
16225a988416SJim Ingham // CommandObjectBreakpointDelete
16235a988416SJim Ingham //-------------------------------------------------------------------------
16245a988416SJim Ingham #pragma mark Delete
16255a988416SJim Ingham 
16265a988416SJim Ingham class CommandObjectBreakpointDelete : public CommandObjectParsed
16275a988416SJim Ingham {
16285a988416SJim Ingham public:
16295a988416SJim Ingham     CommandObjectBreakpointDelete (CommandInterpreter &interpreter) :
16305a988416SJim Ingham         CommandObjectParsed (interpreter,
16315a988416SJim Ingham                              "breakpoint delete",
16325a988416SJim Ingham                              "Delete the specified breakpoint(s).  If no breakpoints are specified, delete them all.",
16335a988416SJim Ingham                              NULL)
16345a988416SJim Ingham     {
16355a988416SJim Ingham         CommandArgumentEntry arg;
16365a988416SJim Ingham         CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
16375a988416SJim Ingham         // Add the entry for the first argument for this command to the object's arguments vector.
16385a988416SJim Ingham         m_arguments.push_back (arg);
16395a988416SJim Ingham     }
16405a988416SJim Ingham 
16415a988416SJim Ingham     virtual
16425a988416SJim Ingham     ~CommandObjectBreakpointDelete () {}
16435a988416SJim Ingham 
16445a988416SJim Ingham protected:
16455a988416SJim Ingham     virtual bool
16465a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
16475a988416SJim Ingham     {
16485a988416SJim Ingham         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
16495a988416SJim Ingham         if (target == NULL)
16505a988416SJim Ingham         {
16515a988416SJim Ingham             result.AppendError ("Invalid target. No existing target or breakpoints.");
16525a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
16535a988416SJim Ingham             return false;
16545a988416SJim Ingham         }
16555a988416SJim Ingham 
16565a988416SJim Ingham         Mutex::Locker locker;
16575a988416SJim Ingham         target->GetBreakpointList().GetListMutex(locker);
16585a988416SJim Ingham 
16595a988416SJim Ingham         const BreakpointList &breakpoints = target->GetBreakpointList();
16605a988416SJim Ingham 
16615a988416SJim Ingham         size_t num_breakpoints = breakpoints.GetSize();
16625a988416SJim Ingham 
16635a988416SJim Ingham         if (num_breakpoints == 0)
16645a988416SJim Ingham         {
16655a988416SJim Ingham             result.AppendError ("No breakpoints exist to be deleted.");
16665a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
16675a988416SJim Ingham             return false;
16685a988416SJim Ingham         }
16695a988416SJim Ingham 
16705a988416SJim Ingham         if (command.GetArgumentCount() == 0)
16715a988416SJim Ingham         {
16725a988416SJim Ingham             if (!m_interpreter.Confirm ("About to delete all breakpoints, do you want to do that?", true))
16735a988416SJim Ingham             {
16745a988416SJim Ingham                 result.AppendMessage("Operation cancelled...");
16755a988416SJim Ingham             }
16765a988416SJim Ingham             else
16775a988416SJim Ingham             {
16785a988416SJim Ingham                 target->RemoveAllBreakpoints ();
1679bb03b8f4SJim Ingham                 result.AppendMessageWithFormat ("All breakpoints removed. (%lu %s)\n", num_breakpoints, num_breakpoints > 1 ? "breakpoints" : "breakpoint");
16805a988416SJim Ingham             }
16815a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
16825a988416SJim Ingham         }
16835a988416SJim Ingham         else
16845a988416SJim Ingham         {
16855a988416SJim Ingham             // Particular breakpoint selected; disable that breakpoint.
16865a988416SJim Ingham             BreakpointIDList valid_bp_ids;
16875a988416SJim Ingham             CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
16885a988416SJim Ingham 
16895a988416SJim Ingham             if (result.Succeeded())
16905a988416SJim Ingham             {
16915a988416SJim Ingham                 int delete_count = 0;
16925a988416SJim Ingham                 int disable_count = 0;
16935a988416SJim Ingham                 const size_t count = valid_bp_ids.GetSize();
16945a988416SJim Ingham                 for (size_t i = 0; i < count; ++i)
16955a988416SJim Ingham                 {
16965a988416SJim Ingham                     BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
16975a988416SJim Ingham 
16985a988416SJim Ingham                     if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
16995a988416SJim Ingham                     {
17005a988416SJim Ingham                         if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
17015a988416SJim Ingham                         {
17025a988416SJim Ingham                             Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
17035a988416SJim Ingham                             BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
17045a988416SJim Ingham                             // It makes no sense to try to delete individual locations, so we disable them instead.
17055a988416SJim Ingham                             if (location)
17065a988416SJim Ingham                             {
17075a988416SJim Ingham                                 location->SetEnabled (false);
17085a988416SJim Ingham                                 ++disable_count;
17095a988416SJim Ingham                             }
17105a988416SJim Ingham                         }
17115a988416SJim Ingham                         else
17125a988416SJim Ingham                         {
17135a988416SJim Ingham                             target->RemoveBreakpointByID (cur_bp_id.GetBreakpointID());
17145a988416SJim Ingham                             ++delete_count;
17155a988416SJim Ingham                         }
17165a988416SJim Ingham                     }
17175a988416SJim Ingham                 }
17185a988416SJim Ingham                 result.AppendMessageWithFormat ("%d breakpoints deleted; %d breakpoint locations disabled.\n",
17195a988416SJim Ingham                                                delete_count, disable_count);
17205a988416SJim Ingham                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
17215a988416SJim Ingham             }
17225a988416SJim Ingham         }
17235a988416SJim Ingham         return result.Succeeded();
17245a988416SJim Ingham     }
17255a988416SJim Ingham };
17265a988416SJim Ingham 
172730fdc8d8SChris Lattner //-------------------------------------------------------------------------
172830fdc8d8SChris Lattner // CommandObjectMultiwordBreakpoint
172930fdc8d8SChris Lattner //-------------------------------------------------------------------------
1730ae1c4cf5SJim Ingham #pragma mark MultiwordBreakpoint
173130fdc8d8SChris Lattner 
17326611103cSGreg Clayton CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint (CommandInterpreter &interpreter) :
1733a7015092SGreg Clayton     CommandObjectMultiword (interpreter,
1734a7015092SGreg Clayton                             "breakpoint",
173546fbc60fSJim Ingham                             "A set of commands for operating on breakpoints. Also see _regexp-break.",
173630fdc8d8SChris Lattner                             "breakpoint <command> [<command-options>]")
173730fdc8d8SChris Lattner {
1738a7015092SGreg Clayton     CommandObjectSP list_command_object (new CommandObjectBreakpointList (interpreter));
1739a7015092SGreg Clayton     CommandObjectSP enable_command_object (new CommandObjectBreakpointEnable (interpreter));
1740a7015092SGreg Clayton     CommandObjectSP disable_command_object (new CommandObjectBreakpointDisable (interpreter));
1741b7234e40SJohnny Chen     CommandObjectSP clear_command_object (new CommandObjectBreakpointClear (interpreter));
1742b7234e40SJohnny Chen     CommandObjectSP delete_command_object (new CommandObjectBreakpointDelete (interpreter));
1743a7015092SGreg Clayton     CommandObjectSP set_command_object (new CommandObjectBreakpointSet (interpreter));
174430fdc8d8SChris Lattner     CommandObjectSP command_command_object (new CommandObjectBreakpointCommand (interpreter));
1745a7015092SGreg Clayton     CommandObjectSP modify_command_object (new CommandObjectBreakpointModify(interpreter));
174630fdc8d8SChris Lattner 
1747b7234e40SJohnny Chen     list_command_object->SetCommandName ("breakpoint list");
174830fdc8d8SChris Lattner     enable_command_object->SetCommandName("breakpoint enable");
174930fdc8d8SChris Lattner     disable_command_object->SetCommandName("breakpoint disable");
1750b7234e40SJohnny Chen     clear_command_object->SetCommandName("breakpoint clear");
1751b7234e40SJohnny Chen     delete_command_object->SetCommandName("breakpoint delete");
1752ae1c4cf5SJim Ingham     set_command_object->SetCommandName("breakpoint set");
1753b7234e40SJohnny Chen     command_command_object->SetCommandName ("breakpoint command");
1754b7234e40SJohnny Chen     modify_command_object->SetCommandName ("breakpoint modify");
175530fdc8d8SChris Lattner 
175623f59509SGreg Clayton     LoadSubCommand ("list",       list_command_object);
175723f59509SGreg Clayton     LoadSubCommand ("enable",     enable_command_object);
175823f59509SGreg Clayton     LoadSubCommand ("disable",    disable_command_object);
175923f59509SGreg Clayton     LoadSubCommand ("clear",      clear_command_object);
176023f59509SGreg Clayton     LoadSubCommand ("delete",     delete_command_object);
176123f59509SGreg Clayton     LoadSubCommand ("set",        set_command_object);
176223f59509SGreg Clayton     LoadSubCommand ("command",    command_command_object);
176323f59509SGreg Clayton     LoadSubCommand ("modify",     modify_command_object);
176430fdc8d8SChris Lattner }
176530fdc8d8SChris Lattner 
176630fdc8d8SChris Lattner CommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint ()
176730fdc8d8SChris Lattner {
176830fdc8d8SChris Lattner }
176930fdc8d8SChris Lattner 
177030fdc8d8SChris Lattner void
177130fdc8d8SChris Lattner CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (Args &args, Target *target, CommandReturnObject &result,
177230fdc8d8SChris Lattner                                                          BreakpointIDList *valid_ids)
177330fdc8d8SChris Lattner {
177430fdc8d8SChris Lattner     // args can be strings representing 1). integers (for breakpoint ids)
177530fdc8d8SChris Lattner     //                                  2). the full breakpoint & location canonical representation
177630fdc8d8SChris Lattner     //                                  3). the word "to" or a hyphen, representing a range (in which case there
177730fdc8d8SChris Lattner     //                                      had *better* be an entry both before & after of one of the first two types.
177836f3b369SJim Ingham     // If args is empty, we will use the last created breakpoint (if there is one.)
177930fdc8d8SChris Lattner 
178030fdc8d8SChris Lattner     Args temp_args;
178130fdc8d8SChris Lattner 
178236f3b369SJim Ingham     if (args.GetArgumentCount() == 0)
178336f3b369SJim Ingham     {
17844d122c40SGreg Clayton         if (target->GetLastCreatedBreakpoint())
178536f3b369SJim Ingham         {
178636f3b369SJim Ingham             valid_ids->AddBreakpointID (BreakpointID(target->GetLastCreatedBreakpoint()->GetID(), LLDB_INVALID_BREAK_ID));
178736f3b369SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
178836f3b369SJim Ingham         }
178936f3b369SJim Ingham         else
179036f3b369SJim Ingham         {
179136f3b369SJim Ingham             result.AppendError("No breakpoint specified and no last created breakpoint.");
179236f3b369SJim Ingham             result.SetStatus (eReturnStatusFailed);
179336f3b369SJim Ingham         }
179436f3b369SJim Ingham         return;
179536f3b369SJim Ingham     }
179636f3b369SJim Ingham 
179730fdc8d8SChris Lattner     // Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff directly from the old ARGS to
179830fdc8d8SChris Lattner     // the new TEMP_ARGS.  Do not copy breakpoint id range strings over; instead generate a list of strings for
179930fdc8d8SChris Lattner     // all the breakpoint ids in the range, and shove all of those breakpoint id strings into TEMP_ARGS.
180030fdc8d8SChris Lattner 
180130fdc8d8SChris Lattner     BreakpointIDList::FindAndReplaceIDRanges (args, target, result, temp_args);
180230fdc8d8SChris Lattner 
180330fdc8d8SChris Lattner     // NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual BreakpointIDList:
180430fdc8d8SChris Lattner 
1805c982c768SGreg Clayton     valid_ids->InsertStringArray (temp_args.GetConstArgumentVector(), temp_args.GetArgumentCount(), result);
180630fdc8d8SChris Lattner 
180730fdc8d8SChris Lattner     // At this point,  all of the breakpoint ids that the user passed in have been converted to breakpoint IDs
180830fdc8d8SChris Lattner     // and put into valid_ids.
180930fdc8d8SChris Lattner 
181030fdc8d8SChris Lattner     if (result.Succeeded())
181130fdc8d8SChris Lattner     {
181230fdc8d8SChris Lattner         // Now that we've converted everything from args into a list of breakpoint ids, go through our tentative list
181330fdc8d8SChris Lattner         // of breakpoint id's and verify that they correspond to valid/currently set breakpoints.
181430fdc8d8SChris Lattner 
1815c982c768SGreg Clayton         const size_t count = valid_ids->GetSize();
1816c982c768SGreg Clayton         for (size_t i = 0; i < count; ++i)
181730fdc8d8SChris Lattner         {
181830fdc8d8SChris Lattner             BreakpointID cur_bp_id = valid_ids->GetBreakpointIDAtIndex (i);
181930fdc8d8SChris Lattner             Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
182030fdc8d8SChris Lattner             if (breakpoint != NULL)
182130fdc8d8SChris Lattner             {
1822c7bece56SGreg Clayton                 const size_t num_locations = breakpoint->GetNumLocations();
182330fdc8d8SChris Lattner                 if (cur_bp_id.GetLocationID() > num_locations)
182430fdc8d8SChris Lattner                 {
182530fdc8d8SChris Lattner                     StreamString id_str;
1826c982c768SGreg Clayton                     BreakpointID::GetCanonicalReference (&id_str,
1827c982c768SGreg Clayton                                                          cur_bp_id.GetBreakpointID(),
182830fdc8d8SChris Lattner                                                          cur_bp_id.GetLocationID());
1829c982c768SGreg Clayton                     i = valid_ids->GetSize() + 1;
183030fdc8d8SChris Lattner                     result.AppendErrorWithFormat ("'%s' is not a currently valid breakpoint/location id.\n",
183130fdc8d8SChris Lattner                                                  id_str.GetData());
183230fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusFailed);
183330fdc8d8SChris Lattner                 }
183430fdc8d8SChris Lattner             }
183530fdc8d8SChris Lattner             else
183630fdc8d8SChris Lattner             {
1837c982c768SGreg Clayton                 i = valid_ids->GetSize() + 1;
183830fdc8d8SChris Lattner                 result.AppendErrorWithFormat ("'%d' is not a currently valid breakpoint id.\n", cur_bp_id.GetBreakpointID());
183930fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
184030fdc8d8SChris Lattner             }
184130fdc8d8SChris Lattner         }
184230fdc8d8SChris Lattner     }
184330fdc8d8SChris Lattner }
1844