blob: 0741cd17feca1cc29d46de17db65847dcb088717 [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 Ingham5a988412012-06-08 21:56:10 +0000115 m_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),
118 m_all_files (false)
Jim Ingham5a988412012-06-08 21:56:10 +0000119 {
120 }
121
122
123 virtual
124 ~CommandOptions () {}
125
126 virtual Error
127 SetOptionValue (uint32_t option_idx, const char *option_arg)
128 {
129 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000130 const int short_option = m_getopt_table[option_idx].val;
Jim Ingham5a988412012-06-08 21:56:10 +0000131
132 switch (short_option)
133 {
134 case 'a':
Greg Claytonb9d5df52012-12-06 22:49:16 +0000135 {
136 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
137 m_load_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
138 }
Jim Ingham5a988412012-06-08 21:56:10 +0000139 break;
140
Jim Inghame7320522015-02-12 17:37:46 +0000141 case 'A':
142 m_all_files = true;
143 break;
144
Jim Inghamca36cd12012-10-05 19:16:31 +0000145 case 'b':
146 m_func_names.push_back (option_arg);
147 m_func_name_type_mask |= eFunctionNameTypeBase;
148 break;
149
Jim Ingham5a988412012-06-08 21:56:10 +0000150 case 'C':
Jim Ingham63129912015-03-16 22:47:38 +0000151 {
152 bool success;
153 m_column = StringConvert::ToUInt32 (option_arg, 0, 0, &success);
154 if (!success)
155 error.SetErrorStringWithFormat("invalid column number: %s", option_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000156 break;
Jim Ingham63129912015-03-16 22:47:38 +0000157 }
Jim Ingham5a988412012-06-08 21:56:10 +0000158 case 'c':
159 m_condition.assign(option_arg);
160 break;
161
Jim Ingham33df7cd2014-12-06 01:28:03 +0000162 case 'D':
163 m_use_dummy = true;
164 break;
165
Jim Ingham5a988412012-06-08 21:56:10 +0000166 case 'E':
167 {
168 LanguageType language = LanguageRuntime::GetLanguageTypeFromString (option_arg);
169
170 switch (language)
171 {
172 case eLanguageTypeC89:
173 case eLanguageTypeC:
174 case eLanguageTypeC99:
Bruce Mitchener1d0089f2014-07-03 00:49:08 +0000175 case eLanguageTypeC11:
Jim Ingham5a988412012-06-08 21:56:10 +0000176 m_language = eLanguageTypeC;
177 break;
178 case eLanguageTypeC_plus_plus:
Bruce Mitchener1d0089f2014-07-03 00:49:08 +0000179 case eLanguageTypeC_plus_plus_03:
180 case eLanguageTypeC_plus_plus_11:
Bruce Mitchener2ba84a62015-02-06 06:46:52 +0000181 case eLanguageTypeC_plus_plus_14:
Jim Ingham5a988412012-06-08 21:56:10 +0000182 m_language = eLanguageTypeC_plus_plus;
183 break;
184 case eLanguageTypeObjC:
185 m_language = eLanguageTypeObjC;
186 break;
187 case eLanguageTypeObjC_plus_plus:
188 error.SetErrorStringWithFormat ("Set exception breakpoints separately for c++ and objective-c");
189 break;
190 case eLanguageTypeUnknown:
191 error.SetErrorStringWithFormat ("Unknown language type: '%s' for exception breakpoint", option_arg);
192 break;
193 default:
194 error.SetErrorStringWithFormat ("Unsupported language type: '%s' for exception breakpoint", option_arg);
195 }
196 }
197 break;
Jim Inghamca36cd12012-10-05 19:16:31 +0000198
199 case 'f':
200 m_filenames.AppendIfUnique (FileSpec(option_arg, false));
201 break;
202
203 case 'F':
204 m_func_names.push_back (option_arg);
205 m_func_name_type_mask |= eFunctionNameTypeFull;
206 break;
207
Jim Ingham5a988412012-06-08 21:56:10 +0000208 case 'h':
Greg Claytoneb023e72013-10-11 19:48:25 +0000209 {
210 bool success;
211 m_catch_bp = Args::StringToBoolean (option_arg, true, &success);
212 if (!success)
213 error.SetErrorStringWithFormat ("Invalid boolean value for on-catch option: '%s'", option_arg);
214 }
215 break;
216
217 case 'H':
218 m_hardware = true;
219 break;
220
Jim Inghamca36cd12012-10-05 19:16:31 +0000221 case 'i':
222 {
Vince Harron5275aaa2015-01-15 20:08:35 +0000223 m_ignore_count = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
Jim Inghamca36cd12012-10-05 19:16:31 +0000224 if (m_ignore_count == UINT32_MAX)
225 error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
226 break;
227 }
228
Jim Ingham5a988412012-06-08 21:56:10 +0000229 case 'K':
230 {
231 bool success;
232 bool value;
233 value = Args::StringToBoolean (option_arg, true, &success);
234 if (value)
235 m_skip_prologue = eLazyBoolYes;
236 else
237 m_skip_prologue = eLazyBoolNo;
238
239 if (!success)
240 error.SetErrorStringWithFormat ("Invalid boolean value for skip prologue option: '%s'", option_arg);
241 }
242 break;
Jim Inghamca36cd12012-10-05 19:16:31 +0000243
244 case 'l':
Jim Ingham63129912015-03-16 22:47:38 +0000245 {
246 bool success;
247 m_line_num = StringConvert::ToUInt32 (option_arg, 0, 0, &success);
248 if (!success)
249 error.SetErrorStringWithFormat ("invalid line number: %s.", option_arg);
Jim Inghamca36cd12012-10-05 19:16:31 +0000250 break;
Jim Ingham63129912015-03-16 22:47:38 +0000251 }
Jim Inghamca36cd12012-10-05 19:16:31 +0000252 case 'M':
253 m_func_names.push_back (option_arg);
254 m_func_name_type_mask |= eFunctionNameTypeMethod;
255 break;
256
257 case 'n':
258 m_func_names.push_back (option_arg);
259 m_func_name_type_mask |= eFunctionNameTypeAuto;
260 break;
261
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000262 case 'N':
263 if (BreakpointID::StringIsBreakpointName(option_arg, error))
264 m_breakpoint_names.push_back (option_arg);
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000265 break;
266
Jim Inghamca36cd12012-10-05 19:16:31 +0000267 case 'o':
268 m_one_shot = true;
269 break;
270
271 case 'p':
272 m_source_text_regexp.assign (option_arg);
273 break;
274
275 case 'q':
276 m_queue_name.assign (option_arg);
277 break;
278
279 case 'r':
280 m_func_regexp.assign (option_arg);
281 break;
282
283 case 's':
284 {
285 m_modules.AppendIfUnique (FileSpec (option_arg, false));
286 break;
287 }
288
289 case 'S':
290 m_func_names.push_back (option_arg);
291 m_func_name_type_mask |= eFunctionNameTypeSelector;
292 break;
293
294 case 't' :
295 {
Vince Harron5275aaa2015-01-15 20:08:35 +0000296 m_thread_id = StringConvert::ToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
Jim Inghamca36cd12012-10-05 19:16:31 +0000297 if (m_thread_id == LLDB_INVALID_THREAD_ID)
298 error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
299 }
300 break;
301
302 case 'T':
303 m_thread_name.assign (option_arg);
304 break;
305
306 case 'w':
307 {
308 bool success;
309 m_throw_bp = Args::StringToBoolean (option_arg, true, &success);
310 if (!success)
311 error.SetErrorStringWithFormat ("Invalid boolean value for on-throw option: '%s'", option_arg);
312 }
313 break;
314
315 case 'x':
316 {
Vince Harron5275aaa2015-01-15 20:08:35 +0000317 m_thread_index = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
Jim Inghamca36cd12012-10-05 19:16:31 +0000318 if (m_thread_id == UINT32_MAX)
319 error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
320
321 }
322 break;
323
Jim Ingham5a988412012-06-08 21:56:10 +0000324 default:
325 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
326 break;
327 }
328
329 return error;
330 }
331 void
332 OptionParsingStarting ()
333 {
334 m_condition.clear();
335 m_filenames.Clear();
336 m_line_num = 0;
337 m_column = 0;
338 m_func_names.clear();
Greg Clayton1f746072012-08-29 21:13:06 +0000339 m_func_name_type_mask = eFunctionNameTypeNone;
Jim Ingham5a988412012-06-08 21:56:10 +0000340 m_func_regexp.clear();
Greg Clayton1f746072012-08-29 21:13:06 +0000341 m_source_text_regexp.clear();
Jim Ingham5a988412012-06-08 21:56:10 +0000342 m_modules.Clear();
Greg Clayton1f746072012-08-29 21:13:06 +0000343 m_load_addr = LLDB_INVALID_ADDRESS;
Jim Ingham5a988412012-06-08 21:56:10 +0000344 m_ignore_count = 0;
345 m_thread_id = LLDB_INVALID_THREAD_ID;
346 m_thread_index = UINT32_MAX;
347 m_thread_name.clear();
348 m_queue_name.clear();
Jim Ingham5a988412012-06-08 21:56:10 +0000349 m_catch_bp = false;
350 m_throw_bp = true;
Greg Claytoneb023e72013-10-11 19:48:25 +0000351 m_hardware = false;
Greg Clayton1f746072012-08-29 21:13:06 +0000352 m_language = eLanguageTypeUnknown;
Jim Ingham5a988412012-06-08 21:56:10 +0000353 m_skip_prologue = eLazyBoolCalculate;
Jim Inghamca36cd12012-10-05 19:16:31 +0000354 m_one_shot = false;
Jim Ingham33df7cd2014-12-06 01:28:03 +0000355 m_use_dummy = false;
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000356 m_breakpoint_names.clear();
Jim Inghame7320522015-02-12 17:37:46 +0000357 m_all_files = false;
Jim Ingham5a988412012-06-08 21:56:10 +0000358 }
359
360 const OptionDefinition*
361 GetDefinitions ()
362 {
363 return g_option_table;
364 }
365
366 // Options table: Required for subclasses of Options.
367
368 static OptionDefinition g_option_table[];
369
370 // Instance variables to hold the values for command options.
371
372 std::string m_condition;
373 FileSpecList m_filenames;
374 uint32_t m_line_num;
375 uint32_t m_column;
Jim Ingham5a988412012-06-08 21:56:10 +0000376 std::vector<std::string> m_func_names;
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000377 std::vector<std::string> m_breakpoint_names;
Jim Ingham5a988412012-06-08 21:56:10 +0000378 uint32_t m_func_name_type_mask;
379 std::string m_func_regexp;
380 std::string m_source_text_regexp;
381 FileSpecList m_modules;
382 lldb::addr_t m_load_addr;
383 uint32_t m_ignore_count;
384 lldb::tid_t m_thread_id;
385 uint32_t m_thread_index;
386 std::string m_thread_name;
387 std::string m_queue_name;
388 bool m_catch_bp;
389 bool m_throw_bp;
Greg Claytoneb023e72013-10-11 19:48:25 +0000390 bool m_hardware; // Request to use hardware breakpoints
Jim Ingham5a988412012-06-08 21:56:10 +0000391 lldb::LanguageType m_language;
392 LazyBool m_skip_prologue;
Jim Inghamca36cd12012-10-05 19:16:31 +0000393 bool m_one_shot;
Jim Ingham33df7cd2014-12-06 01:28:03 +0000394 bool m_use_dummy;
Jim Inghame7320522015-02-12 17:37:46 +0000395 bool m_all_files;
Jim Ingham5a988412012-06-08 21:56:10 +0000396
397 };
398
399protected:
400 virtual bool
401 DoExecute (Args& command,
Jim Ingham33df7cd2014-12-06 01:28:03 +0000402 CommandReturnObject &result)
Jim Ingham5a988412012-06-08 21:56:10 +0000403 {
Jim Ingham33df7cd2014-12-06 01:28:03 +0000404 Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
405
Jim Ingham893c9322014-11-22 01:42:44 +0000406 if (target == nullptr)
Jim Ingham5a988412012-06-08 21:56:10 +0000407 {
408 result.AppendError ("Invalid target. Must set target before setting breakpoints (see 'target create' command).");
409 result.SetStatus (eReturnStatusFailed);
410 return false;
411 }
412
413 // The following are the various types of breakpoints that could be set:
414 // 1). -f -l -p [-s -g] (setting breakpoint by source location)
415 // 2). -a [-s -g] (setting breakpoint by address)
416 // 3). -n [-s -g] (setting breakpoint by function name)
417 // 4). -r [-s -g] (setting breakpoint by function name regular expression)
418 // 5). -p -f (setting a breakpoint by comparing a reg-exp to source text)
419 // 6). -E [-w -h] (setting a breakpoint for exceptions for a given language.)
420
421 BreakpointSetType break_type = eSetTypeInvalid;
422
423 if (m_options.m_line_num != 0)
424 break_type = eSetTypeFileAndLine;
425 else if (m_options.m_load_addr != LLDB_INVALID_ADDRESS)
426 break_type = eSetTypeAddress;
427 else if (!m_options.m_func_names.empty())
428 break_type = eSetTypeFunctionName;
429 else if (!m_options.m_func_regexp.empty())
430 break_type = eSetTypeFunctionRegexp;
431 else if (!m_options.m_source_text_regexp.empty())
432 break_type = eSetTypeSourceRegexp;
433 else if (m_options.m_language != eLanguageTypeUnknown)
434 break_type = eSetTypeException;
435
436 Breakpoint *bp = NULL;
437 FileSpec module_spec;
Jim Ingham5a988412012-06-08 21:56:10 +0000438 const bool internal = false;
439
Jim Ingham5a988412012-06-08 21:56:10 +0000440 switch (break_type)
441 {
442 case eSetTypeFileAndLine: // Breakpoint by source position
443 {
444 FileSpec file;
Greg Claytonc7bece562013-01-25 18:06:21 +0000445 const size_t num_files = m_options.m_filenames.GetSize();
Jim Ingham5a988412012-06-08 21:56:10 +0000446 if (num_files == 0)
447 {
448 if (!GetDefaultFile (target, file, result))
449 {
450 result.AppendError("No file supplied and no default file available.");
451 result.SetStatus (eReturnStatusFailed);
452 return false;
453 }
454 }
455 else if (num_files > 1)
456 {
457 result.AppendError("Only one file at a time is allowed for file and line breakpoints.");
458 result.SetStatus (eReturnStatusFailed);
459 return false;
460 }
461 else
462 file = m_options.m_filenames.GetFileSpecAtIndex(0);
Greg Clayton1f746072012-08-29 21:13:06 +0000463
464 // Only check for inline functions if
465 LazyBool check_inlines = eLazyBoolCalculate;
466
Jim Ingham5a988412012-06-08 21:56:10 +0000467 bp = target->CreateBreakpoint (&(m_options.m_modules),
468 file,
469 m_options.m_line_num,
Greg Clayton1f746072012-08-29 21:13:06 +0000470 check_inlines,
Jim Ingham5a988412012-06-08 21:56:10 +0000471 m_options.m_skip_prologue,
Greg Claytoneb023e72013-10-11 19:48:25 +0000472 internal,
473 m_options.m_hardware).get();
Jim Ingham5a988412012-06-08 21:56:10 +0000474 }
475 break;
476
477 case eSetTypeAddress: // Breakpoint by address
Greg Claytoneb023e72013-10-11 19:48:25 +0000478 bp = target->CreateBreakpoint (m_options.m_load_addr,
479 internal,
480 m_options.m_hardware).get();
Jim Ingham5a988412012-06-08 21:56:10 +0000481 break;
482
483 case eSetTypeFunctionName: // Breakpoint by function name
484 {
485 uint32_t name_type_mask = m_options.m_func_name_type_mask;
486
487 if (name_type_mask == 0)
488 name_type_mask = eFunctionNameTypeAuto;
489
490 bp = target->CreateBreakpoint (&(m_options.m_modules),
491 &(m_options.m_filenames),
492 m_options.m_func_names,
493 name_type_mask,
494 m_options.m_skip_prologue,
Greg Claytoneb023e72013-10-11 19:48:25 +0000495 internal,
496 m_options.m_hardware).get();
Jim Ingham5a988412012-06-08 21:56:10 +0000497 }
498 break;
499
500 case eSetTypeFunctionRegexp: // Breakpoint by regular expression function name
501 {
502 RegularExpression regexp(m_options.m_func_regexp.c_str());
503 if (!regexp.IsValid())
504 {
505 char err_str[1024];
506 regexp.GetErrorAsCString(err_str, sizeof(err_str));
507 result.AppendErrorWithFormat("Function name regular expression could not be compiled: \"%s\"",
508 err_str);
509 result.SetStatus (eReturnStatusFailed);
510 return false;
511 }
512
513 bp = target->CreateFuncRegexBreakpoint (&(m_options.m_modules),
514 &(m_options.m_filenames),
515 regexp,
516 m_options.m_skip_prologue,
Greg Claytoneb023e72013-10-11 19:48:25 +0000517 internal,
518 m_options.m_hardware).get();
Jim Ingham5a988412012-06-08 21:56:10 +0000519 }
520 break;
521 case eSetTypeSourceRegexp: // Breakpoint by regexp on source text.
522 {
Greg Claytonc7bece562013-01-25 18:06:21 +0000523 const size_t num_files = m_options.m_filenames.GetSize();
Jim Ingham5a988412012-06-08 21:56:10 +0000524
Jim Inghame7320522015-02-12 17:37:46 +0000525 if (num_files == 0 && !m_options.m_all_files)
Jim Ingham5a988412012-06-08 21:56:10 +0000526 {
527 FileSpec file;
528 if (!GetDefaultFile (target, file, result))
529 {
530 result.AppendError ("No files provided and could not find default file.");
531 result.SetStatus (eReturnStatusFailed);
532 return false;
533 }
534 else
535 {
536 m_options.m_filenames.Append (file);
537 }
538 }
539
540 RegularExpression regexp(m_options.m_source_text_regexp.c_str());
541 if (!regexp.IsValid())
542 {
543 char err_str[1024];
544 regexp.GetErrorAsCString(err_str, sizeof(err_str));
545 result.AppendErrorWithFormat("Source text regular expression could not be compiled: \"%s\"",
546 err_str);
547 result.SetStatus (eReturnStatusFailed);
548 return false;
549 }
Greg Claytoneb023e72013-10-11 19:48:25 +0000550 bp = target->CreateSourceRegexBreakpoint (&(m_options.m_modules),
551 &(m_options.m_filenames),
552 regexp,
553 internal,
554 m_options.m_hardware).get();
Jim Ingham5a988412012-06-08 21:56:10 +0000555 }
556 break;
557 case eSetTypeException:
558 {
Greg Claytoneb023e72013-10-11 19:48:25 +0000559 bp = target->CreateExceptionBreakpoint (m_options.m_language,
560 m_options.m_catch_bp,
561 m_options.m_throw_bp,
562 m_options.m_hardware).get();
Jim Ingham5a988412012-06-08 21:56:10 +0000563 }
564 break;
565 default:
566 break;
567 }
568
569 // Now set the various options that were passed in:
570 if (bp)
571 {
572 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
573 bp->SetThreadID (m_options.m_thread_id);
574
575 if (m_options.m_thread_index != UINT32_MAX)
576 bp->GetOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index);
577
578 if (!m_options.m_thread_name.empty())
579 bp->GetOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str());
580
581 if (!m_options.m_queue_name.empty())
582 bp->GetOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str());
583
584 if (m_options.m_ignore_count != 0)
585 bp->GetOptions()->SetIgnoreCount(m_options.m_ignore_count);
586
587 if (!m_options.m_condition.empty())
588 bp->GetOptions()->SetCondition(m_options.m_condition.c_str());
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000589
590 if (!m_options.m_breakpoint_names.empty())
591 {
592 Error error; // We don't need to check the error here, since the option parser checked it...
593 for (auto name : m_options.m_breakpoint_names)
594 bp->AddName(name.c_str(), error);
595 }
Jim Inghamca36cd12012-10-05 19:16:31 +0000596
597 bp->SetOneShot (m_options.m_one_shot);
Jim Ingham5a988412012-06-08 21:56:10 +0000598 }
599
600 if (bp)
601 {
602 Stream &output_stream = result.GetOutputStream();
Jim Ingham1391cc72012-09-22 00:04:04 +0000603 const bool show_locations = false;
604 bp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial, show_locations);
Jim Ingham4aeb1982014-12-19 19:45:31 +0000605 if (target == m_interpreter.GetDebugger().GetDummyTarget())
606 output_stream.Printf ("Breakpoint set in dummy target, will get copied into future targets.\n");
607 else
608 {
609 // Don't print out this warning for exception breakpoints. They can get set before the target
610 // is set, but we won't know how to actually set the breakpoint till we run.
611 if (bp->GetNumLocations() == 0 && break_type != eSetTypeException)
612 {
613 output_stream.Printf ("WARNING: Unable to resolve breakpoint to any actual locations.\n");
614 }
615 }
Jim Ingham5a988412012-06-08 21:56:10 +0000616 result.SetStatus (eReturnStatusSuccessFinishResult);
617 }
618 else if (!bp)
619 {
620 result.AppendError ("Breakpoint creation failed: No breakpoint created.");
621 result.SetStatus (eReturnStatusFailed);
622 }
623
624 return result.Succeeded();
625 }
626
627private:
628 bool
629 GetDefaultFile (Target *target, FileSpec &file, CommandReturnObject &result)
630 {
631 uint32_t default_line;
632 // First use the Source Manager's default file.
633 // Then use the current stack frame's file.
634 if (!target->GetSourceManager().GetDefaultFileAndLine(file, default_line))
635 {
Jason Molendab57e4a12013-11-04 09:33:30 +0000636 StackFrame *cur_frame = m_exe_ctx.GetFramePtr();
Jim Ingham5a988412012-06-08 21:56:10 +0000637 if (cur_frame == NULL)
638 {
639 result.AppendError ("No selected frame to use to find the default file.");
640 result.SetStatus (eReturnStatusFailed);
641 return false;
642 }
643 else if (!cur_frame->HasDebugInformation())
644 {
645 result.AppendError ("Cannot use the selected frame to find the default file, it has no debug info.");
646 result.SetStatus (eReturnStatusFailed);
647 return false;
648 }
649 else
650 {
651 const SymbolContext &sc = cur_frame->GetSymbolContext (eSymbolContextLineEntry);
652 if (sc.line_entry.file)
653 {
654 file = sc.line_entry.file;
655 }
656 else
657 {
658 result.AppendError ("Can't find the file for the selected frame to use as the default file.");
659 result.SetStatus (eReturnStatusFailed);
660 return false;
661 }
662 }
663 }
664 return true;
665 }
666
667 CommandOptions m_options;
668};
Johnny Chen6943e7c2012-05-08 00:43:20 +0000669// If an additional option set beyond LLDB_OPTION_SET_10 is added, make sure to
670// update the numbers passed to LLDB_OPT_SET_FROM_TO(...) appropriately.
Johnny Chen4ab2e6b2012-05-07 23:23:41 +0000671#define LLDB_OPT_FILE ( LLDB_OPT_SET_FROM_TO(1, 9) & ~LLDB_OPT_SET_2 )
672#define LLDB_OPT_NOT_10 ( LLDB_OPT_SET_FROM_TO(1, 10) & ~LLDB_OPT_SET_10 )
Jim Inghama8558b62012-05-22 00:12:20 +0000673#define LLDB_OPT_SKIP_PROLOGUE ( LLDB_OPT_SET_1 | LLDB_OPT_SET_FROM_TO(3,8) )
Jim Ingham87df91b2011-09-23 00:54:11 +0000674
Greg Claytone0d378b2011-03-24 21:19:54 +0000675OptionDefinition
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000676CommandObjectBreakpointSet::CommandOptions::g_option_table[] =
677{
Zachary Turnerd37221d2014-07-09 16:31:49 +0000678 { LLDB_OPT_NOT_10, false, "shlib", 's', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName,
Jim Ingham64cc29c2012-05-03 20:30:08 +0000679 "Set the breakpoint only in this shared library. "
680 "Can repeat this option multiple times to specify multiple shared libraries."},
Jim Ingham86511212010-06-15 18:47:14 +0000681
Zachary Turnerd37221d2014-07-09 16:31:49 +0000682 { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeCount,
Caroline Ticedeaab222010-10-01 19:59:14 +0000683 "Set the number of times this breakpoint is skipped before stopping." },
Jim Ingham1b54c882010-06-16 02:00:15 +0000684
Zachary Turnerd37221d2014-07-09 16:31:49 +0000685 { LLDB_OPT_SET_ALL, false, "one-shot", 'o', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
Jim Inghamb2b256a2013-04-09 18:05:22 +0000686 "The breakpoint is deleted the first time it causes a stop." },
Jim Inghamca36cd12012-10-05 19:16:31 +0000687
Zachary Turnerd37221d2014-07-09 16:31:49 +0000688 { LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeExpression,
Johnny Chen7d49c9c2012-05-25 21:10:46 +0000689 "The breakpoint stops only if this condition expression evaluates to true."},
690
Zachary Turnerd37221d2014-07-09 16:31:49 +0000691 { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadIndex,
Jim Inghama89be912013-03-26 18:29:03 +0000692 "The breakpoint stops only for the thread whose indeX matches this argument."},
Jim Ingham1b54c882010-06-16 02:00:15 +0000693
Zachary Turnerd37221d2014-07-09 16:31:49 +0000694 { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadID,
Jim Ingham1b54c882010-06-16 02:00:15 +0000695 "The breakpoint stops only for the thread whose TID matches this argument."},
696
Zachary Turnerd37221d2014-07-09 16:31:49 +0000697 { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadName,
Jim Ingham1b54c882010-06-16 02:00:15 +0000698 "The breakpoint stops only for the thread whose thread name matches this argument."},
699
Zachary Turnerd37221d2014-07-09 16:31:49 +0000700 { LLDB_OPT_SET_ALL, false, "hardware", 'H', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
Greg Claytoneb023e72013-10-11 19:48:25 +0000701 "Require the breakpoint to use hardware breakpoints."},
702
Zachary Turnerd37221d2014-07-09 16:31:49 +0000703 { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeQueueName,
Jim Ingham1b54c882010-06-16 02:00:15 +0000704 "The breakpoint stops only for threads in the queue whose name is given by this argument."},
705
Zachary Turnerd37221d2014-07-09 16:31:49 +0000706 { LLDB_OPT_FILE, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
Jim Ingham289aca62013-02-14 19:10:36 +0000707 "Specifies the source file in which to set this breakpoint. "
708 "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 +0000709 "To set breakpoints on .c/.cpp/.m/.mm files that are #included, set target.inline-breakpoint-strategy"
Jim Ingham289aca62013-02-14 19:10:36 +0000710 " to \"always\"."},
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000711
Zachary Turnerd37221d2014-07-09 16:31:49 +0000712 { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum,
Jim Ingham87df91b2011-09-23 00:54:11 +0000713 "Specifies the line number on which to set this breakpoint."},
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000714
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000715 // Comment out this option for the moment, as we don't actually use it, but will in the future.
716 // This way users won't see it, but the infrastructure is left in place.
Virgile Belloe2607b52013-09-05 16:42:23 +0000717 // { 0, false, "column", 'C', OptionParser::eRequiredArgument, NULL, "<column>",
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000718 // "Set the breakpoint by source location at this particular column."},
719
Zachary Turnerd37221d2014-07-09 16:31:49 +0000720 { LLDB_OPT_SET_2, true, "address", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000721 "Set the breakpoint by address, at the specified address."},
722
Zachary Turnerd37221d2014-07-09 16:31:49 +0000723 { LLDB_OPT_SET_3, true, "name", 'n', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
Jim Ingham551262d2013-03-27 17:36:54 +0000724 "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 +0000725
Zachary Turnerd37221d2014-07-09 16:31:49 +0000726 { LLDB_OPT_SET_4, true, "fullname", 'F', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFullName,
Jim Ingham64cc29c2012-05-03 20:30:08 +0000727 "Set the breakpoint by fully qualified function names. For C++ this means namespaces and all arguments, and "
728 "for Objective C this means a full function prototype with class and selector. "
729 "Can be repeated multiple times to make one breakpoint for multiple names." },
Greg Clayton0c5cd902010-06-28 21:30:43 +0000730
Zachary Turnerd37221d2014-07-09 16:31:49 +0000731 { LLDB_OPT_SET_5, true, "selector", 'S', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeSelector,
Jim Ingham64cc29c2012-05-03 20:30:08 +0000732 "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 +0000733
Zachary Turnerd37221d2014-07-09 16:31:49 +0000734 { LLDB_OPT_SET_6, true, "method", 'M', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeMethod,
Jim Ingham64cc29c2012-05-03 20:30:08 +0000735 "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 +0000736
Zachary Turnerd37221d2014-07-09 16:31:49 +0000737 { LLDB_OPT_SET_7, true, "func-regex", 'r', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeRegularExpression,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000738 "Set the breakpoint by function name, evaluating a regular-expression to find the function name(s)." },
739
Zachary Turnerd37221d2014-07-09 16:31:49 +0000740 { LLDB_OPT_SET_8, true, "basename", 'b', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
Jim Ingham64cc29c2012-05-03 20:30:08 +0000741 "Set the breakpoint by function basename (C++ namespaces and arguments will be ignored). "
742 "Can be repeated multiple times to make one breakpoint for multiple symbols." },
Greg Claytone02b8502010-10-12 04:29:14 +0000743
Zachary Turnerd37221d2014-07-09 16:31:49 +0000744 { LLDB_OPT_SET_9, true, "source-pattern-regexp", 'p', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeRegularExpression,
Jim Inghame96ade82013-06-07 01:13:00 +0000745 "Set the breakpoint by specifying a regular expression which is matched against the source text in a source file or files "
746 "specified with the -f option. The -f option can be specified more than once. "
747 "If no source files are specified, uses the current \"default source file\"" },
Jim Ingham969795f2011-09-21 01:17:13 +0000748
Jim Inghame7320522015-02-12 17:37:46 +0000749 { LLDB_OPT_SET_9, false, "all-files", 'A', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
750 "All files are searched for source pattern matches." },
751
Zachary Turnerd37221d2014-07-09 16:31:49 +0000752 { LLDB_OPT_SET_10, true, "language-exception", 'E', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage,
Jim Inghamfab10e82012-03-06 00:37:27 +0000753 "Set the breakpoint on exceptions thrown by the specified language (without options, on throw but not catch.)" },
754
Zachary Turnerd37221d2014-07-09 16:31:49 +0000755 { LLDB_OPT_SET_10, false, "on-throw", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,
Jim Inghamfab10e82012-03-06 00:37:27 +0000756 "Set the breakpoint on exception throW." },
757
Zachary Turnerd37221d2014-07-09 16:31:49 +0000758 { LLDB_OPT_SET_10, false, "on-catch", 'h', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,
Jim Inghamfab10e82012-03-06 00:37:27 +0000759 "Set the breakpoint on exception catcH." },
Jim Ingham969795f2011-09-21 01:17:13 +0000760
Zachary Turnerd37221d2014-07-09 16:31:49 +0000761 { LLDB_OPT_SKIP_PROLOGUE, false, "skip-prologue", 'K', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,
Jim Inghama8558b62012-05-22 00:12:20 +0000762 "sKip the prologue if the breakpoint is at the beginning of a function. If not set the target.skip-prologue setting is used." },
763
Jim Ingham33df7cd2014-12-06 01:28:03 +0000764 { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
765 "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
766
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000767 { LLDB_OPT_SET_ALL, false, "breakpoint-name", 'N', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBreakpointName,
768 "Adds this to the list of names for this breakopint."},
769
Zachary Turnerd37221d2014-07-09 16:31:49 +0000770 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000771};
772
Jim Ingham5a988412012-06-08 21:56:10 +0000773//-------------------------------------------------------------------------
774// CommandObjectBreakpointModify
775//-------------------------------------------------------------------------
776#pragma mark Modify
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000777
Jim Ingham5a988412012-06-08 21:56:10 +0000778class CommandObjectBreakpointModify : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000779{
Jim Ingham5a988412012-06-08 21:56:10 +0000780public:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000781
Jim Ingham5a988412012-06-08 21:56:10 +0000782 CommandObjectBreakpointModify (CommandInterpreter &interpreter) :
783 CommandObjectParsed (interpreter,
784 "breakpoint modify",
785 "Modify the options on a breakpoint or set of breakpoints in the executable. "
786 "If no breakpoint is specified, acts on the last created breakpoint. "
787 "With the exception of -e, -d and -i, passing an empty argument clears the modification.",
788 NULL),
789 m_options (interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000790 {
Jim Ingham5a988412012-06-08 21:56:10 +0000791 CommandArgumentEntry arg;
792 CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
793 // Add the entry for the first argument for this command to the object's arguments vector.
794 m_arguments.push_back (arg);
795 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000796
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000797
Jim Ingham5a988412012-06-08 21:56:10 +0000798 virtual
799 ~CommandObjectBreakpointModify () {}
Greg Clayton0c5cd902010-06-28 21:30:43 +0000800
Jim Ingham5a988412012-06-08 21:56:10 +0000801 virtual Options *
802 GetOptions ()
803 {
804 return &m_options;
805 }
Johnny Chen7d49c9c2012-05-25 21:10:46 +0000806
Jim Ingham5a988412012-06-08 21:56:10 +0000807 class CommandOptions : public Options
808 {
809 public:
Greg Clayton0c5cd902010-06-28 21:30:43 +0000810
Jim Ingham5a988412012-06-08 21:56:10 +0000811 CommandOptions (CommandInterpreter &interpreter) :
812 Options (interpreter),
813 m_ignore_count (0),
814 m_thread_id(LLDB_INVALID_THREAD_ID),
815 m_thread_id_passed(false),
816 m_thread_index (UINT32_MAX),
817 m_thread_index_passed(false),
818 m_thread_name(),
819 m_queue_name(),
820 m_condition (),
Jim Inghamca36cd12012-10-05 19:16:31 +0000821 m_one_shot (false),
Jim Ingham5a988412012-06-08 21:56:10 +0000822 m_enable_passed (false),
823 m_enable_value (false),
824 m_name_passed (false),
825 m_queue_passed (false),
Jim Inghamca36cd12012-10-05 19:16:31 +0000826 m_condition_passed (false),
Jim Ingham33df7cd2014-12-06 01:28:03 +0000827 m_one_shot_passed (false),
828 m_use_dummy (false)
Jim Ingham5a988412012-06-08 21:56:10 +0000829 {
830 }
Greg Clayton0c5cd902010-06-28 21:30:43 +0000831
Jim Ingham5a988412012-06-08 21:56:10 +0000832 virtual
833 ~CommandOptions () {}
Greg Clayton0c5cd902010-06-28 21:30:43 +0000834
Jim Ingham5a988412012-06-08 21:56:10 +0000835 virtual Error
836 SetOptionValue (uint32_t option_idx, const char *option_arg)
837 {
838 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000839 const int short_option = m_getopt_table[option_idx].val;
Greg Claytone02b8502010-10-12 04:29:14 +0000840
Jim Ingham5a988412012-06-08 21:56:10 +0000841 switch (short_option)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000842 {
Jim Ingham5a988412012-06-08 21:56:10 +0000843 case 'c':
844 if (option_arg != NULL)
845 m_condition.assign (option_arg);
846 else
847 m_condition.clear();
848 m_condition_passed = true;
849 break;
850 case 'd':
851 m_enable_passed = true;
852 m_enable_value = false;
853 break;
Jim Ingham33df7cd2014-12-06 01:28:03 +0000854 case 'D':
855 m_use_dummy = true;
856 break;
Jim Ingham5a988412012-06-08 21:56:10 +0000857 case 'e':
858 m_enable_passed = true;
859 m_enable_value = true;
860 break;
861 case 'i':
862 {
Vince Harron5275aaa2015-01-15 20:08:35 +0000863 m_ignore_count = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
Jim Ingham5a988412012-06-08 21:56:10 +0000864 if (m_ignore_count == UINT32_MAX)
865 error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
866 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000867 break;
Jim Inghamca36cd12012-10-05 19:16:31 +0000868 case 'o':
869 {
870 bool value, success;
871 value = Args::StringToBoolean(option_arg, false, &success);
872 if (success)
873 {
874 m_one_shot_passed = true;
875 m_one_shot = value;
876 }
877 else
878 error.SetErrorStringWithFormat("invalid boolean value '%s' passed for -o option", option_arg);
879 }
880 break;
Jim Ingham5a988412012-06-08 21:56:10 +0000881 case 't' :
Jim Ingham87df91b2011-09-23 00:54:11 +0000882 {
Jim Ingham5a988412012-06-08 21:56:10 +0000883 if (option_arg[0] == '\0')
Jim Ingham87df91b2011-09-23 00:54:11 +0000884 {
Jim Ingham5a988412012-06-08 21:56:10 +0000885 m_thread_id = LLDB_INVALID_THREAD_ID;
886 m_thread_id_passed = true;
Jim Ingham87df91b2011-09-23 00:54:11 +0000887 }
888 else
889 {
Vince Harron5275aaa2015-01-15 20:08:35 +0000890 m_thread_id = StringConvert::ToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
Jim Ingham5a988412012-06-08 21:56:10 +0000891 if (m_thread_id == LLDB_INVALID_THREAD_ID)
892 error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
893 else
894 m_thread_id_passed = true;
Jim Ingham87df91b2011-09-23 00:54:11 +0000895 }
896 }
Jim Ingham5a988412012-06-08 21:56:10 +0000897 break;
898 case 'T':
899 if (option_arg != NULL)
900 m_thread_name.assign (option_arg);
901 else
902 m_thread_name.clear();
903 m_name_passed = true;
904 break;
905 case 'q':
906 if (option_arg != NULL)
907 m_queue_name.assign (option_arg);
908 else
909 m_queue_name.clear();
910 m_queue_passed = true;
911 break;
912 case 'x':
Jim Ingham969795f2011-09-21 01:17:13 +0000913 {
Jim Ingham5a988412012-06-08 21:56:10 +0000914 if (option_arg[0] == '\n')
915 {
916 m_thread_index = UINT32_MAX;
917 m_thread_index_passed = true;
918 }
919 else
920 {
Vince Harron5275aaa2015-01-15 20:08:35 +0000921 m_thread_index = StringConvert::ToUInt32 (option_arg, UINT32_MAX, 0);
Jim Ingham5a988412012-06-08 21:56:10 +0000922 if (m_thread_id == UINT32_MAX)
923 error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
924 else
925 m_thread_index_passed = true;
926 }
Jim Ingham969795f2011-09-21 01:17:13 +0000927 }
Jim Ingham5a988412012-06-08 21:56:10 +0000928 break;
929 default:
930 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
931 break;
Jim Ingham969795f2011-09-21 01:17:13 +0000932 }
Jim Ingham5a988412012-06-08 21:56:10 +0000933
934 return error;
935 }
936 void
937 OptionParsingStarting ()
938 {
939 m_ignore_count = 0;
940 m_thread_id = LLDB_INVALID_THREAD_ID;
941 m_thread_id_passed = false;
942 m_thread_index = UINT32_MAX;
943 m_thread_index_passed = false;
944 m_thread_name.clear();
945 m_queue_name.clear();
946 m_condition.clear();
Jim Inghamca36cd12012-10-05 19:16:31 +0000947 m_one_shot = false;
Jim Ingham5a988412012-06-08 21:56:10 +0000948 m_enable_passed = false;
949 m_queue_passed = false;
950 m_name_passed = false;
951 m_condition_passed = false;
Jim Inghamca36cd12012-10-05 19:16:31 +0000952 m_one_shot_passed = false;
Jim Ingham33df7cd2014-12-06 01:28:03 +0000953 m_use_dummy = false;
Jim Ingham5a988412012-06-08 21:56:10 +0000954 }
955
956 const OptionDefinition*
957 GetDefinitions ()
958 {
959 return g_option_table;
960 }
961
962
963 // Options table: Required for subclasses of Options.
964
965 static OptionDefinition g_option_table[];
966
967 // Instance variables to hold the values for command options.
968
969 uint32_t m_ignore_count;
970 lldb::tid_t m_thread_id;
971 bool m_thread_id_passed;
972 uint32_t m_thread_index;
973 bool m_thread_index_passed;
974 std::string m_thread_name;
975 std::string m_queue_name;
976 std::string m_condition;
Jim Inghamca36cd12012-10-05 19:16:31 +0000977 bool m_one_shot;
Jim Ingham5a988412012-06-08 21:56:10 +0000978 bool m_enable_passed;
979 bool m_enable_value;
980 bool m_name_passed;
981 bool m_queue_passed;
982 bool m_condition_passed;
Jim Inghamca36cd12012-10-05 19:16:31 +0000983 bool m_one_shot_passed;
Jim Ingham33df7cd2014-12-06 01:28:03 +0000984 bool m_use_dummy;
Jim Ingham5a988412012-06-08 21:56:10 +0000985
986 };
987
988protected:
989 virtual bool
990 DoExecute (Args& command, CommandReturnObject &result)
991 {
Jim Ingham33df7cd2014-12-06 01:28:03 +0000992 Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
Jim Ingham5a988412012-06-08 21:56:10 +0000993 if (target == NULL)
994 {
995 result.AppendError ("Invalid target. No existing target or breakpoints.");
996 result.SetStatus (eReturnStatusFailed);
997 return false;
998 }
999
1000 Mutex::Locker locker;
1001 target->GetBreakpointList().GetListMutex(locker);
1002
1003 BreakpointIDList valid_bp_ids;
1004
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001005 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
Jim Ingham5a988412012-06-08 21:56:10 +00001006
1007 if (result.Succeeded())
1008 {
1009 const size_t count = valid_bp_ids.GetSize();
1010 for (size_t i = 0; i < count; ++i)
Jim Inghamfab10e82012-03-06 00:37:27 +00001011 {
Jim Ingham5a988412012-06-08 21:56:10 +00001012 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1013
1014 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
1015 {
1016 Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1017 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
1018 {
1019 BreakpointLocation *location = bp->FindLocationByID (cur_bp_id.GetLocationID()).get();
1020 if (location)
1021 {
1022 if (m_options.m_thread_id_passed)
1023 location->SetThreadID (m_options.m_thread_id);
1024
1025 if (m_options.m_thread_index_passed)
1026 location->SetThreadIndex(m_options.m_thread_index);
1027
1028 if (m_options.m_name_passed)
1029 location->SetThreadName(m_options.m_thread_name.c_str());
1030
1031 if (m_options.m_queue_passed)
1032 location->SetQueueName(m_options.m_queue_name.c_str());
1033
1034 if (m_options.m_ignore_count != 0)
1035 location->SetIgnoreCount(m_options.m_ignore_count);
1036
1037 if (m_options.m_enable_passed)
1038 location->SetEnabled (m_options.m_enable_value);
1039
1040 if (m_options.m_condition_passed)
1041 location->SetCondition (m_options.m_condition.c_str());
1042 }
1043 }
1044 else
1045 {
1046 if (m_options.m_thread_id_passed)
1047 bp->SetThreadID (m_options.m_thread_id);
1048
1049 if (m_options.m_thread_index_passed)
1050 bp->SetThreadIndex(m_options.m_thread_index);
1051
1052 if (m_options.m_name_passed)
1053 bp->SetThreadName(m_options.m_thread_name.c_str());
1054
1055 if (m_options.m_queue_passed)
1056 bp->SetQueueName(m_options.m_queue_name.c_str());
1057
1058 if (m_options.m_ignore_count != 0)
1059 bp->SetIgnoreCount(m_options.m_ignore_count);
1060
1061 if (m_options.m_enable_passed)
1062 bp->SetEnabled (m_options.m_enable_value);
1063
1064 if (m_options.m_condition_passed)
1065 bp->SetCondition (m_options.m_condition.c_str());
1066 }
1067 }
Jim Inghamfab10e82012-03-06 00:37:27 +00001068 }
Jim Ingham5a988412012-06-08 21:56:10 +00001069 }
1070
1071 return result.Succeeded();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001072 }
1073
Jim Ingham5a988412012-06-08 21:56:10 +00001074private:
1075 CommandOptions m_options;
1076};
Johnny Chen7d49c9c2012-05-25 21:10:46 +00001077
Jim Ingham5a988412012-06-08 21:56:10 +00001078#pragma mark Modify::CommandOptions
1079OptionDefinition
1080CommandObjectBreakpointModify::CommandOptions::g_option_table[] =
1081{
Zachary Turnerd37221d2014-07-09 16:31:49 +00001082{ 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." },
1083{ 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." },
1084{ 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."},
1085{ 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."},
1086{ 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."},
1087{ 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."},
1088{ LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeExpression, "The breakpoint stops only if this condition expression evaluates to true."},
1089{ LLDB_OPT_SET_1, false, "enable", 'e', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Enable the breakpoint."},
1090{ LLDB_OPT_SET_2, false, "disable", 'd', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Disable the breakpoint."},
Jim Ingham33df7cd2014-12-06 01:28:03 +00001091{ 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."},
1092
Zachary Turnerd37221d2014-07-09 16:31:49 +00001093{ 0, false, NULL, 0 , 0, NULL, NULL, 0, eArgTypeNone, NULL }
Jim Ingham5a988412012-06-08 21:56:10 +00001094};
1095
1096//-------------------------------------------------------------------------
1097// CommandObjectBreakpointEnable
1098//-------------------------------------------------------------------------
1099#pragma mark Enable
1100
1101class CommandObjectBreakpointEnable : public CommandObjectParsed
1102{
1103public:
1104 CommandObjectBreakpointEnable (CommandInterpreter &interpreter) :
1105 CommandObjectParsed (interpreter,
1106 "enable",
1107 "Enable the specified disabled breakpoint(s). If no breakpoints are specified, enable all of them.",
1108 NULL)
1109 {
1110 CommandArgumentEntry arg;
1111 CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
1112 // Add the entry for the first argument for this command to the object's arguments vector.
1113 m_arguments.push_back (arg);
1114 }
1115
1116
1117 virtual
1118 ~CommandObjectBreakpointEnable () {}
1119
1120protected:
1121 virtual bool
1122 DoExecute (Args& command, CommandReturnObject &result)
1123 {
Jim Ingham893c9322014-11-22 01:42:44 +00001124 Target *target = GetSelectedOrDummyTarget();
Jim Ingham5a988412012-06-08 21:56:10 +00001125 if (target == NULL)
1126 {
1127 result.AppendError ("Invalid target. No existing target or breakpoints.");
1128 result.SetStatus (eReturnStatusFailed);
1129 return false;
1130 }
1131
1132 Mutex::Locker locker;
1133 target->GetBreakpointList().GetListMutex(locker);
1134
1135 const BreakpointList &breakpoints = target->GetBreakpointList();
1136
1137 size_t num_breakpoints = breakpoints.GetSize();
1138
1139 if (num_breakpoints == 0)
1140 {
1141 result.AppendError ("No breakpoints exist to be enabled.");
1142 result.SetStatus (eReturnStatusFailed);
1143 return false;
1144 }
1145
1146 if (command.GetArgumentCount() == 0)
1147 {
1148 // No breakpoint selected; enable all currently set breakpoints.
1149 target->EnableAllBreakpoints ();
Greg Clayton6fea17e2014-03-03 19:15:20 +00001150 result.AppendMessageWithFormat ("All breakpoints enabled. (%" PRIu64 " breakpoints)\n", (uint64_t)num_breakpoints);
Jim Ingham5a988412012-06-08 21:56:10 +00001151 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1152 }
1153 else
1154 {
1155 // Particular breakpoint selected; enable that breakpoint.
1156 BreakpointIDList valid_bp_ids;
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001157 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
Jim Ingham5a988412012-06-08 21:56:10 +00001158
1159 if (result.Succeeded())
1160 {
1161 int enable_count = 0;
1162 int loc_count = 0;
1163 const size_t count = valid_bp_ids.GetSize();
1164 for (size_t i = 0; i < count; ++i)
1165 {
1166 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1167
1168 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
1169 {
1170 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1171 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
1172 {
1173 BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
1174 if (location)
1175 {
1176 location->SetEnabled (true);
1177 ++loc_count;
1178 }
1179 }
1180 else
1181 {
1182 breakpoint->SetEnabled (true);
1183 ++enable_count;
1184 }
1185 }
1186 }
1187 result.AppendMessageWithFormat ("%d breakpoints enabled.\n", enable_count + loc_count);
1188 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1189 }
1190 }
1191
1192 return result.Succeeded();
1193 }
1194};
1195
1196//-------------------------------------------------------------------------
1197// CommandObjectBreakpointDisable
1198//-------------------------------------------------------------------------
1199#pragma mark Disable
1200
1201class CommandObjectBreakpointDisable : public CommandObjectParsed
1202{
1203public:
1204 CommandObjectBreakpointDisable (CommandInterpreter &interpreter) :
1205 CommandObjectParsed (interpreter,
1206 "breakpoint disable",
1207 "Disable the specified breakpoint(s) without removing it/them. If no breakpoints are specified, disable them all.",
1208 NULL)
1209 {
Jim Inghamb0fac502013-03-08 00:31:40 +00001210 SetHelpLong(
1211"Disable the specified breakpoint(s) without removing it/them. \n\
1212If no breakpoints are specified, disable them all.\n\
1213\n\
1214Note: disabling a breakpoint will cause none of its locations to be hit\n\
1215regardless of whether they are enabled or disabled. So the sequence: \n\
1216\n\
1217 (lldb) break disable 1\n\
1218 (lldb) break enable 1.1\n\
1219\n\
1220will NOT cause location 1.1 to get hit. To achieve that, do:\n\
1221\n\
1222 (lldb) break disable 1.*\n\
1223 (lldb) break enable 1.1\n\
1224\n\
1225The first command disables all the locations of breakpoint 1, \n\
1226the second re-enables the first location."
1227 );
1228
Jim Ingham5a988412012-06-08 21:56:10 +00001229 CommandArgumentEntry arg;
1230 CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
1231 // Add the entry for the first argument for this command to the object's arguments vector.
Jim Inghamb0fac502013-03-08 00:31:40 +00001232 m_arguments.push_back (arg);
1233
Jim Ingham5a988412012-06-08 21:56:10 +00001234 }
1235
1236
1237 virtual
1238 ~CommandObjectBreakpointDisable () {}
1239
1240protected:
1241 virtual bool
1242 DoExecute (Args& command, CommandReturnObject &result)
1243 {
Jim Ingham893c9322014-11-22 01:42:44 +00001244 Target *target = GetSelectedOrDummyTarget();
Jim Ingham5a988412012-06-08 21:56:10 +00001245 if (target == NULL)
1246 {
1247 result.AppendError ("Invalid target. No existing target or breakpoints.");
1248 result.SetStatus (eReturnStatusFailed);
1249 return false;
1250 }
1251
1252 Mutex::Locker locker;
1253 target->GetBreakpointList().GetListMutex(locker);
1254
1255 const BreakpointList &breakpoints = target->GetBreakpointList();
1256 size_t num_breakpoints = breakpoints.GetSize();
1257
1258 if (num_breakpoints == 0)
1259 {
1260 result.AppendError ("No breakpoints exist to be disabled.");
1261 result.SetStatus (eReturnStatusFailed);
1262 return false;
1263 }
1264
1265 if (command.GetArgumentCount() == 0)
1266 {
1267 // No breakpoint selected; disable all currently set breakpoints.
1268 target->DisableAllBreakpoints ();
Greg Clayton6fea17e2014-03-03 19:15:20 +00001269 result.AppendMessageWithFormat ("All breakpoints disabled. (%" PRIu64 " breakpoints)\n", (uint64_t)num_breakpoints);
Jim Ingham5a988412012-06-08 21:56:10 +00001270 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1271 }
1272 else
1273 {
1274 // Particular breakpoint selected; disable that breakpoint.
1275 BreakpointIDList valid_bp_ids;
1276
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001277 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
Jim Ingham5a988412012-06-08 21:56:10 +00001278
1279 if (result.Succeeded())
1280 {
1281 int disable_count = 0;
1282 int loc_count = 0;
1283 const size_t count = valid_bp_ids.GetSize();
1284 for (size_t i = 0; i < count; ++i)
1285 {
1286 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1287
1288 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
1289 {
1290 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1291 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
1292 {
1293 BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
1294 if (location)
1295 {
1296 location->SetEnabled (false);
1297 ++loc_count;
1298 }
1299 }
1300 else
1301 {
1302 breakpoint->SetEnabled (false);
1303 ++disable_count;
1304 }
1305 }
1306 }
1307 result.AppendMessageWithFormat ("%d breakpoints disabled.\n", disable_count + loc_count);
1308 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1309 }
1310 }
1311
1312 return result.Succeeded();
1313 }
1314
1315};
1316
1317//-------------------------------------------------------------------------
1318// CommandObjectBreakpointList
1319//-------------------------------------------------------------------------
1320#pragma mark List
1321
1322class CommandObjectBreakpointList : public CommandObjectParsed
1323{
1324public:
1325 CommandObjectBreakpointList (CommandInterpreter &interpreter) :
1326 CommandObjectParsed (interpreter,
1327 "breakpoint list",
1328 "List some or all breakpoints at configurable levels of detail.",
1329 NULL),
1330 m_options (interpreter)
1331 {
1332 CommandArgumentEntry arg;
1333 CommandArgumentData bp_id_arg;
1334
1335 // Define the first (and only) variant of this arg.
1336 bp_id_arg.arg_type = eArgTypeBreakpointID;
1337 bp_id_arg.arg_repetition = eArgRepeatOptional;
1338
1339 // There is only one variant this argument could be; put it into the argument entry.
1340 arg.push_back (bp_id_arg);
1341
1342 // Push the data for the first argument into the m_arguments vector.
1343 m_arguments.push_back (arg);
1344 }
1345
1346
1347 virtual
1348 ~CommandObjectBreakpointList () {}
1349
1350 virtual Options *
1351 GetOptions ()
1352 {
1353 return &m_options;
Jim Ingham1b54c882010-06-16 02:00:15 +00001354 }
1355
Jim Ingham5a988412012-06-08 21:56:10 +00001356 class CommandOptions : public Options
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001357 {
Jim Ingham5a988412012-06-08 21:56:10 +00001358 public:
1359
1360 CommandOptions (CommandInterpreter &interpreter) :
1361 Options (interpreter),
Jim Ingham33df7cd2014-12-06 01:28:03 +00001362 m_level (lldb::eDescriptionLevelBrief),
1363 m_use_dummy(false)
Jim Ingham5a988412012-06-08 21:56:10 +00001364 {
1365 }
1366
1367 virtual
1368 ~CommandOptions () {}
1369
1370 virtual Error
1371 SetOptionValue (uint32_t option_idx, const char *option_arg)
1372 {
1373 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +00001374 const int short_option = m_getopt_table[option_idx].val;
Jim Ingham5a988412012-06-08 21:56:10 +00001375
1376 switch (short_option)
1377 {
1378 case 'b':
1379 m_level = lldb::eDescriptionLevelBrief;
1380 break;
Jim Ingham33df7cd2014-12-06 01:28:03 +00001381 case 'D':
1382 m_use_dummy = true;
1383 break;
Jim Ingham5a988412012-06-08 21:56:10 +00001384 case 'f':
1385 m_level = lldb::eDescriptionLevelFull;
1386 break;
1387 case 'v':
1388 m_level = lldb::eDescriptionLevelVerbose;
1389 break;
1390 case 'i':
1391 m_internal = true;
1392 break;
1393 default:
1394 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1395 break;
1396 }
1397
1398 return error;
1399 }
1400
1401 void
1402 OptionParsingStarting ()
1403 {
1404 m_level = lldb::eDescriptionLevelFull;
1405 m_internal = false;
Jim Ingham33df7cd2014-12-06 01:28:03 +00001406 m_use_dummy = false;
Jim Ingham5a988412012-06-08 21:56:10 +00001407 }
1408
1409 const OptionDefinition *
1410 GetDefinitions ()
1411 {
1412 return g_option_table;
1413 }
1414
1415 // Options table: Required for subclasses of Options.
1416
1417 static OptionDefinition g_option_table[];
1418
1419 // Instance variables to hold the values for command options.
1420
1421 lldb::DescriptionLevel m_level;
1422
1423 bool m_internal;
Jim Ingham33df7cd2014-12-06 01:28:03 +00001424 bool m_use_dummy;
Jim Ingham5a988412012-06-08 21:56:10 +00001425 };
1426
1427protected:
1428 virtual bool
1429 DoExecute (Args& command, CommandReturnObject &result)
1430 {
Jim Ingham33df7cd2014-12-06 01:28:03 +00001431 Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
1432
Jim Ingham5a988412012-06-08 21:56:10 +00001433 if (target == NULL)
1434 {
1435 result.AppendError ("Invalid target. No current target or breakpoints.");
1436 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1437 return true;
1438 }
1439
1440 const BreakpointList &breakpoints = target->GetBreakpointList(m_options.m_internal);
1441 Mutex::Locker locker;
1442 target->GetBreakpointList(m_options.m_internal).GetListMutex(locker);
1443
1444 size_t num_breakpoints = breakpoints.GetSize();
1445
1446 if (num_breakpoints == 0)
1447 {
1448 result.AppendMessage ("No breakpoints currently set.");
1449 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1450 return true;
1451 }
1452
Jim Ingham85e8b812011-02-19 02:53:09 +00001453 Stream &output_stream = result.GetOutputStream();
Jim Ingham5a988412012-06-08 21:56:10 +00001454
1455 if (command.GetArgumentCount() == 0)
1456 {
1457 // No breakpoint selected; show info about all currently set breakpoints.
1458 result.AppendMessage ("Current breakpoints:");
1459 for (size_t i = 0; i < num_breakpoints; ++i)
1460 {
1461 Breakpoint *breakpoint = breakpoints.GetBreakpointAtIndex (i).get();
1462 AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
1463 }
1464 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1465 }
1466 else
1467 {
1468 // Particular breakpoints selected; show info about that breakpoint.
1469 BreakpointIDList valid_bp_ids;
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001470 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
Jim Ingham5a988412012-06-08 21:56:10 +00001471
1472 if (result.Succeeded())
1473 {
1474 for (size_t i = 0; i < valid_bp_ids.GetSize(); ++i)
1475 {
1476 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1477 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1478 AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
1479 }
1480 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1481 }
1482 else
1483 {
1484 result.AppendError ("Invalid breakpoint id.");
1485 result.SetStatus (eReturnStatusFailed);
1486 }
1487 }
1488
1489 return result.Succeeded();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001490 }
1491
Jim Ingham5a988412012-06-08 21:56:10 +00001492private:
1493 CommandOptions m_options;
1494};
1495
1496#pragma mark List::CommandOptions
1497OptionDefinition
1498CommandObjectBreakpointList::CommandOptions::g_option_table[] =
1499{
Zachary Turnerd37221d2014-07-09 16:31:49 +00001500 { LLDB_OPT_SET_ALL, false, "internal", 'i', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
Jim Ingham5a988412012-06-08 21:56:10 +00001501 "Show debugger internal breakpoints" },
1502
Zachary Turnerd37221d2014-07-09 16:31:49 +00001503 { LLDB_OPT_SET_1, false, "brief", 'b', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
Jim Ingham5a988412012-06-08 21:56:10 +00001504 "Give a brief description of the breakpoint (no location info)."},
1505
1506 // FIXME: We need to add an "internal" command, and then add this sort of thing to it.
1507 // But I need to see it for now, and don't want to wait.
Zachary Turnerd37221d2014-07-09 16:31:49 +00001508 { LLDB_OPT_SET_2, false, "full", 'f', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
Jim Ingham5a988412012-06-08 21:56:10 +00001509 "Give a full description of the breakpoint and its locations."},
1510
Zachary Turnerd37221d2014-07-09 16:31:49 +00001511 { LLDB_OPT_SET_3, false, "verbose", 'v', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
Jim Ingham5a988412012-06-08 21:56:10 +00001512 "Explain everything we know about the breakpoint (for debugging debugger bugs)." },
1513
Jim Ingham33df7cd2014-12-06 01:28:03 +00001514 { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
1515 "List Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
1516
Zachary Turnerd37221d2014-07-09 16:31:49 +00001517 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Jim Ingham5a988412012-06-08 21:56:10 +00001518};
1519
1520//-------------------------------------------------------------------------
1521// CommandObjectBreakpointClear
1522//-------------------------------------------------------------------------
1523#pragma mark Clear
1524
1525class CommandObjectBreakpointClear : public CommandObjectParsed
1526{
1527public:
1528
1529 typedef enum BreakpointClearType
1530 {
1531 eClearTypeInvalid,
1532 eClearTypeFileAndLine
1533 } BreakpointClearType;
1534
1535 CommandObjectBreakpointClear (CommandInterpreter &interpreter) :
1536 CommandObjectParsed (interpreter,
1537 "breakpoint clear",
1538 "Clears a breakpoint or set of breakpoints in the executable.",
1539 "breakpoint clear <cmd-options>"),
1540 m_options (interpreter)
1541 {
1542 }
1543
1544 virtual
1545 ~CommandObjectBreakpointClear () {}
1546
1547 virtual Options *
1548 GetOptions ()
1549 {
1550 return &m_options;
1551 }
1552
1553 class CommandOptions : public Options
1554 {
1555 public:
1556
1557 CommandOptions (CommandInterpreter &interpreter) :
1558 Options (interpreter),
1559 m_filename (),
1560 m_line_num (0)
1561 {
1562 }
1563
1564 virtual
1565 ~CommandOptions () {}
1566
1567 virtual Error
1568 SetOptionValue (uint32_t option_idx, const char *option_arg)
1569 {
1570 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +00001571 const int short_option = m_getopt_table[option_idx].val;
Jim Ingham5a988412012-06-08 21:56:10 +00001572
1573 switch (short_option)
1574 {
1575 case 'f':
1576 m_filename.assign (option_arg);
1577 break;
1578
1579 case 'l':
Vince Harron5275aaa2015-01-15 20:08:35 +00001580 m_line_num = StringConvert::ToUInt32 (option_arg, 0);
Jim Ingham5a988412012-06-08 21:56:10 +00001581 break;
1582
1583 default:
1584 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1585 break;
1586 }
1587
1588 return error;
1589 }
1590
1591 void
1592 OptionParsingStarting ()
1593 {
1594 m_filename.clear();
1595 m_line_num = 0;
1596 }
1597
1598 const OptionDefinition*
1599 GetDefinitions ()
1600 {
1601 return g_option_table;
1602 }
1603
1604 // Options table: Required for subclasses of Options.
1605
1606 static OptionDefinition g_option_table[];
1607
1608 // Instance variables to hold the values for command options.
1609
1610 std::string m_filename;
1611 uint32_t m_line_num;
1612
1613 };
1614
1615protected:
1616 virtual bool
1617 DoExecute (Args& command, CommandReturnObject &result)
1618 {
Jim Ingham893c9322014-11-22 01:42:44 +00001619 Target *target = GetSelectedOrDummyTarget();
Jim Ingham5a988412012-06-08 21:56:10 +00001620 if (target == NULL)
1621 {
1622 result.AppendError ("Invalid target. No existing target or breakpoints.");
1623 result.SetStatus (eReturnStatusFailed);
1624 return false;
1625 }
1626
1627 // The following are the various types of breakpoints that could be cleared:
1628 // 1). -f -l (clearing breakpoint by source location)
1629
1630 BreakpointClearType break_type = eClearTypeInvalid;
1631
1632 if (m_options.m_line_num != 0)
1633 break_type = eClearTypeFileAndLine;
1634
1635 Mutex::Locker locker;
1636 target->GetBreakpointList().GetListMutex(locker);
1637
1638 BreakpointList &breakpoints = target->GetBreakpointList();
1639 size_t num_breakpoints = breakpoints.GetSize();
1640
1641 // Early return if there's no breakpoint at all.
1642 if (num_breakpoints == 0)
1643 {
1644 result.AppendError ("Breakpoint clear: No breakpoint cleared.");
1645 result.SetStatus (eReturnStatusFailed);
1646 return result.Succeeded();
1647 }
1648
1649 // Find matching breakpoints and delete them.
1650
1651 // First create a copy of all the IDs.
1652 std::vector<break_id_t> BreakIDs;
1653 for (size_t i = 0; i < num_breakpoints; ++i)
1654 BreakIDs.push_back(breakpoints.GetBreakpointAtIndex(i).get()->GetID());
1655
1656 int num_cleared = 0;
1657 StreamString ss;
1658 switch (break_type)
1659 {
1660 case eClearTypeFileAndLine: // Breakpoint by source position
1661 {
1662 const ConstString filename(m_options.m_filename.c_str());
1663 BreakpointLocationCollection loc_coll;
1664
1665 for (size_t i = 0; i < num_breakpoints; ++i)
1666 {
1667 Breakpoint *bp = breakpoints.FindBreakpointByID(BreakIDs[i]).get();
1668
1669 if (bp->GetMatchingFileLine(filename, m_options.m_line_num, loc_coll))
1670 {
1671 // If the collection size is 0, it's a full match and we can just remove the breakpoint.
1672 if (loc_coll.GetSize() == 0)
1673 {
1674 bp->GetDescription(&ss, lldb::eDescriptionLevelBrief);
1675 ss.EOL();
1676 target->RemoveBreakpointByID (bp->GetID());
1677 ++num_cleared;
1678 }
1679 }
1680 }
1681 }
1682 break;
1683
1684 default:
1685 break;
1686 }
1687
1688 if (num_cleared > 0)
1689 {
1690 Stream &output_stream = result.GetOutputStream();
1691 output_stream.Printf ("%d breakpoints cleared:\n", num_cleared);
1692 output_stream << ss.GetData();
1693 output_stream.EOL();
1694 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1695 }
1696 else
1697 {
1698 result.AppendError ("Breakpoint clear: No breakpoint cleared.");
1699 result.SetStatus (eReturnStatusFailed);
1700 }
1701
1702 return result.Succeeded();
1703 }
1704
1705private:
1706 CommandOptions m_options;
1707};
1708
1709#pragma mark Clear::CommandOptions
1710
1711OptionDefinition
1712CommandObjectBreakpointClear::CommandOptions::g_option_table[] =
1713{
Zachary Turnerd37221d2014-07-09 16:31:49 +00001714 { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
Jim Ingham5a988412012-06-08 21:56:10 +00001715 "Specify the breakpoint by source location in this particular file."},
1716
Zachary Turnerd37221d2014-07-09 16:31:49 +00001717 { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum,
Jim Ingham5a988412012-06-08 21:56:10 +00001718 "Specify the breakpoint by source location at this particular line."},
1719
Zachary Turnerd37221d2014-07-09 16:31:49 +00001720 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Jim Ingham5a988412012-06-08 21:56:10 +00001721};
1722
1723//-------------------------------------------------------------------------
1724// CommandObjectBreakpointDelete
1725//-------------------------------------------------------------------------
1726#pragma mark Delete
1727
1728class CommandObjectBreakpointDelete : public CommandObjectParsed
1729{
1730public:
1731 CommandObjectBreakpointDelete (CommandInterpreter &interpreter) :
1732 CommandObjectParsed (interpreter,
1733 "breakpoint delete",
1734 "Delete the specified breakpoint(s). If no breakpoints are specified, delete them all.",
Jim Ingham33df7cd2014-12-06 01:28:03 +00001735 NULL),
1736 m_options (interpreter)
Jim Ingham5a988412012-06-08 21:56:10 +00001737 {
1738 CommandArgumentEntry arg;
1739 CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
1740 // Add the entry for the first argument for this command to the object's arguments vector.
1741 m_arguments.push_back (arg);
1742 }
1743
1744 virtual
1745 ~CommandObjectBreakpointDelete () {}
1746
Jim Ingham33df7cd2014-12-06 01:28:03 +00001747 virtual Options *
1748 GetOptions ()
1749 {
1750 return &m_options;
1751 }
1752
1753 class CommandOptions : public Options
1754 {
1755 public:
1756
1757 CommandOptions (CommandInterpreter &interpreter) :
1758 Options (interpreter),
1759 m_use_dummy (false),
1760 m_force (false)
1761 {
1762 }
1763
1764 virtual
1765 ~CommandOptions () {}
1766
1767 virtual Error
1768 SetOptionValue (uint32_t option_idx, const char *option_arg)
1769 {
1770 Error error;
1771 const int short_option = m_getopt_table[option_idx].val;
1772
1773 switch (short_option)
1774 {
1775 case 'f':
1776 m_force = true;
1777 break;
1778
1779 case 'D':
1780 m_use_dummy = true;
1781 break;
1782
1783 default:
1784 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1785 break;
1786 }
1787
1788 return error;
1789 }
1790
1791 void
1792 OptionParsingStarting ()
1793 {
1794 m_use_dummy = false;
1795 m_force = false;
1796 }
1797
1798 const OptionDefinition*
1799 GetDefinitions ()
1800 {
1801 return g_option_table;
1802 }
1803
1804 // Options table: Required for subclasses of Options.
1805
1806 static OptionDefinition g_option_table[];
1807
1808 // Instance variables to hold the values for command options.
1809 bool m_use_dummy;
1810 bool m_force;
1811 };
1812
Jim Ingham5a988412012-06-08 21:56:10 +00001813protected:
1814 virtual bool
1815 DoExecute (Args& command, CommandReturnObject &result)
1816 {
Jim Ingham33df7cd2014-12-06 01:28:03 +00001817 Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
1818
Jim Ingham5a988412012-06-08 21:56:10 +00001819 if (target == NULL)
1820 {
1821 result.AppendError ("Invalid target. No existing target or breakpoints.");
1822 result.SetStatus (eReturnStatusFailed);
1823 return false;
1824 }
1825
1826 Mutex::Locker locker;
1827 target->GetBreakpointList().GetListMutex(locker);
1828
1829 const BreakpointList &breakpoints = target->GetBreakpointList();
1830
1831 size_t num_breakpoints = breakpoints.GetSize();
1832
1833 if (num_breakpoints == 0)
1834 {
1835 result.AppendError ("No breakpoints exist to be deleted.");
1836 result.SetStatus (eReturnStatusFailed);
1837 return false;
1838 }
1839
1840 if (command.GetArgumentCount() == 0)
1841 {
Jim Ingham33df7cd2014-12-06 01:28:03 +00001842 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 +00001843 {
1844 result.AppendMessage("Operation cancelled...");
1845 }
1846 else
1847 {
1848 target->RemoveAllBreakpoints ();
Greg Clayton6fea17e2014-03-03 19:15:20 +00001849 result.AppendMessageWithFormat ("All breakpoints removed. (%" PRIu64 " breakpoint%s)\n", (uint64_t)num_breakpoints, num_breakpoints > 1 ? "s" : "");
Jim Ingham5a988412012-06-08 21:56:10 +00001850 }
1851 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1852 }
1853 else
1854 {
1855 // Particular breakpoint selected; disable that breakpoint.
1856 BreakpointIDList valid_bp_ids;
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001857 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
Jim Ingham5a988412012-06-08 21:56:10 +00001858
1859 if (result.Succeeded())
1860 {
1861 int delete_count = 0;
1862 int disable_count = 0;
1863 const size_t count = valid_bp_ids.GetSize();
1864 for (size_t i = 0; i < count; ++i)
1865 {
1866 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1867
1868 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
1869 {
1870 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
1871 {
1872 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1873 BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
1874 // It makes no sense to try to delete individual locations, so we disable them instead.
1875 if (location)
1876 {
1877 location->SetEnabled (false);
1878 ++disable_count;
1879 }
1880 }
1881 else
1882 {
1883 target->RemoveBreakpointByID (cur_bp_id.GetBreakpointID());
1884 ++delete_count;
1885 }
1886 }
1887 }
1888 result.AppendMessageWithFormat ("%d breakpoints deleted; %d breakpoint locations disabled.\n",
1889 delete_count, disable_count);
1890 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1891 }
1892 }
1893 return result.Succeeded();
1894 }
Jim Ingham33df7cd2014-12-06 01:28:03 +00001895private:
1896 CommandOptions m_options;
1897};
1898
1899OptionDefinition
1900CommandObjectBreakpointDelete::CommandOptions::g_option_table[] =
1901{
1902 { LLDB_OPT_SET_1, false, "force", 'f', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
1903 "Delete all breakpoints without querying for confirmation."},
1904
1905 { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
1906 "Delete Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
1907
1908 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Jim Ingham5a988412012-06-08 21:56:10 +00001909};
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001910
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001911//-------------------------------------------------------------------------
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001912// CommandObjectBreakpointName
1913//-------------------------------------------------------------------------
1914
1915static OptionDefinition
1916g_breakpoint_name_options[] =
1917{
1918 { LLDB_OPT_SET_1, false, "name", 'N', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBreakpointName, "Specifies a breakpoint name to use."},
1919 { LLDB_OPT_SET_2, false, "breakpoint-id", 'B', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBreakpointID, "Specify a breakpoint id to use."},
1920 { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
1921 "Operate on Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
1922};
1923class BreakpointNameOptionGroup : public OptionGroup
1924{
1925public:
1926 BreakpointNameOptionGroup() :
1927 OptionGroup(),
1928 m_breakpoint(LLDB_INVALID_BREAK_ID),
1929 m_use_dummy (false)
1930 {
1931
1932 }
1933
1934 virtual
1935 ~BreakpointNameOptionGroup ()
1936 {
1937 }
1938
1939 virtual uint32_t
1940 GetNumDefinitions ()
1941 {
1942 return sizeof (g_breakpoint_name_options) / sizeof (OptionDefinition);
1943 }
1944
1945 virtual const OptionDefinition*
1946 GetDefinitions ()
1947 {
1948 return g_breakpoint_name_options;
1949 }
1950
1951 virtual Error
1952 SetOptionValue (CommandInterpreter &interpreter,
1953 uint32_t option_idx,
1954 const char *option_value)
1955 {
1956 Error error;
1957 const int short_option = g_breakpoint_name_options[option_idx].short_option;
1958
1959 switch (short_option)
1960 {
1961 case 'N':
1962 if (BreakpointID::StringIsBreakpointName(option_value, error) && error.Success())
Pavel Labathc95f7e22015-02-20 11:14:59 +00001963 m_name.SetValueFromString(option_value);
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001964 break;
1965
1966 case 'B':
Pavel Labathc95f7e22015-02-20 11:14:59 +00001967 if (m_breakpoint.SetValueFromString(option_value).Fail())
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001968 error.SetErrorStringWithFormat ("unrecognized value \"%s\" for breakpoint", option_value);
1969 break;
1970 case 'D':
Pavel Labathc95f7e22015-02-20 11:14:59 +00001971 if (m_use_dummy.SetValueFromString(option_value).Fail())
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001972 error.SetErrorStringWithFormat ("unrecognized value \"%s\" for use-dummy", option_value);
1973 break;
1974
1975 default:
1976 error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option);
1977 break;
1978 }
1979 return error;
1980 }
1981
1982 virtual void
1983 OptionParsingStarting (CommandInterpreter &interpreter)
1984 {
1985 m_name.Clear();
1986 m_breakpoint.Clear();
1987 m_use_dummy.Clear();
1988 m_use_dummy.SetDefaultValue(false);
1989 }
1990
1991 OptionValueString m_name;
1992 OptionValueUInt64 m_breakpoint;
1993 OptionValueBoolean m_use_dummy;
1994};
1995
1996
1997class CommandObjectBreakpointNameAdd : public CommandObjectParsed
1998{
1999public:
2000 CommandObjectBreakpointNameAdd (CommandInterpreter &interpreter) :
2001 CommandObjectParsed (interpreter,
2002 "add",
2003 "Add a name to the breakpoints provided.",
2004 "breakpoint name add <command-options> <breakpoint-id-list>"),
2005 m_name_options(),
2006 m_option_group(interpreter)
2007 {
2008 // Create the first variant for the first (and only) argument for this command.
2009 CommandArgumentEntry arg1;
2010 CommandArgumentData id_arg;
2011 id_arg.arg_type = eArgTypeBreakpointID;
2012 id_arg.arg_repetition = eArgRepeatOptional;
2013 arg1.push_back(id_arg);
2014 m_arguments.push_back (arg1);
2015
2016 m_option_group.Append (&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
2017 m_option_group.Finalize();
2018 }
2019
2020 virtual
2021 ~CommandObjectBreakpointNameAdd () {}
2022
2023 Options *
2024 GetOptions ()
2025 {
2026 return &m_option_group;
2027 }
2028
2029protected:
2030 virtual bool
2031 DoExecute (Args& command, CommandReturnObject &result)
2032 {
2033 if (!m_name_options.m_name.OptionWasSet())
2034 {
2035 result.SetError("No name option provided.");
2036 return false;
2037 }
2038
2039 Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
2040
2041 if (target == NULL)
2042 {
2043 result.AppendError ("Invalid target. No existing target or breakpoints.");
2044 result.SetStatus (eReturnStatusFailed);
2045 return false;
2046 }
2047
2048 Mutex::Locker locker;
2049 target->GetBreakpointList().GetListMutex(locker);
2050
2051 const BreakpointList &breakpoints = target->GetBreakpointList();
2052
2053 size_t num_breakpoints = breakpoints.GetSize();
2054 if (num_breakpoints == 0)
2055 {
2056 result.SetError("No breakpoints, cannot add names.");
2057 result.SetStatus (eReturnStatusFailed);
2058 return false;
2059 }
2060
2061 // Particular breakpoint selected; disable that breakpoint.
2062 BreakpointIDList valid_bp_ids;
2063 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
2064
2065 if (result.Succeeded())
2066 {
2067 if (valid_bp_ids.GetSize() == 0)
2068 {
2069 result.SetError("No breakpoints specified, cannot add names.");
2070 result.SetStatus (eReturnStatusFailed);
2071 return false;
2072 }
2073 size_t num_valid_ids = valid_bp_ids.GetSize();
2074 for (size_t index = 0; index < num_valid_ids; index++)
2075 {
2076 lldb::break_id_t bp_id = valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
2077 BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
2078 Error error; // We don't need to check the error here, since the option parser checked it...
2079 bp_sp->AddName(m_name_options.m_name.GetCurrentValue(), error);
2080 }
2081 }
2082
2083 return true;
2084 }
2085
2086private:
2087 BreakpointNameOptionGroup m_name_options;
2088 OptionGroupOptions m_option_group;
2089};
2090
2091
2092
2093class CommandObjectBreakpointNameDelete : public CommandObjectParsed
2094{
2095public:
2096 CommandObjectBreakpointNameDelete (CommandInterpreter &interpreter) :
2097 CommandObjectParsed (interpreter,
2098 "delete",
2099 "Delete a name from the breakpoints provided.",
2100 "breakpoint name delete <command-options> <breakpoint-id-list>"),
2101 m_name_options(),
2102 m_option_group(interpreter)
2103 {
2104 // Create the first variant for the first (and only) argument for this command.
2105 CommandArgumentEntry arg1;
2106 CommandArgumentData id_arg;
2107 id_arg.arg_type = eArgTypeBreakpointID;
2108 id_arg.arg_repetition = eArgRepeatOptional;
2109 arg1.push_back(id_arg);
2110 m_arguments.push_back (arg1);
2111
2112 m_option_group.Append (&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
2113 m_option_group.Finalize();
2114 }
2115
2116 virtual
2117 ~CommandObjectBreakpointNameDelete () {}
2118
2119 Options *
2120 GetOptions ()
2121 {
2122 return &m_option_group;
2123 }
2124
2125protected:
2126 virtual bool
2127 DoExecute (Args& command, CommandReturnObject &result)
2128 {
2129 if (!m_name_options.m_name.OptionWasSet())
2130 {
2131 result.SetError("No name option provided.");
2132 return false;
2133 }
2134
2135 Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
2136
2137 if (target == NULL)
2138 {
2139 result.AppendError ("Invalid target. No existing target or breakpoints.");
2140 result.SetStatus (eReturnStatusFailed);
2141 return false;
2142 }
2143
2144 Mutex::Locker locker;
2145 target->GetBreakpointList().GetListMutex(locker);
2146
2147 const BreakpointList &breakpoints = target->GetBreakpointList();
2148
2149 size_t num_breakpoints = breakpoints.GetSize();
2150 if (num_breakpoints == 0)
2151 {
2152 result.SetError("No breakpoints, cannot delete names.");
2153 result.SetStatus (eReturnStatusFailed);
2154 return false;
2155 }
2156
2157 // Particular breakpoint selected; disable that breakpoint.
2158 BreakpointIDList valid_bp_ids;
2159 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
2160
2161 if (result.Succeeded())
2162 {
2163 if (valid_bp_ids.GetSize() == 0)
2164 {
2165 result.SetError("No breakpoints specified, cannot delete names.");
2166 result.SetStatus (eReturnStatusFailed);
2167 return false;
2168 }
2169 size_t num_valid_ids = valid_bp_ids.GetSize();
2170 for (size_t index = 0; index < num_valid_ids; index++)
2171 {
2172 lldb::break_id_t bp_id = valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
2173 BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
2174 bp_sp->RemoveName(m_name_options.m_name.GetCurrentValue());
2175 }
2176 }
2177
2178 return true;
2179 }
2180
2181private:
2182 BreakpointNameOptionGroup m_name_options;
2183 OptionGroupOptions m_option_group;
2184};
2185
2186class CommandObjectBreakpointNameList : public CommandObjectParsed
2187{
2188public:
2189 CommandObjectBreakpointNameList (CommandInterpreter &interpreter) :
2190 CommandObjectParsed (interpreter,
2191 "list",
2192 "List either the names for a breakpoint or the breakpoints for a given name.",
2193 "breakpoint name list <command-options>"),
2194 m_name_options(),
2195 m_option_group(interpreter)
2196 {
2197 m_option_group.Append (&m_name_options);
2198 m_option_group.Finalize();
2199 }
2200
2201 virtual
2202 ~CommandObjectBreakpointNameList () {}
2203
2204 Options *
2205 GetOptions ()
2206 {
2207 return &m_option_group;
2208 }
2209
2210protected:
2211protected:
2212 virtual bool
2213 DoExecute (Args& command, CommandReturnObject &result)
2214 {
2215 Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
2216
2217 if (target == NULL)
2218 {
2219 result.AppendError ("Invalid target. No existing target or breakpoints.");
2220 result.SetStatus (eReturnStatusFailed);
2221 return false;
2222 }
2223
2224 if (m_name_options.m_name.OptionWasSet())
2225 {
2226 const char *name = m_name_options.m_name.GetCurrentValue();
2227 Mutex::Locker locker;
2228 target->GetBreakpointList().GetListMutex(locker);
2229
2230 BreakpointList &breakpoints = target->GetBreakpointList();
2231 for (BreakpointSP bp_sp : breakpoints.Breakpoints())
2232 {
2233 if (bp_sp->MatchesName(name))
2234 {
2235 StreamString s;
2236 bp_sp->GetDescription(&s, eDescriptionLevelBrief);
2237 s.EOL();
2238 result.AppendMessage(s.GetData());
2239 }
2240 }
2241
2242 }
2243 else if (m_name_options.m_breakpoint.OptionWasSet())
2244 {
2245 BreakpointSP bp_sp = target->GetBreakpointList().FindBreakpointByID(m_name_options.m_breakpoint.GetCurrentValue());
2246 if (bp_sp)
2247 {
2248 std::vector<std::string> names;
2249 bp_sp->GetNames (names);
2250 result.AppendMessage ("Names:");
2251 for (auto name : names)
2252 result.AppendMessageWithFormat (" %s\n", name.c_str());
2253 }
2254 else
2255 {
2256 result.AppendErrorWithFormat ("Could not find breakpoint %" PRId64 ".\n",
2257 m_name_options.m_breakpoint.GetCurrentValue());
2258 result.SetStatus (eReturnStatusFailed);
2259 return false;
2260 }
2261 }
2262 else
2263 {
2264 result.SetError ("Must specify -N or -B option to list.");
2265 result.SetStatus (eReturnStatusFailed);
2266 return false;
2267 }
2268 return true;
2269 }
2270
2271private:
2272 BreakpointNameOptionGroup m_name_options;
2273 OptionGroupOptions m_option_group;
2274};
2275
2276//-------------------------------------------------------------------------
2277// CommandObjectMultiwordBreakpoint
2278//-------------------------------------------------------------------------
2279class CommandObjectBreakpointName : public CommandObjectMultiword
2280{
2281public:
2282 CommandObjectBreakpointName (CommandInterpreter &interpreter) :
2283 CommandObjectMultiword(interpreter,
2284 "name",
2285 "A set of commands to manage name tags for breakpoints",
2286 "breakpoint name <command> [<command-options>]")
2287 {
2288 CommandObjectSP add_command_object (new CommandObjectBreakpointNameAdd (interpreter));
2289 CommandObjectSP delete_command_object (new CommandObjectBreakpointNameDelete (interpreter));
2290 CommandObjectSP list_command_object (new CommandObjectBreakpointNameList (interpreter));
2291
2292 LoadSubCommand ("add", add_command_object);
2293 LoadSubCommand ("delete", delete_command_object);
2294 LoadSubCommand ("list", list_command_object);
2295
2296 }
2297
2298 virtual
2299 ~CommandObjectBreakpointName ()
2300 {
2301 }
2302
2303};
2304
2305
2306//-------------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002307// CommandObjectMultiwordBreakpoint
2308//-------------------------------------------------------------------------
Jim Inghamae1c4cf2010-06-18 00:58:52 +00002309#pragma mark MultiwordBreakpoint
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002310
Greg Clayton66111032010-06-23 01:19:29 +00002311CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint (CommandInterpreter &interpreter) :
Greg Claytona7015092010-09-18 01:14:36 +00002312 CommandObjectMultiword (interpreter,
2313 "breakpoint",
Jim Ingham46fbc602011-05-26 20:39:01 +00002314 "A set of commands for operating on breakpoints. Also see _regexp-break.",
Greg Claytona7015092010-09-18 01:14:36 +00002315 "breakpoint <command> [<command-options>]")
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002316{
Greg Claytona7015092010-09-18 01:14:36 +00002317 CommandObjectSP list_command_object (new CommandObjectBreakpointList (interpreter));
Greg Claytona7015092010-09-18 01:14:36 +00002318 CommandObjectSP enable_command_object (new CommandObjectBreakpointEnable (interpreter));
2319 CommandObjectSP disable_command_object (new CommandObjectBreakpointDisable (interpreter));
Johnny Chenb7234e42010-10-28 17:27:46 +00002320 CommandObjectSP clear_command_object (new CommandObjectBreakpointClear (interpreter));
2321 CommandObjectSP delete_command_object (new CommandObjectBreakpointDelete (interpreter));
Greg Claytona7015092010-09-18 01:14:36 +00002322 CommandObjectSP set_command_object (new CommandObjectBreakpointSet (interpreter));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002323 CommandObjectSP command_command_object (new CommandObjectBreakpointCommand (interpreter));
Greg Claytona7015092010-09-18 01:14:36 +00002324 CommandObjectSP modify_command_object (new CommandObjectBreakpointModify(interpreter));
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002325 CommandObjectSP name_command_object (new CommandObjectBreakpointName(interpreter));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002326
Johnny Chenb7234e42010-10-28 17:27:46 +00002327 list_command_object->SetCommandName ("breakpoint list");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002328 enable_command_object->SetCommandName("breakpoint enable");
2329 disable_command_object->SetCommandName("breakpoint disable");
Johnny Chenb7234e42010-10-28 17:27:46 +00002330 clear_command_object->SetCommandName("breakpoint clear");
2331 delete_command_object->SetCommandName("breakpoint delete");
Jim Inghamae1c4cf2010-06-18 00:58:52 +00002332 set_command_object->SetCommandName("breakpoint set");
Johnny Chenb7234e42010-10-28 17:27:46 +00002333 command_command_object->SetCommandName ("breakpoint command");
2334 modify_command_object->SetCommandName ("breakpoint modify");
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002335 name_command_object->SetCommandName ("breakpoint name");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002336
Greg Clayton23f59502012-07-17 03:23:13 +00002337 LoadSubCommand ("list", list_command_object);
2338 LoadSubCommand ("enable", enable_command_object);
2339 LoadSubCommand ("disable", disable_command_object);
2340 LoadSubCommand ("clear", clear_command_object);
2341 LoadSubCommand ("delete", delete_command_object);
2342 LoadSubCommand ("set", set_command_object);
2343 LoadSubCommand ("command", command_command_object);
2344 LoadSubCommand ("modify", modify_command_object);
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002345 LoadSubCommand ("name", name_command_object);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002346}
2347
2348CommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint ()
2349{
2350}
2351
2352void
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002353CommandObjectMultiwordBreakpoint::VerifyIDs (Args &args,
2354 Target *target,
2355 bool allow_locations,
2356 CommandReturnObject &result,
2357 BreakpointIDList *valid_ids)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002358{
2359 // args can be strings representing 1). integers (for breakpoint ids)
2360 // 2). the full breakpoint & location canonical representation
2361 // 3). the word "to" or a hyphen, representing a range (in which case there
2362 // had *better* be an entry both before & after of one of the first two types.
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002363 // 4). A breakpoint name
Jim Ingham36f3b362010-10-14 23:45:03 +00002364 // If args is empty, we will use the last created breakpoint (if there is one.)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002365
2366 Args temp_args;
2367
Jim Ingham36f3b362010-10-14 23:45:03 +00002368 if (args.GetArgumentCount() == 0)
2369 {
Greg Clayton4d122c42011-09-17 08:33:22 +00002370 if (target->GetLastCreatedBreakpoint())
Jim Ingham36f3b362010-10-14 23:45:03 +00002371 {
2372 valid_ids->AddBreakpointID (BreakpointID(target->GetLastCreatedBreakpoint()->GetID(), LLDB_INVALID_BREAK_ID));
2373 result.SetStatus (eReturnStatusSuccessFinishNoResult);
2374 }
2375 else
2376 {
2377 result.AppendError("No breakpoint specified and no last created breakpoint.");
2378 result.SetStatus (eReturnStatusFailed);
2379 }
2380 return;
2381 }
2382
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002383 // Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff directly from the old ARGS to
2384 // the new TEMP_ARGS. Do not copy breakpoint id range strings over; instead generate a list of strings for
2385 // all the breakpoint ids in the range, and shove all of those breakpoint id strings into TEMP_ARGS.
2386
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002387 BreakpointIDList::FindAndReplaceIDRanges (args, target, allow_locations, result, temp_args);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002388
2389 // NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual BreakpointIDList:
2390
Greg Claytonc982c762010-07-09 20:39:50 +00002391 valid_ids->InsertStringArray (temp_args.GetConstArgumentVector(), temp_args.GetArgumentCount(), result);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002392
2393 // At this point, all of the breakpoint ids that the user passed in have been converted to breakpoint IDs
2394 // and put into valid_ids.
2395
2396 if (result.Succeeded())
2397 {
2398 // Now that we've converted everything from args into a list of breakpoint ids, go through our tentative list
2399 // of breakpoint id's and verify that they correspond to valid/currently set breakpoints.
2400
Greg Claytonc982c762010-07-09 20:39:50 +00002401 const size_t count = valid_ids->GetSize();
2402 for (size_t i = 0; i < count; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002403 {
2404 BreakpointID cur_bp_id = valid_ids->GetBreakpointIDAtIndex (i);
2405 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
2406 if (breakpoint != NULL)
2407 {
Greg Claytonc7bece562013-01-25 18:06:21 +00002408 const size_t num_locations = breakpoint->GetNumLocations();
Saleem Abdulrasool3985c8c2014-04-02 03:51:35 +00002409 if (static_cast<size_t>(cur_bp_id.GetLocationID()) > num_locations)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002410 {
2411 StreamString id_str;
Greg Claytonc982c762010-07-09 20:39:50 +00002412 BreakpointID::GetCanonicalReference (&id_str,
2413 cur_bp_id.GetBreakpointID(),
2414 cur_bp_id.GetLocationID());
2415 i = valid_ids->GetSize() + 1;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002416 result.AppendErrorWithFormat ("'%s' is not a currently valid breakpoint/location id.\n",
2417 id_str.GetData());
2418 result.SetStatus (eReturnStatusFailed);
2419 }
2420 }
2421 else
2422 {
Greg Claytonc982c762010-07-09 20:39:50 +00002423 i = valid_ids->GetSize() + 1;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002424 result.AppendErrorWithFormat ("'%d' is not a currently valid breakpoint id.\n", cur_bp_id.GetBreakpointID());
2425 result.SetStatus (eReturnStatusFailed);
2426 }
2427 }
2428 }
2429}