blob: bb59e1f82e8dc7e734640d92a0e36b96fb4a0666 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- CommandObjectBreakpoint.cpp -----------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "CommandObjectBreakpoint.h"
11#include "CommandObjectBreakpointCommand.h"
12
13// C Includes
14// C++ Includes
15// Other libraries and framework includes
16// Project includes
17#include "lldb/Breakpoint/Breakpoint.h"
18#include "lldb/Breakpoint/BreakpointIDList.h"
19#include "lldb/Breakpoint/BreakpointLocation.h"
Vince Harron5275aaa2015-01-15 20:08:35 +000020#include "lldb/Host/StringConvert.h"
Jim Ingham40af72e2010-06-15 19:49:27 +000021#include "lldb/Interpreter/Options.h"
Zachary Turner32abc6e2015-03-03 19:23:09 +000022#include "lldb/Interpreter/OptionValueBoolean.h"
Jim Ingham5e09c8c2014-12-16 23:40:14 +000023#include "lldb/Interpreter/OptionValueString.h"
24#include "lldb/Interpreter/OptionValueUInt64.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000025#include "lldb/Core/RegularExpression.h"
26#include "lldb/Core/StreamString.h"
27#include "lldb/Interpreter/CommandInterpreter.h"
28#include "lldb/Interpreter/CommandReturnObject.h"
Jim Ingham0e0984e2015-09-02 01:06:46 +000029#include "lldb/Target/Language.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000030#include "lldb/Target/Target.h"
31#include "lldb/Interpreter/CommandCompletions.h"
Jason Molendab57e4a12013-11-04 09:33:30 +000032#include "lldb/Target/StackFrame.h"
Jim Ingham1b54c882010-06-16 02:00:15 +000033#include "lldb/Target/Thread.h"
34#include "lldb/Target/ThreadSpec.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000035
Johnny Chenb7234e42010-10-28 17:27:46 +000036#include <vector>
37
Chris Lattner30fdc8d2010-06-08 16:52:24 +000038using namespace lldb;
39using namespace lldb_private;
40
41static void
Jim Ingham85e8b812011-02-19 02:53:09 +000042AddBreakpointDescription (Stream *s, Breakpoint *bp, lldb::DescriptionLevel level)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000043{
44 s->IndentMore();
45 bp->GetDescription (s, level, true);
46 s->IndentLess();
47 s->EOL();
48}
49
50//-------------------------------------------------------------------------
Jim Ingham5a988412012-06-08 21:56:10 +000051// CommandObjectBreakpointSet
Chris Lattner30fdc8d2010-06-08 16:52:24 +000052//-------------------------------------------------------------------------
53
Jim Ingham5a988412012-06-08 21:56:10 +000054
55class CommandObjectBreakpointSet : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +000056{
Jim Ingham5a988412012-06-08 21:56:10 +000057public:
Chris Lattner30fdc8d2010-06-08 16:52:24 +000058
Jim Ingham5a988412012-06-08 21:56:10 +000059 typedef enum BreakpointSetType
60 {
61 eSetTypeInvalid,
62 eSetTypeFileAndLine,
63 eSetTypeAddress,
64 eSetTypeFunctionName,
65 eSetTypeFunctionRegexp,
66 eSetTypeSourceRegexp,
67 eSetTypeException
68 } BreakpointSetType;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000069
Jim Ingham5a988412012-06-08 21:56:10 +000070 CommandObjectBreakpointSet (CommandInterpreter &interpreter) :
71 CommandObjectParsed (interpreter,
72 "breakpoint set",
73 "Sets a breakpoint or set of breakpoints in the executable.",
74 "breakpoint set <cmd-options>"),
75 m_options (interpreter)
76 {
77 }
78
79
Bruce Mitchener13d21e92015-10-07 16:56:17 +000080 ~CommandObjectBreakpointSet () override {}
Jim Ingham5a988412012-06-08 21:56:10 +000081
Bruce Mitchener13d21e92015-10-07 16:56:17 +000082 Options *
83 GetOptions () override
Jim Ingham5a988412012-06-08 21:56:10 +000084 {
85 return &m_options;
86 }
87
88 class CommandOptions : public Options
89 {
90 public:
91
92 CommandOptions (CommandInterpreter &interpreter) :
93 Options (interpreter),
94 m_condition (),
95 m_filenames (),
96 m_line_num (0),
97 m_column (0),
Jim Ingham5a988412012-06-08 21:56:10 +000098 m_func_names (),
99 m_func_name_type_mask (eFunctionNameTypeNone),
100 m_func_regexp (),
101 m_source_text_regexp(),
102 m_modules (),
103 m_load_addr(),
104 m_ignore_count (0),
105 m_thread_id(LLDB_INVALID_THREAD_ID),
106 m_thread_index (UINT32_MAX),
107 m_thread_name(),
108 m_queue_name(),
109 m_catch_bp (false),
Greg Clayton1f746072012-08-29 21:13:06 +0000110 m_throw_bp (true),
Greg Claytoneb023e72013-10-11 19:48:25 +0000111 m_hardware (false),
Jim Inghama72b31c2015-04-22 19:42:18 +0000112 m_exception_language (eLanguageTypeUnknown),
Dawn Perchik23b1dec2015-07-21 22:05:07 +0000113 m_language (lldb::eLanguageTypeUnknown),
Jim Inghamca36cd12012-10-05 19:16:31 +0000114 m_skip_prologue (eLazyBoolCalculate),
Jim Inghame7320522015-02-12 17:37:46 +0000115 m_one_shot (false),
Ilia K055ad9b2015-05-18 13:41:01 +0000116 m_all_files (false),
117 m_move_to_nearest_code (eLazyBoolCalculate)
Jim Ingham5a988412012-06-08 21:56:10 +0000118 {
119 }
120
121
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000122 ~CommandOptions () override {}
Jim Ingham5a988412012-06-08 21:56:10 +0000123
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000124 Error
125 SetOptionValue (uint32_t option_idx, const char *option_arg) override
Jim Ingham5a988412012-06-08 21:56:10 +0000126 {
127 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000128 const int short_option = m_getopt_table[option_idx].val;
Jim Ingham5a988412012-06-08 21:56:10 +0000129
130 switch (short_option)
131 {
132 case 'a':
Greg Claytonb9d5df52012-12-06 22:49:16 +0000133 {
134 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
135 m_load_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
136 }
Jim Ingham5a988412012-06-08 21:56:10 +0000137 break;
138
Jim Inghame7320522015-02-12 17:37:46 +0000139 case 'A':
140 m_all_files = true;
141 break;
142
Jim Inghamca36cd12012-10-05 19:16:31 +0000143 case 'b':
144 m_func_names.push_back (option_arg);
145 m_func_name_type_mask |= eFunctionNameTypeBase;
146 break;
147
Jim Ingham5a988412012-06-08 21:56:10 +0000148 case 'C':
Jim Ingham63129912015-03-16 22:47:38 +0000149 {
150 bool success;
151 m_column = StringConvert::ToUInt32 (option_arg, 0, 0, &success);
152 if (!success)
153 error.SetErrorStringWithFormat("invalid column number: %s", option_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000154 break;
Jim Ingham63129912015-03-16 22:47:38 +0000155 }
Jim Ingham5a988412012-06-08 21:56:10 +0000156 case 'c':
157 m_condition.assign(option_arg);
158 break;
159
Jim Ingham33df7cd2014-12-06 01:28:03 +0000160 case 'D':
161 m_use_dummy = true;
162 break;
163
Jim Ingham5a988412012-06-08 21:56:10 +0000164 case 'E':
165 {
Jim Ingham0e0984e2015-09-02 01:06:46 +0000166 LanguageType language = Language::GetLanguageTypeFromString (option_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000167
168 switch (language)
169 {
170 case eLanguageTypeC89:
171 case eLanguageTypeC:
172 case eLanguageTypeC99:
Bruce Mitchener1d0089f2014-07-03 00:49:08 +0000173 case eLanguageTypeC11:
Jim Inghama72b31c2015-04-22 19:42:18 +0000174 m_exception_language = eLanguageTypeC;
Jim Ingham5a988412012-06-08 21:56:10 +0000175 break;
176 case eLanguageTypeC_plus_plus:
Bruce Mitchener1d0089f2014-07-03 00:49:08 +0000177 case eLanguageTypeC_plus_plus_03:
178 case eLanguageTypeC_plus_plus_11:
Bruce Mitchener2ba84a62015-02-06 06:46:52 +0000179 case eLanguageTypeC_plus_plus_14:
Jim Inghama72b31c2015-04-22 19:42:18 +0000180 m_exception_language = eLanguageTypeC_plus_plus;
Jim Ingham5a988412012-06-08 21:56:10 +0000181 break;
182 case eLanguageTypeObjC:
Jim Inghama72b31c2015-04-22 19:42:18 +0000183 m_exception_language = eLanguageTypeObjC;
Jim Ingham5a988412012-06-08 21:56:10 +0000184 break;
185 case eLanguageTypeObjC_plus_plus:
186 error.SetErrorStringWithFormat ("Set exception breakpoints separately for c++ and objective-c");
187 break;
188 case eLanguageTypeUnknown:
189 error.SetErrorStringWithFormat ("Unknown language type: '%s' for exception breakpoint", option_arg);
190 break;
191 default:
192 error.SetErrorStringWithFormat ("Unsupported language type: '%s' for exception breakpoint", option_arg);
193 }
194 }
195 break;
Jim Inghamca36cd12012-10-05 19:16:31 +0000196
197 case 'f':
198 m_filenames.AppendIfUnique (FileSpec(option_arg, false));
199 break;
200
201 case 'F':
202 m_func_names.push_back (option_arg);
203 m_func_name_type_mask |= eFunctionNameTypeFull;
204 break;
205
Jim Ingham5a988412012-06-08 21:56:10 +0000206 case 'h':
Greg Claytoneb023e72013-10-11 19:48:25 +0000207 {
208 bool success;
209 m_catch_bp = Args::StringToBoolean (option_arg, true, &success);
210 if (!success)
211 error.SetErrorStringWithFormat ("Invalid boolean value for on-catch option: '%s'", option_arg);
212 }
213 break;
214
215 case 'H':
216 m_hardware = true;
217 break;
218
Jim Inghamca36cd12012-10-05 19:16:31 +0000219 case 'i':
220 {
Vince Harron5275aaa2015-01-15 20:08:35 +0000221 m_ignore_count = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
Jim Inghamca36cd12012-10-05 19:16:31 +0000222 if (m_ignore_count == UINT32_MAX)
223 error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
224 break;
225 }
226
Jim Ingham5a988412012-06-08 21:56:10 +0000227 case 'K':
228 {
229 bool success;
230 bool value;
231 value = Args::StringToBoolean (option_arg, true, &success);
232 if (value)
233 m_skip_prologue = eLazyBoolYes;
234 else
235 m_skip_prologue = eLazyBoolNo;
236
237 if (!success)
238 error.SetErrorStringWithFormat ("Invalid boolean value for skip prologue option: '%s'", option_arg);
239 }
240 break;
Jim Inghamca36cd12012-10-05 19:16:31 +0000241
242 case 'l':
Jim Ingham63129912015-03-16 22:47:38 +0000243 {
244 bool success;
245 m_line_num = StringConvert::ToUInt32 (option_arg, 0, 0, &success);
246 if (!success)
247 error.SetErrorStringWithFormat ("invalid line number: %s.", option_arg);
Jim Inghamca36cd12012-10-05 19:16:31 +0000248 break;
Jim Ingham63129912015-03-16 22:47:38 +0000249 }
Ilia K055ad9b2015-05-18 13:41:01 +0000250
Dawn Perchik23b1dec2015-07-21 22:05:07 +0000251 case 'L':
Jim Ingham0e0984e2015-09-02 01:06:46 +0000252 m_language = Language::GetLanguageTypeFromString (option_arg);
Dawn Perchik23b1dec2015-07-21 22:05:07 +0000253 if (m_language == eLanguageTypeUnknown)
254 error.SetErrorStringWithFormat ("Unknown language type: '%s' for breakpoint", option_arg);
255 break;
256
Ilia K055ad9b2015-05-18 13:41:01 +0000257 case 'm':
258 {
259 bool success;
260 bool value;
261 value = Args::StringToBoolean (option_arg, true, &success);
262 if (value)
263 m_move_to_nearest_code = eLazyBoolYes;
264 else
265 m_move_to_nearest_code = eLazyBoolNo;
266
267 if (!success)
268 error.SetErrorStringWithFormat ("Invalid boolean value for move-to-nearest-code option: '%s'", option_arg);
269 break;
270 }
271
Jim Inghamca36cd12012-10-05 19:16:31 +0000272 case 'M':
273 m_func_names.push_back (option_arg);
274 m_func_name_type_mask |= eFunctionNameTypeMethod;
275 break;
276
277 case 'n':
278 m_func_names.push_back (option_arg);
279 m_func_name_type_mask |= eFunctionNameTypeAuto;
280 break;
281
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000282 case 'N':
283 if (BreakpointID::StringIsBreakpointName(option_arg, error))
284 m_breakpoint_names.push_back (option_arg);
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000285 break;
286
Jim Inghamca36cd12012-10-05 19:16:31 +0000287 case 'o':
288 m_one_shot = true;
289 break;
290
Jim Inghama72b31c2015-04-22 19:42:18 +0000291 case 'O':
292 m_exception_extra_args.AppendArgument ("-O");
293 m_exception_extra_args.AppendArgument (option_arg);
294 break;
295
Jim Inghamca36cd12012-10-05 19:16:31 +0000296 case 'p':
297 m_source_text_regexp.assign (option_arg);
298 break;
299
300 case 'q':
301 m_queue_name.assign (option_arg);
302 break;
303
304 case 'r':
305 m_func_regexp.assign (option_arg);
306 break;
307
308 case 's':
309 {
310 m_modules.AppendIfUnique (FileSpec (option_arg, false));
311 break;
312 }
313
314 case 'S':
315 m_func_names.push_back (option_arg);
316 m_func_name_type_mask |= eFunctionNameTypeSelector;
317 break;
318
319 case 't' :
320 {
Vince Harron5275aaa2015-01-15 20:08:35 +0000321 m_thread_id = StringConvert::ToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
Jim Inghamca36cd12012-10-05 19:16:31 +0000322 if (m_thread_id == LLDB_INVALID_THREAD_ID)
323 error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
324 }
325 break;
326
327 case 'T':
328 m_thread_name.assign (option_arg);
329 break;
330
331 case 'w':
332 {
333 bool success;
334 m_throw_bp = Args::StringToBoolean (option_arg, true, &success);
335 if (!success)
336 error.SetErrorStringWithFormat ("Invalid boolean value for on-throw option: '%s'", option_arg);
337 }
338 break;
339
340 case 'x':
341 {
Vince Harron5275aaa2015-01-15 20:08:35 +0000342 m_thread_index = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
Jim Inghamca36cd12012-10-05 19:16:31 +0000343 if (m_thread_id == UINT32_MAX)
344 error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
345
346 }
347 break;
348
Jim Ingham5a988412012-06-08 21:56:10 +0000349 default:
350 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
351 break;
352 }
353
354 return error;
355 }
356 void
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000357 OptionParsingStarting () override
Jim Ingham5a988412012-06-08 21:56:10 +0000358 {
359 m_condition.clear();
360 m_filenames.Clear();
361 m_line_num = 0;
362 m_column = 0;
363 m_func_names.clear();
Greg Clayton1f746072012-08-29 21:13:06 +0000364 m_func_name_type_mask = eFunctionNameTypeNone;
Jim Ingham5a988412012-06-08 21:56:10 +0000365 m_func_regexp.clear();
Greg Clayton1f746072012-08-29 21:13:06 +0000366 m_source_text_regexp.clear();
Jim Ingham5a988412012-06-08 21:56:10 +0000367 m_modules.Clear();
Greg Clayton1f746072012-08-29 21:13:06 +0000368 m_load_addr = LLDB_INVALID_ADDRESS;
Jim Ingham5a988412012-06-08 21:56:10 +0000369 m_ignore_count = 0;
370 m_thread_id = LLDB_INVALID_THREAD_ID;
371 m_thread_index = UINT32_MAX;
372 m_thread_name.clear();
373 m_queue_name.clear();
Jim Ingham5a988412012-06-08 21:56:10 +0000374 m_catch_bp = false;
375 m_throw_bp = true;
Greg Claytoneb023e72013-10-11 19:48:25 +0000376 m_hardware = false;
Jim Inghama72b31c2015-04-22 19:42:18 +0000377 m_exception_language = eLanguageTypeUnknown;
Dawn Perchik23b1dec2015-07-21 22:05:07 +0000378 m_language = lldb::eLanguageTypeUnknown;
Jim Ingham5a988412012-06-08 21:56:10 +0000379 m_skip_prologue = eLazyBoolCalculate;
Jim Inghamca36cd12012-10-05 19:16:31 +0000380 m_one_shot = false;
Jim Ingham33df7cd2014-12-06 01:28:03 +0000381 m_use_dummy = false;
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000382 m_breakpoint_names.clear();
Jim Inghame7320522015-02-12 17:37:46 +0000383 m_all_files = false;
Jim Inghama72b31c2015-04-22 19:42:18 +0000384 m_exception_extra_args.Clear();
Ilia K055ad9b2015-05-18 13:41:01 +0000385 m_move_to_nearest_code = eLazyBoolCalculate;
Jim Ingham5a988412012-06-08 21:56:10 +0000386 }
387
388 const OptionDefinition*
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000389 GetDefinitions () override
Jim Ingham5a988412012-06-08 21:56:10 +0000390 {
391 return g_option_table;
392 }
393
394 // Options table: Required for subclasses of Options.
395
396 static OptionDefinition g_option_table[];
397
398 // Instance variables to hold the values for command options.
399
400 std::string m_condition;
401 FileSpecList m_filenames;
402 uint32_t m_line_num;
403 uint32_t m_column;
Jim Ingham5a988412012-06-08 21:56:10 +0000404 std::vector<std::string> m_func_names;
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000405 std::vector<std::string> m_breakpoint_names;
Jim Ingham5a988412012-06-08 21:56:10 +0000406 uint32_t m_func_name_type_mask;
407 std::string m_func_regexp;
408 std::string m_source_text_regexp;
409 FileSpecList m_modules;
410 lldb::addr_t m_load_addr;
411 uint32_t m_ignore_count;
412 lldb::tid_t m_thread_id;
413 uint32_t m_thread_index;
414 std::string m_thread_name;
415 std::string m_queue_name;
416 bool m_catch_bp;
417 bool m_throw_bp;
Greg Claytoneb023e72013-10-11 19:48:25 +0000418 bool m_hardware; // Request to use hardware breakpoints
Jim Inghama72b31c2015-04-22 19:42:18 +0000419 lldb::LanguageType m_exception_language;
Dawn Perchik23b1dec2015-07-21 22:05:07 +0000420 lldb::LanguageType m_language;
Jim Ingham5a988412012-06-08 21:56:10 +0000421 LazyBool m_skip_prologue;
Jim Inghamca36cd12012-10-05 19:16:31 +0000422 bool m_one_shot;
Jim Ingham33df7cd2014-12-06 01:28:03 +0000423 bool m_use_dummy;
Jim Inghame7320522015-02-12 17:37:46 +0000424 bool m_all_files;
Jim Inghama72b31c2015-04-22 19:42:18 +0000425 Args m_exception_extra_args;
Ilia K055ad9b2015-05-18 13:41:01 +0000426 LazyBool m_move_to_nearest_code;
Jim Ingham5a988412012-06-08 21:56:10 +0000427
428 };
429
430protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000431 bool
Jim Ingham5a988412012-06-08 21:56:10 +0000432 DoExecute (Args& command,
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000433 CommandReturnObject &result) override
Jim Ingham5a988412012-06-08 21:56:10 +0000434 {
Jim Ingham33df7cd2014-12-06 01:28:03 +0000435 Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
436
Jim Ingham893c9322014-11-22 01:42:44 +0000437 if (target == nullptr)
Jim Ingham5a988412012-06-08 21:56:10 +0000438 {
439 result.AppendError ("Invalid target. Must set target before setting breakpoints (see 'target create' command).");
440 result.SetStatus (eReturnStatusFailed);
441 return false;
442 }
443
444 // The following are the various types of breakpoints that could be set:
445 // 1). -f -l -p [-s -g] (setting breakpoint by source location)
446 // 2). -a [-s -g] (setting breakpoint by address)
447 // 3). -n [-s -g] (setting breakpoint by function name)
448 // 4). -r [-s -g] (setting breakpoint by function name regular expression)
449 // 5). -p -f (setting a breakpoint by comparing a reg-exp to source text)
450 // 6). -E [-w -h] (setting a breakpoint for exceptions for a given language.)
451
452 BreakpointSetType break_type = eSetTypeInvalid;
453
454 if (m_options.m_line_num != 0)
455 break_type = eSetTypeFileAndLine;
456 else if (m_options.m_load_addr != LLDB_INVALID_ADDRESS)
457 break_type = eSetTypeAddress;
458 else if (!m_options.m_func_names.empty())
459 break_type = eSetTypeFunctionName;
460 else if (!m_options.m_func_regexp.empty())
461 break_type = eSetTypeFunctionRegexp;
462 else if (!m_options.m_source_text_regexp.empty())
463 break_type = eSetTypeSourceRegexp;
Jim Inghama72b31c2015-04-22 19:42:18 +0000464 else if (m_options.m_exception_language != eLanguageTypeUnknown)
Jim Ingham5a988412012-06-08 21:56:10 +0000465 break_type = eSetTypeException;
466
467 Breakpoint *bp = NULL;
468 FileSpec module_spec;
Jim Ingham5a988412012-06-08 21:56:10 +0000469 const bool internal = false;
470
Jim Ingham5a988412012-06-08 21:56:10 +0000471 switch (break_type)
472 {
473 case eSetTypeFileAndLine: // Breakpoint by source position
474 {
475 FileSpec file;
Greg Claytonc7bece562013-01-25 18:06:21 +0000476 const size_t num_files = m_options.m_filenames.GetSize();
Jim Ingham5a988412012-06-08 21:56:10 +0000477 if (num_files == 0)
478 {
479 if (!GetDefaultFile (target, file, result))
480 {
481 result.AppendError("No file supplied and no default file available.");
482 result.SetStatus (eReturnStatusFailed);
483 return false;
484 }
485 }
486 else if (num_files > 1)
487 {
488 result.AppendError("Only one file at a time is allowed for file and line breakpoints.");
489 result.SetStatus (eReturnStatusFailed);
490 return false;
491 }
492 else
493 file = m_options.m_filenames.GetFileSpecAtIndex(0);
Greg Clayton1f746072012-08-29 21:13:06 +0000494
495 // Only check for inline functions if
496 LazyBool check_inlines = eLazyBoolCalculate;
497
Jim Ingham5a988412012-06-08 21:56:10 +0000498 bp = target->CreateBreakpoint (&(m_options.m_modules),
499 file,
500 m_options.m_line_num,
Greg Clayton1f746072012-08-29 21:13:06 +0000501 check_inlines,
Jim Ingham5a988412012-06-08 21:56:10 +0000502 m_options.m_skip_prologue,
Greg Claytoneb023e72013-10-11 19:48:25 +0000503 internal,
Ilia K055ad9b2015-05-18 13:41:01 +0000504 m_options.m_hardware,
505 m_options.m_move_to_nearest_code).get();
Jim Ingham5a988412012-06-08 21:56:10 +0000506 }
507 break;
508
509 case eSetTypeAddress: // Breakpoint by address
Jim Ingham055a08a2015-11-17 03:39:13 +0000510 {
511 // If a shared library has been specified, make an lldb_private::Address with the library, and
512 // use that. That way the address breakpoint will track the load location of the library.
513 size_t num_modules_specified = m_options.m_modules.GetSize();
514 if (num_modules_specified == 1)
515 {
516 const FileSpec *file_spec = m_options.m_modules.GetFileSpecPointerAtIndex(0);
517 bp = target->CreateAddressInModuleBreakpoint (m_options.m_load_addr,
518 internal,
519 file_spec,
520 m_options.m_hardware).get();
521 }
522 else if (num_modules_specified == 0)
523 {
524 bp = target->CreateBreakpoint (m_options.m_load_addr,
525 internal,
526 m_options.m_hardware).get();
527 }
528 else
529 {
530 result.AppendError("Only one shared library can be specified for address breakpoints.");
531 result.SetStatus(eReturnStatusFailed);
532 return false;
533 }
Jim Ingham5a988412012-06-08 21:56:10 +0000534 break;
Jim Ingham055a08a2015-11-17 03:39:13 +0000535 }
Jim Ingham5a988412012-06-08 21:56:10 +0000536 case eSetTypeFunctionName: // Breakpoint by function name
537 {
538 uint32_t name_type_mask = m_options.m_func_name_type_mask;
539
540 if (name_type_mask == 0)
541 name_type_mask = eFunctionNameTypeAuto;
542
543 bp = target->CreateBreakpoint (&(m_options.m_modules),
544 &(m_options.m_filenames),
545 m_options.m_func_names,
546 name_type_mask,
Dawn Perchik23b1dec2015-07-21 22:05:07 +0000547 m_options.m_language,
Jim Ingham5a988412012-06-08 21:56:10 +0000548 m_options.m_skip_prologue,
Greg Claytoneb023e72013-10-11 19:48:25 +0000549 internal,
550 m_options.m_hardware).get();
Jim Ingham5a988412012-06-08 21:56:10 +0000551 }
552 break;
553
554 case eSetTypeFunctionRegexp: // Breakpoint by regular expression function name
555 {
556 RegularExpression regexp(m_options.m_func_regexp.c_str());
557 if (!regexp.IsValid())
558 {
559 char err_str[1024];
560 regexp.GetErrorAsCString(err_str, sizeof(err_str));
561 result.AppendErrorWithFormat("Function name regular expression could not be compiled: \"%s\"",
562 err_str);
563 result.SetStatus (eReturnStatusFailed);
564 return false;
565 }
566
567 bp = target->CreateFuncRegexBreakpoint (&(m_options.m_modules),
568 &(m_options.m_filenames),
569 regexp,
Jim Ingham0fcdac32015-11-06 22:48:59 +0000570 m_options.m_language,
Jim Ingham5a988412012-06-08 21:56:10 +0000571 m_options.m_skip_prologue,
Greg Claytoneb023e72013-10-11 19:48:25 +0000572 internal,
573 m_options.m_hardware).get();
Jim Ingham5a988412012-06-08 21:56:10 +0000574 }
575 break;
576 case eSetTypeSourceRegexp: // Breakpoint by regexp on source text.
577 {
Greg Claytonc7bece562013-01-25 18:06:21 +0000578 const size_t num_files = m_options.m_filenames.GetSize();
Jim Ingham5a988412012-06-08 21:56:10 +0000579
Jim Inghame7320522015-02-12 17:37:46 +0000580 if (num_files == 0 && !m_options.m_all_files)
Jim Ingham5a988412012-06-08 21:56:10 +0000581 {
582 FileSpec file;
583 if (!GetDefaultFile (target, file, result))
584 {
585 result.AppendError ("No files provided and could not find default file.");
586 result.SetStatus (eReturnStatusFailed);
587 return false;
588 }
589 else
590 {
591 m_options.m_filenames.Append (file);
592 }
593 }
594
595 RegularExpression regexp(m_options.m_source_text_regexp.c_str());
596 if (!regexp.IsValid())
597 {
598 char err_str[1024];
599 regexp.GetErrorAsCString(err_str, sizeof(err_str));
600 result.AppendErrorWithFormat("Source text regular expression could not be compiled: \"%s\"",
601 err_str);
602 result.SetStatus (eReturnStatusFailed);
603 return false;
604 }
Greg Claytoneb023e72013-10-11 19:48:25 +0000605 bp = target->CreateSourceRegexBreakpoint (&(m_options.m_modules),
606 &(m_options.m_filenames),
607 regexp,
608 internal,
Ilia K055ad9b2015-05-18 13:41:01 +0000609 m_options.m_hardware,
610 m_options.m_move_to_nearest_code).get();
Jim Ingham5a988412012-06-08 21:56:10 +0000611 }
612 break;
613 case eSetTypeException:
614 {
Jim Inghama72b31c2015-04-22 19:42:18 +0000615 Error precond_error;
616 bp = target->CreateExceptionBreakpoint (m_options.m_exception_language,
Greg Claytoneb023e72013-10-11 19:48:25 +0000617 m_options.m_catch_bp,
618 m_options.m_throw_bp,
Jim Inghama72b31c2015-04-22 19:42:18 +0000619 internal,
620 &m_options.m_exception_extra_args,
621 &precond_error).get();
622 if (precond_error.Fail())
623 {
624 result.AppendErrorWithFormat("Error setting extra exception arguments: %s",
625 precond_error.AsCString());
626 target->RemoveBreakpointByID(bp->GetID());
627 result.SetStatus(eReturnStatusFailed);
628 return false;
629 }
Jim Ingham5a988412012-06-08 21:56:10 +0000630 }
631 break;
632 default:
633 break;
634 }
635
636 // Now set the various options that were passed in:
637 if (bp)
638 {
639 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
640 bp->SetThreadID (m_options.m_thread_id);
641
642 if (m_options.m_thread_index != UINT32_MAX)
643 bp->GetOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index);
644
645 if (!m_options.m_thread_name.empty())
646 bp->GetOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str());
647
648 if (!m_options.m_queue_name.empty())
649 bp->GetOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str());
650
651 if (m_options.m_ignore_count != 0)
652 bp->GetOptions()->SetIgnoreCount(m_options.m_ignore_count);
653
654 if (!m_options.m_condition.empty())
655 bp->GetOptions()->SetCondition(m_options.m_condition.c_str());
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000656
657 if (!m_options.m_breakpoint_names.empty())
658 {
659 Error error; // We don't need to check the error here, since the option parser checked it...
660 for (auto name : m_options.m_breakpoint_names)
661 bp->AddName(name.c_str(), error);
662 }
Jim Inghamca36cd12012-10-05 19:16:31 +0000663
664 bp->SetOneShot (m_options.m_one_shot);
Jim Ingham5a988412012-06-08 21:56:10 +0000665 }
666
667 if (bp)
668 {
669 Stream &output_stream = result.GetOutputStream();
Jim Ingham1391cc72012-09-22 00:04:04 +0000670 const bool show_locations = false;
671 bp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial, show_locations);
Jim Ingham4aeb1982014-12-19 19:45:31 +0000672 if (target == m_interpreter.GetDebugger().GetDummyTarget())
673 output_stream.Printf ("Breakpoint set in dummy target, will get copied into future targets.\n");
674 else
675 {
676 // Don't print out this warning for exception breakpoints. They can get set before the target
677 // is set, but we won't know how to actually set the breakpoint till we run.
678 if (bp->GetNumLocations() == 0 && break_type != eSetTypeException)
679 {
680 output_stream.Printf ("WARNING: Unable to resolve breakpoint to any actual locations.\n");
681 }
682 }
Jim Ingham5a988412012-06-08 21:56:10 +0000683 result.SetStatus (eReturnStatusSuccessFinishResult);
684 }
685 else if (!bp)
686 {
687 result.AppendError ("Breakpoint creation failed: No breakpoint created.");
688 result.SetStatus (eReturnStatusFailed);
689 }
690
691 return result.Succeeded();
692 }
693
694private:
695 bool
696 GetDefaultFile (Target *target, FileSpec &file, CommandReturnObject &result)
697 {
698 uint32_t default_line;
699 // First use the Source Manager's default file.
700 // Then use the current stack frame's file.
701 if (!target->GetSourceManager().GetDefaultFileAndLine(file, default_line))
702 {
Jason Molendab57e4a12013-11-04 09:33:30 +0000703 StackFrame *cur_frame = m_exe_ctx.GetFramePtr();
Jim Ingham5a988412012-06-08 21:56:10 +0000704 if (cur_frame == NULL)
705 {
706 result.AppendError ("No selected frame to use to find the default file.");
707 result.SetStatus (eReturnStatusFailed);
708 return false;
709 }
710 else if (!cur_frame->HasDebugInformation())
711 {
712 result.AppendError ("Cannot use the selected frame to find the default file, it has no debug info.");
713 result.SetStatus (eReturnStatusFailed);
714 return false;
715 }
716 else
717 {
718 const SymbolContext &sc = cur_frame->GetSymbolContext (eSymbolContextLineEntry);
719 if (sc.line_entry.file)
720 {
721 file = sc.line_entry.file;
722 }
723 else
724 {
725 result.AppendError ("Can't find the file for the selected frame to use as the default file.");
726 result.SetStatus (eReturnStatusFailed);
727 return false;
728 }
729 }
730 }
731 return true;
732 }
733
734 CommandOptions m_options;
735};
Johnny Chen6943e7c2012-05-08 00:43:20 +0000736// If an additional option set beyond LLDB_OPTION_SET_10 is added, make sure to
737// update the numbers passed to LLDB_OPT_SET_FROM_TO(...) appropriately.
Johnny Chen4ab2e6b2012-05-07 23:23:41 +0000738#define LLDB_OPT_FILE ( LLDB_OPT_SET_FROM_TO(1, 9) & ~LLDB_OPT_SET_2 )
739#define LLDB_OPT_NOT_10 ( LLDB_OPT_SET_FROM_TO(1, 10) & ~LLDB_OPT_SET_10 )
Jim Inghama8558b62012-05-22 00:12:20 +0000740#define LLDB_OPT_SKIP_PROLOGUE ( LLDB_OPT_SET_1 | LLDB_OPT_SET_FROM_TO(3,8) )
Ilia K055ad9b2015-05-18 13:41:01 +0000741#define LLDB_OPT_MOVE_TO_NEAREST_CODE ( LLDB_OPT_SET_1 | LLDB_OPT_SET_9 )
Jim Ingham0fcdac32015-11-06 22:48:59 +0000742#define LLDB_OPT_EXPR_LANGUAGE ( LLDB_OPT_SET_FROM_TO(3, 8) )
Jim Ingham87df91b2011-09-23 00:54:11 +0000743
Greg Claytone0d378b2011-03-24 21:19:54 +0000744OptionDefinition
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000745CommandObjectBreakpointSet::CommandOptions::g_option_table[] =
746{
Zachary Turnerd37221d2014-07-09 16:31:49 +0000747 { LLDB_OPT_NOT_10, false, "shlib", 's', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName,
Jim Ingham64cc29c2012-05-03 20:30:08 +0000748 "Set the breakpoint only in this shared library. "
749 "Can repeat this option multiple times to specify multiple shared libraries."},
Jim Ingham86511212010-06-15 18:47:14 +0000750
Zachary Turnerd37221d2014-07-09 16:31:49 +0000751 { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeCount,
Caroline Ticedeaab222010-10-01 19:59:14 +0000752 "Set the number of times this breakpoint is skipped before stopping." },
Jim Ingham1b54c882010-06-16 02:00:15 +0000753
Zachary Turnerd37221d2014-07-09 16:31:49 +0000754 { LLDB_OPT_SET_ALL, false, "one-shot", 'o', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
Jim Inghamb2b256a2013-04-09 18:05:22 +0000755 "The breakpoint is deleted the first time it causes a stop." },
Jim Inghamca36cd12012-10-05 19:16:31 +0000756
Zachary Turnerd37221d2014-07-09 16:31:49 +0000757 { LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeExpression,
Johnny Chen7d49c9c2012-05-25 21:10:46 +0000758 "The breakpoint stops only if this condition expression evaluates to true."},
759
Zachary Turnerd37221d2014-07-09 16:31:49 +0000760 { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadIndex,
Jim Inghama89be912013-03-26 18:29:03 +0000761 "The breakpoint stops only for the thread whose indeX matches this argument."},
Jim Ingham1b54c882010-06-16 02:00:15 +0000762
Zachary Turnerd37221d2014-07-09 16:31:49 +0000763 { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadID,
Jim Ingham1b54c882010-06-16 02:00:15 +0000764 "The breakpoint stops only for the thread whose TID matches this argument."},
765
Zachary Turnerd37221d2014-07-09 16:31:49 +0000766 { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadName,
Jim Ingham1b54c882010-06-16 02:00:15 +0000767 "The breakpoint stops only for the thread whose thread name matches this argument."},
768
Zachary Turnerd37221d2014-07-09 16:31:49 +0000769 { LLDB_OPT_SET_ALL, false, "hardware", 'H', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
Greg Claytoneb023e72013-10-11 19:48:25 +0000770 "Require the breakpoint to use hardware breakpoints."},
771
Zachary Turnerd37221d2014-07-09 16:31:49 +0000772 { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeQueueName,
Jim Ingham1b54c882010-06-16 02:00:15 +0000773 "The breakpoint stops only for threads in the queue whose name is given by this argument."},
774
Zachary Turnerd37221d2014-07-09 16:31:49 +0000775 { LLDB_OPT_FILE, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
Jim Ingham289aca62013-02-14 19:10:36 +0000776 "Specifies the source file in which to set this breakpoint. "
777 "Note, by default lldb only looks for files that are #included if they use the standard include file extensions. "
Jim Ingham63944792013-02-14 19:30:35 +0000778 "To set breakpoints on .c/.cpp/.m/.mm files that are #included, set target.inline-breakpoint-strategy"
Jim Ingham289aca62013-02-14 19:10:36 +0000779 " to \"always\"."},
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000780
Zachary Turnerd37221d2014-07-09 16:31:49 +0000781 { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum,
Jim Ingham87df91b2011-09-23 00:54:11 +0000782 "Specifies the line number on which to set this breakpoint."},
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000783
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000784 // Comment out this option for the moment, as we don't actually use it, but will in the future.
785 // This way users won't see it, but the infrastructure is left in place.
Virgile Belloe2607b52013-09-05 16:42:23 +0000786 // { 0, false, "column", 'C', OptionParser::eRequiredArgument, NULL, "<column>",
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000787 // "Set the breakpoint by source location at this particular column."},
788
Zachary Turnerd37221d2014-07-09 16:31:49 +0000789 { LLDB_OPT_SET_2, true, "address", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression,
Jim Ingham055a08a2015-11-17 03:39:13 +0000790 "Set the breakpoint at the specified address. "
791 "If the address maps uniquely to a particular "
792 "binary, then the address will be converted to a \"file\" address, so that the breakpoint will track that binary+offset no matter where "
793 "the binary eventually loads. "
794 "Alternately, if you also specify the module - with the -s option - then the address will be treated as "
795 "a file address in that module, and resolved accordingly. Again, this will allow lldb to track that offset on "
796 "subsequent reloads. The module need not have been loaded at the time you specify this breakpoint, and will "
797 "get resolved when the module is loaded."},
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000798
Zachary Turnerd37221d2014-07-09 16:31:49 +0000799 { LLDB_OPT_SET_3, true, "name", 'n', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
Jim Ingham551262d2013-03-27 17:36:54 +0000800 "Set the breakpoint by function name. Can be repeated multiple times to make one breakpoint for multiple names" },
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000801
Zachary Turnerd37221d2014-07-09 16:31:49 +0000802 { LLDB_OPT_SET_4, true, "fullname", 'F', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFullName,
Jim Ingham64cc29c2012-05-03 20:30:08 +0000803 "Set the breakpoint by fully qualified function names. For C++ this means namespaces and all arguments, and "
Jason Molendac8badb72015-09-28 23:02:00 +0000804 "for Objective C this means a full function prototype with class and selector. "
Jim Ingham64cc29c2012-05-03 20:30:08 +0000805 "Can be repeated multiple times to make one breakpoint for multiple names." },
Greg Clayton0c5cd902010-06-28 21:30:43 +0000806
Zachary Turnerd37221d2014-07-09 16:31:49 +0000807 { LLDB_OPT_SET_5, true, "selector", 'S', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeSelector,
Jim Ingham64cc29c2012-05-03 20:30:08 +0000808 "Set the breakpoint by ObjC selector name. Can be repeated multiple times to make one breakpoint for multiple Selectors." },
Greg Clayton0c5cd902010-06-28 21:30:43 +0000809
Zachary Turnerd37221d2014-07-09 16:31:49 +0000810 { LLDB_OPT_SET_6, true, "method", 'M', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeMethod,
Jim Ingham64cc29c2012-05-03 20:30:08 +0000811 "Set the breakpoint by C++ method names. Can be repeated multiple times to make one breakpoint for multiple methods." },
Greg Clayton0c5cd902010-06-28 21:30:43 +0000812
Zachary Turnerd37221d2014-07-09 16:31:49 +0000813 { LLDB_OPT_SET_7, true, "func-regex", 'r', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeRegularExpression,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000814 "Set the breakpoint by function name, evaluating a regular-expression to find the function name(s)." },
815
Zachary Turnerd37221d2014-07-09 16:31:49 +0000816 { LLDB_OPT_SET_8, true, "basename", 'b', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
Jim Ingham64cc29c2012-05-03 20:30:08 +0000817 "Set the breakpoint by function basename (C++ namespaces and arguments will be ignored). "
818 "Can be repeated multiple times to make one breakpoint for multiple symbols." },
Greg Claytone02b8502010-10-12 04:29:14 +0000819
Zachary Turnerd37221d2014-07-09 16:31:49 +0000820 { LLDB_OPT_SET_9, true, "source-pattern-regexp", 'p', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeRegularExpression,
Jim Inghame96ade82013-06-07 01:13:00 +0000821 "Set the breakpoint by specifying a regular expression which is matched against the source text in a source file or files "
822 "specified with the -f option. The -f option can be specified more than once. "
823 "If no source files are specified, uses the current \"default source file\"" },
Jim Ingham969795f2011-09-21 01:17:13 +0000824
Jim Inghame7320522015-02-12 17:37:46 +0000825 { LLDB_OPT_SET_9, false, "all-files", 'A', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
826 "All files are searched for source pattern matches." },
827
Zachary Turnerd37221d2014-07-09 16:31:49 +0000828 { LLDB_OPT_SET_10, true, "language-exception", 'E', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage,
Jim Inghamfab10e82012-03-06 00:37:27 +0000829 "Set the breakpoint on exceptions thrown by the specified language (without options, on throw but not catch.)" },
830
Zachary Turnerd37221d2014-07-09 16:31:49 +0000831 { LLDB_OPT_SET_10, false, "on-throw", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,
Jim Inghamfab10e82012-03-06 00:37:27 +0000832 "Set the breakpoint on exception throW." },
833
Zachary Turnerd37221d2014-07-09 16:31:49 +0000834 { LLDB_OPT_SET_10, false, "on-catch", 'h', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,
Jim Inghamfab10e82012-03-06 00:37:27 +0000835 "Set the breakpoint on exception catcH." },
Jim Ingham969795f2011-09-21 01:17:13 +0000836
Jim Inghama72b31c2015-04-22 19:42:18 +0000837// Don't add this option till it actually does something useful...
838// { LLDB_OPT_SET_10, false, "exception-typename", 'O', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeTypeName,
839// "The breakpoint will only stop if an exception Object of this type is thrown. Can be repeated multiple times to stop for multiple object types" },
840
Dawn Perchik23b1dec2015-07-21 22:05:07 +0000841 { LLDB_OPT_EXPR_LANGUAGE, false, "language", 'L', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage,
Dawn Perchik4112ab92015-07-22 02:01:32 +0000842 "Specifies the Language to use when interpreting the breakpoint's expression (note: currently only implemented for setting breakpoints on identifiers). If not set the target.language setting is used." },
Dawn Perchik23b1dec2015-07-21 22:05:07 +0000843
Zachary Turnerd37221d2014-07-09 16:31:49 +0000844 { LLDB_OPT_SKIP_PROLOGUE, false, "skip-prologue", 'K', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,
Jim Inghama8558b62012-05-22 00:12:20 +0000845 "sKip the prologue if the breakpoint is at the beginning of a function. If not set the target.skip-prologue setting is used." },
846
Jim Ingham33df7cd2014-12-06 01:28:03 +0000847 { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
848 "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
849
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000850 { LLDB_OPT_SET_ALL, false, "breakpoint-name", 'N', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBreakpointName,
851 "Adds this to the list of names for this breakopint."},
852
Ilia K055ad9b2015-05-18 13:41:01 +0000853 { LLDB_OPT_MOVE_TO_NEAREST_CODE, false, "move-to-nearest-code", 'm', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,
854 "Move breakpoints to nearest code. If not set the target.move-to-nearest-code setting is used." },
855
Zachary Turnerd37221d2014-07-09 16:31:49 +0000856 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000857};
858
Jim Ingham5a988412012-06-08 21:56:10 +0000859//-------------------------------------------------------------------------
860// CommandObjectBreakpointModify
861//-------------------------------------------------------------------------
862#pragma mark Modify
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000863
Jim Ingham5a988412012-06-08 21:56:10 +0000864class CommandObjectBreakpointModify : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000865{
Jim Ingham5a988412012-06-08 21:56:10 +0000866public:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000867
Jim Ingham5a988412012-06-08 21:56:10 +0000868 CommandObjectBreakpointModify (CommandInterpreter &interpreter) :
869 CommandObjectParsed (interpreter,
870 "breakpoint modify",
871 "Modify the options on a breakpoint or set of breakpoints in the executable. "
872 "If no breakpoint is specified, acts on the last created breakpoint. "
873 "With the exception of -e, -d and -i, passing an empty argument clears the modification.",
874 NULL),
875 m_options (interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000876 {
Jim Ingham5a988412012-06-08 21:56:10 +0000877 CommandArgumentEntry arg;
878 CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
879 // Add the entry for the first argument for this command to the object's arguments vector.
880 m_arguments.push_back (arg);
881 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000882
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000883
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000884 ~CommandObjectBreakpointModify () override {}
Greg Clayton0c5cd902010-06-28 21:30:43 +0000885
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000886 Options *
887 GetOptions () override
Jim Ingham5a988412012-06-08 21:56:10 +0000888 {
889 return &m_options;
890 }
Johnny Chen7d49c9c2012-05-25 21:10:46 +0000891
Jim Ingham5a988412012-06-08 21:56:10 +0000892 class CommandOptions : public Options
893 {
894 public:
Greg Clayton0c5cd902010-06-28 21:30:43 +0000895
Jim Ingham5a988412012-06-08 21:56:10 +0000896 CommandOptions (CommandInterpreter &interpreter) :
897 Options (interpreter),
898 m_ignore_count (0),
899 m_thread_id(LLDB_INVALID_THREAD_ID),
900 m_thread_id_passed(false),
901 m_thread_index (UINT32_MAX),
902 m_thread_index_passed(false),
903 m_thread_name(),
904 m_queue_name(),
905 m_condition (),
Jim Inghamca36cd12012-10-05 19:16:31 +0000906 m_one_shot (false),
Jim Ingham5a988412012-06-08 21:56:10 +0000907 m_enable_passed (false),
908 m_enable_value (false),
909 m_name_passed (false),
910 m_queue_passed (false),
Jim Inghamca36cd12012-10-05 19:16:31 +0000911 m_condition_passed (false),
Jim Ingham33df7cd2014-12-06 01:28:03 +0000912 m_one_shot_passed (false),
913 m_use_dummy (false)
Jim Ingham5a988412012-06-08 21:56:10 +0000914 {
915 }
Greg Clayton0c5cd902010-06-28 21:30:43 +0000916
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000917 ~CommandOptions () override {}
Greg Clayton0c5cd902010-06-28 21:30:43 +0000918
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000919 Error
920 SetOptionValue (uint32_t option_idx, const char *option_arg) override
Jim Ingham5a988412012-06-08 21:56:10 +0000921 {
922 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000923 const int short_option = m_getopt_table[option_idx].val;
Greg Claytone02b8502010-10-12 04:29:14 +0000924
Jim Ingham5a988412012-06-08 21:56:10 +0000925 switch (short_option)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000926 {
Jim Ingham5a988412012-06-08 21:56:10 +0000927 case 'c':
928 if (option_arg != NULL)
929 m_condition.assign (option_arg);
930 else
931 m_condition.clear();
932 m_condition_passed = true;
933 break;
934 case 'd':
935 m_enable_passed = true;
936 m_enable_value = false;
937 break;
Jim Ingham33df7cd2014-12-06 01:28:03 +0000938 case 'D':
939 m_use_dummy = true;
940 break;
Jim Ingham5a988412012-06-08 21:56:10 +0000941 case 'e':
942 m_enable_passed = true;
943 m_enable_value = true;
944 break;
945 case 'i':
946 {
Vince Harron5275aaa2015-01-15 20:08:35 +0000947 m_ignore_count = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
Jim Ingham5a988412012-06-08 21:56:10 +0000948 if (m_ignore_count == UINT32_MAX)
949 error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
950 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000951 break;
Jim Inghamca36cd12012-10-05 19:16:31 +0000952 case 'o':
953 {
954 bool value, success;
955 value = Args::StringToBoolean(option_arg, false, &success);
956 if (success)
957 {
958 m_one_shot_passed = true;
959 m_one_shot = value;
960 }
961 else
962 error.SetErrorStringWithFormat("invalid boolean value '%s' passed for -o option", option_arg);
963 }
964 break;
Jim Ingham5a988412012-06-08 21:56:10 +0000965 case 't' :
Jim Ingham87df91b2011-09-23 00:54:11 +0000966 {
Jim Ingham5a988412012-06-08 21:56:10 +0000967 if (option_arg[0] == '\0')
Jim Ingham87df91b2011-09-23 00:54:11 +0000968 {
Jim Ingham5a988412012-06-08 21:56:10 +0000969 m_thread_id = LLDB_INVALID_THREAD_ID;
970 m_thread_id_passed = true;
Jim Ingham87df91b2011-09-23 00:54:11 +0000971 }
972 else
973 {
Vince Harron5275aaa2015-01-15 20:08:35 +0000974 m_thread_id = StringConvert::ToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
Jim Ingham5a988412012-06-08 21:56:10 +0000975 if (m_thread_id == LLDB_INVALID_THREAD_ID)
976 error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
977 else
978 m_thread_id_passed = true;
Jim Ingham87df91b2011-09-23 00:54:11 +0000979 }
980 }
Jim Ingham5a988412012-06-08 21:56:10 +0000981 break;
982 case 'T':
983 if (option_arg != NULL)
984 m_thread_name.assign (option_arg);
985 else
986 m_thread_name.clear();
987 m_name_passed = true;
988 break;
989 case 'q':
990 if (option_arg != NULL)
991 m_queue_name.assign (option_arg);
992 else
993 m_queue_name.clear();
994 m_queue_passed = true;
995 break;
996 case 'x':
Jim Ingham969795f2011-09-21 01:17:13 +0000997 {
Jim Ingham5a988412012-06-08 21:56:10 +0000998 if (option_arg[0] == '\n')
999 {
1000 m_thread_index = UINT32_MAX;
1001 m_thread_index_passed = true;
1002 }
1003 else
1004 {
Vince Harron5275aaa2015-01-15 20:08:35 +00001005 m_thread_index = StringConvert::ToUInt32 (option_arg, UINT32_MAX, 0);
Jim Ingham5a988412012-06-08 21:56:10 +00001006 if (m_thread_id == UINT32_MAX)
1007 error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
1008 else
1009 m_thread_index_passed = true;
1010 }
Jim Ingham969795f2011-09-21 01:17:13 +00001011 }
Jim Ingham5a988412012-06-08 21:56:10 +00001012 break;
1013 default:
1014 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1015 break;
Jim Ingham969795f2011-09-21 01:17:13 +00001016 }
Jim Ingham5a988412012-06-08 21:56:10 +00001017
1018 return error;
1019 }
1020 void
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001021 OptionParsingStarting () override
Jim Ingham5a988412012-06-08 21:56:10 +00001022 {
1023 m_ignore_count = 0;
1024 m_thread_id = LLDB_INVALID_THREAD_ID;
1025 m_thread_id_passed = false;
1026 m_thread_index = UINT32_MAX;
1027 m_thread_index_passed = false;
1028 m_thread_name.clear();
1029 m_queue_name.clear();
1030 m_condition.clear();
Jim Inghamca36cd12012-10-05 19:16:31 +00001031 m_one_shot = false;
Jim Ingham5a988412012-06-08 21:56:10 +00001032 m_enable_passed = false;
1033 m_queue_passed = false;
1034 m_name_passed = false;
1035 m_condition_passed = false;
Jim Inghamca36cd12012-10-05 19:16:31 +00001036 m_one_shot_passed = false;
Jim Ingham33df7cd2014-12-06 01:28:03 +00001037 m_use_dummy = false;
Jim Ingham5a988412012-06-08 21:56:10 +00001038 }
1039
1040 const OptionDefinition*
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001041 GetDefinitions () override
Jim Ingham5a988412012-06-08 21:56:10 +00001042 {
1043 return g_option_table;
1044 }
1045
1046
1047 // Options table: Required for subclasses of Options.
1048
1049 static OptionDefinition g_option_table[];
1050
1051 // Instance variables to hold the values for command options.
1052
1053 uint32_t m_ignore_count;
1054 lldb::tid_t m_thread_id;
1055 bool m_thread_id_passed;
1056 uint32_t m_thread_index;
1057 bool m_thread_index_passed;
1058 std::string m_thread_name;
1059 std::string m_queue_name;
1060 std::string m_condition;
Jim Inghamca36cd12012-10-05 19:16:31 +00001061 bool m_one_shot;
Jim Ingham5a988412012-06-08 21:56:10 +00001062 bool m_enable_passed;
1063 bool m_enable_value;
1064 bool m_name_passed;
1065 bool m_queue_passed;
1066 bool m_condition_passed;
Jim Inghamca36cd12012-10-05 19:16:31 +00001067 bool m_one_shot_passed;
Jim Ingham33df7cd2014-12-06 01:28:03 +00001068 bool m_use_dummy;
Jim Ingham5a988412012-06-08 21:56:10 +00001069
1070 };
1071
1072protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001073 bool
1074 DoExecute (Args& command, CommandReturnObject &result) override
Jim Ingham5a988412012-06-08 21:56:10 +00001075 {
Jim Ingham33df7cd2014-12-06 01:28:03 +00001076 Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
Jim Ingham5a988412012-06-08 21:56:10 +00001077 if (target == NULL)
1078 {
1079 result.AppendError ("Invalid target. No existing target or breakpoints.");
1080 result.SetStatus (eReturnStatusFailed);
1081 return false;
1082 }
1083
1084 Mutex::Locker locker;
1085 target->GetBreakpointList().GetListMutex(locker);
1086
1087 BreakpointIDList valid_bp_ids;
1088
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001089 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
Jim Ingham5a988412012-06-08 21:56:10 +00001090
1091 if (result.Succeeded())
1092 {
1093 const size_t count = valid_bp_ids.GetSize();
1094 for (size_t i = 0; i < count; ++i)
Jim Inghamfab10e82012-03-06 00:37:27 +00001095 {
Jim Ingham5a988412012-06-08 21:56:10 +00001096 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1097
1098 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
1099 {
1100 Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1101 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
1102 {
1103 BreakpointLocation *location = bp->FindLocationByID (cur_bp_id.GetLocationID()).get();
1104 if (location)
1105 {
1106 if (m_options.m_thread_id_passed)
1107 location->SetThreadID (m_options.m_thread_id);
1108
1109 if (m_options.m_thread_index_passed)
1110 location->SetThreadIndex(m_options.m_thread_index);
1111
1112 if (m_options.m_name_passed)
1113 location->SetThreadName(m_options.m_thread_name.c_str());
1114
1115 if (m_options.m_queue_passed)
1116 location->SetQueueName(m_options.m_queue_name.c_str());
1117
1118 if (m_options.m_ignore_count != 0)
1119 location->SetIgnoreCount(m_options.m_ignore_count);
1120
1121 if (m_options.m_enable_passed)
1122 location->SetEnabled (m_options.m_enable_value);
1123
1124 if (m_options.m_condition_passed)
1125 location->SetCondition (m_options.m_condition.c_str());
1126 }
1127 }
1128 else
1129 {
1130 if (m_options.m_thread_id_passed)
1131 bp->SetThreadID (m_options.m_thread_id);
1132
1133 if (m_options.m_thread_index_passed)
1134 bp->SetThreadIndex(m_options.m_thread_index);
1135
1136 if (m_options.m_name_passed)
1137 bp->SetThreadName(m_options.m_thread_name.c_str());
1138
1139 if (m_options.m_queue_passed)
1140 bp->SetQueueName(m_options.m_queue_name.c_str());
1141
1142 if (m_options.m_ignore_count != 0)
1143 bp->SetIgnoreCount(m_options.m_ignore_count);
1144
1145 if (m_options.m_enable_passed)
1146 bp->SetEnabled (m_options.m_enable_value);
1147
1148 if (m_options.m_condition_passed)
1149 bp->SetCondition (m_options.m_condition.c_str());
1150 }
1151 }
Jim Inghamfab10e82012-03-06 00:37:27 +00001152 }
Jim Ingham5a988412012-06-08 21:56:10 +00001153 }
1154
1155 return result.Succeeded();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001156 }
1157
Jim Ingham5a988412012-06-08 21:56:10 +00001158private:
1159 CommandOptions m_options;
1160};
Johnny Chen7d49c9c2012-05-25 21:10:46 +00001161
Jim Ingham5a988412012-06-08 21:56:10 +00001162#pragma mark Modify::CommandOptions
1163OptionDefinition
1164CommandObjectBreakpointModify::CommandOptions::g_option_table[] =
1165{
Zachary Turnerd37221d2014-07-09 16:31:49 +00001166{ LLDB_OPT_SET_ALL, false, "ignore-count", 'i', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeCount, "Set the number of times this breakpoint is skipped before stopping." },
1167{ LLDB_OPT_SET_ALL, false, "one-shot", 'o', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "The breakpoint is deleted the first time it stop causes a stop." },
1168{ LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadIndex, "The breakpoint stops only for the thread whose index matches this argument."},
1169{ LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadID, "The breakpoint stops only for the thread whose TID matches this argument."},
1170{ LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadName, "The breakpoint stops only for the thread whose thread name matches this argument."},
1171{ LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeQueueName, "The breakpoint stops only for threads in the queue whose name is given by this argument."},
1172{ LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeExpression, "The breakpoint stops only if this condition expression evaluates to true."},
1173{ LLDB_OPT_SET_1, false, "enable", 'e', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Enable the breakpoint."},
1174{ LLDB_OPT_SET_2, false, "disable", 'd', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Disable the breakpoint."},
Jim Ingham33df7cd2014-12-06 01:28:03 +00001175{ LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
1176
Zachary Turnerd37221d2014-07-09 16:31:49 +00001177{ 0, false, NULL, 0 , 0, NULL, NULL, 0, eArgTypeNone, NULL }
Jim Ingham5a988412012-06-08 21:56:10 +00001178};
1179
1180//-------------------------------------------------------------------------
1181// CommandObjectBreakpointEnable
1182//-------------------------------------------------------------------------
1183#pragma mark Enable
1184
1185class CommandObjectBreakpointEnable : public CommandObjectParsed
1186{
1187public:
1188 CommandObjectBreakpointEnable (CommandInterpreter &interpreter) :
1189 CommandObjectParsed (interpreter,
1190 "enable",
1191 "Enable the specified disabled breakpoint(s). If no breakpoints are specified, enable all of them.",
1192 NULL)
1193 {
1194 CommandArgumentEntry arg;
1195 CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
1196 // Add the entry for the first argument for this command to the object's arguments vector.
1197 m_arguments.push_back (arg);
1198 }
1199
1200
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001201 ~CommandObjectBreakpointEnable () override {}
Jim Ingham5a988412012-06-08 21:56:10 +00001202
1203protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001204 bool
1205 DoExecute (Args& command, CommandReturnObject &result) override
Jim Ingham5a988412012-06-08 21:56:10 +00001206 {
Jim Ingham893c9322014-11-22 01:42:44 +00001207 Target *target = GetSelectedOrDummyTarget();
Jim Ingham5a988412012-06-08 21:56:10 +00001208 if (target == NULL)
1209 {
1210 result.AppendError ("Invalid target. No existing target or breakpoints.");
1211 result.SetStatus (eReturnStatusFailed);
1212 return false;
1213 }
1214
1215 Mutex::Locker locker;
1216 target->GetBreakpointList().GetListMutex(locker);
1217
1218 const BreakpointList &breakpoints = target->GetBreakpointList();
1219
1220 size_t num_breakpoints = breakpoints.GetSize();
1221
1222 if (num_breakpoints == 0)
1223 {
1224 result.AppendError ("No breakpoints exist to be enabled.");
1225 result.SetStatus (eReturnStatusFailed);
1226 return false;
1227 }
1228
1229 if (command.GetArgumentCount() == 0)
1230 {
1231 // No breakpoint selected; enable all currently set breakpoints.
1232 target->EnableAllBreakpoints ();
Greg Clayton6fea17e2014-03-03 19:15:20 +00001233 result.AppendMessageWithFormat ("All breakpoints enabled. (%" PRIu64 " breakpoints)\n", (uint64_t)num_breakpoints);
Jim Ingham5a988412012-06-08 21:56:10 +00001234 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1235 }
1236 else
1237 {
1238 // Particular breakpoint selected; enable that breakpoint.
1239 BreakpointIDList valid_bp_ids;
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001240 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
Jim Ingham5a988412012-06-08 21:56:10 +00001241
1242 if (result.Succeeded())
1243 {
1244 int enable_count = 0;
1245 int loc_count = 0;
1246 const size_t count = valid_bp_ids.GetSize();
1247 for (size_t i = 0; i < count; ++i)
1248 {
1249 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1250
1251 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
1252 {
1253 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1254 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
1255 {
1256 BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
1257 if (location)
1258 {
1259 location->SetEnabled (true);
1260 ++loc_count;
1261 }
1262 }
1263 else
1264 {
1265 breakpoint->SetEnabled (true);
1266 ++enable_count;
1267 }
1268 }
1269 }
1270 result.AppendMessageWithFormat ("%d breakpoints enabled.\n", enable_count + loc_count);
1271 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1272 }
1273 }
1274
1275 return result.Succeeded();
1276 }
1277};
1278
1279//-------------------------------------------------------------------------
1280// CommandObjectBreakpointDisable
1281//-------------------------------------------------------------------------
1282#pragma mark Disable
1283
1284class CommandObjectBreakpointDisable : public CommandObjectParsed
1285{
1286public:
1287 CommandObjectBreakpointDisable (CommandInterpreter &interpreter) :
1288 CommandObjectParsed (interpreter,
1289 "breakpoint disable",
Kate Stoneea671fb2015-07-14 05:48:36 +00001290 "Disable the specified breakpoint(s) without removing them. If none are specified, disable all breakpoints.",
Jim Ingham5a988412012-06-08 21:56:10 +00001291 NULL)
1292 {
Jim Inghamb0fac502013-03-08 00:31:40 +00001293 SetHelpLong(
Kate Stoneea671fb2015-07-14 05:48:36 +00001294"Disable the specified breakpoint(s) without removing them. \
1295If none are specified, disable all breakpoints." R"(
1296
1297)" "Note: disabling a breakpoint will cause none of its locations to be hit \
1298regardless of whether they are enabled or disabled. After the sequence:" R"(
1299
1300 (lldb) break disable 1
1301 (lldb) break enable 1.1
1302
1303execution will NOT stop at location 1.1. To achieve that, type:
1304
1305 (lldb) break disable 1.*
1306 (lldb) break enable 1.1
1307
1308)" "The first command disables all the locations of breakpoint 1, \
Jim Inghamb0fac502013-03-08 00:31:40 +00001309the second re-enables the first location."
Kate Stoneea671fb2015-07-14 05:48:36 +00001310 );
Jim Inghamb0fac502013-03-08 00:31:40 +00001311
Jim Ingham5a988412012-06-08 21:56:10 +00001312 CommandArgumentEntry arg;
1313 CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
1314 // Add the entry for the first argument for this command to the object's arguments vector.
Jim Inghamb0fac502013-03-08 00:31:40 +00001315 m_arguments.push_back (arg);
1316
Jim Ingham5a988412012-06-08 21:56:10 +00001317 }
1318
1319
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001320 ~CommandObjectBreakpointDisable () override {}
Jim Ingham5a988412012-06-08 21:56:10 +00001321
1322protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001323 bool
1324 DoExecute (Args& command, CommandReturnObject &result) override
Jim Ingham5a988412012-06-08 21:56:10 +00001325 {
Jim Ingham893c9322014-11-22 01:42:44 +00001326 Target *target = GetSelectedOrDummyTarget();
Jim Ingham5a988412012-06-08 21:56:10 +00001327 if (target == NULL)
1328 {
1329 result.AppendError ("Invalid target. No existing target or breakpoints.");
1330 result.SetStatus (eReturnStatusFailed);
1331 return false;
1332 }
1333
1334 Mutex::Locker locker;
1335 target->GetBreakpointList().GetListMutex(locker);
1336
1337 const BreakpointList &breakpoints = target->GetBreakpointList();
1338 size_t num_breakpoints = breakpoints.GetSize();
1339
1340 if (num_breakpoints == 0)
1341 {
1342 result.AppendError ("No breakpoints exist to be disabled.");
1343 result.SetStatus (eReturnStatusFailed);
1344 return false;
1345 }
1346
1347 if (command.GetArgumentCount() == 0)
1348 {
1349 // No breakpoint selected; disable all currently set breakpoints.
1350 target->DisableAllBreakpoints ();
Greg Clayton6fea17e2014-03-03 19:15:20 +00001351 result.AppendMessageWithFormat ("All breakpoints disabled. (%" PRIu64 " breakpoints)\n", (uint64_t)num_breakpoints);
Jim Ingham5a988412012-06-08 21:56:10 +00001352 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1353 }
1354 else
1355 {
1356 // Particular breakpoint selected; disable that breakpoint.
1357 BreakpointIDList valid_bp_ids;
1358
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001359 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
Jim Ingham5a988412012-06-08 21:56:10 +00001360
1361 if (result.Succeeded())
1362 {
1363 int disable_count = 0;
1364 int loc_count = 0;
1365 const size_t count = valid_bp_ids.GetSize();
1366 for (size_t i = 0; i < count; ++i)
1367 {
1368 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1369
1370 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
1371 {
1372 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1373 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
1374 {
1375 BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
1376 if (location)
1377 {
1378 location->SetEnabled (false);
1379 ++loc_count;
1380 }
1381 }
1382 else
1383 {
1384 breakpoint->SetEnabled (false);
1385 ++disable_count;
1386 }
1387 }
1388 }
1389 result.AppendMessageWithFormat ("%d breakpoints disabled.\n", disable_count + loc_count);
1390 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1391 }
1392 }
1393
1394 return result.Succeeded();
1395 }
1396
1397};
1398
1399//-------------------------------------------------------------------------
1400// CommandObjectBreakpointList
1401//-------------------------------------------------------------------------
1402#pragma mark List
1403
1404class CommandObjectBreakpointList : public CommandObjectParsed
1405{
1406public:
1407 CommandObjectBreakpointList (CommandInterpreter &interpreter) :
1408 CommandObjectParsed (interpreter,
1409 "breakpoint list",
1410 "List some or all breakpoints at configurable levels of detail.",
1411 NULL),
1412 m_options (interpreter)
1413 {
1414 CommandArgumentEntry arg;
1415 CommandArgumentData bp_id_arg;
1416
1417 // Define the first (and only) variant of this arg.
1418 bp_id_arg.arg_type = eArgTypeBreakpointID;
1419 bp_id_arg.arg_repetition = eArgRepeatOptional;
1420
1421 // There is only one variant this argument could be; put it into the argument entry.
1422 arg.push_back (bp_id_arg);
1423
1424 // Push the data for the first argument into the m_arguments vector.
1425 m_arguments.push_back (arg);
1426 }
1427
1428
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001429 ~CommandObjectBreakpointList () override {}
Jim Ingham5a988412012-06-08 21:56:10 +00001430
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001431 Options *
1432 GetOptions () override
Jim Ingham5a988412012-06-08 21:56:10 +00001433 {
1434 return &m_options;
Jim Ingham1b54c882010-06-16 02:00:15 +00001435 }
1436
Jim Ingham5a988412012-06-08 21:56:10 +00001437 class CommandOptions : public Options
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001438 {
Jim Ingham5a988412012-06-08 21:56:10 +00001439 public:
1440
1441 CommandOptions (CommandInterpreter &interpreter) :
1442 Options (interpreter),
Jim Ingham33df7cd2014-12-06 01:28:03 +00001443 m_level (lldb::eDescriptionLevelBrief),
1444 m_use_dummy(false)
Jim Ingham5a988412012-06-08 21:56:10 +00001445 {
1446 }
1447
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001448 ~CommandOptions () override {}
Jim Ingham5a988412012-06-08 21:56:10 +00001449
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001450 Error
1451 SetOptionValue (uint32_t option_idx, const char *option_arg) override
Jim Ingham5a988412012-06-08 21:56:10 +00001452 {
1453 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +00001454 const int short_option = m_getopt_table[option_idx].val;
Jim Ingham5a988412012-06-08 21:56:10 +00001455
1456 switch (short_option)
1457 {
1458 case 'b':
1459 m_level = lldb::eDescriptionLevelBrief;
1460 break;
Jim Ingham33df7cd2014-12-06 01:28:03 +00001461 case 'D':
1462 m_use_dummy = true;
1463 break;
Jim Ingham5a988412012-06-08 21:56:10 +00001464 case 'f':
1465 m_level = lldb::eDescriptionLevelFull;
1466 break;
1467 case 'v':
1468 m_level = lldb::eDescriptionLevelVerbose;
1469 break;
1470 case 'i':
1471 m_internal = true;
1472 break;
1473 default:
1474 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1475 break;
1476 }
1477
1478 return error;
1479 }
1480
1481 void
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001482 OptionParsingStarting () override
Jim Ingham5a988412012-06-08 21:56:10 +00001483 {
1484 m_level = lldb::eDescriptionLevelFull;
1485 m_internal = false;
Jim Ingham33df7cd2014-12-06 01:28:03 +00001486 m_use_dummy = false;
Jim Ingham5a988412012-06-08 21:56:10 +00001487 }
1488
1489 const OptionDefinition *
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001490 GetDefinitions () override
Jim Ingham5a988412012-06-08 21:56:10 +00001491 {
1492 return g_option_table;
1493 }
1494
1495 // Options table: Required for subclasses of Options.
1496
1497 static OptionDefinition g_option_table[];
1498
1499 // Instance variables to hold the values for command options.
1500
1501 lldb::DescriptionLevel m_level;
1502
1503 bool m_internal;
Jim Ingham33df7cd2014-12-06 01:28:03 +00001504 bool m_use_dummy;
Jim Ingham5a988412012-06-08 21:56:10 +00001505 };
1506
1507protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001508 bool
1509 DoExecute (Args& command, CommandReturnObject &result) override
Jim Ingham5a988412012-06-08 21:56:10 +00001510 {
Jim Ingham33df7cd2014-12-06 01:28:03 +00001511 Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
1512
Jim Ingham5a988412012-06-08 21:56:10 +00001513 if (target == NULL)
1514 {
1515 result.AppendError ("Invalid target. No current target or breakpoints.");
1516 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1517 return true;
1518 }
1519
1520 const BreakpointList &breakpoints = target->GetBreakpointList(m_options.m_internal);
1521 Mutex::Locker locker;
1522 target->GetBreakpointList(m_options.m_internal).GetListMutex(locker);
1523
1524 size_t num_breakpoints = breakpoints.GetSize();
1525
1526 if (num_breakpoints == 0)
1527 {
1528 result.AppendMessage ("No breakpoints currently set.");
1529 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1530 return true;
1531 }
1532
Jim Ingham85e8b812011-02-19 02:53:09 +00001533 Stream &output_stream = result.GetOutputStream();
Jim Ingham5a988412012-06-08 21:56:10 +00001534
1535 if (command.GetArgumentCount() == 0)
1536 {
1537 // No breakpoint selected; show info about all currently set breakpoints.
1538 result.AppendMessage ("Current breakpoints:");
1539 for (size_t i = 0; i < num_breakpoints; ++i)
1540 {
1541 Breakpoint *breakpoint = breakpoints.GetBreakpointAtIndex (i).get();
1542 AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
1543 }
1544 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1545 }
1546 else
1547 {
1548 // Particular breakpoints selected; show info about that breakpoint.
1549 BreakpointIDList valid_bp_ids;
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001550 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
Jim Ingham5a988412012-06-08 21:56:10 +00001551
1552 if (result.Succeeded())
1553 {
1554 for (size_t i = 0; i < valid_bp_ids.GetSize(); ++i)
1555 {
1556 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1557 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1558 AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
1559 }
1560 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1561 }
1562 else
1563 {
1564 result.AppendError ("Invalid breakpoint id.");
1565 result.SetStatus (eReturnStatusFailed);
1566 }
1567 }
1568
1569 return result.Succeeded();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001570 }
1571
Jim Ingham5a988412012-06-08 21:56:10 +00001572private:
1573 CommandOptions m_options;
1574};
1575
1576#pragma mark List::CommandOptions
1577OptionDefinition
1578CommandObjectBreakpointList::CommandOptions::g_option_table[] =
1579{
Zachary Turnerd37221d2014-07-09 16:31:49 +00001580 { LLDB_OPT_SET_ALL, false, "internal", 'i', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
Jim Ingham5a988412012-06-08 21:56:10 +00001581 "Show debugger internal breakpoints" },
1582
Zachary Turnerd37221d2014-07-09 16:31:49 +00001583 { LLDB_OPT_SET_1, false, "brief", 'b', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
Jim Ingham5a988412012-06-08 21:56:10 +00001584 "Give a brief description of the breakpoint (no location info)."},
1585
1586 // FIXME: We need to add an "internal" command, and then add this sort of thing to it.
1587 // But I need to see it for now, and don't want to wait.
Zachary Turnerd37221d2014-07-09 16:31:49 +00001588 { LLDB_OPT_SET_2, false, "full", 'f', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
Jim Ingham5a988412012-06-08 21:56:10 +00001589 "Give a full description of the breakpoint and its locations."},
1590
Zachary Turnerd37221d2014-07-09 16:31:49 +00001591 { LLDB_OPT_SET_3, false, "verbose", 'v', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
Jim Ingham5a988412012-06-08 21:56:10 +00001592 "Explain everything we know about the breakpoint (for debugging debugger bugs)." },
1593
Jim Ingham33df7cd2014-12-06 01:28:03 +00001594 { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
1595 "List Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
1596
Zachary Turnerd37221d2014-07-09 16:31:49 +00001597 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Jim Ingham5a988412012-06-08 21:56:10 +00001598};
1599
1600//-------------------------------------------------------------------------
1601// CommandObjectBreakpointClear
1602//-------------------------------------------------------------------------
1603#pragma mark Clear
1604
1605class CommandObjectBreakpointClear : public CommandObjectParsed
1606{
1607public:
1608
1609 typedef enum BreakpointClearType
1610 {
1611 eClearTypeInvalid,
1612 eClearTypeFileAndLine
1613 } BreakpointClearType;
1614
1615 CommandObjectBreakpointClear (CommandInterpreter &interpreter) :
1616 CommandObjectParsed (interpreter,
1617 "breakpoint clear",
1618 "Clears a breakpoint or set of breakpoints in the executable.",
1619 "breakpoint clear <cmd-options>"),
1620 m_options (interpreter)
1621 {
1622 }
1623
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001624 ~CommandObjectBreakpointClear () override {}
Jim Ingham5a988412012-06-08 21:56:10 +00001625
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001626 Options *
1627 GetOptions () override
Jim Ingham5a988412012-06-08 21:56:10 +00001628 {
1629 return &m_options;
1630 }
1631
1632 class CommandOptions : public Options
1633 {
1634 public:
1635
1636 CommandOptions (CommandInterpreter &interpreter) :
1637 Options (interpreter),
1638 m_filename (),
1639 m_line_num (0)
1640 {
1641 }
1642
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001643 ~CommandOptions () override {}
Jim Ingham5a988412012-06-08 21:56:10 +00001644
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001645 Error
1646 SetOptionValue (uint32_t option_idx, const char *option_arg) override
Jim Ingham5a988412012-06-08 21:56:10 +00001647 {
1648 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +00001649 const int short_option = m_getopt_table[option_idx].val;
Jim Ingham5a988412012-06-08 21:56:10 +00001650
1651 switch (short_option)
1652 {
1653 case 'f':
1654 m_filename.assign (option_arg);
1655 break;
1656
1657 case 'l':
Vince Harron5275aaa2015-01-15 20:08:35 +00001658 m_line_num = StringConvert::ToUInt32 (option_arg, 0);
Jim Ingham5a988412012-06-08 21:56:10 +00001659 break;
1660
1661 default:
1662 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1663 break;
1664 }
1665
1666 return error;
1667 }
1668
1669 void
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001670 OptionParsingStarting () override
Jim Ingham5a988412012-06-08 21:56:10 +00001671 {
1672 m_filename.clear();
1673 m_line_num = 0;
1674 }
1675
1676 const OptionDefinition*
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001677 GetDefinitions () override
Jim Ingham5a988412012-06-08 21:56:10 +00001678 {
1679 return g_option_table;
1680 }
1681
1682 // Options table: Required for subclasses of Options.
1683
1684 static OptionDefinition g_option_table[];
1685
1686 // Instance variables to hold the values for command options.
1687
1688 std::string m_filename;
1689 uint32_t m_line_num;
1690
1691 };
1692
1693protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001694 bool
1695 DoExecute (Args& command, CommandReturnObject &result) override
Jim Ingham5a988412012-06-08 21:56:10 +00001696 {
Jim Ingham893c9322014-11-22 01:42:44 +00001697 Target *target = GetSelectedOrDummyTarget();
Jim Ingham5a988412012-06-08 21:56:10 +00001698 if (target == NULL)
1699 {
1700 result.AppendError ("Invalid target. No existing target or breakpoints.");
1701 result.SetStatus (eReturnStatusFailed);
1702 return false;
1703 }
1704
1705 // The following are the various types of breakpoints that could be cleared:
1706 // 1). -f -l (clearing breakpoint by source location)
1707
1708 BreakpointClearType break_type = eClearTypeInvalid;
1709
1710 if (m_options.m_line_num != 0)
1711 break_type = eClearTypeFileAndLine;
1712
1713 Mutex::Locker locker;
1714 target->GetBreakpointList().GetListMutex(locker);
1715
1716 BreakpointList &breakpoints = target->GetBreakpointList();
1717 size_t num_breakpoints = breakpoints.GetSize();
1718
1719 // Early return if there's no breakpoint at all.
1720 if (num_breakpoints == 0)
1721 {
1722 result.AppendError ("Breakpoint clear: No breakpoint cleared.");
1723 result.SetStatus (eReturnStatusFailed);
1724 return result.Succeeded();
1725 }
1726
1727 // Find matching breakpoints and delete them.
1728
1729 // First create a copy of all the IDs.
1730 std::vector<break_id_t> BreakIDs;
1731 for (size_t i = 0; i < num_breakpoints; ++i)
1732 BreakIDs.push_back(breakpoints.GetBreakpointAtIndex(i).get()->GetID());
1733
1734 int num_cleared = 0;
1735 StreamString ss;
1736 switch (break_type)
1737 {
1738 case eClearTypeFileAndLine: // Breakpoint by source position
1739 {
1740 const ConstString filename(m_options.m_filename.c_str());
1741 BreakpointLocationCollection loc_coll;
1742
1743 for (size_t i = 0; i < num_breakpoints; ++i)
1744 {
1745 Breakpoint *bp = breakpoints.FindBreakpointByID(BreakIDs[i]).get();
1746
1747 if (bp->GetMatchingFileLine(filename, m_options.m_line_num, loc_coll))
1748 {
1749 // If the collection size is 0, it's a full match and we can just remove the breakpoint.
1750 if (loc_coll.GetSize() == 0)
1751 {
1752 bp->GetDescription(&ss, lldb::eDescriptionLevelBrief);
1753 ss.EOL();
1754 target->RemoveBreakpointByID (bp->GetID());
1755 ++num_cleared;
1756 }
1757 }
1758 }
1759 }
1760 break;
1761
1762 default:
1763 break;
1764 }
1765
1766 if (num_cleared > 0)
1767 {
1768 Stream &output_stream = result.GetOutputStream();
1769 output_stream.Printf ("%d breakpoints cleared:\n", num_cleared);
1770 output_stream << ss.GetData();
1771 output_stream.EOL();
1772 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1773 }
1774 else
1775 {
1776 result.AppendError ("Breakpoint clear: No breakpoint cleared.");
1777 result.SetStatus (eReturnStatusFailed);
1778 }
1779
1780 return result.Succeeded();
1781 }
1782
1783private:
1784 CommandOptions m_options;
1785};
1786
1787#pragma mark Clear::CommandOptions
1788
1789OptionDefinition
1790CommandObjectBreakpointClear::CommandOptions::g_option_table[] =
1791{
Zachary Turnerd37221d2014-07-09 16:31:49 +00001792 { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
Jim Ingham5a988412012-06-08 21:56:10 +00001793 "Specify the breakpoint by source location in this particular file."},
1794
Zachary Turnerd37221d2014-07-09 16:31:49 +00001795 { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum,
Jim Ingham5a988412012-06-08 21:56:10 +00001796 "Specify the breakpoint by source location at this particular line."},
1797
Zachary Turnerd37221d2014-07-09 16:31:49 +00001798 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Jim Ingham5a988412012-06-08 21:56:10 +00001799};
1800
1801//-------------------------------------------------------------------------
1802// CommandObjectBreakpointDelete
1803//-------------------------------------------------------------------------
1804#pragma mark Delete
1805
1806class CommandObjectBreakpointDelete : public CommandObjectParsed
1807{
1808public:
1809 CommandObjectBreakpointDelete (CommandInterpreter &interpreter) :
1810 CommandObjectParsed (interpreter,
1811 "breakpoint delete",
1812 "Delete the specified breakpoint(s). If no breakpoints are specified, delete them all.",
Jim Ingham33df7cd2014-12-06 01:28:03 +00001813 NULL),
1814 m_options (interpreter)
Jim Ingham5a988412012-06-08 21:56:10 +00001815 {
1816 CommandArgumentEntry arg;
1817 CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
1818 // Add the entry for the first argument for this command to the object's arguments vector.
1819 m_arguments.push_back (arg);
1820 }
1821
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001822 ~CommandObjectBreakpointDelete () override {}
Jim Ingham5a988412012-06-08 21:56:10 +00001823
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001824 Options *
1825 GetOptions () override
Jim Ingham33df7cd2014-12-06 01:28:03 +00001826 {
1827 return &m_options;
1828 }
1829
1830 class CommandOptions : public Options
1831 {
1832 public:
1833
1834 CommandOptions (CommandInterpreter &interpreter) :
1835 Options (interpreter),
1836 m_use_dummy (false),
1837 m_force (false)
1838 {
1839 }
1840
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001841 ~CommandOptions () override {}
Jim Ingham33df7cd2014-12-06 01:28:03 +00001842
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001843 Error
1844 SetOptionValue (uint32_t option_idx, const char *option_arg) override
Jim Ingham33df7cd2014-12-06 01:28:03 +00001845 {
1846 Error error;
1847 const int short_option = m_getopt_table[option_idx].val;
1848
1849 switch (short_option)
1850 {
1851 case 'f':
1852 m_force = true;
1853 break;
1854
1855 case 'D':
1856 m_use_dummy = true;
1857 break;
1858
1859 default:
1860 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1861 break;
1862 }
1863
1864 return error;
1865 }
1866
1867 void
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001868 OptionParsingStarting () override
Jim Ingham33df7cd2014-12-06 01:28:03 +00001869 {
1870 m_use_dummy = false;
1871 m_force = false;
1872 }
1873
1874 const OptionDefinition*
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001875 GetDefinitions () override
Jim Ingham33df7cd2014-12-06 01:28:03 +00001876 {
1877 return g_option_table;
1878 }
1879
1880 // Options table: Required for subclasses of Options.
1881
1882 static OptionDefinition g_option_table[];
1883
1884 // Instance variables to hold the values for command options.
1885 bool m_use_dummy;
1886 bool m_force;
1887 };
1888
Jim Ingham5a988412012-06-08 21:56:10 +00001889protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001890 bool
1891 DoExecute (Args& command, CommandReturnObject &result) override
Jim Ingham5a988412012-06-08 21:56:10 +00001892 {
Jim Ingham33df7cd2014-12-06 01:28:03 +00001893 Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
1894
Jim Ingham5a988412012-06-08 21:56:10 +00001895 if (target == NULL)
1896 {
1897 result.AppendError ("Invalid target. No existing target or breakpoints.");
1898 result.SetStatus (eReturnStatusFailed);
1899 return false;
1900 }
1901
1902 Mutex::Locker locker;
1903 target->GetBreakpointList().GetListMutex(locker);
1904
1905 const BreakpointList &breakpoints = target->GetBreakpointList();
1906
1907 size_t num_breakpoints = breakpoints.GetSize();
1908
1909 if (num_breakpoints == 0)
1910 {
1911 result.AppendError ("No breakpoints exist to be deleted.");
1912 result.SetStatus (eReturnStatusFailed);
1913 return false;
1914 }
1915
1916 if (command.GetArgumentCount() == 0)
1917 {
Jim Ingham33df7cd2014-12-06 01:28:03 +00001918 if (!m_options.m_force && !m_interpreter.Confirm ("About to delete all breakpoints, do you want to do that?", true))
Jim Ingham5a988412012-06-08 21:56:10 +00001919 {
1920 result.AppendMessage("Operation cancelled...");
1921 }
1922 else
1923 {
1924 target->RemoveAllBreakpoints ();
Greg Clayton6fea17e2014-03-03 19:15:20 +00001925 result.AppendMessageWithFormat ("All breakpoints removed. (%" PRIu64 " breakpoint%s)\n", (uint64_t)num_breakpoints, num_breakpoints > 1 ? "s" : "");
Jim Ingham5a988412012-06-08 21:56:10 +00001926 }
1927 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1928 }
1929 else
1930 {
1931 // Particular breakpoint selected; disable that breakpoint.
1932 BreakpointIDList valid_bp_ids;
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001933 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
Jim Ingham5a988412012-06-08 21:56:10 +00001934
1935 if (result.Succeeded())
1936 {
1937 int delete_count = 0;
1938 int disable_count = 0;
1939 const size_t count = valid_bp_ids.GetSize();
1940 for (size_t i = 0; i < count; ++i)
1941 {
1942 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1943
1944 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
1945 {
1946 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
1947 {
1948 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1949 BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
1950 // It makes no sense to try to delete individual locations, so we disable them instead.
1951 if (location)
1952 {
1953 location->SetEnabled (false);
1954 ++disable_count;
1955 }
1956 }
1957 else
1958 {
1959 target->RemoveBreakpointByID (cur_bp_id.GetBreakpointID());
1960 ++delete_count;
1961 }
1962 }
1963 }
1964 result.AppendMessageWithFormat ("%d breakpoints deleted; %d breakpoint locations disabled.\n",
1965 delete_count, disable_count);
1966 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1967 }
1968 }
1969 return result.Succeeded();
1970 }
Jim Ingham33df7cd2014-12-06 01:28:03 +00001971private:
1972 CommandOptions m_options;
1973};
1974
1975OptionDefinition
1976CommandObjectBreakpointDelete::CommandOptions::g_option_table[] =
1977{
1978 { LLDB_OPT_SET_1, false, "force", 'f', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
1979 "Delete all breakpoints without querying for confirmation."},
1980
1981 { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
1982 "Delete Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
1983
1984 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Jim Ingham5a988412012-06-08 21:56:10 +00001985};
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001986
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001987//-------------------------------------------------------------------------
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001988// CommandObjectBreakpointName
1989//-------------------------------------------------------------------------
1990
1991static OptionDefinition
1992g_breakpoint_name_options[] =
1993{
1994 { LLDB_OPT_SET_1, false, "name", 'N', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBreakpointName, "Specifies a breakpoint name to use."},
1995 { LLDB_OPT_SET_2, false, "breakpoint-id", 'B', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBreakpointID, "Specify a breakpoint id to use."},
1996 { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
1997 "Operate on Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
1998};
1999class BreakpointNameOptionGroup : public OptionGroup
2000{
2001public:
2002 BreakpointNameOptionGroup() :
2003 OptionGroup(),
2004 m_breakpoint(LLDB_INVALID_BREAK_ID),
2005 m_use_dummy (false)
2006 {
2007
2008 }
2009
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002010 ~BreakpointNameOptionGroup () override
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002011 {
2012 }
2013
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002014 uint32_t
2015 GetNumDefinitions () override
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002016 {
2017 return sizeof (g_breakpoint_name_options) / sizeof (OptionDefinition);
2018 }
2019
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002020 const OptionDefinition*
2021 GetDefinitions () override
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002022 {
2023 return g_breakpoint_name_options;
2024 }
2025
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002026 Error
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002027 SetOptionValue (CommandInterpreter &interpreter,
2028 uint32_t option_idx,
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002029 const char *option_value) override
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002030 {
2031 Error error;
2032 const int short_option = g_breakpoint_name_options[option_idx].short_option;
2033
2034 switch (short_option)
2035 {
2036 case 'N':
2037 if (BreakpointID::StringIsBreakpointName(option_value, error) && error.Success())
Pavel Labathc95f7e22015-02-20 11:14:59 +00002038 m_name.SetValueFromString(option_value);
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002039 break;
2040
2041 case 'B':
Pavel Labathc95f7e22015-02-20 11:14:59 +00002042 if (m_breakpoint.SetValueFromString(option_value).Fail())
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002043 error.SetErrorStringWithFormat ("unrecognized value \"%s\" for breakpoint", option_value);
2044 break;
2045 case 'D':
Pavel Labathc95f7e22015-02-20 11:14:59 +00002046 if (m_use_dummy.SetValueFromString(option_value).Fail())
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002047 error.SetErrorStringWithFormat ("unrecognized value \"%s\" for use-dummy", option_value);
2048 break;
2049
2050 default:
2051 error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option);
2052 break;
2053 }
2054 return error;
2055 }
2056
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002057 void
2058 OptionParsingStarting (CommandInterpreter &interpreter) override
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002059 {
2060 m_name.Clear();
2061 m_breakpoint.Clear();
2062 m_use_dummy.Clear();
2063 m_use_dummy.SetDefaultValue(false);
2064 }
2065
2066 OptionValueString m_name;
2067 OptionValueUInt64 m_breakpoint;
2068 OptionValueBoolean m_use_dummy;
2069};
2070
2071
2072class CommandObjectBreakpointNameAdd : public CommandObjectParsed
2073{
2074public:
2075 CommandObjectBreakpointNameAdd (CommandInterpreter &interpreter) :
2076 CommandObjectParsed (interpreter,
2077 "add",
2078 "Add a name to the breakpoints provided.",
2079 "breakpoint name add <command-options> <breakpoint-id-list>"),
2080 m_name_options(),
2081 m_option_group(interpreter)
2082 {
2083 // Create the first variant for the first (and only) argument for this command.
2084 CommandArgumentEntry arg1;
2085 CommandArgumentData id_arg;
2086 id_arg.arg_type = eArgTypeBreakpointID;
2087 id_arg.arg_repetition = eArgRepeatOptional;
2088 arg1.push_back(id_arg);
2089 m_arguments.push_back (arg1);
2090
2091 m_option_group.Append (&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
2092 m_option_group.Finalize();
2093 }
2094
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002095 ~CommandObjectBreakpointNameAdd () override {}
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002096
2097 Options *
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002098 GetOptions () override
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002099 {
2100 return &m_option_group;
2101 }
2102
2103protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002104 bool
2105 DoExecute (Args& command, CommandReturnObject &result) override
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002106 {
2107 if (!m_name_options.m_name.OptionWasSet())
2108 {
2109 result.SetError("No name option provided.");
2110 return false;
2111 }
2112
2113 Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
2114
2115 if (target == NULL)
2116 {
2117 result.AppendError ("Invalid target. No existing target or breakpoints.");
2118 result.SetStatus (eReturnStatusFailed);
2119 return false;
2120 }
2121
2122 Mutex::Locker locker;
2123 target->GetBreakpointList().GetListMutex(locker);
2124
2125 const BreakpointList &breakpoints = target->GetBreakpointList();
2126
2127 size_t num_breakpoints = breakpoints.GetSize();
2128 if (num_breakpoints == 0)
2129 {
2130 result.SetError("No breakpoints, cannot add names.");
2131 result.SetStatus (eReturnStatusFailed);
2132 return false;
2133 }
2134
2135 // Particular breakpoint selected; disable that breakpoint.
2136 BreakpointIDList valid_bp_ids;
2137 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
2138
2139 if (result.Succeeded())
2140 {
2141 if (valid_bp_ids.GetSize() == 0)
2142 {
2143 result.SetError("No breakpoints specified, cannot add names.");
2144 result.SetStatus (eReturnStatusFailed);
2145 return false;
2146 }
2147 size_t num_valid_ids = valid_bp_ids.GetSize();
2148 for (size_t index = 0; index < num_valid_ids; index++)
2149 {
2150 lldb::break_id_t bp_id = valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
2151 BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
2152 Error error; // We don't need to check the error here, since the option parser checked it...
2153 bp_sp->AddName(m_name_options.m_name.GetCurrentValue(), error);
2154 }
2155 }
2156
2157 return true;
2158 }
2159
2160private:
2161 BreakpointNameOptionGroup m_name_options;
2162 OptionGroupOptions m_option_group;
2163};
2164
2165
2166
2167class CommandObjectBreakpointNameDelete : public CommandObjectParsed
2168{
2169public:
2170 CommandObjectBreakpointNameDelete (CommandInterpreter &interpreter) :
2171 CommandObjectParsed (interpreter,
2172 "delete",
2173 "Delete a name from the breakpoints provided.",
2174 "breakpoint name delete <command-options> <breakpoint-id-list>"),
2175 m_name_options(),
2176 m_option_group(interpreter)
2177 {
2178 // Create the first variant for the first (and only) argument for this command.
2179 CommandArgumentEntry arg1;
2180 CommandArgumentData id_arg;
2181 id_arg.arg_type = eArgTypeBreakpointID;
2182 id_arg.arg_repetition = eArgRepeatOptional;
2183 arg1.push_back(id_arg);
2184 m_arguments.push_back (arg1);
2185
2186 m_option_group.Append (&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
2187 m_option_group.Finalize();
2188 }
2189
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002190 ~CommandObjectBreakpointNameDelete () override {}
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002191
2192 Options *
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002193 GetOptions () override
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002194 {
2195 return &m_option_group;
2196 }
2197
2198protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002199 bool
2200 DoExecute (Args& command, CommandReturnObject &result) override
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002201 {
2202 if (!m_name_options.m_name.OptionWasSet())
2203 {
2204 result.SetError("No name option provided.");
2205 return false;
2206 }
2207
2208 Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
2209
2210 if (target == NULL)
2211 {
2212 result.AppendError ("Invalid target. No existing target or breakpoints.");
2213 result.SetStatus (eReturnStatusFailed);
2214 return false;
2215 }
2216
2217 Mutex::Locker locker;
2218 target->GetBreakpointList().GetListMutex(locker);
2219
2220 const BreakpointList &breakpoints = target->GetBreakpointList();
2221
2222 size_t num_breakpoints = breakpoints.GetSize();
2223 if (num_breakpoints == 0)
2224 {
2225 result.SetError("No breakpoints, cannot delete names.");
2226 result.SetStatus (eReturnStatusFailed);
2227 return false;
2228 }
2229
2230 // Particular breakpoint selected; disable that breakpoint.
2231 BreakpointIDList valid_bp_ids;
2232 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
2233
2234 if (result.Succeeded())
2235 {
2236 if (valid_bp_ids.GetSize() == 0)
2237 {
2238 result.SetError("No breakpoints specified, cannot delete names.");
2239 result.SetStatus (eReturnStatusFailed);
2240 return false;
2241 }
2242 size_t num_valid_ids = valid_bp_ids.GetSize();
2243 for (size_t index = 0; index < num_valid_ids; index++)
2244 {
2245 lldb::break_id_t bp_id = valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
2246 BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
2247 bp_sp->RemoveName(m_name_options.m_name.GetCurrentValue());
2248 }
2249 }
2250
2251 return true;
2252 }
2253
2254private:
2255 BreakpointNameOptionGroup m_name_options;
2256 OptionGroupOptions m_option_group;
2257};
2258
2259class CommandObjectBreakpointNameList : public CommandObjectParsed
2260{
2261public:
2262 CommandObjectBreakpointNameList (CommandInterpreter &interpreter) :
2263 CommandObjectParsed (interpreter,
2264 "list",
2265 "List either the names for a breakpoint or the breakpoints for a given name.",
2266 "breakpoint name list <command-options>"),
2267 m_name_options(),
2268 m_option_group(interpreter)
2269 {
2270 m_option_group.Append (&m_name_options);
2271 m_option_group.Finalize();
2272 }
2273
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002274 ~CommandObjectBreakpointNameList () override {}
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002275
2276 Options *
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002277 GetOptions () override
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002278 {
2279 return &m_option_group;
2280 }
2281
2282protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002283 bool
2284 DoExecute (Args& command, CommandReturnObject &result) override
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002285 {
2286 Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
2287
2288 if (target == NULL)
2289 {
2290 result.AppendError ("Invalid target. No existing target or breakpoints.");
2291 result.SetStatus (eReturnStatusFailed);
2292 return false;
2293 }
2294
2295 if (m_name_options.m_name.OptionWasSet())
2296 {
2297 const char *name = m_name_options.m_name.GetCurrentValue();
2298 Mutex::Locker locker;
2299 target->GetBreakpointList().GetListMutex(locker);
2300
2301 BreakpointList &breakpoints = target->GetBreakpointList();
2302 for (BreakpointSP bp_sp : breakpoints.Breakpoints())
2303 {
2304 if (bp_sp->MatchesName(name))
2305 {
2306 StreamString s;
2307 bp_sp->GetDescription(&s, eDescriptionLevelBrief);
2308 s.EOL();
2309 result.AppendMessage(s.GetData());
2310 }
2311 }
2312
2313 }
2314 else if (m_name_options.m_breakpoint.OptionWasSet())
2315 {
2316 BreakpointSP bp_sp = target->GetBreakpointList().FindBreakpointByID(m_name_options.m_breakpoint.GetCurrentValue());
2317 if (bp_sp)
2318 {
2319 std::vector<std::string> names;
2320 bp_sp->GetNames (names);
2321 result.AppendMessage ("Names:");
2322 for (auto name : names)
2323 result.AppendMessageWithFormat (" %s\n", name.c_str());
2324 }
2325 else
2326 {
2327 result.AppendErrorWithFormat ("Could not find breakpoint %" PRId64 ".\n",
2328 m_name_options.m_breakpoint.GetCurrentValue());
2329 result.SetStatus (eReturnStatusFailed);
2330 return false;
2331 }
2332 }
2333 else
2334 {
2335 result.SetError ("Must specify -N or -B option to list.");
2336 result.SetStatus (eReturnStatusFailed);
2337 return false;
2338 }
2339 return true;
2340 }
2341
2342private:
2343 BreakpointNameOptionGroup m_name_options;
2344 OptionGroupOptions m_option_group;
2345};
2346
2347//-------------------------------------------------------------------------
2348// CommandObjectMultiwordBreakpoint
2349//-------------------------------------------------------------------------
2350class CommandObjectBreakpointName : public CommandObjectMultiword
2351{
2352public:
2353 CommandObjectBreakpointName (CommandInterpreter &interpreter) :
2354 CommandObjectMultiword(interpreter,
2355 "name",
2356 "A set of commands to manage name tags for breakpoints",
2357 "breakpoint name <command> [<command-options>]")
2358 {
2359 CommandObjectSP add_command_object (new CommandObjectBreakpointNameAdd (interpreter));
2360 CommandObjectSP delete_command_object (new CommandObjectBreakpointNameDelete (interpreter));
2361 CommandObjectSP list_command_object (new CommandObjectBreakpointNameList (interpreter));
2362
2363 LoadSubCommand ("add", add_command_object);
2364 LoadSubCommand ("delete", delete_command_object);
2365 LoadSubCommand ("list", list_command_object);
2366
2367 }
2368
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002369 ~CommandObjectBreakpointName () override
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002370 {
2371 }
2372
2373};
2374
2375
2376//-------------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002377// CommandObjectMultiwordBreakpoint
2378//-------------------------------------------------------------------------
Jim Inghamae1c4cf2010-06-18 00:58:52 +00002379#pragma mark MultiwordBreakpoint
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002380
Greg Clayton66111032010-06-23 01:19:29 +00002381CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint (CommandInterpreter &interpreter) :
Greg Claytona7015092010-09-18 01:14:36 +00002382 CommandObjectMultiword (interpreter,
2383 "breakpoint",
Jim Ingham46fbc602011-05-26 20:39:01 +00002384 "A set of commands for operating on breakpoints. Also see _regexp-break.",
Greg Claytona7015092010-09-18 01:14:36 +00002385 "breakpoint <command> [<command-options>]")
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002386{
Greg Claytona7015092010-09-18 01:14:36 +00002387 CommandObjectSP list_command_object (new CommandObjectBreakpointList (interpreter));
Greg Claytona7015092010-09-18 01:14:36 +00002388 CommandObjectSP enable_command_object (new CommandObjectBreakpointEnable (interpreter));
2389 CommandObjectSP disable_command_object (new CommandObjectBreakpointDisable (interpreter));
Johnny Chenb7234e42010-10-28 17:27:46 +00002390 CommandObjectSP clear_command_object (new CommandObjectBreakpointClear (interpreter));
2391 CommandObjectSP delete_command_object (new CommandObjectBreakpointDelete (interpreter));
Greg Claytona7015092010-09-18 01:14:36 +00002392 CommandObjectSP set_command_object (new CommandObjectBreakpointSet (interpreter));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002393 CommandObjectSP command_command_object (new CommandObjectBreakpointCommand (interpreter));
Greg Claytona7015092010-09-18 01:14:36 +00002394 CommandObjectSP modify_command_object (new CommandObjectBreakpointModify(interpreter));
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002395 CommandObjectSP name_command_object (new CommandObjectBreakpointName(interpreter));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002396
Johnny Chenb7234e42010-10-28 17:27:46 +00002397 list_command_object->SetCommandName ("breakpoint list");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002398 enable_command_object->SetCommandName("breakpoint enable");
2399 disable_command_object->SetCommandName("breakpoint disable");
Johnny Chenb7234e42010-10-28 17:27:46 +00002400 clear_command_object->SetCommandName("breakpoint clear");
2401 delete_command_object->SetCommandName("breakpoint delete");
Jim Inghamae1c4cf2010-06-18 00:58:52 +00002402 set_command_object->SetCommandName("breakpoint set");
Johnny Chenb7234e42010-10-28 17:27:46 +00002403 command_command_object->SetCommandName ("breakpoint command");
2404 modify_command_object->SetCommandName ("breakpoint modify");
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002405 name_command_object->SetCommandName ("breakpoint name");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002406
Greg Clayton23f59502012-07-17 03:23:13 +00002407 LoadSubCommand ("list", list_command_object);
2408 LoadSubCommand ("enable", enable_command_object);
2409 LoadSubCommand ("disable", disable_command_object);
2410 LoadSubCommand ("clear", clear_command_object);
2411 LoadSubCommand ("delete", delete_command_object);
2412 LoadSubCommand ("set", set_command_object);
2413 LoadSubCommand ("command", command_command_object);
2414 LoadSubCommand ("modify", modify_command_object);
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002415 LoadSubCommand ("name", name_command_object);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002416}
2417
2418CommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint ()
2419{
2420}
2421
2422void
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002423CommandObjectMultiwordBreakpoint::VerifyIDs (Args &args,
2424 Target *target,
2425 bool allow_locations,
2426 CommandReturnObject &result,
2427 BreakpointIDList *valid_ids)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002428{
2429 // args can be strings representing 1). integers (for breakpoint ids)
2430 // 2). the full breakpoint & location canonical representation
2431 // 3). the word "to" or a hyphen, representing a range (in which case there
2432 // had *better* be an entry both before & after of one of the first two types.
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002433 // 4). A breakpoint name
Jim Ingham36f3b362010-10-14 23:45:03 +00002434 // If args is empty, we will use the last created breakpoint (if there is one.)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002435
2436 Args temp_args;
2437
Jim Ingham36f3b362010-10-14 23:45:03 +00002438 if (args.GetArgumentCount() == 0)
2439 {
Greg Clayton4d122c42011-09-17 08:33:22 +00002440 if (target->GetLastCreatedBreakpoint())
Jim Ingham36f3b362010-10-14 23:45:03 +00002441 {
2442 valid_ids->AddBreakpointID (BreakpointID(target->GetLastCreatedBreakpoint()->GetID(), LLDB_INVALID_BREAK_ID));
2443 result.SetStatus (eReturnStatusSuccessFinishNoResult);
2444 }
2445 else
2446 {
2447 result.AppendError("No breakpoint specified and no last created breakpoint.");
2448 result.SetStatus (eReturnStatusFailed);
2449 }
2450 return;
2451 }
2452
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002453 // Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff directly from the old ARGS to
2454 // the new TEMP_ARGS. Do not copy breakpoint id range strings over; instead generate a list of strings for
2455 // all the breakpoint ids in the range, and shove all of those breakpoint id strings into TEMP_ARGS.
2456
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002457 BreakpointIDList::FindAndReplaceIDRanges (args, target, allow_locations, result, temp_args);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002458
2459 // NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual BreakpointIDList:
2460
Greg Claytonc982c762010-07-09 20:39:50 +00002461 valid_ids->InsertStringArray (temp_args.GetConstArgumentVector(), temp_args.GetArgumentCount(), result);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002462
2463 // At this point, all of the breakpoint ids that the user passed in have been converted to breakpoint IDs
2464 // and put into valid_ids.
2465
2466 if (result.Succeeded())
2467 {
2468 // Now that we've converted everything from args into a list of breakpoint ids, go through our tentative list
2469 // of breakpoint id's and verify that they correspond to valid/currently set breakpoints.
2470
Greg Claytonc982c762010-07-09 20:39:50 +00002471 const size_t count = valid_ids->GetSize();
2472 for (size_t i = 0; i < count; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002473 {
2474 BreakpointID cur_bp_id = valid_ids->GetBreakpointIDAtIndex (i);
2475 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
2476 if (breakpoint != NULL)
2477 {
Greg Claytonc7bece562013-01-25 18:06:21 +00002478 const size_t num_locations = breakpoint->GetNumLocations();
Saleem Abdulrasool3985c8c2014-04-02 03:51:35 +00002479 if (static_cast<size_t>(cur_bp_id.GetLocationID()) > num_locations)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002480 {
2481 StreamString id_str;
Greg Claytonc982c762010-07-09 20:39:50 +00002482 BreakpointID::GetCanonicalReference (&id_str,
2483 cur_bp_id.GetBreakpointID(),
2484 cur_bp_id.GetLocationID());
2485 i = valid_ids->GetSize() + 1;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002486 result.AppendErrorWithFormat ("'%s' is not a currently valid breakpoint/location id.\n",
2487 id_str.GetData());
2488 result.SetStatus (eReturnStatusFailed);
2489 }
2490 }
2491 else
2492 {
Greg Claytonc982c762010-07-09 20:39:50 +00002493 i = valid_ids->GetSize() + 1;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002494 result.AppendErrorWithFormat ("'%d' is not a currently valid breakpoint id.\n", cur_bp_id.GetBreakpointID());
2495 result.SetStatus (eReturnStatusFailed);
2496 }
2497 }
2498 }
2499}