blob: 9fdea4ec1f1e6e675808f2172b30534301649aec [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
Daniel Malea93a64302012-12-05 00:20:57 +000010#include "lldb/lldb-python.h"
11
Chris Lattner30fdc8d2010-06-08 16:52:24 +000012#include "CommandObjectBreakpoint.h"
13#include "CommandObjectBreakpointCommand.h"
14
15// C Includes
16// C++ Includes
17// Other libraries and framework includes
18// Project includes
19#include "lldb/Breakpoint/Breakpoint.h"
20#include "lldb/Breakpoint/BreakpointIDList.h"
21#include "lldb/Breakpoint/BreakpointLocation.h"
Vince Harron5275aaa2015-01-15 20:08:35 +000022#include "lldb/Host/StringConvert.h"
Jim Ingham40af72e2010-06-15 19:49:27 +000023#include "lldb/Interpreter/Options.h"
Zachary Turner32abc6e2015-03-03 19:23:09 +000024#include "lldb/Interpreter/OptionValueBoolean.h"
Jim Ingham5e09c8c2014-12-16 23:40:14 +000025#include "lldb/Interpreter/OptionValueString.h"
26#include "lldb/Interpreter/OptionValueUInt64.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000027#include "lldb/Core/RegularExpression.h"
28#include "lldb/Core/StreamString.h"
29#include "lldb/Interpreter/CommandInterpreter.h"
30#include "lldb/Interpreter/CommandReturnObject.h"
Zachary Turnera78bd7f2015-03-03 23:11:11 +000031#include "lldb/Target/LanguageRuntime.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000032#include "lldb/Target/Target.h"
33#include "lldb/Interpreter/CommandCompletions.h"
Jason Molendab57e4a12013-11-04 09:33:30 +000034#include "lldb/Target/StackFrame.h"
Jim Ingham1b54c882010-06-16 02:00:15 +000035#include "lldb/Target/Thread.h"
36#include "lldb/Target/ThreadSpec.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000037
Johnny Chenb7234e42010-10-28 17:27:46 +000038#include <vector>
39
Chris Lattner30fdc8d2010-06-08 16:52:24 +000040using namespace lldb;
41using namespace lldb_private;
42
43static void
Jim Ingham85e8b812011-02-19 02:53:09 +000044AddBreakpointDescription (Stream *s, Breakpoint *bp, lldb::DescriptionLevel level)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000045{
46 s->IndentMore();
47 bp->GetDescription (s, level, true);
48 s->IndentLess();
49 s->EOL();
50}
51
52//-------------------------------------------------------------------------
Jim Ingham5a988412012-06-08 21:56:10 +000053// CommandObjectBreakpointSet
Chris Lattner30fdc8d2010-06-08 16:52:24 +000054//-------------------------------------------------------------------------
55
Jim Ingham5a988412012-06-08 21:56:10 +000056
57class CommandObjectBreakpointSet : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +000058{
Jim Ingham5a988412012-06-08 21:56:10 +000059public:
Chris Lattner30fdc8d2010-06-08 16:52:24 +000060
Jim Ingham5a988412012-06-08 21:56:10 +000061 typedef enum BreakpointSetType
62 {
63 eSetTypeInvalid,
64 eSetTypeFileAndLine,
65 eSetTypeAddress,
66 eSetTypeFunctionName,
67 eSetTypeFunctionRegexp,
68 eSetTypeSourceRegexp,
69 eSetTypeException
70 } BreakpointSetType;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000071
Jim Ingham5a988412012-06-08 21:56:10 +000072 CommandObjectBreakpointSet (CommandInterpreter &interpreter) :
73 CommandObjectParsed (interpreter,
74 "breakpoint set",
75 "Sets a breakpoint or set of breakpoints in the executable.",
76 "breakpoint set <cmd-options>"),
77 m_options (interpreter)
78 {
79 }
80
81
82 virtual
83 ~CommandObjectBreakpointSet () {}
84
85 virtual Options *
86 GetOptions ()
87 {
88 return &m_options;
89 }
90
91 class CommandOptions : public Options
92 {
93 public:
94
95 CommandOptions (CommandInterpreter &interpreter) :
96 Options (interpreter),
97 m_condition (),
98 m_filenames (),
99 m_line_num (0),
100 m_column (0),
Jim Ingham5a988412012-06-08 21:56:10 +0000101 m_func_names (),
102 m_func_name_type_mask (eFunctionNameTypeNone),
103 m_func_regexp (),
104 m_source_text_regexp(),
105 m_modules (),
106 m_load_addr(),
107 m_ignore_count (0),
108 m_thread_id(LLDB_INVALID_THREAD_ID),
109 m_thread_index (UINT32_MAX),
110 m_thread_name(),
111 m_queue_name(),
112 m_catch_bp (false),
Greg Clayton1f746072012-08-29 21:13:06 +0000113 m_throw_bp (true),
Greg Claytoneb023e72013-10-11 19:48:25 +0000114 m_hardware (false),
Jim Inghama72b31c2015-04-22 19:42:18 +0000115 m_exception_language (eLanguageTypeUnknown),
Jim Inghamca36cd12012-10-05 19:16:31 +0000116 m_skip_prologue (eLazyBoolCalculate),
Jim Inghame7320522015-02-12 17:37:46 +0000117 m_one_shot (false),
Ilia K055ad9b2015-05-18 13:41:01 +0000118 m_all_files (false),
119 m_move_to_nearest_code (eLazyBoolCalculate)
Jim Ingham5a988412012-06-08 21:56:10 +0000120 {
121 }
122
123
124 virtual
125 ~CommandOptions () {}
126
127 virtual Error
128 SetOptionValue (uint32_t option_idx, const char *option_arg)
129 {
130 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000131 const int short_option = m_getopt_table[option_idx].val;
Jim Ingham5a988412012-06-08 21:56:10 +0000132
133 switch (short_option)
134 {
135 case 'a':
Greg Claytonb9d5df52012-12-06 22:49:16 +0000136 {
137 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
138 m_load_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
139 }
Jim Ingham5a988412012-06-08 21:56:10 +0000140 break;
141
Jim Inghame7320522015-02-12 17:37:46 +0000142 case 'A':
143 m_all_files = true;
144 break;
145
Jim Inghamca36cd12012-10-05 19:16:31 +0000146 case 'b':
147 m_func_names.push_back (option_arg);
148 m_func_name_type_mask |= eFunctionNameTypeBase;
149 break;
150
Jim Ingham5a988412012-06-08 21:56:10 +0000151 case 'C':
Jim Ingham63129912015-03-16 22:47:38 +0000152 {
153 bool success;
154 m_column = StringConvert::ToUInt32 (option_arg, 0, 0, &success);
155 if (!success)
156 error.SetErrorStringWithFormat("invalid column number: %s", option_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000157 break;
Jim Ingham63129912015-03-16 22:47:38 +0000158 }
Jim Ingham5a988412012-06-08 21:56:10 +0000159 case 'c':
160 m_condition.assign(option_arg);
161 break;
162
Jim Ingham33df7cd2014-12-06 01:28:03 +0000163 case 'D':
164 m_use_dummy = true;
165 break;
166
Jim Ingham5a988412012-06-08 21:56:10 +0000167 case 'E':
168 {
169 LanguageType language = LanguageRuntime::GetLanguageTypeFromString (option_arg);
170
171 switch (language)
172 {
173 case eLanguageTypeC89:
174 case eLanguageTypeC:
175 case eLanguageTypeC99:
Bruce Mitchener1d0089f2014-07-03 00:49:08 +0000176 case eLanguageTypeC11:
Jim Inghama72b31c2015-04-22 19:42:18 +0000177 m_exception_language = eLanguageTypeC;
Jim Ingham5a988412012-06-08 21:56:10 +0000178 break;
179 case eLanguageTypeC_plus_plus:
Bruce Mitchener1d0089f2014-07-03 00:49:08 +0000180 case eLanguageTypeC_plus_plus_03:
181 case eLanguageTypeC_plus_plus_11:
Bruce Mitchener2ba84a62015-02-06 06:46:52 +0000182 case eLanguageTypeC_plus_plus_14:
Jim Inghama72b31c2015-04-22 19:42:18 +0000183 m_exception_language = eLanguageTypeC_plus_plus;
Jim Ingham5a988412012-06-08 21:56:10 +0000184 break;
185 case eLanguageTypeObjC:
Jim Inghama72b31c2015-04-22 19:42:18 +0000186 m_exception_language = eLanguageTypeObjC;
Jim Ingham5a988412012-06-08 21:56:10 +0000187 break;
188 case eLanguageTypeObjC_plus_plus:
189 error.SetErrorStringWithFormat ("Set exception breakpoints separately for c++ and objective-c");
190 break;
191 case eLanguageTypeUnknown:
192 error.SetErrorStringWithFormat ("Unknown language type: '%s' for exception breakpoint", option_arg);
193 break;
194 default:
195 error.SetErrorStringWithFormat ("Unsupported language type: '%s' for exception breakpoint", option_arg);
196 }
197 }
198 break;
Jim Inghamca36cd12012-10-05 19:16:31 +0000199
200 case 'f':
201 m_filenames.AppendIfUnique (FileSpec(option_arg, false));
202 break;
203
204 case 'F':
205 m_func_names.push_back (option_arg);
206 m_func_name_type_mask |= eFunctionNameTypeFull;
207 break;
208
Jim Ingham5a988412012-06-08 21:56:10 +0000209 case 'h':
Greg Claytoneb023e72013-10-11 19:48:25 +0000210 {
211 bool success;
212 m_catch_bp = Args::StringToBoolean (option_arg, true, &success);
213 if (!success)
214 error.SetErrorStringWithFormat ("Invalid boolean value for on-catch option: '%s'", option_arg);
215 }
216 break;
217
218 case 'H':
219 m_hardware = true;
220 break;
221
Jim Inghamca36cd12012-10-05 19:16:31 +0000222 case 'i':
223 {
Vince Harron5275aaa2015-01-15 20:08:35 +0000224 m_ignore_count = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
Jim Inghamca36cd12012-10-05 19:16:31 +0000225 if (m_ignore_count == UINT32_MAX)
226 error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
227 break;
228 }
229
Jim Ingham5a988412012-06-08 21:56:10 +0000230 case 'K':
231 {
232 bool success;
233 bool value;
234 value = Args::StringToBoolean (option_arg, true, &success);
235 if (value)
236 m_skip_prologue = eLazyBoolYes;
237 else
238 m_skip_prologue = eLazyBoolNo;
239
240 if (!success)
241 error.SetErrorStringWithFormat ("Invalid boolean value for skip prologue option: '%s'", option_arg);
242 }
243 break;
Jim Inghamca36cd12012-10-05 19:16:31 +0000244
245 case 'l':
Jim Ingham63129912015-03-16 22:47:38 +0000246 {
247 bool success;
248 m_line_num = StringConvert::ToUInt32 (option_arg, 0, 0, &success);
249 if (!success)
250 error.SetErrorStringWithFormat ("invalid line number: %s.", option_arg);
Jim Inghamca36cd12012-10-05 19:16:31 +0000251 break;
Jim Ingham63129912015-03-16 22:47:38 +0000252 }
Ilia K055ad9b2015-05-18 13:41:01 +0000253
254 case 'm':
255 {
256 bool success;
257 bool value;
258 value = Args::StringToBoolean (option_arg, true, &success);
259 if (value)
260 m_move_to_nearest_code = eLazyBoolYes;
261 else
262 m_move_to_nearest_code = eLazyBoolNo;
263
264 if (!success)
265 error.SetErrorStringWithFormat ("Invalid boolean value for move-to-nearest-code option: '%s'", option_arg);
266 break;
267 }
268
Jim Inghamca36cd12012-10-05 19:16:31 +0000269 case 'M':
270 m_func_names.push_back (option_arg);
271 m_func_name_type_mask |= eFunctionNameTypeMethod;
272 break;
273
274 case 'n':
275 m_func_names.push_back (option_arg);
276 m_func_name_type_mask |= eFunctionNameTypeAuto;
277 break;
278
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000279 case 'N':
280 if (BreakpointID::StringIsBreakpointName(option_arg, error))
281 m_breakpoint_names.push_back (option_arg);
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000282 break;
283
Jim Inghamca36cd12012-10-05 19:16:31 +0000284 case 'o':
285 m_one_shot = true;
286 break;
287
Jim Inghama72b31c2015-04-22 19:42:18 +0000288 case 'O':
289 m_exception_extra_args.AppendArgument ("-O");
290 m_exception_extra_args.AppendArgument (option_arg);
291 break;
292
Jim Inghamca36cd12012-10-05 19:16:31 +0000293 case 'p':
294 m_source_text_regexp.assign (option_arg);
295 break;
296
297 case 'q':
298 m_queue_name.assign (option_arg);
299 break;
300
301 case 'r':
302 m_func_regexp.assign (option_arg);
303 break;
304
305 case 's':
306 {
307 m_modules.AppendIfUnique (FileSpec (option_arg, false));
308 break;
309 }
310
311 case 'S':
312 m_func_names.push_back (option_arg);
313 m_func_name_type_mask |= eFunctionNameTypeSelector;
314 break;
315
316 case 't' :
317 {
Vince Harron5275aaa2015-01-15 20:08:35 +0000318 m_thread_id = StringConvert::ToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
Jim Inghamca36cd12012-10-05 19:16:31 +0000319 if (m_thread_id == LLDB_INVALID_THREAD_ID)
320 error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
321 }
322 break;
323
324 case 'T':
325 m_thread_name.assign (option_arg);
326 break;
327
328 case 'w':
329 {
330 bool success;
331 m_throw_bp = Args::StringToBoolean (option_arg, true, &success);
332 if (!success)
333 error.SetErrorStringWithFormat ("Invalid boolean value for on-throw option: '%s'", option_arg);
334 }
335 break;
336
337 case 'x':
338 {
Vince Harron5275aaa2015-01-15 20:08:35 +0000339 m_thread_index = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
Jim Inghamca36cd12012-10-05 19:16:31 +0000340 if (m_thread_id == UINT32_MAX)
341 error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
342
343 }
344 break;
345
Jim Ingham5a988412012-06-08 21:56:10 +0000346 default:
347 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
348 break;
349 }
350
351 return error;
352 }
353 void
354 OptionParsingStarting ()
355 {
356 m_condition.clear();
357 m_filenames.Clear();
358 m_line_num = 0;
359 m_column = 0;
360 m_func_names.clear();
Greg Clayton1f746072012-08-29 21:13:06 +0000361 m_func_name_type_mask = eFunctionNameTypeNone;
Jim Ingham5a988412012-06-08 21:56:10 +0000362 m_func_regexp.clear();
Greg Clayton1f746072012-08-29 21:13:06 +0000363 m_source_text_regexp.clear();
Jim Ingham5a988412012-06-08 21:56:10 +0000364 m_modules.Clear();
Greg Clayton1f746072012-08-29 21:13:06 +0000365 m_load_addr = LLDB_INVALID_ADDRESS;
Jim Ingham5a988412012-06-08 21:56:10 +0000366 m_ignore_count = 0;
367 m_thread_id = LLDB_INVALID_THREAD_ID;
368 m_thread_index = UINT32_MAX;
369 m_thread_name.clear();
370 m_queue_name.clear();
Jim Ingham5a988412012-06-08 21:56:10 +0000371 m_catch_bp = false;
372 m_throw_bp = true;
Greg Claytoneb023e72013-10-11 19:48:25 +0000373 m_hardware = false;
Jim Inghama72b31c2015-04-22 19:42:18 +0000374 m_exception_language = eLanguageTypeUnknown;
Jim Ingham5a988412012-06-08 21:56:10 +0000375 m_skip_prologue = eLazyBoolCalculate;
Jim Inghamca36cd12012-10-05 19:16:31 +0000376 m_one_shot = false;
Jim Ingham33df7cd2014-12-06 01:28:03 +0000377 m_use_dummy = false;
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000378 m_breakpoint_names.clear();
Jim Inghame7320522015-02-12 17:37:46 +0000379 m_all_files = false;
Jim Inghama72b31c2015-04-22 19:42:18 +0000380 m_exception_extra_args.Clear();
Ilia K055ad9b2015-05-18 13:41:01 +0000381 m_move_to_nearest_code = eLazyBoolCalculate;
Jim Ingham5a988412012-06-08 21:56:10 +0000382 }
383
384 const OptionDefinition*
385 GetDefinitions ()
386 {
387 return g_option_table;
388 }
389
390 // Options table: Required for subclasses of Options.
391
392 static OptionDefinition g_option_table[];
393
394 // Instance variables to hold the values for command options.
395
396 std::string m_condition;
397 FileSpecList m_filenames;
398 uint32_t m_line_num;
399 uint32_t m_column;
Jim Ingham5a988412012-06-08 21:56:10 +0000400 std::vector<std::string> m_func_names;
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000401 std::vector<std::string> m_breakpoint_names;
Jim Ingham5a988412012-06-08 21:56:10 +0000402 uint32_t m_func_name_type_mask;
403 std::string m_func_regexp;
404 std::string m_source_text_regexp;
405 FileSpecList m_modules;
406 lldb::addr_t m_load_addr;
407 uint32_t m_ignore_count;
408 lldb::tid_t m_thread_id;
409 uint32_t m_thread_index;
410 std::string m_thread_name;
411 std::string m_queue_name;
412 bool m_catch_bp;
413 bool m_throw_bp;
Greg Claytoneb023e72013-10-11 19:48:25 +0000414 bool m_hardware; // Request to use hardware breakpoints
Jim Inghama72b31c2015-04-22 19:42:18 +0000415 lldb::LanguageType m_exception_language;
Jim Ingham5a988412012-06-08 21:56:10 +0000416 LazyBool m_skip_prologue;
Jim Inghamca36cd12012-10-05 19:16:31 +0000417 bool m_one_shot;
Jim Ingham33df7cd2014-12-06 01:28:03 +0000418 bool m_use_dummy;
Jim Inghame7320522015-02-12 17:37:46 +0000419 bool m_all_files;
Jim Inghama72b31c2015-04-22 19:42:18 +0000420 Args m_exception_extra_args;
Ilia K055ad9b2015-05-18 13:41:01 +0000421 LazyBool m_move_to_nearest_code;
Jim Ingham5a988412012-06-08 21:56:10 +0000422
423 };
424
425protected:
426 virtual bool
427 DoExecute (Args& command,
Jim Ingham33df7cd2014-12-06 01:28:03 +0000428 CommandReturnObject &result)
Jim Ingham5a988412012-06-08 21:56:10 +0000429 {
Jim Ingham33df7cd2014-12-06 01:28:03 +0000430 Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
431
Jim Ingham893c9322014-11-22 01:42:44 +0000432 if (target == nullptr)
Jim Ingham5a988412012-06-08 21:56:10 +0000433 {
434 result.AppendError ("Invalid target. Must set target before setting breakpoints (see 'target create' command).");
435 result.SetStatus (eReturnStatusFailed);
436 return false;
437 }
438
439 // The following are the various types of breakpoints that could be set:
440 // 1). -f -l -p [-s -g] (setting breakpoint by source location)
441 // 2). -a [-s -g] (setting breakpoint by address)
442 // 3). -n [-s -g] (setting breakpoint by function name)
443 // 4). -r [-s -g] (setting breakpoint by function name regular expression)
444 // 5). -p -f (setting a breakpoint by comparing a reg-exp to source text)
445 // 6). -E [-w -h] (setting a breakpoint for exceptions for a given language.)
446
447 BreakpointSetType break_type = eSetTypeInvalid;
448
449 if (m_options.m_line_num != 0)
450 break_type = eSetTypeFileAndLine;
451 else if (m_options.m_load_addr != LLDB_INVALID_ADDRESS)
452 break_type = eSetTypeAddress;
453 else if (!m_options.m_func_names.empty())
454 break_type = eSetTypeFunctionName;
455 else if (!m_options.m_func_regexp.empty())
456 break_type = eSetTypeFunctionRegexp;
457 else if (!m_options.m_source_text_regexp.empty())
458 break_type = eSetTypeSourceRegexp;
Jim Inghama72b31c2015-04-22 19:42:18 +0000459 else if (m_options.m_exception_language != eLanguageTypeUnknown)
Jim Ingham5a988412012-06-08 21:56:10 +0000460 break_type = eSetTypeException;
461
462 Breakpoint *bp = NULL;
463 FileSpec module_spec;
Jim Ingham5a988412012-06-08 21:56:10 +0000464 const bool internal = false;
465
Jim Ingham5a988412012-06-08 21:56:10 +0000466 switch (break_type)
467 {
468 case eSetTypeFileAndLine: // Breakpoint by source position
469 {
470 FileSpec file;
Greg Claytonc7bece562013-01-25 18:06:21 +0000471 const size_t num_files = m_options.m_filenames.GetSize();
Jim Ingham5a988412012-06-08 21:56:10 +0000472 if (num_files == 0)
473 {
474 if (!GetDefaultFile (target, file, result))
475 {
476 result.AppendError("No file supplied and no default file available.");
477 result.SetStatus (eReturnStatusFailed);
478 return false;
479 }
480 }
481 else if (num_files > 1)
482 {
483 result.AppendError("Only one file at a time is allowed for file and line breakpoints.");
484 result.SetStatus (eReturnStatusFailed);
485 return false;
486 }
487 else
488 file = m_options.m_filenames.GetFileSpecAtIndex(0);
Greg Clayton1f746072012-08-29 21:13:06 +0000489
490 // Only check for inline functions if
491 LazyBool check_inlines = eLazyBoolCalculate;
492
Jim Ingham5a988412012-06-08 21:56:10 +0000493 bp = target->CreateBreakpoint (&(m_options.m_modules),
494 file,
495 m_options.m_line_num,
Greg Clayton1f746072012-08-29 21:13:06 +0000496 check_inlines,
Jim Ingham5a988412012-06-08 21:56:10 +0000497 m_options.m_skip_prologue,
Greg Claytoneb023e72013-10-11 19:48:25 +0000498 internal,
Ilia K055ad9b2015-05-18 13:41:01 +0000499 m_options.m_hardware,
500 m_options.m_move_to_nearest_code).get();
Jim Ingham5a988412012-06-08 21:56:10 +0000501 }
502 break;
503
504 case eSetTypeAddress: // Breakpoint by address
Greg Claytoneb023e72013-10-11 19:48:25 +0000505 bp = target->CreateBreakpoint (m_options.m_load_addr,
506 internal,
507 m_options.m_hardware).get();
Jim Ingham5a988412012-06-08 21:56:10 +0000508 break;
509
510 case eSetTypeFunctionName: // Breakpoint by function name
511 {
512 uint32_t name_type_mask = m_options.m_func_name_type_mask;
513
514 if (name_type_mask == 0)
515 name_type_mask = eFunctionNameTypeAuto;
516
517 bp = target->CreateBreakpoint (&(m_options.m_modules),
518 &(m_options.m_filenames),
519 m_options.m_func_names,
520 name_type_mask,
521 m_options.m_skip_prologue,
Greg Claytoneb023e72013-10-11 19:48:25 +0000522 internal,
523 m_options.m_hardware).get();
Jim Ingham5a988412012-06-08 21:56:10 +0000524 }
525 break;
526
527 case eSetTypeFunctionRegexp: // Breakpoint by regular expression function name
528 {
529 RegularExpression regexp(m_options.m_func_regexp.c_str());
530 if (!regexp.IsValid())
531 {
532 char err_str[1024];
533 regexp.GetErrorAsCString(err_str, sizeof(err_str));
534 result.AppendErrorWithFormat("Function name regular expression could not be compiled: \"%s\"",
535 err_str);
536 result.SetStatus (eReturnStatusFailed);
537 return false;
538 }
539
540 bp = target->CreateFuncRegexBreakpoint (&(m_options.m_modules),
541 &(m_options.m_filenames),
542 regexp,
543 m_options.m_skip_prologue,
Greg Claytoneb023e72013-10-11 19:48:25 +0000544 internal,
545 m_options.m_hardware).get();
Jim Ingham5a988412012-06-08 21:56:10 +0000546 }
547 break;
548 case eSetTypeSourceRegexp: // Breakpoint by regexp on source text.
549 {
Greg Claytonc7bece562013-01-25 18:06:21 +0000550 const size_t num_files = m_options.m_filenames.GetSize();
Jim Ingham5a988412012-06-08 21:56:10 +0000551
Jim Inghame7320522015-02-12 17:37:46 +0000552 if (num_files == 0 && !m_options.m_all_files)
Jim Ingham5a988412012-06-08 21:56:10 +0000553 {
554 FileSpec file;
555 if (!GetDefaultFile (target, file, result))
556 {
557 result.AppendError ("No files provided and could not find default file.");
558 result.SetStatus (eReturnStatusFailed);
559 return false;
560 }
561 else
562 {
563 m_options.m_filenames.Append (file);
564 }
565 }
566
567 RegularExpression regexp(m_options.m_source_text_regexp.c_str());
568 if (!regexp.IsValid())
569 {
570 char err_str[1024];
571 regexp.GetErrorAsCString(err_str, sizeof(err_str));
572 result.AppendErrorWithFormat("Source text regular expression could not be compiled: \"%s\"",
573 err_str);
574 result.SetStatus (eReturnStatusFailed);
575 return false;
576 }
Greg Claytoneb023e72013-10-11 19:48:25 +0000577 bp = target->CreateSourceRegexBreakpoint (&(m_options.m_modules),
578 &(m_options.m_filenames),
579 regexp,
580 internal,
Ilia K055ad9b2015-05-18 13:41:01 +0000581 m_options.m_hardware,
582 m_options.m_move_to_nearest_code).get();
Jim Ingham5a988412012-06-08 21:56:10 +0000583 }
584 break;
585 case eSetTypeException:
586 {
Jim Inghama72b31c2015-04-22 19:42:18 +0000587 Error precond_error;
588 bp = target->CreateExceptionBreakpoint (m_options.m_exception_language,
Greg Claytoneb023e72013-10-11 19:48:25 +0000589 m_options.m_catch_bp,
590 m_options.m_throw_bp,
Jim Inghama72b31c2015-04-22 19:42:18 +0000591 internal,
592 &m_options.m_exception_extra_args,
593 &precond_error).get();
594 if (precond_error.Fail())
595 {
596 result.AppendErrorWithFormat("Error setting extra exception arguments: %s",
597 precond_error.AsCString());
598 target->RemoveBreakpointByID(bp->GetID());
599 result.SetStatus(eReturnStatusFailed);
600 return false;
601 }
Jim Ingham5a988412012-06-08 21:56:10 +0000602 }
603 break;
604 default:
605 break;
606 }
607
608 // Now set the various options that were passed in:
609 if (bp)
610 {
611 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
612 bp->SetThreadID (m_options.m_thread_id);
613
614 if (m_options.m_thread_index != UINT32_MAX)
615 bp->GetOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index);
616
617 if (!m_options.m_thread_name.empty())
618 bp->GetOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str());
619
620 if (!m_options.m_queue_name.empty())
621 bp->GetOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str());
622
623 if (m_options.m_ignore_count != 0)
624 bp->GetOptions()->SetIgnoreCount(m_options.m_ignore_count);
625
626 if (!m_options.m_condition.empty())
627 bp->GetOptions()->SetCondition(m_options.m_condition.c_str());
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000628
629 if (!m_options.m_breakpoint_names.empty())
630 {
631 Error error; // We don't need to check the error here, since the option parser checked it...
632 for (auto name : m_options.m_breakpoint_names)
633 bp->AddName(name.c_str(), error);
634 }
Jim Inghamca36cd12012-10-05 19:16:31 +0000635
636 bp->SetOneShot (m_options.m_one_shot);
Jim Ingham5a988412012-06-08 21:56:10 +0000637 }
638
639 if (bp)
640 {
641 Stream &output_stream = result.GetOutputStream();
Jim Ingham1391cc72012-09-22 00:04:04 +0000642 const bool show_locations = false;
643 bp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial, show_locations);
Jim Ingham4aeb1982014-12-19 19:45:31 +0000644 if (target == m_interpreter.GetDebugger().GetDummyTarget())
645 output_stream.Printf ("Breakpoint set in dummy target, will get copied into future targets.\n");
646 else
647 {
648 // Don't print out this warning for exception breakpoints. They can get set before the target
649 // is set, but we won't know how to actually set the breakpoint till we run.
650 if (bp->GetNumLocations() == 0 && break_type != eSetTypeException)
651 {
652 output_stream.Printf ("WARNING: Unable to resolve breakpoint to any actual locations.\n");
653 }
654 }
Jim Ingham5a988412012-06-08 21:56:10 +0000655 result.SetStatus (eReturnStatusSuccessFinishResult);
656 }
657 else if (!bp)
658 {
659 result.AppendError ("Breakpoint creation failed: No breakpoint created.");
660 result.SetStatus (eReturnStatusFailed);
661 }
662
663 return result.Succeeded();
664 }
665
666private:
667 bool
668 GetDefaultFile (Target *target, FileSpec &file, CommandReturnObject &result)
669 {
670 uint32_t default_line;
671 // First use the Source Manager's default file.
672 // Then use the current stack frame's file.
673 if (!target->GetSourceManager().GetDefaultFileAndLine(file, default_line))
674 {
Jason Molendab57e4a12013-11-04 09:33:30 +0000675 StackFrame *cur_frame = m_exe_ctx.GetFramePtr();
Jim Ingham5a988412012-06-08 21:56:10 +0000676 if (cur_frame == NULL)
677 {
678 result.AppendError ("No selected frame to use to find the default file.");
679 result.SetStatus (eReturnStatusFailed);
680 return false;
681 }
682 else if (!cur_frame->HasDebugInformation())
683 {
684 result.AppendError ("Cannot use the selected frame to find the default file, it has no debug info.");
685 result.SetStatus (eReturnStatusFailed);
686 return false;
687 }
688 else
689 {
690 const SymbolContext &sc = cur_frame->GetSymbolContext (eSymbolContextLineEntry);
691 if (sc.line_entry.file)
692 {
693 file = sc.line_entry.file;
694 }
695 else
696 {
697 result.AppendError ("Can't find the file for the selected frame to use as the default file.");
698 result.SetStatus (eReturnStatusFailed);
699 return false;
700 }
701 }
702 }
703 return true;
704 }
705
706 CommandOptions m_options;
707};
Johnny Chen6943e7c2012-05-08 00:43:20 +0000708// If an additional option set beyond LLDB_OPTION_SET_10 is added, make sure to
709// update the numbers passed to LLDB_OPT_SET_FROM_TO(...) appropriately.
Johnny Chen4ab2e6b2012-05-07 23:23:41 +0000710#define LLDB_OPT_FILE ( LLDB_OPT_SET_FROM_TO(1, 9) & ~LLDB_OPT_SET_2 )
711#define LLDB_OPT_NOT_10 ( LLDB_OPT_SET_FROM_TO(1, 10) & ~LLDB_OPT_SET_10 )
Jim Inghama8558b62012-05-22 00:12:20 +0000712#define LLDB_OPT_SKIP_PROLOGUE ( LLDB_OPT_SET_1 | LLDB_OPT_SET_FROM_TO(3,8) )
Ilia K055ad9b2015-05-18 13:41:01 +0000713#define LLDB_OPT_MOVE_TO_NEAREST_CODE ( LLDB_OPT_SET_1 | LLDB_OPT_SET_9 )
Jim Ingham87df91b2011-09-23 00:54:11 +0000714
Greg Claytone0d378b2011-03-24 21:19:54 +0000715OptionDefinition
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000716CommandObjectBreakpointSet::CommandOptions::g_option_table[] =
717{
Zachary Turnerd37221d2014-07-09 16:31:49 +0000718 { LLDB_OPT_NOT_10, false, "shlib", 's', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName,
Jim Ingham64cc29c2012-05-03 20:30:08 +0000719 "Set the breakpoint only in this shared library. "
720 "Can repeat this option multiple times to specify multiple shared libraries."},
Jim Ingham86511212010-06-15 18:47:14 +0000721
Zachary Turnerd37221d2014-07-09 16:31:49 +0000722 { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeCount,
Caroline Ticedeaab222010-10-01 19:59:14 +0000723 "Set the number of times this breakpoint is skipped before stopping." },
Jim Ingham1b54c882010-06-16 02:00:15 +0000724
Zachary Turnerd37221d2014-07-09 16:31:49 +0000725 { LLDB_OPT_SET_ALL, false, "one-shot", 'o', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
Jim Inghamb2b256a2013-04-09 18:05:22 +0000726 "The breakpoint is deleted the first time it causes a stop." },
Jim Inghamca36cd12012-10-05 19:16:31 +0000727
Zachary Turnerd37221d2014-07-09 16:31:49 +0000728 { LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeExpression,
Johnny Chen7d49c9c2012-05-25 21:10:46 +0000729 "The breakpoint stops only if this condition expression evaluates to true."},
730
Zachary Turnerd37221d2014-07-09 16:31:49 +0000731 { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadIndex,
Jim Inghama89be912013-03-26 18:29:03 +0000732 "The breakpoint stops only for the thread whose indeX matches this argument."},
Jim Ingham1b54c882010-06-16 02:00:15 +0000733
Zachary Turnerd37221d2014-07-09 16:31:49 +0000734 { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadID,
Jim Ingham1b54c882010-06-16 02:00:15 +0000735 "The breakpoint stops only for the thread whose TID matches this argument."},
736
Zachary Turnerd37221d2014-07-09 16:31:49 +0000737 { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadName,
Jim Ingham1b54c882010-06-16 02:00:15 +0000738 "The breakpoint stops only for the thread whose thread name matches this argument."},
739
Zachary Turnerd37221d2014-07-09 16:31:49 +0000740 { LLDB_OPT_SET_ALL, false, "hardware", 'H', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
Greg Claytoneb023e72013-10-11 19:48:25 +0000741 "Require the breakpoint to use hardware breakpoints."},
742
Zachary Turnerd37221d2014-07-09 16:31:49 +0000743 { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeQueueName,
Jim Ingham1b54c882010-06-16 02:00:15 +0000744 "The breakpoint stops only for threads in the queue whose name is given by this argument."},
745
Zachary Turnerd37221d2014-07-09 16:31:49 +0000746 { LLDB_OPT_FILE, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
Jim Ingham289aca62013-02-14 19:10:36 +0000747 "Specifies the source file in which to set this breakpoint. "
748 "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 +0000749 "To set breakpoints on .c/.cpp/.m/.mm files that are #included, set target.inline-breakpoint-strategy"
Jim Ingham289aca62013-02-14 19:10:36 +0000750 " to \"always\"."},
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000751
Zachary Turnerd37221d2014-07-09 16:31:49 +0000752 { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum,
Jim Ingham87df91b2011-09-23 00:54:11 +0000753 "Specifies the line number on which to set this breakpoint."},
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000754
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000755 // Comment out this option for the moment, as we don't actually use it, but will in the future.
756 // This way users won't see it, but the infrastructure is left in place.
Virgile Belloe2607b52013-09-05 16:42:23 +0000757 // { 0, false, "column", 'C', OptionParser::eRequiredArgument, NULL, "<column>",
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000758 // "Set the breakpoint by source location at this particular column."},
759
Zachary Turnerd37221d2014-07-09 16:31:49 +0000760 { LLDB_OPT_SET_2, true, "address", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000761 "Set the breakpoint by address, at the specified address."},
762
Zachary Turnerd37221d2014-07-09 16:31:49 +0000763 { LLDB_OPT_SET_3, true, "name", 'n', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
Jim Ingham551262d2013-03-27 17:36:54 +0000764 "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 +0000765
Zachary Turnerd37221d2014-07-09 16:31:49 +0000766 { LLDB_OPT_SET_4, true, "fullname", 'F', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFullName,
Jim Ingham64cc29c2012-05-03 20:30:08 +0000767 "Set the breakpoint by fully qualified function names. For C++ this means namespaces and all arguments, and "
768 "for Objective C this means a full function prototype with class and selector. "
769 "Can be repeated multiple times to make one breakpoint for multiple names." },
Greg Clayton0c5cd902010-06-28 21:30:43 +0000770
Zachary Turnerd37221d2014-07-09 16:31:49 +0000771 { LLDB_OPT_SET_5, true, "selector", 'S', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeSelector,
Jim Ingham64cc29c2012-05-03 20:30:08 +0000772 "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 +0000773
Zachary Turnerd37221d2014-07-09 16:31:49 +0000774 { LLDB_OPT_SET_6, true, "method", 'M', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeMethod,
Jim Ingham64cc29c2012-05-03 20:30:08 +0000775 "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 +0000776
Zachary Turnerd37221d2014-07-09 16:31:49 +0000777 { LLDB_OPT_SET_7, true, "func-regex", 'r', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeRegularExpression,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000778 "Set the breakpoint by function name, evaluating a regular-expression to find the function name(s)." },
779
Zachary Turnerd37221d2014-07-09 16:31:49 +0000780 { LLDB_OPT_SET_8, true, "basename", 'b', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
Jim Ingham64cc29c2012-05-03 20:30:08 +0000781 "Set the breakpoint by function basename (C++ namespaces and arguments will be ignored). "
782 "Can be repeated multiple times to make one breakpoint for multiple symbols." },
Greg Claytone02b8502010-10-12 04:29:14 +0000783
Zachary Turnerd37221d2014-07-09 16:31:49 +0000784 { LLDB_OPT_SET_9, true, "source-pattern-regexp", 'p', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeRegularExpression,
Jim Inghame96ade82013-06-07 01:13:00 +0000785 "Set the breakpoint by specifying a regular expression which is matched against the source text in a source file or files "
786 "specified with the -f option. The -f option can be specified more than once. "
787 "If no source files are specified, uses the current \"default source file\"" },
Jim Ingham969795f2011-09-21 01:17:13 +0000788
Jim Inghame7320522015-02-12 17:37:46 +0000789 { LLDB_OPT_SET_9, false, "all-files", 'A', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
790 "All files are searched for source pattern matches." },
791
Zachary Turnerd37221d2014-07-09 16:31:49 +0000792 { LLDB_OPT_SET_10, true, "language-exception", 'E', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage,
Jim Inghamfab10e82012-03-06 00:37:27 +0000793 "Set the breakpoint on exceptions thrown by the specified language (without options, on throw but not catch.)" },
794
Zachary Turnerd37221d2014-07-09 16:31:49 +0000795 { LLDB_OPT_SET_10, false, "on-throw", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,
Jim Inghamfab10e82012-03-06 00:37:27 +0000796 "Set the breakpoint on exception throW." },
797
Zachary Turnerd37221d2014-07-09 16:31:49 +0000798 { LLDB_OPT_SET_10, false, "on-catch", 'h', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,
Jim Inghamfab10e82012-03-06 00:37:27 +0000799 "Set the breakpoint on exception catcH." },
Jim Ingham969795f2011-09-21 01:17:13 +0000800
Jim Inghama72b31c2015-04-22 19:42:18 +0000801// Don't add this option till it actually does something useful...
802// { LLDB_OPT_SET_10, false, "exception-typename", 'O', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeTypeName,
803// "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" },
804
Zachary Turnerd37221d2014-07-09 16:31:49 +0000805 { LLDB_OPT_SKIP_PROLOGUE, false, "skip-prologue", 'K', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,
Jim Inghama8558b62012-05-22 00:12:20 +0000806 "sKip the prologue if the breakpoint is at the beginning of a function. If not set the target.skip-prologue setting is used." },
807
Jim Ingham33df7cd2014-12-06 01:28:03 +0000808 { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
809 "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
810
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000811 { LLDB_OPT_SET_ALL, false, "breakpoint-name", 'N', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBreakpointName,
812 "Adds this to the list of names for this breakopint."},
813
Ilia K055ad9b2015-05-18 13:41:01 +0000814 { LLDB_OPT_MOVE_TO_NEAREST_CODE, false, "move-to-nearest-code", 'm', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,
815 "Move breakpoints to nearest code. If not set the target.move-to-nearest-code setting is used." },
816
Zachary Turnerd37221d2014-07-09 16:31:49 +0000817 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000818};
819
Jim Ingham5a988412012-06-08 21:56:10 +0000820//-------------------------------------------------------------------------
821// CommandObjectBreakpointModify
822//-------------------------------------------------------------------------
823#pragma mark Modify
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000824
Jim Ingham5a988412012-06-08 21:56:10 +0000825class CommandObjectBreakpointModify : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000826{
Jim Ingham5a988412012-06-08 21:56:10 +0000827public:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000828
Jim Ingham5a988412012-06-08 21:56:10 +0000829 CommandObjectBreakpointModify (CommandInterpreter &interpreter) :
830 CommandObjectParsed (interpreter,
831 "breakpoint modify",
832 "Modify the options on a breakpoint or set of breakpoints in the executable. "
833 "If no breakpoint is specified, acts on the last created breakpoint. "
834 "With the exception of -e, -d and -i, passing an empty argument clears the modification.",
835 NULL),
836 m_options (interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000837 {
Jim Ingham5a988412012-06-08 21:56:10 +0000838 CommandArgumentEntry arg;
839 CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
840 // Add the entry for the first argument for this command to the object's arguments vector.
841 m_arguments.push_back (arg);
842 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000843
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000844
Jim Ingham5a988412012-06-08 21:56:10 +0000845 virtual
846 ~CommandObjectBreakpointModify () {}
Greg Clayton0c5cd902010-06-28 21:30:43 +0000847
Jim Ingham5a988412012-06-08 21:56:10 +0000848 virtual Options *
849 GetOptions ()
850 {
851 return &m_options;
852 }
Johnny Chen7d49c9c2012-05-25 21:10:46 +0000853
Jim Ingham5a988412012-06-08 21:56:10 +0000854 class CommandOptions : public Options
855 {
856 public:
Greg Clayton0c5cd902010-06-28 21:30:43 +0000857
Jim Ingham5a988412012-06-08 21:56:10 +0000858 CommandOptions (CommandInterpreter &interpreter) :
859 Options (interpreter),
860 m_ignore_count (0),
861 m_thread_id(LLDB_INVALID_THREAD_ID),
862 m_thread_id_passed(false),
863 m_thread_index (UINT32_MAX),
864 m_thread_index_passed(false),
865 m_thread_name(),
866 m_queue_name(),
867 m_condition (),
Jim Inghamca36cd12012-10-05 19:16:31 +0000868 m_one_shot (false),
Jim Ingham5a988412012-06-08 21:56:10 +0000869 m_enable_passed (false),
870 m_enable_value (false),
871 m_name_passed (false),
872 m_queue_passed (false),
Jim Inghamca36cd12012-10-05 19:16:31 +0000873 m_condition_passed (false),
Jim Ingham33df7cd2014-12-06 01:28:03 +0000874 m_one_shot_passed (false),
875 m_use_dummy (false)
Jim Ingham5a988412012-06-08 21:56:10 +0000876 {
877 }
Greg Clayton0c5cd902010-06-28 21:30:43 +0000878
Jim Ingham5a988412012-06-08 21:56:10 +0000879 virtual
880 ~CommandOptions () {}
Greg Clayton0c5cd902010-06-28 21:30:43 +0000881
Jim Ingham5a988412012-06-08 21:56:10 +0000882 virtual Error
883 SetOptionValue (uint32_t option_idx, const char *option_arg)
884 {
885 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000886 const int short_option = m_getopt_table[option_idx].val;
Greg Claytone02b8502010-10-12 04:29:14 +0000887
Jim Ingham5a988412012-06-08 21:56:10 +0000888 switch (short_option)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000889 {
Jim Ingham5a988412012-06-08 21:56:10 +0000890 case 'c':
891 if (option_arg != NULL)
892 m_condition.assign (option_arg);
893 else
894 m_condition.clear();
895 m_condition_passed = true;
896 break;
897 case 'd':
898 m_enable_passed = true;
899 m_enable_value = false;
900 break;
Jim Ingham33df7cd2014-12-06 01:28:03 +0000901 case 'D':
902 m_use_dummy = true;
903 break;
Jim Ingham5a988412012-06-08 21:56:10 +0000904 case 'e':
905 m_enable_passed = true;
906 m_enable_value = true;
907 break;
908 case 'i':
909 {
Vince Harron5275aaa2015-01-15 20:08:35 +0000910 m_ignore_count = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
Jim Ingham5a988412012-06-08 21:56:10 +0000911 if (m_ignore_count == UINT32_MAX)
912 error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
913 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000914 break;
Jim Inghamca36cd12012-10-05 19:16:31 +0000915 case 'o':
916 {
917 bool value, success;
918 value = Args::StringToBoolean(option_arg, false, &success);
919 if (success)
920 {
921 m_one_shot_passed = true;
922 m_one_shot = value;
923 }
924 else
925 error.SetErrorStringWithFormat("invalid boolean value '%s' passed for -o option", option_arg);
926 }
927 break;
Jim Ingham5a988412012-06-08 21:56:10 +0000928 case 't' :
Jim Ingham87df91b2011-09-23 00:54:11 +0000929 {
Jim Ingham5a988412012-06-08 21:56:10 +0000930 if (option_arg[0] == '\0')
Jim Ingham87df91b2011-09-23 00:54:11 +0000931 {
Jim Ingham5a988412012-06-08 21:56:10 +0000932 m_thread_id = LLDB_INVALID_THREAD_ID;
933 m_thread_id_passed = true;
Jim Ingham87df91b2011-09-23 00:54:11 +0000934 }
935 else
936 {
Vince Harron5275aaa2015-01-15 20:08:35 +0000937 m_thread_id = StringConvert::ToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
Jim Ingham5a988412012-06-08 21:56:10 +0000938 if (m_thread_id == LLDB_INVALID_THREAD_ID)
939 error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
940 else
941 m_thread_id_passed = true;
Jim Ingham87df91b2011-09-23 00:54:11 +0000942 }
943 }
Jim Ingham5a988412012-06-08 21:56:10 +0000944 break;
945 case 'T':
946 if (option_arg != NULL)
947 m_thread_name.assign (option_arg);
948 else
949 m_thread_name.clear();
950 m_name_passed = true;
951 break;
952 case 'q':
953 if (option_arg != NULL)
954 m_queue_name.assign (option_arg);
955 else
956 m_queue_name.clear();
957 m_queue_passed = true;
958 break;
959 case 'x':
Jim Ingham969795f2011-09-21 01:17:13 +0000960 {
Jim Ingham5a988412012-06-08 21:56:10 +0000961 if (option_arg[0] == '\n')
962 {
963 m_thread_index = UINT32_MAX;
964 m_thread_index_passed = true;
965 }
966 else
967 {
Vince Harron5275aaa2015-01-15 20:08:35 +0000968 m_thread_index = StringConvert::ToUInt32 (option_arg, UINT32_MAX, 0);
Jim Ingham5a988412012-06-08 21:56:10 +0000969 if (m_thread_id == UINT32_MAX)
970 error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
971 else
972 m_thread_index_passed = true;
973 }
Jim Ingham969795f2011-09-21 01:17:13 +0000974 }
Jim Ingham5a988412012-06-08 21:56:10 +0000975 break;
976 default:
977 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
978 break;
Jim Ingham969795f2011-09-21 01:17:13 +0000979 }
Jim Ingham5a988412012-06-08 21:56:10 +0000980
981 return error;
982 }
983 void
984 OptionParsingStarting ()
985 {
986 m_ignore_count = 0;
987 m_thread_id = LLDB_INVALID_THREAD_ID;
988 m_thread_id_passed = false;
989 m_thread_index = UINT32_MAX;
990 m_thread_index_passed = false;
991 m_thread_name.clear();
992 m_queue_name.clear();
993 m_condition.clear();
Jim Inghamca36cd12012-10-05 19:16:31 +0000994 m_one_shot = false;
Jim Ingham5a988412012-06-08 21:56:10 +0000995 m_enable_passed = false;
996 m_queue_passed = false;
997 m_name_passed = false;
998 m_condition_passed = false;
Jim Inghamca36cd12012-10-05 19:16:31 +0000999 m_one_shot_passed = false;
Jim Ingham33df7cd2014-12-06 01:28:03 +00001000 m_use_dummy = false;
Jim Ingham5a988412012-06-08 21:56:10 +00001001 }
1002
1003 const OptionDefinition*
1004 GetDefinitions ()
1005 {
1006 return g_option_table;
1007 }
1008
1009
1010 // Options table: Required for subclasses of Options.
1011
1012 static OptionDefinition g_option_table[];
1013
1014 // Instance variables to hold the values for command options.
1015
1016 uint32_t m_ignore_count;
1017 lldb::tid_t m_thread_id;
1018 bool m_thread_id_passed;
1019 uint32_t m_thread_index;
1020 bool m_thread_index_passed;
1021 std::string m_thread_name;
1022 std::string m_queue_name;
1023 std::string m_condition;
Jim Inghamca36cd12012-10-05 19:16:31 +00001024 bool m_one_shot;
Jim Ingham5a988412012-06-08 21:56:10 +00001025 bool m_enable_passed;
1026 bool m_enable_value;
1027 bool m_name_passed;
1028 bool m_queue_passed;
1029 bool m_condition_passed;
Jim Inghamca36cd12012-10-05 19:16:31 +00001030 bool m_one_shot_passed;
Jim Ingham33df7cd2014-12-06 01:28:03 +00001031 bool m_use_dummy;
Jim Ingham5a988412012-06-08 21:56:10 +00001032
1033 };
1034
1035protected:
1036 virtual bool
1037 DoExecute (Args& command, CommandReturnObject &result)
1038 {
Jim Ingham33df7cd2014-12-06 01:28:03 +00001039 Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
Jim Ingham5a988412012-06-08 21:56:10 +00001040 if (target == NULL)
1041 {
1042 result.AppendError ("Invalid target. No existing target or breakpoints.");
1043 result.SetStatus (eReturnStatusFailed);
1044 return false;
1045 }
1046
1047 Mutex::Locker locker;
1048 target->GetBreakpointList().GetListMutex(locker);
1049
1050 BreakpointIDList valid_bp_ids;
1051
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001052 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
Jim Ingham5a988412012-06-08 21:56:10 +00001053
1054 if (result.Succeeded())
1055 {
1056 const size_t count = valid_bp_ids.GetSize();
1057 for (size_t i = 0; i < count; ++i)
Jim Inghamfab10e82012-03-06 00:37:27 +00001058 {
Jim Ingham5a988412012-06-08 21:56:10 +00001059 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1060
1061 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
1062 {
1063 Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1064 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
1065 {
1066 BreakpointLocation *location = bp->FindLocationByID (cur_bp_id.GetLocationID()).get();
1067 if (location)
1068 {
1069 if (m_options.m_thread_id_passed)
1070 location->SetThreadID (m_options.m_thread_id);
1071
1072 if (m_options.m_thread_index_passed)
1073 location->SetThreadIndex(m_options.m_thread_index);
1074
1075 if (m_options.m_name_passed)
1076 location->SetThreadName(m_options.m_thread_name.c_str());
1077
1078 if (m_options.m_queue_passed)
1079 location->SetQueueName(m_options.m_queue_name.c_str());
1080
1081 if (m_options.m_ignore_count != 0)
1082 location->SetIgnoreCount(m_options.m_ignore_count);
1083
1084 if (m_options.m_enable_passed)
1085 location->SetEnabled (m_options.m_enable_value);
1086
1087 if (m_options.m_condition_passed)
1088 location->SetCondition (m_options.m_condition.c_str());
1089 }
1090 }
1091 else
1092 {
1093 if (m_options.m_thread_id_passed)
1094 bp->SetThreadID (m_options.m_thread_id);
1095
1096 if (m_options.m_thread_index_passed)
1097 bp->SetThreadIndex(m_options.m_thread_index);
1098
1099 if (m_options.m_name_passed)
1100 bp->SetThreadName(m_options.m_thread_name.c_str());
1101
1102 if (m_options.m_queue_passed)
1103 bp->SetQueueName(m_options.m_queue_name.c_str());
1104
1105 if (m_options.m_ignore_count != 0)
1106 bp->SetIgnoreCount(m_options.m_ignore_count);
1107
1108 if (m_options.m_enable_passed)
1109 bp->SetEnabled (m_options.m_enable_value);
1110
1111 if (m_options.m_condition_passed)
1112 bp->SetCondition (m_options.m_condition.c_str());
1113 }
1114 }
Jim Inghamfab10e82012-03-06 00:37:27 +00001115 }
Jim Ingham5a988412012-06-08 21:56:10 +00001116 }
1117
1118 return result.Succeeded();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001119 }
1120
Jim Ingham5a988412012-06-08 21:56:10 +00001121private:
1122 CommandOptions m_options;
1123};
Johnny Chen7d49c9c2012-05-25 21:10:46 +00001124
Jim Ingham5a988412012-06-08 21:56:10 +00001125#pragma mark Modify::CommandOptions
1126OptionDefinition
1127CommandObjectBreakpointModify::CommandOptions::g_option_table[] =
1128{
Zachary Turnerd37221d2014-07-09 16:31:49 +00001129{ 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." },
1130{ 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." },
1131{ 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."},
1132{ 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."},
1133{ 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."},
1134{ 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."},
1135{ LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeExpression, "The breakpoint stops only if this condition expression evaluates to true."},
1136{ LLDB_OPT_SET_1, false, "enable", 'e', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Enable the breakpoint."},
1137{ LLDB_OPT_SET_2, false, "disable", 'd', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Disable the breakpoint."},
Jim Ingham33df7cd2014-12-06 01:28:03 +00001138{ 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."},
1139
Zachary Turnerd37221d2014-07-09 16:31:49 +00001140{ 0, false, NULL, 0 , 0, NULL, NULL, 0, eArgTypeNone, NULL }
Jim Ingham5a988412012-06-08 21:56:10 +00001141};
1142
1143//-------------------------------------------------------------------------
1144// CommandObjectBreakpointEnable
1145//-------------------------------------------------------------------------
1146#pragma mark Enable
1147
1148class CommandObjectBreakpointEnable : public CommandObjectParsed
1149{
1150public:
1151 CommandObjectBreakpointEnable (CommandInterpreter &interpreter) :
1152 CommandObjectParsed (interpreter,
1153 "enable",
1154 "Enable the specified disabled breakpoint(s). If no breakpoints are specified, enable all of them.",
1155 NULL)
1156 {
1157 CommandArgumentEntry arg;
1158 CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
1159 // Add the entry for the first argument for this command to the object's arguments vector.
1160 m_arguments.push_back (arg);
1161 }
1162
1163
1164 virtual
1165 ~CommandObjectBreakpointEnable () {}
1166
1167protected:
1168 virtual bool
1169 DoExecute (Args& command, CommandReturnObject &result)
1170 {
Jim Ingham893c9322014-11-22 01:42:44 +00001171 Target *target = GetSelectedOrDummyTarget();
Jim Ingham5a988412012-06-08 21:56:10 +00001172 if (target == NULL)
1173 {
1174 result.AppendError ("Invalid target. No existing target or breakpoints.");
1175 result.SetStatus (eReturnStatusFailed);
1176 return false;
1177 }
1178
1179 Mutex::Locker locker;
1180 target->GetBreakpointList().GetListMutex(locker);
1181
1182 const BreakpointList &breakpoints = target->GetBreakpointList();
1183
1184 size_t num_breakpoints = breakpoints.GetSize();
1185
1186 if (num_breakpoints == 0)
1187 {
1188 result.AppendError ("No breakpoints exist to be enabled.");
1189 result.SetStatus (eReturnStatusFailed);
1190 return false;
1191 }
1192
1193 if (command.GetArgumentCount() == 0)
1194 {
1195 // No breakpoint selected; enable all currently set breakpoints.
1196 target->EnableAllBreakpoints ();
Greg Clayton6fea17e2014-03-03 19:15:20 +00001197 result.AppendMessageWithFormat ("All breakpoints enabled. (%" PRIu64 " breakpoints)\n", (uint64_t)num_breakpoints);
Jim Ingham5a988412012-06-08 21:56:10 +00001198 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1199 }
1200 else
1201 {
1202 // Particular breakpoint selected; enable that breakpoint.
1203 BreakpointIDList valid_bp_ids;
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001204 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
Jim Ingham5a988412012-06-08 21:56:10 +00001205
1206 if (result.Succeeded())
1207 {
1208 int enable_count = 0;
1209 int loc_count = 0;
1210 const size_t count = valid_bp_ids.GetSize();
1211 for (size_t i = 0; i < count; ++i)
1212 {
1213 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1214
1215 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
1216 {
1217 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1218 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
1219 {
1220 BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
1221 if (location)
1222 {
1223 location->SetEnabled (true);
1224 ++loc_count;
1225 }
1226 }
1227 else
1228 {
1229 breakpoint->SetEnabled (true);
1230 ++enable_count;
1231 }
1232 }
1233 }
1234 result.AppendMessageWithFormat ("%d breakpoints enabled.\n", enable_count + loc_count);
1235 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1236 }
1237 }
1238
1239 return result.Succeeded();
1240 }
1241};
1242
1243//-------------------------------------------------------------------------
1244// CommandObjectBreakpointDisable
1245//-------------------------------------------------------------------------
1246#pragma mark Disable
1247
1248class CommandObjectBreakpointDisable : public CommandObjectParsed
1249{
1250public:
1251 CommandObjectBreakpointDisable (CommandInterpreter &interpreter) :
1252 CommandObjectParsed (interpreter,
1253 "breakpoint disable",
1254 "Disable the specified breakpoint(s) without removing it/them. If no breakpoints are specified, disable them all.",
1255 NULL)
1256 {
Jim Inghamb0fac502013-03-08 00:31:40 +00001257 SetHelpLong(
1258"Disable the specified breakpoint(s) without removing it/them. \n\
1259If no breakpoints are specified, disable them all.\n\
1260\n\
1261Note: disabling a breakpoint will cause none of its locations to be hit\n\
1262regardless of whether they are enabled or disabled. So the sequence: \n\
1263\n\
1264 (lldb) break disable 1\n\
1265 (lldb) break enable 1.1\n\
1266\n\
1267will NOT cause location 1.1 to get hit. To achieve that, do:\n\
1268\n\
1269 (lldb) break disable 1.*\n\
1270 (lldb) break enable 1.1\n\
1271\n\
1272The first command disables all the locations of breakpoint 1, \n\
1273the second re-enables the first location."
1274 );
1275
Jim Ingham5a988412012-06-08 21:56:10 +00001276 CommandArgumentEntry arg;
1277 CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
1278 // Add the entry for the first argument for this command to the object's arguments vector.
Jim Inghamb0fac502013-03-08 00:31:40 +00001279 m_arguments.push_back (arg);
1280
Jim Ingham5a988412012-06-08 21:56:10 +00001281 }
1282
1283
1284 virtual
1285 ~CommandObjectBreakpointDisable () {}
1286
1287protected:
1288 virtual bool
1289 DoExecute (Args& command, CommandReturnObject &result)
1290 {
Jim Ingham893c9322014-11-22 01:42:44 +00001291 Target *target = GetSelectedOrDummyTarget();
Jim Ingham5a988412012-06-08 21:56:10 +00001292 if (target == NULL)
1293 {
1294 result.AppendError ("Invalid target. No existing target or breakpoints.");
1295 result.SetStatus (eReturnStatusFailed);
1296 return false;
1297 }
1298
1299 Mutex::Locker locker;
1300 target->GetBreakpointList().GetListMutex(locker);
1301
1302 const BreakpointList &breakpoints = target->GetBreakpointList();
1303 size_t num_breakpoints = breakpoints.GetSize();
1304
1305 if (num_breakpoints == 0)
1306 {
1307 result.AppendError ("No breakpoints exist to be disabled.");
1308 result.SetStatus (eReturnStatusFailed);
1309 return false;
1310 }
1311
1312 if (command.GetArgumentCount() == 0)
1313 {
1314 // No breakpoint selected; disable all currently set breakpoints.
1315 target->DisableAllBreakpoints ();
Greg Clayton6fea17e2014-03-03 19:15:20 +00001316 result.AppendMessageWithFormat ("All breakpoints disabled. (%" PRIu64 " breakpoints)\n", (uint64_t)num_breakpoints);
Jim Ingham5a988412012-06-08 21:56:10 +00001317 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1318 }
1319 else
1320 {
1321 // Particular breakpoint selected; disable that breakpoint.
1322 BreakpointIDList valid_bp_ids;
1323
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001324 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
Jim Ingham5a988412012-06-08 21:56:10 +00001325
1326 if (result.Succeeded())
1327 {
1328 int disable_count = 0;
1329 int loc_count = 0;
1330 const size_t count = valid_bp_ids.GetSize();
1331 for (size_t i = 0; i < count; ++i)
1332 {
1333 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1334
1335 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
1336 {
1337 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1338 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
1339 {
1340 BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
1341 if (location)
1342 {
1343 location->SetEnabled (false);
1344 ++loc_count;
1345 }
1346 }
1347 else
1348 {
1349 breakpoint->SetEnabled (false);
1350 ++disable_count;
1351 }
1352 }
1353 }
1354 result.AppendMessageWithFormat ("%d breakpoints disabled.\n", disable_count + loc_count);
1355 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1356 }
1357 }
1358
1359 return result.Succeeded();
1360 }
1361
1362};
1363
1364//-------------------------------------------------------------------------
1365// CommandObjectBreakpointList
1366//-------------------------------------------------------------------------
1367#pragma mark List
1368
1369class CommandObjectBreakpointList : public CommandObjectParsed
1370{
1371public:
1372 CommandObjectBreakpointList (CommandInterpreter &interpreter) :
1373 CommandObjectParsed (interpreter,
1374 "breakpoint list",
1375 "List some or all breakpoints at configurable levels of detail.",
1376 NULL),
1377 m_options (interpreter)
1378 {
1379 CommandArgumentEntry arg;
1380 CommandArgumentData bp_id_arg;
1381
1382 // Define the first (and only) variant of this arg.
1383 bp_id_arg.arg_type = eArgTypeBreakpointID;
1384 bp_id_arg.arg_repetition = eArgRepeatOptional;
1385
1386 // There is only one variant this argument could be; put it into the argument entry.
1387 arg.push_back (bp_id_arg);
1388
1389 // Push the data for the first argument into the m_arguments vector.
1390 m_arguments.push_back (arg);
1391 }
1392
1393
1394 virtual
1395 ~CommandObjectBreakpointList () {}
1396
1397 virtual Options *
1398 GetOptions ()
1399 {
1400 return &m_options;
Jim Ingham1b54c882010-06-16 02:00:15 +00001401 }
1402
Jim Ingham5a988412012-06-08 21:56:10 +00001403 class CommandOptions : public Options
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001404 {
Jim Ingham5a988412012-06-08 21:56:10 +00001405 public:
1406
1407 CommandOptions (CommandInterpreter &interpreter) :
1408 Options (interpreter),
Jim Ingham33df7cd2014-12-06 01:28:03 +00001409 m_level (lldb::eDescriptionLevelBrief),
1410 m_use_dummy(false)
Jim Ingham5a988412012-06-08 21:56:10 +00001411 {
1412 }
1413
1414 virtual
1415 ~CommandOptions () {}
1416
1417 virtual Error
1418 SetOptionValue (uint32_t option_idx, const char *option_arg)
1419 {
1420 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +00001421 const int short_option = m_getopt_table[option_idx].val;
Jim Ingham5a988412012-06-08 21:56:10 +00001422
1423 switch (short_option)
1424 {
1425 case 'b':
1426 m_level = lldb::eDescriptionLevelBrief;
1427 break;
Jim Ingham33df7cd2014-12-06 01:28:03 +00001428 case 'D':
1429 m_use_dummy = true;
1430 break;
Jim Ingham5a988412012-06-08 21:56:10 +00001431 case 'f':
1432 m_level = lldb::eDescriptionLevelFull;
1433 break;
1434 case 'v':
1435 m_level = lldb::eDescriptionLevelVerbose;
1436 break;
1437 case 'i':
1438 m_internal = true;
1439 break;
1440 default:
1441 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1442 break;
1443 }
1444
1445 return error;
1446 }
1447
1448 void
1449 OptionParsingStarting ()
1450 {
1451 m_level = lldb::eDescriptionLevelFull;
1452 m_internal = false;
Jim Ingham33df7cd2014-12-06 01:28:03 +00001453 m_use_dummy = false;
Jim Ingham5a988412012-06-08 21:56:10 +00001454 }
1455
1456 const OptionDefinition *
1457 GetDefinitions ()
1458 {
1459 return g_option_table;
1460 }
1461
1462 // Options table: Required for subclasses of Options.
1463
1464 static OptionDefinition g_option_table[];
1465
1466 // Instance variables to hold the values for command options.
1467
1468 lldb::DescriptionLevel m_level;
1469
1470 bool m_internal;
Jim Ingham33df7cd2014-12-06 01:28:03 +00001471 bool m_use_dummy;
Jim Ingham5a988412012-06-08 21:56:10 +00001472 };
1473
1474protected:
1475 virtual bool
1476 DoExecute (Args& command, CommandReturnObject &result)
1477 {
Jim Ingham33df7cd2014-12-06 01:28:03 +00001478 Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
1479
Jim Ingham5a988412012-06-08 21:56:10 +00001480 if (target == NULL)
1481 {
1482 result.AppendError ("Invalid target. No current target or breakpoints.");
1483 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1484 return true;
1485 }
1486
1487 const BreakpointList &breakpoints = target->GetBreakpointList(m_options.m_internal);
1488 Mutex::Locker locker;
1489 target->GetBreakpointList(m_options.m_internal).GetListMutex(locker);
1490
1491 size_t num_breakpoints = breakpoints.GetSize();
1492
1493 if (num_breakpoints == 0)
1494 {
1495 result.AppendMessage ("No breakpoints currently set.");
1496 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1497 return true;
1498 }
1499
Jim Ingham85e8b812011-02-19 02:53:09 +00001500 Stream &output_stream = result.GetOutputStream();
Jim Ingham5a988412012-06-08 21:56:10 +00001501
1502 if (command.GetArgumentCount() == 0)
1503 {
1504 // No breakpoint selected; show info about all currently set breakpoints.
1505 result.AppendMessage ("Current breakpoints:");
1506 for (size_t i = 0; i < num_breakpoints; ++i)
1507 {
1508 Breakpoint *breakpoint = breakpoints.GetBreakpointAtIndex (i).get();
1509 AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
1510 }
1511 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1512 }
1513 else
1514 {
1515 // Particular breakpoints selected; show info about that breakpoint.
1516 BreakpointIDList valid_bp_ids;
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001517 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
Jim Ingham5a988412012-06-08 21:56:10 +00001518
1519 if (result.Succeeded())
1520 {
1521 for (size_t i = 0; i < valid_bp_ids.GetSize(); ++i)
1522 {
1523 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1524 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1525 AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
1526 }
1527 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1528 }
1529 else
1530 {
1531 result.AppendError ("Invalid breakpoint id.");
1532 result.SetStatus (eReturnStatusFailed);
1533 }
1534 }
1535
1536 return result.Succeeded();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001537 }
1538
Jim Ingham5a988412012-06-08 21:56:10 +00001539private:
1540 CommandOptions m_options;
1541};
1542
1543#pragma mark List::CommandOptions
1544OptionDefinition
1545CommandObjectBreakpointList::CommandOptions::g_option_table[] =
1546{
Zachary Turnerd37221d2014-07-09 16:31:49 +00001547 { LLDB_OPT_SET_ALL, false, "internal", 'i', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
Jim Ingham5a988412012-06-08 21:56:10 +00001548 "Show debugger internal breakpoints" },
1549
Zachary Turnerd37221d2014-07-09 16:31:49 +00001550 { LLDB_OPT_SET_1, false, "brief", 'b', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
Jim Ingham5a988412012-06-08 21:56:10 +00001551 "Give a brief description of the breakpoint (no location info)."},
1552
1553 // FIXME: We need to add an "internal" command, and then add this sort of thing to it.
1554 // But I need to see it for now, and don't want to wait.
Zachary Turnerd37221d2014-07-09 16:31:49 +00001555 { LLDB_OPT_SET_2, false, "full", 'f', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
Jim Ingham5a988412012-06-08 21:56:10 +00001556 "Give a full description of the breakpoint and its locations."},
1557
Zachary Turnerd37221d2014-07-09 16:31:49 +00001558 { LLDB_OPT_SET_3, false, "verbose", 'v', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
Jim Ingham5a988412012-06-08 21:56:10 +00001559 "Explain everything we know about the breakpoint (for debugging debugger bugs)." },
1560
Jim Ingham33df7cd2014-12-06 01:28:03 +00001561 { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
1562 "List Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
1563
Zachary Turnerd37221d2014-07-09 16:31:49 +00001564 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Jim Ingham5a988412012-06-08 21:56:10 +00001565};
1566
1567//-------------------------------------------------------------------------
1568// CommandObjectBreakpointClear
1569//-------------------------------------------------------------------------
1570#pragma mark Clear
1571
1572class CommandObjectBreakpointClear : public CommandObjectParsed
1573{
1574public:
1575
1576 typedef enum BreakpointClearType
1577 {
1578 eClearTypeInvalid,
1579 eClearTypeFileAndLine
1580 } BreakpointClearType;
1581
1582 CommandObjectBreakpointClear (CommandInterpreter &interpreter) :
1583 CommandObjectParsed (interpreter,
1584 "breakpoint clear",
1585 "Clears a breakpoint or set of breakpoints in the executable.",
1586 "breakpoint clear <cmd-options>"),
1587 m_options (interpreter)
1588 {
1589 }
1590
1591 virtual
1592 ~CommandObjectBreakpointClear () {}
1593
1594 virtual Options *
1595 GetOptions ()
1596 {
1597 return &m_options;
1598 }
1599
1600 class CommandOptions : public Options
1601 {
1602 public:
1603
1604 CommandOptions (CommandInterpreter &interpreter) :
1605 Options (interpreter),
1606 m_filename (),
1607 m_line_num (0)
1608 {
1609 }
1610
1611 virtual
1612 ~CommandOptions () {}
1613
1614 virtual Error
1615 SetOptionValue (uint32_t option_idx, const char *option_arg)
1616 {
1617 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +00001618 const int short_option = m_getopt_table[option_idx].val;
Jim Ingham5a988412012-06-08 21:56:10 +00001619
1620 switch (short_option)
1621 {
1622 case 'f':
1623 m_filename.assign (option_arg);
1624 break;
1625
1626 case 'l':
Vince Harron5275aaa2015-01-15 20:08:35 +00001627 m_line_num = StringConvert::ToUInt32 (option_arg, 0);
Jim Ingham5a988412012-06-08 21:56:10 +00001628 break;
1629
1630 default:
1631 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1632 break;
1633 }
1634
1635 return error;
1636 }
1637
1638 void
1639 OptionParsingStarting ()
1640 {
1641 m_filename.clear();
1642 m_line_num = 0;
1643 }
1644
1645 const OptionDefinition*
1646 GetDefinitions ()
1647 {
1648 return g_option_table;
1649 }
1650
1651 // Options table: Required for subclasses of Options.
1652
1653 static OptionDefinition g_option_table[];
1654
1655 // Instance variables to hold the values for command options.
1656
1657 std::string m_filename;
1658 uint32_t m_line_num;
1659
1660 };
1661
1662protected:
1663 virtual bool
1664 DoExecute (Args& command, CommandReturnObject &result)
1665 {
Jim Ingham893c9322014-11-22 01:42:44 +00001666 Target *target = GetSelectedOrDummyTarget();
Jim Ingham5a988412012-06-08 21:56:10 +00001667 if (target == NULL)
1668 {
1669 result.AppendError ("Invalid target. No existing target or breakpoints.");
1670 result.SetStatus (eReturnStatusFailed);
1671 return false;
1672 }
1673
1674 // The following are the various types of breakpoints that could be cleared:
1675 // 1). -f -l (clearing breakpoint by source location)
1676
1677 BreakpointClearType break_type = eClearTypeInvalid;
1678
1679 if (m_options.m_line_num != 0)
1680 break_type = eClearTypeFileAndLine;
1681
1682 Mutex::Locker locker;
1683 target->GetBreakpointList().GetListMutex(locker);
1684
1685 BreakpointList &breakpoints = target->GetBreakpointList();
1686 size_t num_breakpoints = breakpoints.GetSize();
1687
1688 // Early return if there's no breakpoint at all.
1689 if (num_breakpoints == 0)
1690 {
1691 result.AppendError ("Breakpoint clear: No breakpoint cleared.");
1692 result.SetStatus (eReturnStatusFailed);
1693 return result.Succeeded();
1694 }
1695
1696 // Find matching breakpoints and delete them.
1697
1698 // First create a copy of all the IDs.
1699 std::vector<break_id_t> BreakIDs;
1700 for (size_t i = 0; i < num_breakpoints; ++i)
1701 BreakIDs.push_back(breakpoints.GetBreakpointAtIndex(i).get()->GetID());
1702
1703 int num_cleared = 0;
1704 StreamString ss;
1705 switch (break_type)
1706 {
1707 case eClearTypeFileAndLine: // Breakpoint by source position
1708 {
1709 const ConstString filename(m_options.m_filename.c_str());
1710 BreakpointLocationCollection loc_coll;
1711
1712 for (size_t i = 0; i < num_breakpoints; ++i)
1713 {
1714 Breakpoint *bp = breakpoints.FindBreakpointByID(BreakIDs[i]).get();
1715
1716 if (bp->GetMatchingFileLine(filename, m_options.m_line_num, loc_coll))
1717 {
1718 // If the collection size is 0, it's a full match and we can just remove the breakpoint.
1719 if (loc_coll.GetSize() == 0)
1720 {
1721 bp->GetDescription(&ss, lldb::eDescriptionLevelBrief);
1722 ss.EOL();
1723 target->RemoveBreakpointByID (bp->GetID());
1724 ++num_cleared;
1725 }
1726 }
1727 }
1728 }
1729 break;
1730
1731 default:
1732 break;
1733 }
1734
1735 if (num_cleared > 0)
1736 {
1737 Stream &output_stream = result.GetOutputStream();
1738 output_stream.Printf ("%d breakpoints cleared:\n", num_cleared);
1739 output_stream << ss.GetData();
1740 output_stream.EOL();
1741 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1742 }
1743 else
1744 {
1745 result.AppendError ("Breakpoint clear: No breakpoint cleared.");
1746 result.SetStatus (eReturnStatusFailed);
1747 }
1748
1749 return result.Succeeded();
1750 }
1751
1752private:
1753 CommandOptions m_options;
1754};
1755
1756#pragma mark Clear::CommandOptions
1757
1758OptionDefinition
1759CommandObjectBreakpointClear::CommandOptions::g_option_table[] =
1760{
Zachary Turnerd37221d2014-07-09 16:31:49 +00001761 { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
Jim Ingham5a988412012-06-08 21:56:10 +00001762 "Specify the breakpoint by source location in this particular file."},
1763
Zachary Turnerd37221d2014-07-09 16:31:49 +00001764 { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum,
Jim Ingham5a988412012-06-08 21:56:10 +00001765 "Specify the breakpoint by source location at this particular line."},
1766
Zachary Turnerd37221d2014-07-09 16:31:49 +00001767 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Jim Ingham5a988412012-06-08 21:56:10 +00001768};
1769
1770//-------------------------------------------------------------------------
1771// CommandObjectBreakpointDelete
1772//-------------------------------------------------------------------------
1773#pragma mark Delete
1774
1775class CommandObjectBreakpointDelete : public CommandObjectParsed
1776{
1777public:
1778 CommandObjectBreakpointDelete (CommandInterpreter &interpreter) :
1779 CommandObjectParsed (interpreter,
1780 "breakpoint delete",
1781 "Delete the specified breakpoint(s). If no breakpoints are specified, delete them all.",
Jim Ingham33df7cd2014-12-06 01:28:03 +00001782 NULL),
1783 m_options (interpreter)
Jim Ingham5a988412012-06-08 21:56:10 +00001784 {
1785 CommandArgumentEntry arg;
1786 CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
1787 // Add the entry for the first argument for this command to the object's arguments vector.
1788 m_arguments.push_back (arg);
1789 }
1790
1791 virtual
1792 ~CommandObjectBreakpointDelete () {}
1793
Jim Ingham33df7cd2014-12-06 01:28:03 +00001794 virtual Options *
1795 GetOptions ()
1796 {
1797 return &m_options;
1798 }
1799
1800 class CommandOptions : public Options
1801 {
1802 public:
1803
1804 CommandOptions (CommandInterpreter &interpreter) :
1805 Options (interpreter),
1806 m_use_dummy (false),
1807 m_force (false)
1808 {
1809 }
1810
1811 virtual
1812 ~CommandOptions () {}
1813
1814 virtual Error
1815 SetOptionValue (uint32_t option_idx, const char *option_arg)
1816 {
1817 Error error;
1818 const int short_option = m_getopt_table[option_idx].val;
1819
1820 switch (short_option)
1821 {
1822 case 'f':
1823 m_force = true;
1824 break;
1825
1826 case 'D':
1827 m_use_dummy = true;
1828 break;
1829
1830 default:
1831 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1832 break;
1833 }
1834
1835 return error;
1836 }
1837
1838 void
1839 OptionParsingStarting ()
1840 {
1841 m_use_dummy = false;
1842 m_force = false;
1843 }
1844
1845 const OptionDefinition*
1846 GetDefinitions ()
1847 {
1848 return g_option_table;
1849 }
1850
1851 // Options table: Required for subclasses of Options.
1852
1853 static OptionDefinition g_option_table[];
1854
1855 // Instance variables to hold the values for command options.
1856 bool m_use_dummy;
1857 bool m_force;
1858 };
1859
Jim Ingham5a988412012-06-08 21:56:10 +00001860protected:
1861 virtual bool
1862 DoExecute (Args& command, CommandReturnObject &result)
1863 {
Jim Ingham33df7cd2014-12-06 01:28:03 +00001864 Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
1865
Jim Ingham5a988412012-06-08 21:56:10 +00001866 if (target == NULL)
1867 {
1868 result.AppendError ("Invalid target. No existing target or breakpoints.");
1869 result.SetStatus (eReturnStatusFailed);
1870 return false;
1871 }
1872
1873 Mutex::Locker locker;
1874 target->GetBreakpointList().GetListMutex(locker);
1875
1876 const BreakpointList &breakpoints = target->GetBreakpointList();
1877
1878 size_t num_breakpoints = breakpoints.GetSize();
1879
1880 if (num_breakpoints == 0)
1881 {
1882 result.AppendError ("No breakpoints exist to be deleted.");
1883 result.SetStatus (eReturnStatusFailed);
1884 return false;
1885 }
1886
1887 if (command.GetArgumentCount() == 0)
1888 {
Jim Ingham33df7cd2014-12-06 01:28:03 +00001889 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 +00001890 {
1891 result.AppendMessage("Operation cancelled...");
1892 }
1893 else
1894 {
1895 target->RemoveAllBreakpoints ();
Greg Clayton6fea17e2014-03-03 19:15:20 +00001896 result.AppendMessageWithFormat ("All breakpoints removed. (%" PRIu64 " breakpoint%s)\n", (uint64_t)num_breakpoints, num_breakpoints > 1 ? "s" : "");
Jim Ingham5a988412012-06-08 21:56:10 +00001897 }
1898 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1899 }
1900 else
1901 {
1902 // Particular breakpoint selected; disable that breakpoint.
1903 BreakpointIDList valid_bp_ids;
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001904 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
Jim Ingham5a988412012-06-08 21:56:10 +00001905
1906 if (result.Succeeded())
1907 {
1908 int delete_count = 0;
1909 int disable_count = 0;
1910 const size_t count = valid_bp_ids.GetSize();
1911 for (size_t i = 0; i < count; ++i)
1912 {
1913 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1914
1915 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
1916 {
1917 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
1918 {
1919 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1920 BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
1921 // It makes no sense to try to delete individual locations, so we disable them instead.
1922 if (location)
1923 {
1924 location->SetEnabled (false);
1925 ++disable_count;
1926 }
1927 }
1928 else
1929 {
1930 target->RemoveBreakpointByID (cur_bp_id.GetBreakpointID());
1931 ++delete_count;
1932 }
1933 }
1934 }
1935 result.AppendMessageWithFormat ("%d breakpoints deleted; %d breakpoint locations disabled.\n",
1936 delete_count, disable_count);
1937 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1938 }
1939 }
1940 return result.Succeeded();
1941 }
Jim Ingham33df7cd2014-12-06 01:28:03 +00001942private:
1943 CommandOptions m_options;
1944};
1945
1946OptionDefinition
1947CommandObjectBreakpointDelete::CommandOptions::g_option_table[] =
1948{
1949 { LLDB_OPT_SET_1, false, "force", 'f', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
1950 "Delete all breakpoints without querying for confirmation."},
1951
1952 { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
1953 "Delete Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
1954
1955 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Jim Ingham5a988412012-06-08 21:56:10 +00001956};
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001957
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001958//-------------------------------------------------------------------------
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001959// CommandObjectBreakpointName
1960//-------------------------------------------------------------------------
1961
1962static OptionDefinition
1963g_breakpoint_name_options[] =
1964{
1965 { LLDB_OPT_SET_1, false, "name", 'N', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBreakpointName, "Specifies a breakpoint name to use."},
1966 { LLDB_OPT_SET_2, false, "breakpoint-id", 'B', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBreakpointID, "Specify a breakpoint id to use."},
1967 { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
1968 "Operate on Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
1969};
1970class BreakpointNameOptionGroup : public OptionGroup
1971{
1972public:
1973 BreakpointNameOptionGroup() :
1974 OptionGroup(),
1975 m_breakpoint(LLDB_INVALID_BREAK_ID),
1976 m_use_dummy (false)
1977 {
1978
1979 }
1980
1981 virtual
1982 ~BreakpointNameOptionGroup ()
1983 {
1984 }
1985
1986 virtual uint32_t
1987 GetNumDefinitions ()
1988 {
1989 return sizeof (g_breakpoint_name_options) / sizeof (OptionDefinition);
1990 }
1991
1992 virtual const OptionDefinition*
1993 GetDefinitions ()
1994 {
1995 return g_breakpoint_name_options;
1996 }
1997
1998 virtual Error
1999 SetOptionValue (CommandInterpreter &interpreter,
2000 uint32_t option_idx,
2001 const char *option_value)
2002 {
2003 Error error;
2004 const int short_option = g_breakpoint_name_options[option_idx].short_option;
2005
2006 switch (short_option)
2007 {
2008 case 'N':
2009 if (BreakpointID::StringIsBreakpointName(option_value, error) && error.Success())
Pavel Labathc95f7e22015-02-20 11:14:59 +00002010 m_name.SetValueFromString(option_value);
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002011 break;
2012
2013 case 'B':
Pavel Labathc95f7e22015-02-20 11:14:59 +00002014 if (m_breakpoint.SetValueFromString(option_value).Fail())
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002015 error.SetErrorStringWithFormat ("unrecognized value \"%s\" for breakpoint", option_value);
2016 break;
2017 case 'D':
Pavel Labathc95f7e22015-02-20 11:14:59 +00002018 if (m_use_dummy.SetValueFromString(option_value).Fail())
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002019 error.SetErrorStringWithFormat ("unrecognized value \"%s\" for use-dummy", option_value);
2020 break;
2021
2022 default:
2023 error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option);
2024 break;
2025 }
2026 return error;
2027 }
2028
2029 virtual void
2030 OptionParsingStarting (CommandInterpreter &interpreter)
2031 {
2032 m_name.Clear();
2033 m_breakpoint.Clear();
2034 m_use_dummy.Clear();
2035 m_use_dummy.SetDefaultValue(false);
2036 }
2037
2038 OptionValueString m_name;
2039 OptionValueUInt64 m_breakpoint;
2040 OptionValueBoolean m_use_dummy;
2041};
2042
2043
2044class CommandObjectBreakpointNameAdd : public CommandObjectParsed
2045{
2046public:
2047 CommandObjectBreakpointNameAdd (CommandInterpreter &interpreter) :
2048 CommandObjectParsed (interpreter,
2049 "add",
2050 "Add a name to the breakpoints provided.",
2051 "breakpoint name add <command-options> <breakpoint-id-list>"),
2052 m_name_options(),
2053 m_option_group(interpreter)
2054 {
2055 // Create the first variant for the first (and only) argument for this command.
2056 CommandArgumentEntry arg1;
2057 CommandArgumentData id_arg;
2058 id_arg.arg_type = eArgTypeBreakpointID;
2059 id_arg.arg_repetition = eArgRepeatOptional;
2060 arg1.push_back(id_arg);
2061 m_arguments.push_back (arg1);
2062
2063 m_option_group.Append (&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
2064 m_option_group.Finalize();
2065 }
2066
2067 virtual
2068 ~CommandObjectBreakpointNameAdd () {}
2069
2070 Options *
2071 GetOptions ()
2072 {
2073 return &m_option_group;
2074 }
2075
2076protected:
2077 virtual bool
2078 DoExecute (Args& command, CommandReturnObject &result)
2079 {
2080 if (!m_name_options.m_name.OptionWasSet())
2081 {
2082 result.SetError("No name option provided.");
2083 return false;
2084 }
2085
2086 Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
2087
2088 if (target == NULL)
2089 {
2090 result.AppendError ("Invalid target. No existing target or breakpoints.");
2091 result.SetStatus (eReturnStatusFailed);
2092 return false;
2093 }
2094
2095 Mutex::Locker locker;
2096 target->GetBreakpointList().GetListMutex(locker);
2097
2098 const BreakpointList &breakpoints = target->GetBreakpointList();
2099
2100 size_t num_breakpoints = breakpoints.GetSize();
2101 if (num_breakpoints == 0)
2102 {
2103 result.SetError("No breakpoints, cannot add names.");
2104 result.SetStatus (eReturnStatusFailed);
2105 return false;
2106 }
2107
2108 // Particular breakpoint selected; disable that breakpoint.
2109 BreakpointIDList valid_bp_ids;
2110 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
2111
2112 if (result.Succeeded())
2113 {
2114 if (valid_bp_ids.GetSize() == 0)
2115 {
2116 result.SetError("No breakpoints specified, cannot add names.");
2117 result.SetStatus (eReturnStatusFailed);
2118 return false;
2119 }
2120 size_t num_valid_ids = valid_bp_ids.GetSize();
2121 for (size_t index = 0; index < num_valid_ids; index++)
2122 {
2123 lldb::break_id_t bp_id = valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
2124 BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
2125 Error error; // We don't need to check the error here, since the option parser checked it...
2126 bp_sp->AddName(m_name_options.m_name.GetCurrentValue(), error);
2127 }
2128 }
2129
2130 return true;
2131 }
2132
2133private:
2134 BreakpointNameOptionGroup m_name_options;
2135 OptionGroupOptions m_option_group;
2136};
2137
2138
2139
2140class CommandObjectBreakpointNameDelete : public CommandObjectParsed
2141{
2142public:
2143 CommandObjectBreakpointNameDelete (CommandInterpreter &interpreter) :
2144 CommandObjectParsed (interpreter,
2145 "delete",
2146 "Delete a name from the breakpoints provided.",
2147 "breakpoint name delete <command-options> <breakpoint-id-list>"),
2148 m_name_options(),
2149 m_option_group(interpreter)
2150 {
2151 // Create the first variant for the first (and only) argument for this command.
2152 CommandArgumentEntry arg1;
2153 CommandArgumentData id_arg;
2154 id_arg.arg_type = eArgTypeBreakpointID;
2155 id_arg.arg_repetition = eArgRepeatOptional;
2156 arg1.push_back(id_arg);
2157 m_arguments.push_back (arg1);
2158
2159 m_option_group.Append (&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
2160 m_option_group.Finalize();
2161 }
2162
2163 virtual
2164 ~CommandObjectBreakpointNameDelete () {}
2165
2166 Options *
2167 GetOptions ()
2168 {
2169 return &m_option_group;
2170 }
2171
2172protected:
2173 virtual bool
2174 DoExecute (Args& command, CommandReturnObject &result)
2175 {
2176 if (!m_name_options.m_name.OptionWasSet())
2177 {
2178 result.SetError("No name option provided.");
2179 return false;
2180 }
2181
2182 Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
2183
2184 if (target == NULL)
2185 {
2186 result.AppendError ("Invalid target. No existing target or breakpoints.");
2187 result.SetStatus (eReturnStatusFailed);
2188 return false;
2189 }
2190
2191 Mutex::Locker locker;
2192 target->GetBreakpointList().GetListMutex(locker);
2193
2194 const BreakpointList &breakpoints = target->GetBreakpointList();
2195
2196 size_t num_breakpoints = breakpoints.GetSize();
2197 if (num_breakpoints == 0)
2198 {
2199 result.SetError("No breakpoints, cannot delete names.");
2200 result.SetStatus (eReturnStatusFailed);
2201 return false;
2202 }
2203
2204 // Particular breakpoint selected; disable that breakpoint.
2205 BreakpointIDList valid_bp_ids;
2206 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
2207
2208 if (result.Succeeded())
2209 {
2210 if (valid_bp_ids.GetSize() == 0)
2211 {
2212 result.SetError("No breakpoints specified, cannot delete names.");
2213 result.SetStatus (eReturnStatusFailed);
2214 return false;
2215 }
2216 size_t num_valid_ids = valid_bp_ids.GetSize();
2217 for (size_t index = 0; index < num_valid_ids; index++)
2218 {
2219 lldb::break_id_t bp_id = valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
2220 BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
2221 bp_sp->RemoveName(m_name_options.m_name.GetCurrentValue());
2222 }
2223 }
2224
2225 return true;
2226 }
2227
2228private:
2229 BreakpointNameOptionGroup m_name_options;
2230 OptionGroupOptions m_option_group;
2231};
2232
2233class CommandObjectBreakpointNameList : public CommandObjectParsed
2234{
2235public:
2236 CommandObjectBreakpointNameList (CommandInterpreter &interpreter) :
2237 CommandObjectParsed (interpreter,
2238 "list",
2239 "List either the names for a breakpoint or the breakpoints for a given name.",
2240 "breakpoint name list <command-options>"),
2241 m_name_options(),
2242 m_option_group(interpreter)
2243 {
2244 m_option_group.Append (&m_name_options);
2245 m_option_group.Finalize();
2246 }
2247
2248 virtual
2249 ~CommandObjectBreakpointNameList () {}
2250
2251 Options *
2252 GetOptions ()
2253 {
2254 return &m_option_group;
2255 }
2256
2257protected:
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002258 virtual bool
2259 DoExecute (Args& command, CommandReturnObject &result)
2260 {
2261 Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
2262
2263 if (target == NULL)
2264 {
2265 result.AppendError ("Invalid target. No existing target or breakpoints.");
2266 result.SetStatus (eReturnStatusFailed);
2267 return false;
2268 }
2269
2270 if (m_name_options.m_name.OptionWasSet())
2271 {
2272 const char *name = m_name_options.m_name.GetCurrentValue();
2273 Mutex::Locker locker;
2274 target->GetBreakpointList().GetListMutex(locker);
2275
2276 BreakpointList &breakpoints = target->GetBreakpointList();
2277 for (BreakpointSP bp_sp : breakpoints.Breakpoints())
2278 {
2279 if (bp_sp->MatchesName(name))
2280 {
2281 StreamString s;
2282 bp_sp->GetDescription(&s, eDescriptionLevelBrief);
2283 s.EOL();
2284 result.AppendMessage(s.GetData());
2285 }
2286 }
2287
2288 }
2289 else if (m_name_options.m_breakpoint.OptionWasSet())
2290 {
2291 BreakpointSP bp_sp = target->GetBreakpointList().FindBreakpointByID(m_name_options.m_breakpoint.GetCurrentValue());
2292 if (bp_sp)
2293 {
2294 std::vector<std::string> names;
2295 bp_sp->GetNames (names);
2296 result.AppendMessage ("Names:");
2297 for (auto name : names)
2298 result.AppendMessageWithFormat (" %s\n", name.c_str());
2299 }
2300 else
2301 {
2302 result.AppendErrorWithFormat ("Could not find breakpoint %" PRId64 ".\n",
2303 m_name_options.m_breakpoint.GetCurrentValue());
2304 result.SetStatus (eReturnStatusFailed);
2305 return false;
2306 }
2307 }
2308 else
2309 {
2310 result.SetError ("Must specify -N or -B option to list.");
2311 result.SetStatus (eReturnStatusFailed);
2312 return false;
2313 }
2314 return true;
2315 }
2316
2317private:
2318 BreakpointNameOptionGroup m_name_options;
2319 OptionGroupOptions m_option_group;
2320};
2321
2322//-------------------------------------------------------------------------
2323// CommandObjectMultiwordBreakpoint
2324//-------------------------------------------------------------------------
2325class CommandObjectBreakpointName : public CommandObjectMultiword
2326{
2327public:
2328 CommandObjectBreakpointName (CommandInterpreter &interpreter) :
2329 CommandObjectMultiword(interpreter,
2330 "name",
2331 "A set of commands to manage name tags for breakpoints",
2332 "breakpoint name <command> [<command-options>]")
2333 {
2334 CommandObjectSP add_command_object (new CommandObjectBreakpointNameAdd (interpreter));
2335 CommandObjectSP delete_command_object (new CommandObjectBreakpointNameDelete (interpreter));
2336 CommandObjectSP list_command_object (new CommandObjectBreakpointNameList (interpreter));
2337
2338 LoadSubCommand ("add", add_command_object);
2339 LoadSubCommand ("delete", delete_command_object);
2340 LoadSubCommand ("list", list_command_object);
2341
2342 }
2343
2344 virtual
2345 ~CommandObjectBreakpointName ()
2346 {
2347 }
2348
2349};
2350
2351
2352//-------------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002353// CommandObjectMultiwordBreakpoint
2354//-------------------------------------------------------------------------
Jim Inghamae1c4cf2010-06-18 00:58:52 +00002355#pragma mark MultiwordBreakpoint
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002356
Greg Clayton66111032010-06-23 01:19:29 +00002357CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint (CommandInterpreter &interpreter) :
Greg Claytona7015092010-09-18 01:14:36 +00002358 CommandObjectMultiword (interpreter,
2359 "breakpoint",
Jim Ingham46fbc602011-05-26 20:39:01 +00002360 "A set of commands for operating on breakpoints. Also see _regexp-break.",
Greg Claytona7015092010-09-18 01:14:36 +00002361 "breakpoint <command> [<command-options>]")
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002362{
Greg Claytona7015092010-09-18 01:14:36 +00002363 CommandObjectSP list_command_object (new CommandObjectBreakpointList (interpreter));
Greg Claytona7015092010-09-18 01:14:36 +00002364 CommandObjectSP enable_command_object (new CommandObjectBreakpointEnable (interpreter));
2365 CommandObjectSP disable_command_object (new CommandObjectBreakpointDisable (interpreter));
Johnny Chenb7234e42010-10-28 17:27:46 +00002366 CommandObjectSP clear_command_object (new CommandObjectBreakpointClear (interpreter));
2367 CommandObjectSP delete_command_object (new CommandObjectBreakpointDelete (interpreter));
Greg Claytona7015092010-09-18 01:14:36 +00002368 CommandObjectSP set_command_object (new CommandObjectBreakpointSet (interpreter));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002369 CommandObjectSP command_command_object (new CommandObjectBreakpointCommand (interpreter));
Greg Claytona7015092010-09-18 01:14:36 +00002370 CommandObjectSP modify_command_object (new CommandObjectBreakpointModify(interpreter));
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002371 CommandObjectSP name_command_object (new CommandObjectBreakpointName(interpreter));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002372
Johnny Chenb7234e42010-10-28 17:27:46 +00002373 list_command_object->SetCommandName ("breakpoint list");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002374 enable_command_object->SetCommandName("breakpoint enable");
2375 disable_command_object->SetCommandName("breakpoint disable");
Johnny Chenb7234e42010-10-28 17:27:46 +00002376 clear_command_object->SetCommandName("breakpoint clear");
2377 delete_command_object->SetCommandName("breakpoint delete");
Jim Inghamae1c4cf2010-06-18 00:58:52 +00002378 set_command_object->SetCommandName("breakpoint set");
Johnny Chenb7234e42010-10-28 17:27:46 +00002379 command_command_object->SetCommandName ("breakpoint command");
2380 modify_command_object->SetCommandName ("breakpoint modify");
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002381 name_command_object->SetCommandName ("breakpoint name");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002382
Greg Clayton23f59502012-07-17 03:23:13 +00002383 LoadSubCommand ("list", list_command_object);
2384 LoadSubCommand ("enable", enable_command_object);
2385 LoadSubCommand ("disable", disable_command_object);
2386 LoadSubCommand ("clear", clear_command_object);
2387 LoadSubCommand ("delete", delete_command_object);
2388 LoadSubCommand ("set", set_command_object);
2389 LoadSubCommand ("command", command_command_object);
2390 LoadSubCommand ("modify", modify_command_object);
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002391 LoadSubCommand ("name", name_command_object);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002392}
2393
2394CommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint ()
2395{
2396}
2397
2398void
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002399CommandObjectMultiwordBreakpoint::VerifyIDs (Args &args,
2400 Target *target,
2401 bool allow_locations,
2402 CommandReturnObject &result,
2403 BreakpointIDList *valid_ids)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002404{
2405 // args can be strings representing 1). integers (for breakpoint ids)
2406 // 2). the full breakpoint & location canonical representation
2407 // 3). the word "to" or a hyphen, representing a range (in which case there
2408 // had *better* be an entry both before & after of one of the first two types.
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002409 // 4). A breakpoint name
Jim Ingham36f3b362010-10-14 23:45:03 +00002410 // If args is empty, we will use the last created breakpoint (if there is one.)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002411
2412 Args temp_args;
2413
Jim Ingham36f3b362010-10-14 23:45:03 +00002414 if (args.GetArgumentCount() == 0)
2415 {
Greg Clayton4d122c42011-09-17 08:33:22 +00002416 if (target->GetLastCreatedBreakpoint())
Jim Ingham36f3b362010-10-14 23:45:03 +00002417 {
2418 valid_ids->AddBreakpointID (BreakpointID(target->GetLastCreatedBreakpoint()->GetID(), LLDB_INVALID_BREAK_ID));
2419 result.SetStatus (eReturnStatusSuccessFinishNoResult);
2420 }
2421 else
2422 {
2423 result.AppendError("No breakpoint specified and no last created breakpoint.");
2424 result.SetStatus (eReturnStatusFailed);
2425 }
2426 return;
2427 }
2428
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002429 // Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff directly from the old ARGS to
2430 // the new TEMP_ARGS. Do not copy breakpoint id range strings over; instead generate a list of strings for
2431 // all the breakpoint ids in the range, and shove all of those breakpoint id strings into TEMP_ARGS.
2432
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002433 BreakpointIDList::FindAndReplaceIDRanges (args, target, allow_locations, result, temp_args);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002434
2435 // NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual BreakpointIDList:
2436
Greg Claytonc982c762010-07-09 20:39:50 +00002437 valid_ids->InsertStringArray (temp_args.GetConstArgumentVector(), temp_args.GetArgumentCount(), result);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002438
2439 // At this point, all of the breakpoint ids that the user passed in have been converted to breakpoint IDs
2440 // and put into valid_ids.
2441
2442 if (result.Succeeded())
2443 {
2444 // Now that we've converted everything from args into a list of breakpoint ids, go through our tentative list
2445 // of breakpoint id's and verify that they correspond to valid/currently set breakpoints.
2446
Greg Claytonc982c762010-07-09 20:39:50 +00002447 const size_t count = valid_ids->GetSize();
2448 for (size_t i = 0; i < count; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002449 {
2450 BreakpointID cur_bp_id = valid_ids->GetBreakpointIDAtIndex (i);
2451 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
2452 if (breakpoint != NULL)
2453 {
Greg Claytonc7bece562013-01-25 18:06:21 +00002454 const size_t num_locations = breakpoint->GetNumLocations();
Saleem Abdulrasool3985c8c2014-04-02 03:51:35 +00002455 if (static_cast<size_t>(cur_bp_id.GetLocationID()) > num_locations)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002456 {
2457 StreamString id_str;
Greg Claytonc982c762010-07-09 20:39:50 +00002458 BreakpointID::GetCanonicalReference (&id_str,
2459 cur_bp_id.GetBreakpointID(),
2460 cur_bp_id.GetLocationID());
2461 i = valid_ids->GetSize() + 1;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002462 result.AppendErrorWithFormat ("'%s' is not a currently valid breakpoint/location id.\n",
2463 id_str.GetData());
2464 result.SetStatus (eReturnStatusFailed);
2465 }
2466 }
2467 else
2468 {
Greg Claytonc982c762010-07-09 20:39:50 +00002469 i = valid_ids->GetSize() + 1;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002470 result.AppendErrorWithFormat ("'%d' is not a currently valid breakpoint id.\n", cur_bp_id.GetBreakpointID());
2471 result.SetStatus (eReturnStatusFailed);
2472 }
2473 }
2474 }
2475}