blob: f3b22972637283b7a6b91af2a487c4634d41159d [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
Chris Lattner30fdc8d2010-06-08 16:52:24 +000010// C Includes
11// C++ Includes
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +000012#include <vector>
13
Chris Lattner30fdc8d2010-06-08 16:52:24 +000014// Other libraries and framework includes
15// Project includes
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +000016#include "CommandObjectBreakpoint.h"
17#include "CommandObjectBreakpointCommand.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000018#include "lldb/Breakpoint/Breakpoint.h"
19#include "lldb/Breakpoint/BreakpointIDList.h"
20#include "lldb/Breakpoint/BreakpointLocation.h"
Vince Harron5275aaa2015-01-15 20:08:35 +000021#include "lldb/Host/StringConvert.h"
Jim Ingham40af72e2010-06-15 19:49:27 +000022#include "lldb/Interpreter/Options.h"
Zachary Turner32abc6e2015-03-03 19:23:09 +000023#include "lldb/Interpreter/OptionValueBoolean.h"
Jim Ingham5e09c8c2014-12-16 23:40:14 +000024#include "lldb/Interpreter/OptionValueString.h"
25#include "lldb/Interpreter/OptionValueUInt64.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000026#include "lldb/Core/RegularExpression.h"
27#include "lldb/Core/StreamString.h"
28#include "lldb/Interpreter/CommandInterpreter.h"
29#include "lldb/Interpreter/CommandReturnObject.h"
Jim Ingham0e0984e2015-09-02 01:06:46 +000030#include "lldb/Target/Language.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000031#include "lldb/Target/Target.h"
32#include "lldb/Interpreter/CommandCompletions.h"
Jason Molendab57e4a12013-11-04 09:33:30 +000033#include "lldb/Target/StackFrame.h"
Jim Ingham1b54c882010-06-16 02:00:15 +000034#include "lldb/Target/Thread.h"
35#include "lldb/Target/ThreadSpec.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000036
37using namespace lldb;
38using namespace lldb_private;
39
40static void
Jim Ingham85e8b812011-02-19 02:53:09 +000041AddBreakpointDescription (Stream *s, Breakpoint *bp, lldb::DescriptionLevel level)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000042{
43 s->IndentMore();
44 bp->GetDescription (s, level, true);
45 s->IndentLess();
46 s->EOL();
47}
48
49//-------------------------------------------------------------------------
Jim Ingham5a988412012-06-08 21:56:10 +000050// CommandObjectBreakpointSet
Chris Lattner30fdc8d2010-06-08 16:52:24 +000051//-------------------------------------------------------------------------
52
Jim Ingham5a988412012-06-08 21:56:10 +000053class CommandObjectBreakpointSet : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +000054{
Jim Ingham5a988412012-06-08 21:56:10 +000055public:
Jim Ingham5a988412012-06-08 21:56:10 +000056 typedef enum BreakpointSetType
57 {
58 eSetTypeInvalid,
59 eSetTypeFileAndLine,
60 eSetTypeAddress,
61 eSetTypeFunctionName,
62 eSetTypeFunctionRegexp,
63 eSetTypeSourceRegexp,
64 eSetTypeException
65 } BreakpointSetType;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000066
Jim Ingham5a988412012-06-08 21:56:10 +000067 CommandObjectBreakpointSet (CommandInterpreter &interpreter) :
68 CommandObjectParsed (interpreter,
69 "breakpoint set",
70 "Sets a breakpoint or set of breakpoints in the executable.",
71 "breakpoint set <cmd-options>"),
72 m_options (interpreter)
73 {
74 }
75
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +000076 ~CommandObjectBreakpointSet() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +000077
Bruce Mitchener13d21e92015-10-07 16:56:17 +000078 Options *
79 GetOptions () override
Jim Ingham5a988412012-06-08 21:56:10 +000080 {
81 return &m_options;
82 }
83
84 class CommandOptions : public Options
85 {
86 public:
Jim Ingham5a988412012-06-08 21:56:10 +000087 CommandOptions (CommandInterpreter &interpreter) :
88 Options (interpreter),
89 m_condition (),
90 m_filenames (),
91 m_line_num (0),
92 m_column (0),
Jim Ingham5a988412012-06-08 21:56:10 +000093 m_func_names (),
94 m_func_name_type_mask (eFunctionNameTypeNone),
95 m_func_regexp (),
96 m_source_text_regexp(),
97 m_modules (),
98 m_load_addr(),
99 m_ignore_count (0),
100 m_thread_id(LLDB_INVALID_THREAD_ID),
101 m_thread_index (UINT32_MAX),
102 m_thread_name(),
103 m_queue_name(),
104 m_catch_bp (false),
Greg Clayton1f746072012-08-29 21:13:06 +0000105 m_throw_bp (true),
Greg Claytoneb023e72013-10-11 19:48:25 +0000106 m_hardware (false),
Jim Inghama72b31c2015-04-22 19:42:18 +0000107 m_exception_language (eLanguageTypeUnknown),
Dawn Perchik23b1dec2015-07-21 22:05:07 +0000108 m_language (lldb::eLanguageTypeUnknown),
Jim Inghamca36cd12012-10-05 19:16:31 +0000109 m_skip_prologue (eLazyBoolCalculate),
Jim Inghame7320522015-02-12 17:37:46 +0000110 m_one_shot (false),
Ilia K055ad9b2015-05-18 13:41:01 +0000111 m_all_files (false),
112 m_move_to_nearest_code (eLazyBoolCalculate)
Jim Ingham5a988412012-06-08 21:56:10 +0000113 {
114 }
115
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000116 ~CommandOptions() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +0000117
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000118 Error
119 SetOptionValue (uint32_t option_idx, const char *option_arg) override
Jim Ingham5a988412012-06-08 21:56:10 +0000120 {
121 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000122 const int short_option = m_getopt_table[option_idx].val;
Jim Ingham5a988412012-06-08 21:56:10 +0000123
124 switch (short_option)
125 {
126 case 'a':
Greg Claytonb9d5df52012-12-06 22:49:16 +0000127 {
128 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
129 m_load_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
130 }
Jim Ingham5a988412012-06-08 21:56:10 +0000131 break;
132
Jim Inghame7320522015-02-12 17:37:46 +0000133 case 'A':
134 m_all_files = true;
135 break;
136
Jim Inghamca36cd12012-10-05 19:16:31 +0000137 case 'b':
138 m_func_names.push_back (option_arg);
139 m_func_name_type_mask |= eFunctionNameTypeBase;
140 break;
141
Jim Ingham5a988412012-06-08 21:56:10 +0000142 case 'C':
Jim Ingham63129912015-03-16 22:47:38 +0000143 {
144 bool success;
145 m_column = StringConvert::ToUInt32 (option_arg, 0, 0, &success);
146 if (!success)
147 error.SetErrorStringWithFormat("invalid column number: %s", option_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000148 break;
Jim Ingham63129912015-03-16 22:47:38 +0000149 }
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000150
Jim Ingham5a988412012-06-08 21:56:10 +0000151 case 'c':
152 m_condition.assign(option_arg);
153 break;
154
Jim Ingham33df7cd2014-12-06 01:28:03 +0000155 case 'D':
156 m_use_dummy = true;
157 break;
158
Jim Ingham5a988412012-06-08 21:56:10 +0000159 case 'E':
160 {
Jim Ingham0e0984e2015-09-02 01:06:46 +0000161 LanguageType language = Language::GetLanguageTypeFromString (option_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000162
163 switch (language)
164 {
165 case eLanguageTypeC89:
166 case eLanguageTypeC:
167 case eLanguageTypeC99:
Bruce Mitchener1d0089f2014-07-03 00:49:08 +0000168 case eLanguageTypeC11:
Jim Inghama72b31c2015-04-22 19:42:18 +0000169 m_exception_language = eLanguageTypeC;
Jim Ingham5a988412012-06-08 21:56:10 +0000170 break;
171 case eLanguageTypeC_plus_plus:
Bruce Mitchener1d0089f2014-07-03 00:49:08 +0000172 case eLanguageTypeC_plus_plus_03:
173 case eLanguageTypeC_plus_plus_11:
Bruce Mitchener2ba84a62015-02-06 06:46:52 +0000174 case eLanguageTypeC_plus_plus_14:
Jim Inghama72b31c2015-04-22 19:42:18 +0000175 m_exception_language = eLanguageTypeC_plus_plus;
Jim Ingham5a988412012-06-08 21:56:10 +0000176 break;
177 case eLanguageTypeObjC:
Jim Inghama72b31c2015-04-22 19:42:18 +0000178 m_exception_language = eLanguageTypeObjC;
Jim Ingham5a988412012-06-08 21:56:10 +0000179 break;
180 case eLanguageTypeObjC_plus_plus:
181 error.SetErrorStringWithFormat ("Set exception breakpoints separately for c++ and objective-c");
182 break;
183 case eLanguageTypeUnknown:
184 error.SetErrorStringWithFormat ("Unknown language type: '%s' for exception breakpoint", option_arg);
185 break;
186 default:
187 error.SetErrorStringWithFormat ("Unsupported language type: '%s' for exception breakpoint", option_arg);
188 }
189 }
190 break;
Jim Inghamca36cd12012-10-05 19:16:31 +0000191
192 case 'f':
193 m_filenames.AppendIfUnique (FileSpec(option_arg, false));
194 break;
195
196 case 'F':
197 m_func_names.push_back (option_arg);
198 m_func_name_type_mask |= eFunctionNameTypeFull;
199 break;
200
Jim Ingham5a988412012-06-08 21:56:10 +0000201 case 'h':
Greg Claytoneb023e72013-10-11 19:48:25 +0000202 {
203 bool success;
204 m_catch_bp = Args::StringToBoolean (option_arg, true, &success);
205 if (!success)
206 error.SetErrorStringWithFormat ("Invalid boolean value for on-catch option: '%s'", option_arg);
207 }
208 break;
209
210 case 'H':
211 m_hardware = true;
212 break;
213
Jim Inghamca36cd12012-10-05 19:16:31 +0000214 case 'i':
Vince Harron5275aaa2015-01-15 20:08:35 +0000215 m_ignore_count = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
Jim Inghamca36cd12012-10-05 19:16:31 +0000216 if (m_ignore_count == UINT32_MAX)
217 error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
218 break;
Jim Inghamca36cd12012-10-05 19:16:31 +0000219
Jim Ingham5a988412012-06-08 21:56:10 +0000220 case 'K':
221 {
222 bool success;
223 bool value;
224 value = Args::StringToBoolean (option_arg, true, &success);
225 if (value)
226 m_skip_prologue = eLazyBoolYes;
227 else
228 m_skip_prologue = eLazyBoolNo;
229
230 if (!success)
231 error.SetErrorStringWithFormat ("Invalid boolean value for skip prologue option: '%s'", option_arg);
232 }
233 break;
Jim Inghamca36cd12012-10-05 19:16:31 +0000234
235 case 'l':
Jim Ingham63129912015-03-16 22:47:38 +0000236 {
237 bool success;
238 m_line_num = StringConvert::ToUInt32 (option_arg, 0, 0, &success);
239 if (!success)
240 error.SetErrorStringWithFormat ("invalid line number: %s.", option_arg);
Jim Inghamca36cd12012-10-05 19:16:31 +0000241 break;
Jim Ingham63129912015-03-16 22:47:38 +0000242 }
Ilia K055ad9b2015-05-18 13:41:01 +0000243
Dawn Perchik23b1dec2015-07-21 22:05:07 +0000244 case 'L':
Jim Ingham0e0984e2015-09-02 01:06:46 +0000245 m_language = Language::GetLanguageTypeFromString (option_arg);
Dawn Perchik23b1dec2015-07-21 22:05:07 +0000246 if (m_language == eLanguageTypeUnknown)
247 error.SetErrorStringWithFormat ("Unknown language type: '%s' for breakpoint", option_arg);
248 break;
249
Ilia K055ad9b2015-05-18 13:41:01 +0000250 case 'm':
251 {
252 bool success;
253 bool value;
254 value = Args::StringToBoolean (option_arg, true, &success);
255 if (value)
256 m_move_to_nearest_code = eLazyBoolYes;
257 else
258 m_move_to_nearest_code = eLazyBoolNo;
259
260 if (!success)
261 error.SetErrorStringWithFormat ("Invalid boolean value for move-to-nearest-code option: '%s'", option_arg);
262 break;
263 }
264
Jim Inghamca36cd12012-10-05 19:16:31 +0000265 case 'M':
266 m_func_names.push_back (option_arg);
267 m_func_name_type_mask |= eFunctionNameTypeMethod;
268 break;
269
270 case 'n':
271 m_func_names.push_back (option_arg);
272 m_func_name_type_mask |= eFunctionNameTypeAuto;
273 break;
274
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000275 case 'N':
276 if (BreakpointID::StringIsBreakpointName(option_arg, error))
277 m_breakpoint_names.push_back (option_arg);
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000278 break;
279
Jim Inghamca36cd12012-10-05 19:16:31 +0000280 case 'o':
281 m_one_shot = true;
282 break;
283
Jim Inghama72b31c2015-04-22 19:42:18 +0000284 case 'O':
285 m_exception_extra_args.AppendArgument ("-O");
286 m_exception_extra_args.AppendArgument (option_arg);
287 break;
288
Jim Inghamca36cd12012-10-05 19:16:31 +0000289 case 'p':
290 m_source_text_regexp.assign (option_arg);
291 break;
292
293 case 'q':
294 m_queue_name.assign (option_arg);
295 break;
296
297 case 'r':
298 m_func_regexp.assign (option_arg);
299 break;
300
301 case 's':
Jim Inghamca36cd12012-10-05 19:16:31 +0000302 m_modules.AppendIfUnique (FileSpec (option_arg, false));
303 break;
Jim Inghamca36cd12012-10-05 19:16:31 +0000304
305 case 'S':
306 m_func_names.push_back (option_arg);
307 m_func_name_type_mask |= eFunctionNameTypeSelector;
308 break;
309
310 case 't' :
Vince Harron5275aaa2015-01-15 20:08:35 +0000311 m_thread_id = StringConvert::ToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
Jim Inghamca36cd12012-10-05 19:16:31 +0000312 if (m_thread_id == LLDB_INVALID_THREAD_ID)
313 error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000314 break;
Jim Inghamca36cd12012-10-05 19:16:31 +0000315
316 case 'T':
317 m_thread_name.assign (option_arg);
318 break;
319
320 case 'w':
321 {
322 bool success;
323 m_throw_bp = Args::StringToBoolean (option_arg, true, &success);
324 if (!success)
325 error.SetErrorStringWithFormat ("Invalid boolean value for on-throw option: '%s'", option_arg);
326 }
327 break;
328
329 case 'x':
Vince Harron5275aaa2015-01-15 20:08:35 +0000330 m_thread_index = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
Jim Inghamca36cd12012-10-05 19:16:31 +0000331 if (m_thread_id == UINT32_MAX)
332 error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000333 break;
Jim Inghamca36cd12012-10-05 19:16:31 +0000334
Jim Ingham5a988412012-06-08 21:56:10 +0000335 default:
336 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
337 break;
338 }
339
340 return error;
341 }
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000342
Jim Ingham5a988412012-06-08 21:56:10 +0000343 void
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000344 OptionParsingStarting () override
Jim Ingham5a988412012-06-08 21:56:10 +0000345 {
346 m_condition.clear();
347 m_filenames.Clear();
348 m_line_num = 0;
349 m_column = 0;
350 m_func_names.clear();
Greg Clayton1f746072012-08-29 21:13:06 +0000351 m_func_name_type_mask = eFunctionNameTypeNone;
Jim Ingham5a988412012-06-08 21:56:10 +0000352 m_func_regexp.clear();
Greg Clayton1f746072012-08-29 21:13:06 +0000353 m_source_text_regexp.clear();
Jim Ingham5a988412012-06-08 21:56:10 +0000354 m_modules.Clear();
Greg Clayton1f746072012-08-29 21:13:06 +0000355 m_load_addr = LLDB_INVALID_ADDRESS;
Jim Ingham5a988412012-06-08 21:56:10 +0000356 m_ignore_count = 0;
357 m_thread_id = LLDB_INVALID_THREAD_ID;
358 m_thread_index = UINT32_MAX;
359 m_thread_name.clear();
360 m_queue_name.clear();
Jim Ingham5a988412012-06-08 21:56:10 +0000361 m_catch_bp = false;
362 m_throw_bp = true;
Greg Claytoneb023e72013-10-11 19:48:25 +0000363 m_hardware = false;
Jim Inghama72b31c2015-04-22 19:42:18 +0000364 m_exception_language = eLanguageTypeUnknown;
Dawn Perchik23b1dec2015-07-21 22:05:07 +0000365 m_language = lldb::eLanguageTypeUnknown;
Jim Ingham5a988412012-06-08 21:56:10 +0000366 m_skip_prologue = eLazyBoolCalculate;
Jim Inghamca36cd12012-10-05 19:16:31 +0000367 m_one_shot = false;
Jim Ingham33df7cd2014-12-06 01:28:03 +0000368 m_use_dummy = false;
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000369 m_breakpoint_names.clear();
Jim Inghame7320522015-02-12 17:37:46 +0000370 m_all_files = false;
Jim Inghama72b31c2015-04-22 19:42:18 +0000371 m_exception_extra_args.Clear();
Ilia K055ad9b2015-05-18 13:41:01 +0000372 m_move_to_nearest_code = eLazyBoolCalculate;
Jim Ingham5a988412012-06-08 21:56:10 +0000373 }
374
375 const OptionDefinition*
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000376 GetDefinitions () override
Jim Ingham5a988412012-06-08 21:56:10 +0000377 {
378 return g_option_table;
379 }
380
381 // Options table: Required for subclasses of Options.
382
383 static OptionDefinition g_option_table[];
384
385 // Instance variables to hold the values for command options.
386
387 std::string m_condition;
388 FileSpecList m_filenames;
389 uint32_t m_line_num;
390 uint32_t m_column;
Jim Ingham5a988412012-06-08 21:56:10 +0000391 std::vector<std::string> m_func_names;
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000392 std::vector<std::string> m_breakpoint_names;
Jim Ingham5a988412012-06-08 21:56:10 +0000393 uint32_t m_func_name_type_mask;
394 std::string m_func_regexp;
395 std::string m_source_text_regexp;
396 FileSpecList m_modules;
397 lldb::addr_t m_load_addr;
398 uint32_t m_ignore_count;
399 lldb::tid_t m_thread_id;
400 uint32_t m_thread_index;
401 std::string m_thread_name;
402 std::string m_queue_name;
403 bool m_catch_bp;
404 bool m_throw_bp;
Greg Claytoneb023e72013-10-11 19:48:25 +0000405 bool m_hardware; // Request to use hardware breakpoints
Jim Inghama72b31c2015-04-22 19:42:18 +0000406 lldb::LanguageType m_exception_language;
Dawn Perchik23b1dec2015-07-21 22:05:07 +0000407 lldb::LanguageType m_language;
Jim Ingham5a988412012-06-08 21:56:10 +0000408 LazyBool m_skip_prologue;
Jim Inghamca36cd12012-10-05 19:16:31 +0000409 bool m_one_shot;
Jim Ingham33df7cd2014-12-06 01:28:03 +0000410 bool m_use_dummy;
Jim Inghame7320522015-02-12 17:37:46 +0000411 bool m_all_files;
Jim Inghama72b31c2015-04-22 19:42:18 +0000412 Args m_exception_extra_args;
Ilia K055ad9b2015-05-18 13:41:01 +0000413 LazyBool m_move_to_nearest_code;
Jim Ingham5a988412012-06-08 21:56:10 +0000414 };
415
416protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000417 bool
Jim Ingham5a988412012-06-08 21:56:10 +0000418 DoExecute (Args& command,
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000419 CommandReturnObject &result) override
Jim Ingham5a988412012-06-08 21:56:10 +0000420 {
Jim Ingham33df7cd2014-12-06 01:28:03 +0000421 Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
422
Jim Ingham893c9322014-11-22 01:42:44 +0000423 if (target == nullptr)
Jim Ingham5a988412012-06-08 21:56:10 +0000424 {
425 result.AppendError ("Invalid target. Must set target before setting breakpoints (see 'target create' command).");
426 result.SetStatus (eReturnStatusFailed);
427 return false;
428 }
429
430 // The following are the various types of breakpoints that could be set:
431 // 1). -f -l -p [-s -g] (setting breakpoint by source location)
432 // 2). -a [-s -g] (setting breakpoint by address)
433 // 3). -n [-s -g] (setting breakpoint by function name)
434 // 4). -r [-s -g] (setting breakpoint by function name regular expression)
435 // 5). -p -f (setting a breakpoint by comparing a reg-exp to source text)
436 // 6). -E [-w -h] (setting a breakpoint for exceptions for a given language.)
437
438 BreakpointSetType break_type = eSetTypeInvalid;
439
440 if (m_options.m_line_num != 0)
441 break_type = eSetTypeFileAndLine;
442 else if (m_options.m_load_addr != LLDB_INVALID_ADDRESS)
443 break_type = eSetTypeAddress;
444 else if (!m_options.m_func_names.empty())
445 break_type = eSetTypeFunctionName;
446 else if (!m_options.m_func_regexp.empty())
447 break_type = eSetTypeFunctionRegexp;
448 else if (!m_options.m_source_text_regexp.empty())
449 break_type = eSetTypeSourceRegexp;
Jim Inghama72b31c2015-04-22 19:42:18 +0000450 else if (m_options.m_exception_language != eLanguageTypeUnknown)
Jim Ingham5a988412012-06-08 21:56:10 +0000451 break_type = eSetTypeException;
452
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000453 Breakpoint *bp = nullptr;
Jim Ingham5a988412012-06-08 21:56:10 +0000454 FileSpec module_spec;
Jim Ingham5a988412012-06-08 21:56:10 +0000455 const bool internal = false;
456
Jim Ingham5a988412012-06-08 21:56:10 +0000457 switch (break_type)
458 {
459 case eSetTypeFileAndLine: // Breakpoint by source position
460 {
461 FileSpec file;
Greg Claytonc7bece562013-01-25 18:06:21 +0000462 const size_t num_files = m_options.m_filenames.GetSize();
Jim Ingham5a988412012-06-08 21:56:10 +0000463 if (num_files == 0)
464 {
465 if (!GetDefaultFile (target, file, result))
466 {
467 result.AppendError("No file supplied and no default file available.");
468 result.SetStatus (eReturnStatusFailed);
469 return false;
470 }
471 }
472 else if (num_files > 1)
473 {
474 result.AppendError("Only one file at a time is allowed for file and line breakpoints.");
475 result.SetStatus (eReturnStatusFailed);
476 return false;
477 }
478 else
479 file = m_options.m_filenames.GetFileSpecAtIndex(0);
Greg Clayton1f746072012-08-29 21:13:06 +0000480
481 // Only check for inline functions if
482 LazyBool check_inlines = eLazyBoolCalculate;
483
Jim Ingham5a988412012-06-08 21:56:10 +0000484 bp = target->CreateBreakpoint (&(m_options.m_modules),
485 file,
486 m_options.m_line_num,
Greg Clayton1f746072012-08-29 21:13:06 +0000487 check_inlines,
Jim Ingham5a988412012-06-08 21:56:10 +0000488 m_options.m_skip_prologue,
Greg Claytoneb023e72013-10-11 19:48:25 +0000489 internal,
Ilia K055ad9b2015-05-18 13:41:01 +0000490 m_options.m_hardware,
491 m_options.m_move_to_nearest_code).get();
Jim Ingham5a988412012-06-08 21:56:10 +0000492 }
493 break;
494
495 case eSetTypeAddress: // Breakpoint by address
Jim Ingham055a08a2015-11-17 03:39:13 +0000496 {
497 // If a shared library has been specified, make an lldb_private::Address with the library, and
498 // use that. That way the address breakpoint will track the load location of the library.
499 size_t num_modules_specified = m_options.m_modules.GetSize();
500 if (num_modules_specified == 1)
501 {
502 const FileSpec *file_spec = m_options.m_modules.GetFileSpecPointerAtIndex(0);
503 bp = target->CreateAddressInModuleBreakpoint (m_options.m_load_addr,
504 internal,
505 file_spec,
506 m_options.m_hardware).get();
507 }
508 else if (num_modules_specified == 0)
509 {
510 bp = target->CreateBreakpoint (m_options.m_load_addr,
511 internal,
512 m_options.m_hardware).get();
513 }
514 else
515 {
516 result.AppendError("Only one shared library can be specified for address breakpoints.");
517 result.SetStatus(eReturnStatusFailed);
518 return false;
519 }
Jim Ingham5a988412012-06-08 21:56:10 +0000520 break;
Jim Ingham055a08a2015-11-17 03:39:13 +0000521 }
Jim Ingham5a988412012-06-08 21:56:10 +0000522 case eSetTypeFunctionName: // Breakpoint by function name
523 {
524 uint32_t name_type_mask = m_options.m_func_name_type_mask;
525
526 if (name_type_mask == 0)
527 name_type_mask = eFunctionNameTypeAuto;
528
529 bp = target->CreateBreakpoint (&(m_options.m_modules),
530 &(m_options.m_filenames),
531 m_options.m_func_names,
532 name_type_mask,
Dawn Perchik23b1dec2015-07-21 22:05:07 +0000533 m_options.m_language,
Jim Ingham5a988412012-06-08 21:56:10 +0000534 m_options.m_skip_prologue,
Greg Claytoneb023e72013-10-11 19:48:25 +0000535 internal,
536 m_options.m_hardware).get();
Jim Ingham5a988412012-06-08 21:56:10 +0000537 }
538 break;
539
540 case eSetTypeFunctionRegexp: // Breakpoint by regular expression function name
541 {
542 RegularExpression regexp(m_options.m_func_regexp.c_str());
543 if (!regexp.IsValid())
544 {
545 char err_str[1024];
546 regexp.GetErrorAsCString(err_str, sizeof(err_str));
547 result.AppendErrorWithFormat("Function name regular expression could not be compiled: \"%s\"",
548 err_str);
549 result.SetStatus (eReturnStatusFailed);
550 return false;
551 }
552
553 bp = target->CreateFuncRegexBreakpoint (&(m_options.m_modules),
554 &(m_options.m_filenames),
555 regexp,
Jim Ingham0fcdac32015-11-06 22:48:59 +0000556 m_options.m_language,
Jim Ingham5a988412012-06-08 21:56:10 +0000557 m_options.m_skip_prologue,
Greg Claytoneb023e72013-10-11 19:48:25 +0000558 internal,
559 m_options.m_hardware).get();
Jim Ingham5a988412012-06-08 21:56:10 +0000560 }
561 break;
562 case eSetTypeSourceRegexp: // Breakpoint by regexp on source text.
563 {
Greg Claytonc7bece562013-01-25 18:06:21 +0000564 const size_t num_files = m_options.m_filenames.GetSize();
Jim Ingham5a988412012-06-08 21:56:10 +0000565
Jim Inghame7320522015-02-12 17:37:46 +0000566 if (num_files == 0 && !m_options.m_all_files)
Jim Ingham5a988412012-06-08 21:56:10 +0000567 {
568 FileSpec file;
569 if (!GetDefaultFile (target, file, result))
570 {
571 result.AppendError ("No files provided and could not find default file.");
572 result.SetStatus (eReturnStatusFailed);
573 return false;
574 }
575 else
576 {
577 m_options.m_filenames.Append (file);
578 }
579 }
580
581 RegularExpression regexp(m_options.m_source_text_regexp.c_str());
582 if (!regexp.IsValid())
583 {
584 char err_str[1024];
585 regexp.GetErrorAsCString(err_str, sizeof(err_str));
586 result.AppendErrorWithFormat("Source text regular expression could not be compiled: \"%s\"",
587 err_str);
588 result.SetStatus (eReturnStatusFailed);
589 return false;
590 }
Greg Claytoneb023e72013-10-11 19:48:25 +0000591 bp = target->CreateSourceRegexBreakpoint (&(m_options.m_modules),
592 &(m_options.m_filenames),
593 regexp,
594 internal,
Ilia K055ad9b2015-05-18 13:41:01 +0000595 m_options.m_hardware,
596 m_options.m_move_to_nearest_code).get();
Jim Ingham5a988412012-06-08 21:56:10 +0000597 }
598 break;
599 case eSetTypeException:
600 {
Jim Inghama72b31c2015-04-22 19:42:18 +0000601 Error precond_error;
602 bp = target->CreateExceptionBreakpoint (m_options.m_exception_language,
Greg Claytoneb023e72013-10-11 19:48:25 +0000603 m_options.m_catch_bp,
604 m_options.m_throw_bp,
Jim Inghama72b31c2015-04-22 19:42:18 +0000605 internal,
606 &m_options.m_exception_extra_args,
607 &precond_error).get();
608 if (precond_error.Fail())
609 {
610 result.AppendErrorWithFormat("Error setting extra exception arguments: %s",
611 precond_error.AsCString());
612 target->RemoveBreakpointByID(bp->GetID());
613 result.SetStatus(eReturnStatusFailed);
614 return false;
615 }
Jim Ingham5a988412012-06-08 21:56:10 +0000616 }
617 break;
618 default:
619 break;
620 }
621
622 // Now set the various options that were passed in:
623 if (bp)
624 {
625 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
626 bp->SetThreadID (m_options.m_thread_id);
627
628 if (m_options.m_thread_index != UINT32_MAX)
629 bp->GetOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index);
630
631 if (!m_options.m_thread_name.empty())
632 bp->GetOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str());
633
634 if (!m_options.m_queue_name.empty())
635 bp->GetOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str());
636
637 if (m_options.m_ignore_count != 0)
638 bp->GetOptions()->SetIgnoreCount(m_options.m_ignore_count);
639
640 if (!m_options.m_condition.empty())
641 bp->GetOptions()->SetCondition(m_options.m_condition.c_str());
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000642
643 if (!m_options.m_breakpoint_names.empty())
644 {
645 Error error; // We don't need to check the error here, since the option parser checked it...
646 for (auto name : m_options.m_breakpoint_names)
647 bp->AddName(name.c_str(), error);
648 }
Jim Inghamca36cd12012-10-05 19:16:31 +0000649
650 bp->SetOneShot (m_options.m_one_shot);
Jim Ingham5a988412012-06-08 21:56:10 +0000651 }
652
653 if (bp)
654 {
655 Stream &output_stream = result.GetOutputStream();
Jim Ingham1391cc72012-09-22 00:04:04 +0000656 const bool show_locations = false;
657 bp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial, show_locations);
Jim Ingham4aeb1982014-12-19 19:45:31 +0000658 if (target == m_interpreter.GetDebugger().GetDummyTarget())
659 output_stream.Printf ("Breakpoint set in dummy target, will get copied into future targets.\n");
660 else
661 {
662 // Don't print out this warning for exception breakpoints. They can get set before the target
663 // is set, but we won't know how to actually set the breakpoint till we run.
664 if (bp->GetNumLocations() == 0 && break_type != eSetTypeException)
665 {
666 output_stream.Printf ("WARNING: Unable to resolve breakpoint to any actual locations.\n");
667 }
668 }
Jim Ingham5a988412012-06-08 21:56:10 +0000669 result.SetStatus (eReturnStatusSuccessFinishResult);
670 }
671 else if (!bp)
672 {
673 result.AppendError ("Breakpoint creation failed: No breakpoint created.");
674 result.SetStatus (eReturnStatusFailed);
675 }
676
677 return result.Succeeded();
678 }
679
680private:
681 bool
682 GetDefaultFile (Target *target, FileSpec &file, CommandReturnObject &result)
683 {
684 uint32_t default_line;
685 // First use the Source Manager's default file.
686 // Then use the current stack frame's file.
687 if (!target->GetSourceManager().GetDefaultFileAndLine(file, default_line))
688 {
Jason Molendab57e4a12013-11-04 09:33:30 +0000689 StackFrame *cur_frame = m_exe_ctx.GetFramePtr();
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000690 if (cur_frame == nullptr)
Jim Ingham5a988412012-06-08 21:56:10 +0000691 {
692 result.AppendError ("No selected frame to use to find the default file.");
693 result.SetStatus (eReturnStatusFailed);
694 return false;
695 }
696 else if (!cur_frame->HasDebugInformation())
697 {
698 result.AppendError ("Cannot use the selected frame to find the default file, it has no debug info.");
699 result.SetStatus (eReturnStatusFailed);
700 return false;
701 }
702 else
703 {
704 const SymbolContext &sc = cur_frame->GetSymbolContext (eSymbolContextLineEntry);
705 if (sc.line_entry.file)
706 {
707 file = sc.line_entry.file;
708 }
709 else
710 {
711 result.AppendError ("Can't find the file for the selected frame to use as the default file.");
712 result.SetStatus (eReturnStatusFailed);
713 return false;
714 }
715 }
716 }
717 return true;
718 }
719
720 CommandOptions m_options;
721};
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000722
Johnny Chen6943e7c2012-05-08 00:43:20 +0000723// If an additional option set beyond LLDB_OPTION_SET_10 is added, make sure to
724// update the numbers passed to LLDB_OPT_SET_FROM_TO(...) appropriately.
Johnny Chen4ab2e6b2012-05-07 23:23:41 +0000725#define LLDB_OPT_FILE ( LLDB_OPT_SET_FROM_TO(1, 9) & ~LLDB_OPT_SET_2 )
726#define LLDB_OPT_NOT_10 ( LLDB_OPT_SET_FROM_TO(1, 10) & ~LLDB_OPT_SET_10 )
Jim Inghama8558b62012-05-22 00:12:20 +0000727#define LLDB_OPT_SKIP_PROLOGUE ( LLDB_OPT_SET_1 | LLDB_OPT_SET_FROM_TO(3,8) )
Ilia K055ad9b2015-05-18 13:41:01 +0000728#define LLDB_OPT_MOVE_TO_NEAREST_CODE ( LLDB_OPT_SET_1 | LLDB_OPT_SET_9 )
Jim Ingham0fcdac32015-11-06 22:48:59 +0000729#define LLDB_OPT_EXPR_LANGUAGE ( LLDB_OPT_SET_FROM_TO(3, 8) )
Jim Ingham87df91b2011-09-23 00:54:11 +0000730
Greg Claytone0d378b2011-03-24 21:19:54 +0000731OptionDefinition
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000732CommandObjectBreakpointSet::CommandOptions::g_option_table[] =
733{
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000734 { LLDB_OPT_NOT_10, false, "shlib", 's', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eModuleCompletion, eArgTypeShlibName,
Jim Ingham64cc29c2012-05-03 20:30:08 +0000735 "Set the breakpoint only in this shared library. "
736 "Can repeat this option multiple times to specify multiple shared libraries."},
Jim Ingham86511212010-06-15 18:47:14 +0000737
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000738 { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount,
Caroline Ticedeaab222010-10-01 19:59:14 +0000739 "Set the number of times this breakpoint is skipped before stopping." },
Jim Ingham1b54c882010-06-16 02:00:15 +0000740
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000741 { LLDB_OPT_SET_ALL, false, "one-shot", 'o', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
Jim Inghamb2b256a2013-04-09 18:05:22 +0000742 "The breakpoint is deleted the first time it causes a stop." },
Jim Inghamca36cd12012-10-05 19:16:31 +0000743
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000744 { LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeExpression,
Johnny Chen7d49c9c2012-05-25 21:10:46 +0000745 "The breakpoint stops only if this condition expression evaluates to true."},
746
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000747 { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadIndex,
Jim Inghama89be912013-03-26 18:29:03 +0000748 "The breakpoint stops only for the thread whose indeX matches this argument."},
Jim Ingham1b54c882010-06-16 02:00:15 +0000749
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000750 { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadID,
Jim Ingham1b54c882010-06-16 02:00:15 +0000751 "The breakpoint stops only for the thread whose TID matches this argument."},
752
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000753 { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadName,
Jim Ingham1b54c882010-06-16 02:00:15 +0000754 "The breakpoint stops only for the thread whose thread name matches this argument."},
755
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000756 { LLDB_OPT_SET_ALL, false, "hardware", 'H', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
Greg Claytoneb023e72013-10-11 19:48:25 +0000757 "Require the breakpoint to use hardware breakpoints."},
758
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000759 { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeQueueName,
Jim Ingham1b54c882010-06-16 02:00:15 +0000760 "The breakpoint stops only for threads in the queue whose name is given by this argument."},
761
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000762 { LLDB_OPT_FILE, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
Jim Ingham289aca62013-02-14 19:10:36 +0000763 "Specifies the source file in which to set this breakpoint. "
764 "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 +0000765 "To set breakpoints on .c/.cpp/.m/.mm files that are #included, set target.inline-breakpoint-strategy"
Jim Ingham289aca62013-02-14 19:10:36 +0000766 " to \"always\"."},
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000767
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000768 { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum,
Jim Ingham87df91b2011-09-23 00:54:11 +0000769 "Specifies the line number on which to set this breakpoint."},
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000770
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000771 // Comment out this option for the moment, as we don't actually use it, but will in the future.
772 // This way users won't see it, but the infrastructure is left in place.
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000773 // { 0, false, "column", 'C', OptionParser::eRequiredArgument, nullptr, "<column>",
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000774 // "Set the breakpoint by source location at this particular column."},
775
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000776 { LLDB_OPT_SET_2, true, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression,
Jim Ingham055a08a2015-11-17 03:39:13 +0000777 "Set the breakpoint at the specified address. "
778 "If the address maps uniquely to a particular "
779 "binary, then the address will be converted to a \"file\" address, so that the breakpoint will track that binary+offset no matter where "
780 "the binary eventually loads. "
781 "Alternately, if you also specify the module - with the -s option - then the address will be treated as "
782 "a file address in that module, and resolved accordingly. Again, this will allow lldb to track that offset on "
783 "subsequent reloads. The module need not have been loaded at the time you specify this breakpoint, and will "
784 "get resolved when the module is loaded."},
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000785
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000786 { LLDB_OPT_SET_3, true, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
Jim Ingham551262d2013-03-27 17:36:54 +0000787 "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 +0000788
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000789 { LLDB_OPT_SET_4, true, "fullname", 'F', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFullName,
Jim Ingham64cc29c2012-05-03 20:30:08 +0000790 "Set the breakpoint by fully qualified function names. For C++ this means namespaces and all arguments, and "
Jason Molendac8badb72015-09-28 23:02:00 +0000791 "for Objective C this means a full function prototype with class and selector. "
Jim Ingham64cc29c2012-05-03 20:30:08 +0000792 "Can be repeated multiple times to make one breakpoint for multiple names." },
Greg Clayton0c5cd902010-06-28 21:30:43 +0000793
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000794 { LLDB_OPT_SET_5, true, "selector", 'S', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeSelector,
Jim Ingham64cc29c2012-05-03 20:30:08 +0000795 "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 +0000796
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000797 { LLDB_OPT_SET_6, true, "method", 'M', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeMethod,
Jim Ingham64cc29c2012-05-03 20:30:08 +0000798 "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 +0000799
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000800 { LLDB_OPT_SET_7, true, "func-regex", 'r', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeRegularExpression,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000801 "Set the breakpoint by function name, evaluating a regular-expression to find the function name(s)." },
802
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000803 { LLDB_OPT_SET_8, true, "basename", 'b', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
Jim Ingham64cc29c2012-05-03 20:30:08 +0000804 "Set the breakpoint by function basename (C++ namespaces and arguments will be ignored). "
805 "Can be repeated multiple times to make one breakpoint for multiple symbols." },
Greg Claytone02b8502010-10-12 04:29:14 +0000806
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000807 { LLDB_OPT_SET_9, true, "source-pattern-regexp", 'p', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeRegularExpression,
Jim Inghame96ade82013-06-07 01:13:00 +0000808 "Set the breakpoint by specifying a regular expression which is matched against the source text in a source file or files "
809 "specified with the -f option. The -f option can be specified more than once. "
Jim Inghamcc3a4592016-02-09 18:53:49 +0000810 "If no source files are specified, uses the current \"default source file\". "
811 "If you want to match against all source files, pass the \"--all-files\" option." },
Jim Ingham969795f2011-09-21 01:17:13 +0000812
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000813 { LLDB_OPT_SET_9, false, "all-files", 'A', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
Jim Inghame7320522015-02-12 17:37:46 +0000814 "All files are searched for source pattern matches." },
815
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000816 { LLDB_OPT_SET_10, true, "language-exception", 'E', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage,
Jim Inghamfab10e82012-03-06 00:37:27 +0000817 "Set the breakpoint on exceptions thrown by the specified language (without options, on throw but not catch.)" },
818
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000819 { LLDB_OPT_SET_10, false, "on-throw", 'w', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean,
Jim Inghamb4a5aa22016-02-10 22:30:20 +0000820 "Set the breakpoint on exception throW." },
Jim Inghamfab10e82012-03-06 00:37:27 +0000821
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000822 { LLDB_OPT_SET_10, false, "on-catch", 'h', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean,
Jim Inghamb4a5aa22016-02-10 22:30:20 +0000823 "Set the breakpoint on exception catcH." },
Jim Ingham969795f2011-09-21 01:17:13 +0000824
Jim Inghama72b31c2015-04-22 19:42:18 +0000825// Don't add this option till it actually does something useful...
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000826// { LLDB_OPT_SET_10, false, "exception-typename", 'O', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeTypeName,
Jim Inghama72b31c2015-04-22 19:42:18 +0000827// "The breakpoint will only stop if an exception Object of this type is thrown. Can be repeated multiple times to stop for multiple object types" },
828
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000829 { LLDB_OPT_EXPR_LANGUAGE, false, "language", 'L', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage,
Dawn Perchik4112ab92015-07-22 02:01:32 +0000830 "Specifies the Language to use when interpreting the breakpoint's expression (note: currently only implemented for setting breakpoints on identifiers). If not set the target.language setting is used." },
Dawn Perchik23b1dec2015-07-21 22:05:07 +0000831
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000832 { LLDB_OPT_SKIP_PROLOGUE, false, "skip-prologue", 'K', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean,
Jim Inghama8558b62012-05-22 00:12:20 +0000833 "sKip the prologue if the breakpoint is at the beginning of a function. If not set the target.skip-prologue setting is used." },
834
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000835 { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
Jim Ingham33df7cd2014-12-06 01:28:03 +0000836 "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
837
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000838 { LLDB_OPT_SET_ALL, false, "breakpoint-name", 'N', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBreakpointName,
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000839 "Adds this to the list of names for this breakopint."},
840
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000841 { LLDB_OPT_MOVE_TO_NEAREST_CODE, false, "move-to-nearest-code", 'm', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean,
Ilia K055ad9b2015-05-18 13:41:01 +0000842 "Move breakpoints to nearest code. If not set the target.move-to-nearest-code setting is used." },
843
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000844 { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000845};
846
Jim Ingham5a988412012-06-08 21:56:10 +0000847//-------------------------------------------------------------------------
848// CommandObjectBreakpointModify
849//-------------------------------------------------------------------------
850#pragma mark Modify
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000851
Jim Ingham5a988412012-06-08 21:56:10 +0000852class CommandObjectBreakpointModify : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000853{
Jim Ingham5a988412012-06-08 21:56:10 +0000854public:
Jim Ingham5a988412012-06-08 21:56:10 +0000855 CommandObjectBreakpointModify (CommandInterpreter &interpreter) :
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000856 CommandObjectParsed(interpreter,
857 "breakpoint modify",
858 "Modify the options on a breakpoint or set of breakpoints in the executable. "
859 "If no breakpoint is specified, acts on the last created breakpoint. "
860 "With the exception of -e, -d and -i, passing an empty argument clears the modification.",
861 nullptr),
Jim Ingham5a988412012-06-08 21:56:10 +0000862 m_options (interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000863 {
Jim Ingham5a988412012-06-08 21:56:10 +0000864 CommandArgumentEntry arg;
865 CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
866 // Add the entry for the first argument for this command to the object's arguments vector.
867 m_arguments.push_back (arg);
868 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000869
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000870 ~CommandObjectBreakpointModify() override = default;
Greg Clayton0c5cd902010-06-28 21:30:43 +0000871
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000872 Options *
873 GetOptions () override
Jim Ingham5a988412012-06-08 21:56:10 +0000874 {
875 return &m_options;
876 }
Johnny Chen7d49c9c2012-05-25 21:10:46 +0000877
Jim Ingham5a988412012-06-08 21:56:10 +0000878 class CommandOptions : public Options
879 {
880 public:
Jim Ingham5a988412012-06-08 21:56:10 +0000881 CommandOptions (CommandInterpreter &interpreter) :
882 Options (interpreter),
883 m_ignore_count (0),
884 m_thread_id(LLDB_INVALID_THREAD_ID),
885 m_thread_id_passed(false),
886 m_thread_index (UINT32_MAX),
887 m_thread_index_passed(false),
888 m_thread_name(),
889 m_queue_name(),
890 m_condition (),
Jim Inghamca36cd12012-10-05 19:16:31 +0000891 m_one_shot (false),
Jim Ingham5a988412012-06-08 21:56:10 +0000892 m_enable_passed (false),
893 m_enable_value (false),
894 m_name_passed (false),
895 m_queue_passed (false),
Jim Inghamca36cd12012-10-05 19:16:31 +0000896 m_condition_passed (false),
Jim Ingham33df7cd2014-12-06 01:28:03 +0000897 m_one_shot_passed (false),
898 m_use_dummy (false)
Jim Ingham5a988412012-06-08 21:56:10 +0000899 {
900 }
Greg Clayton0c5cd902010-06-28 21:30:43 +0000901
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000902 ~CommandOptions() override = default;
Greg Clayton0c5cd902010-06-28 21:30:43 +0000903
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000904 Error
905 SetOptionValue (uint32_t option_idx, const char *option_arg) override
Jim Ingham5a988412012-06-08 21:56:10 +0000906 {
907 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000908 const int short_option = m_getopt_table[option_idx].val;
Greg Claytone02b8502010-10-12 04:29:14 +0000909
Jim Ingham5a988412012-06-08 21:56:10 +0000910 switch (short_option)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000911 {
Jim Ingham5a988412012-06-08 21:56:10 +0000912 case 'c':
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000913 if (option_arg != nullptr)
Jim Ingham5a988412012-06-08 21:56:10 +0000914 m_condition.assign (option_arg);
915 else
916 m_condition.clear();
917 m_condition_passed = true;
918 break;
919 case 'd':
920 m_enable_passed = true;
921 m_enable_value = false;
922 break;
Jim Ingham33df7cd2014-12-06 01:28:03 +0000923 case 'D':
924 m_use_dummy = true;
925 break;
Jim Ingham5a988412012-06-08 21:56:10 +0000926 case 'e':
927 m_enable_passed = true;
928 m_enable_value = true;
929 break;
930 case 'i':
Vince Harron5275aaa2015-01-15 20:08:35 +0000931 m_ignore_count = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
Jim Ingham5a988412012-06-08 21:56:10 +0000932 if (m_ignore_count == UINT32_MAX)
933 error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000934 break;
Jim Inghamca36cd12012-10-05 19:16:31 +0000935 case 'o':
936 {
937 bool value, success;
938 value = Args::StringToBoolean(option_arg, false, &success);
939 if (success)
940 {
941 m_one_shot_passed = true;
942 m_one_shot = value;
943 }
944 else
945 error.SetErrorStringWithFormat("invalid boolean value '%s' passed for -o option", option_arg);
946 }
947 break;
Jim Ingham5a988412012-06-08 21:56:10 +0000948 case 't' :
Jim Ingham5a988412012-06-08 21:56:10 +0000949 if (option_arg[0] == '\0')
Jim Ingham87df91b2011-09-23 00:54:11 +0000950 {
Jim Ingham5a988412012-06-08 21:56:10 +0000951 m_thread_id = LLDB_INVALID_THREAD_ID;
952 m_thread_id_passed = true;
Jim Ingham87df91b2011-09-23 00:54:11 +0000953 }
954 else
955 {
Vince Harron5275aaa2015-01-15 20:08:35 +0000956 m_thread_id = StringConvert::ToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
Jim Ingham5a988412012-06-08 21:56:10 +0000957 if (m_thread_id == LLDB_INVALID_THREAD_ID)
958 error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
959 else
960 m_thread_id_passed = true;
Jim Ingham87df91b2011-09-23 00:54:11 +0000961 }
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000962 break;
Jim Ingham5a988412012-06-08 21:56:10 +0000963 case 'T':
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000964 if (option_arg != nullptr)
Jim Ingham5a988412012-06-08 21:56:10 +0000965 m_thread_name.assign (option_arg);
966 else
967 m_thread_name.clear();
968 m_name_passed = true;
969 break;
970 case 'q':
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000971 if (option_arg != nullptr)
Jim Ingham5a988412012-06-08 21:56:10 +0000972 m_queue_name.assign (option_arg);
973 else
974 m_queue_name.clear();
975 m_queue_passed = true;
976 break;
977 case 'x':
Jim Ingham5a988412012-06-08 21:56:10 +0000978 if (option_arg[0] == '\n')
979 {
980 m_thread_index = UINT32_MAX;
981 m_thread_index_passed = true;
982 }
983 else
984 {
Vince Harron5275aaa2015-01-15 20:08:35 +0000985 m_thread_index = StringConvert::ToUInt32 (option_arg, UINT32_MAX, 0);
Jim Ingham5a988412012-06-08 21:56:10 +0000986 if (m_thread_id == UINT32_MAX)
987 error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
988 else
989 m_thread_index_passed = true;
990 }
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000991 break;
Jim Ingham5a988412012-06-08 21:56:10 +0000992 default:
993 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
994 break;
Jim Ingham969795f2011-09-21 01:17:13 +0000995 }
Jim Ingham5a988412012-06-08 21:56:10 +0000996
997 return error;
998 }
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +0000999
Jim Ingham5a988412012-06-08 21:56:10 +00001000 void
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001001 OptionParsingStarting () override
Jim Ingham5a988412012-06-08 21:56:10 +00001002 {
1003 m_ignore_count = 0;
1004 m_thread_id = LLDB_INVALID_THREAD_ID;
1005 m_thread_id_passed = false;
1006 m_thread_index = UINT32_MAX;
1007 m_thread_index_passed = false;
1008 m_thread_name.clear();
1009 m_queue_name.clear();
1010 m_condition.clear();
Jim Inghamca36cd12012-10-05 19:16:31 +00001011 m_one_shot = false;
Jim Ingham5a988412012-06-08 21:56:10 +00001012 m_enable_passed = false;
1013 m_queue_passed = false;
1014 m_name_passed = false;
1015 m_condition_passed = false;
Jim Inghamca36cd12012-10-05 19:16:31 +00001016 m_one_shot_passed = false;
Jim Ingham33df7cd2014-12-06 01:28:03 +00001017 m_use_dummy = false;
Jim Ingham5a988412012-06-08 21:56:10 +00001018 }
1019
1020 const OptionDefinition*
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001021 GetDefinitions () override
Jim Ingham5a988412012-06-08 21:56:10 +00001022 {
1023 return g_option_table;
1024 }
1025
Jim Ingham5a988412012-06-08 21:56:10 +00001026 // Options table: Required for subclasses of Options.
1027
1028 static OptionDefinition g_option_table[];
1029
1030 // Instance variables to hold the values for command options.
1031
1032 uint32_t m_ignore_count;
1033 lldb::tid_t m_thread_id;
1034 bool m_thread_id_passed;
1035 uint32_t m_thread_index;
1036 bool m_thread_index_passed;
1037 std::string m_thread_name;
1038 std::string m_queue_name;
1039 std::string m_condition;
Jim Inghamca36cd12012-10-05 19:16:31 +00001040 bool m_one_shot;
Jim Ingham5a988412012-06-08 21:56:10 +00001041 bool m_enable_passed;
1042 bool m_enable_value;
1043 bool m_name_passed;
1044 bool m_queue_passed;
1045 bool m_condition_passed;
Jim Inghamca36cd12012-10-05 19:16:31 +00001046 bool m_one_shot_passed;
Jim Ingham33df7cd2014-12-06 01:28:03 +00001047 bool m_use_dummy;
Jim Ingham5a988412012-06-08 21:56:10 +00001048 };
1049
1050protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001051 bool
1052 DoExecute (Args& command, CommandReturnObject &result) override
Jim Ingham5a988412012-06-08 21:56:10 +00001053 {
Jim Ingham33df7cd2014-12-06 01:28:03 +00001054 Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00001055 if (target == nullptr)
Jim Ingham5a988412012-06-08 21:56:10 +00001056 {
1057 result.AppendError ("Invalid target. No existing target or breakpoints.");
1058 result.SetStatus (eReturnStatusFailed);
1059 return false;
1060 }
1061
1062 Mutex::Locker locker;
1063 target->GetBreakpointList().GetListMutex(locker);
1064
1065 BreakpointIDList valid_bp_ids;
1066
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001067 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
Jim Ingham5a988412012-06-08 21:56:10 +00001068
1069 if (result.Succeeded())
1070 {
1071 const size_t count = valid_bp_ids.GetSize();
1072 for (size_t i = 0; i < count; ++i)
Jim Inghamfab10e82012-03-06 00:37:27 +00001073 {
Jim Ingham5a988412012-06-08 21:56:10 +00001074 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1075
1076 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
1077 {
1078 Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1079 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
1080 {
1081 BreakpointLocation *location = bp->FindLocationByID (cur_bp_id.GetLocationID()).get();
1082 if (location)
1083 {
1084 if (m_options.m_thread_id_passed)
1085 location->SetThreadID (m_options.m_thread_id);
1086
1087 if (m_options.m_thread_index_passed)
1088 location->SetThreadIndex(m_options.m_thread_index);
1089
1090 if (m_options.m_name_passed)
1091 location->SetThreadName(m_options.m_thread_name.c_str());
1092
1093 if (m_options.m_queue_passed)
1094 location->SetQueueName(m_options.m_queue_name.c_str());
1095
1096 if (m_options.m_ignore_count != 0)
1097 location->SetIgnoreCount(m_options.m_ignore_count);
1098
1099 if (m_options.m_enable_passed)
1100 location->SetEnabled (m_options.m_enable_value);
1101
1102 if (m_options.m_condition_passed)
1103 location->SetCondition (m_options.m_condition.c_str());
1104 }
1105 }
1106 else
1107 {
1108 if (m_options.m_thread_id_passed)
1109 bp->SetThreadID (m_options.m_thread_id);
1110
1111 if (m_options.m_thread_index_passed)
1112 bp->SetThreadIndex(m_options.m_thread_index);
1113
1114 if (m_options.m_name_passed)
1115 bp->SetThreadName(m_options.m_thread_name.c_str());
1116
1117 if (m_options.m_queue_passed)
1118 bp->SetQueueName(m_options.m_queue_name.c_str());
1119
1120 if (m_options.m_ignore_count != 0)
1121 bp->SetIgnoreCount(m_options.m_ignore_count);
1122
1123 if (m_options.m_enable_passed)
1124 bp->SetEnabled (m_options.m_enable_value);
1125
1126 if (m_options.m_condition_passed)
1127 bp->SetCondition (m_options.m_condition.c_str());
1128 }
1129 }
Jim Inghamfab10e82012-03-06 00:37:27 +00001130 }
Jim Ingham5a988412012-06-08 21:56:10 +00001131 }
1132
1133 return result.Succeeded();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001134 }
1135
Jim Ingham5a988412012-06-08 21:56:10 +00001136private:
1137 CommandOptions m_options;
1138};
Johnny Chen7d49c9c2012-05-25 21:10:46 +00001139
Jim Ingham5a988412012-06-08 21:56:10 +00001140#pragma mark Modify::CommandOptions
1141OptionDefinition
1142CommandObjectBreakpointModify::CommandOptions::g_option_table[] =
1143{
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00001144{ LLDB_OPT_SET_ALL, false, "ignore-count", 'i', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount, "Set the number of times this breakpoint is skipped before stopping." },
1145{ LLDB_OPT_SET_ALL, false, "one-shot", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "The breakpoint is deleted the first time it stop causes a stop." },
1146{ LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadIndex, "The breakpoint stops only for the thread whose index matches this argument."},
1147{ LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadID, "The breakpoint stops only for the thread whose TID matches this argument."},
1148{ LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadName, "The breakpoint stops only for the thread whose thread name matches this argument."},
1149{ LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeQueueName, "The breakpoint stops only for threads in the queue whose name is given by this argument."},
1150{ LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeExpression, "The breakpoint stops only if this condition expression evaluates to true."},
1151{ LLDB_OPT_SET_1, false, "enable", 'e', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Enable the breakpoint."},
1152{ LLDB_OPT_SET_2, false, "disable", 'd', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Disable the breakpoint."},
1153{ LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
Jim Ingham33df7cd2014-12-06 01:28:03 +00001154
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00001155{ 0, false, nullptr, 0 , 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
Jim Ingham5a988412012-06-08 21:56:10 +00001156};
1157
1158//-------------------------------------------------------------------------
1159// CommandObjectBreakpointEnable
1160//-------------------------------------------------------------------------
1161#pragma mark Enable
1162
1163class CommandObjectBreakpointEnable : public CommandObjectParsed
1164{
1165public:
1166 CommandObjectBreakpointEnable (CommandInterpreter &interpreter) :
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00001167 CommandObjectParsed(interpreter,
1168 "enable",
1169 "Enable the specified disabled breakpoint(s). If no breakpoints are specified, enable all of them.",
1170 nullptr)
Jim Ingham5a988412012-06-08 21:56:10 +00001171 {
1172 CommandArgumentEntry arg;
1173 CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
1174 // Add the entry for the first argument for this command to the object's arguments vector.
1175 m_arguments.push_back (arg);
1176 }
1177
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00001178 ~CommandObjectBreakpointEnable() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +00001179
1180protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001181 bool
1182 DoExecute (Args& command, CommandReturnObject &result) override
Jim Ingham5a988412012-06-08 21:56:10 +00001183 {
Jim Ingham893c9322014-11-22 01:42:44 +00001184 Target *target = GetSelectedOrDummyTarget();
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00001185 if (target == nullptr)
Jim Ingham5a988412012-06-08 21:56:10 +00001186 {
1187 result.AppendError ("Invalid target. No existing target or breakpoints.");
1188 result.SetStatus (eReturnStatusFailed);
1189 return false;
1190 }
1191
1192 Mutex::Locker locker;
1193 target->GetBreakpointList().GetListMutex(locker);
1194
1195 const BreakpointList &breakpoints = target->GetBreakpointList();
1196
1197 size_t num_breakpoints = breakpoints.GetSize();
1198
1199 if (num_breakpoints == 0)
1200 {
1201 result.AppendError ("No breakpoints exist to be enabled.");
1202 result.SetStatus (eReturnStatusFailed);
1203 return false;
1204 }
1205
1206 if (command.GetArgumentCount() == 0)
1207 {
1208 // No breakpoint selected; enable all currently set breakpoints.
1209 target->EnableAllBreakpoints ();
Greg Clayton6fea17e2014-03-03 19:15:20 +00001210 result.AppendMessageWithFormat ("All breakpoints enabled. (%" PRIu64 " breakpoints)\n", (uint64_t)num_breakpoints);
Jim Ingham5a988412012-06-08 21:56:10 +00001211 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1212 }
1213 else
1214 {
1215 // Particular breakpoint selected; enable that breakpoint.
1216 BreakpointIDList valid_bp_ids;
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001217 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
Jim Ingham5a988412012-06-08 21:56:10 +00001218
1219 if (result.Succeeded())
1220 {
1221 int enable_count = 0;
1222 int loc_count = 0;
1223 const size_t count = valid_bp_ids.GetSize();
1224 for (size_t i = 0; i < count; ++i)
1225 {
1226 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1227
1228 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
1229 {
1230 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1231 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
1232 {
1233 BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
1234 if (location)
1235 {
1236 location->SetEnabled (true);
1237 ++loc_count;
1238 }
1239 }
1240 else
1241 {
1242 breakpoint->SetEnabled (true);
1243 ++enable_count;
1244 }
1245 }
1246 }
1247 result.AppendMessageWithFormat ("%d breakpoints enabled.\n", enable_count + loc_count);
1248 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1249 }
1250 }
1251
1252 return result.Succeeded();
1253 }
1254};
1255
1256//-------------------------------------------------------------------------
1257// CommandObjectBreakpointDisable
1258//-------------------------------------------------------------------------
1259#pragma mark Disable
1260
1261class CommandObjectBreakpointDisable : public CommandObjectParsed
1262{
1263public:
1264 CommandObjectBreakpointDisable (CommandInterpreter &interpreter) :
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00001265 CommandObjectParsed(interpreter,
1266 "breakpoint disable",
1267 "Disable the specified breakpoint(s) without removing them. If none are specified, disable all breakpoints.",
1268 nullptr)
Jim Ingham5a988412012-06-08 21:56:10 +00001269 {
Jim Inghamb0fac502013-03-08 00:31:40 +00001270 SetHelpLong(
Kate Stoneea671fb2015-07-14 05:48:36 +00001271"Disable the specified breakpoint(s) without removing them. \
1272If none are specified, disable all breakpoints." R"(
1273
1274)" "Note: disabling a breakpoint will cause none of its locations to be hit \
1275regardless of whether they are enabled or disabled. After the sequence:" R"(
1276
1277 (lldb) break disable 1
1278 (lldb) break enable 1.1
1279
1280execution will NOT stop at location 1.1. To achieve that, type:
1281
1282 (lldb) break disable 1.*
1283 (lldb) break enable 1.1
1284
1285)" "The first command disables all the locations of breakpoint 1, \
Jim Inghamb0fac502013-03-08 00:31:40 +00001286the second re-enables the first location."
Kate Stoneea671fb2015-07-14 05:48:36 +00001287 );
Jim Inghamb0fac502013-03-08 00:31:40 +00001288
Jim Ingham5a988412012-06-08 21:56:10 +00001289 CommandArgumentEntry arg;
1290 CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
1291 // Add the entry for the first argument for this command to the object's arguments vector.
Jim Inghamb0fac502013-03-08 00:31:40 +00001292 m_arguments.push_back (arg);
Jim Ingham5a988412012-06-08 21:56:10 +00001293 }
1294
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00001295 ~CommandObjectBreakpointDisable() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +00001296
1297protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001298 bool
1299 DoExecute (Args& command, CommandReturnObject &result) override
Jim Ingham5a988412012-06-08 21:56:10 +00001300 {
Jim Ingham893c9322014-11-22 01:42:44 +00001301 Target *target = GetSelectedOrDummyTarget();
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00001302 if (target == nullptr)
Jim Ingham5a988412012-06-08 21:56:10 +00001303 {
1304 result.AppendError ("Invalid target. No existing target or breakpoints.");
1305 result.SetStatus (eReturnStatusFailed);
1306 return false;
1307 }
1308
1309 Mutex::Locker locker;
1310 target->GetBreakpointList().GetListMutex(locker);
1311
1312 const BreakpointList &breakpoints = target->GetBreakpointList();
1313 size_t num_breakpoints = breakpoints.GetSize();
1314
1315 if (num_breakpoints == 0)
1316 {
1317 result.AppendError ("No breakpoints exist to be disabled.");
1318 result.SetStatus (eReturnStatusFailed);
1319 return false;
1320 }
1321
1322 if (command.GetArgumentCount() == 0)
1323 {
1324 // No breakpoint selected; disable all currently set breakpoints.
1325 target->DisableAllBreakpoints ();
Greg Clayton6fea17e2014-03-03 19:15:20 +00001326 result.AppendMessageWithFormat ("All breakpoints disabled. (%" PRIu64 " breakpoints)\n", (uint64_t)num_breakpoints);
Jim Ingham5a988412012-06-08 21:56:10 +00001327 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1328 }
1329 else
1330 {
1331 // Particular breakpoint selected; disable that breakpoint.
1332 BreakpointIDList valid_bp_ids;
1333
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001334 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
Jim Ingham5a988412012-06-08 21:56:10 +00001335
1336 if (result.Succeeded())
1337 {
1338 int disable_count = 0;
1339 int loc_count = 0;
1340 const size_t count = valid_bp_ids.GetSize();
1341 for (size_t i = 0; i < count; ++i)
1342 {
1343 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1344
1345 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
1346 {
1347 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1348 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
1349 {
1350 BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
1351 if (location)
1352 {
1353 location->SetEnabled (false);
1354 ++loc_count;
1355 }
1356 }
1357 else
1358 {
1359 breakpoint->SetEnabled (false);
1360 ++disable_count;
1361 }
1362 }
1363 }
1364 result.AppendMessageWithFormat ("%d breakpoints disabled.\n", disable_count + loc_count);
1365 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1366 }
1367 }
1368
1369 return result.Succeeded();
1370 }
Jim Ingham5a988412012-06-08 21:56:10 +00001371};
1372
1373//-------------------------------------------------------------------------
1374// CommandObjectBreakpointList
1375//-------------------------------------------------------------------------
1376#pragma mark List
1377
1378class CommandObjectBreakpointList : public CommandObjectParsed
1379{
1380public:
1381 CommandObjectBreakpointList (CommandInterpreter &interpreter) :
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00001382 CommandObjectParsed(interpreter,
1383 "breakpoint list",
1384 "List some or all breakpoints at configurable levels of detail.",
1385 nullptr),
Jim Ingham5a988412012-06-08 21:56:10 +00001386 m_options (interpreter)
1387 {
1388 CommandArgumentEntry arg;
1389 CommandArgumentData bp_id_arg;
1390
1391 // Define the first (and only) variant of this arg.
1392 bp_id_arg.arg_type = eArgTypeBreakpointID;
1393 bp_id_arg.arg_repetition = eArgRepeatOptional;
1394
1395 // There is only one variant this argument could be; put it into the argument entry.
1396 arg.push_back (bp_id_arg);
1397
1398 // Push the data for the first argument into the m_arguments vector.
1399 m_arguments.push_back (arg);
1400 }
1401
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00001402 ~CommandObjectBreakpointList() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +00001403
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001404 Options *
1405 GetOptions () override
Jim Ingham5a988412012-06-08 21:56:10 +00001406 {
1407 return &m_options;
Jim Ingham1b54c882010-06-16 02:00:15 +00001408 }
1409
Jim Ingham5a988412012-06-08 21:56:10 +00001410 class CommandOptions : public Options
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001411 {
Jim Ingham5a988412012-06-08 21:56:10 +00001412 public:
Jim Ingham5a988412012-06-08 21:56:10 +00001413 CommandOptions (CommandInterpreter &interpreter) :
1414 Options (interpreter),
Jim Ingham33df7cd2014-12-06 01:28:03 +00001415 m_level (lldb::eDescriptionLevelBrief),
1416 m_use_dummy(false)
Jim Ingham5a988412012-06-08 21:56:10 +00001417 {
1418 }
1419
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00001420 ~CommandOptions() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +00001421
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001422 Error
1423 SetOptionValue (uint32_t option_idx, const char *option_arg) override
Jim Ingham5a988412012-06-08 21:56:10 +00001424 {
1425 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +00001426 const int short_option = m_getopt_table[option_idx].val;
Jim Ingham5a988412012-06-08 21:56:10 +00001427
1428 switch (short_option)
1429 {
1430 case 'b':
1431 m_level = lldb::eDescriptionLevelBrief;
1432 break;
Jim Ingham33df7cd2014-12-06 01:28:03 +00001433 case 'D':
1434 m_use_dummy = true;
1435 break;
Jim Ingham5a988412012-06-08 21:56:10 +00001436 case 'f':
1437 m_level = lldb::eDescriptionLevelFull;
1438 break;
1439 case 'v':
1440 m_level = lldb::eDescriptionLevelVerbose;
1441 break;
1442 case 'i':
1443 m_internal = true;
1444 break;
1445 default:
1446 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1447 break;
1448 }
1449
1450 return error;
1451 }
1452
1453 void
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001454 OptionParsingStarting () override
Jim Ingham5a988412012-06-08 21:56:10 +00001455 {
1456 m_level = lldb::eDescriptionLevelFull;
1457 m_internal = false;
Jim Ingham33df7cd2014-12-06 01:28:03 +00001458 m_use_dummy = false;
Jim Ingham5a988412012-06-08 21:56:10 +00001459 }
1460
1461 const OptionDefinition *
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001462 GetDefinitions () override
Jim Ingham5a988412012-06-08 21:56:10 +00001463 {
1464 return g_option_table;
1465 }
1466
1467 // Options table: Required for subclasses of Options.
1468
1469 static OptionDefinition g_option_table[];
1470
1471 // Instance variables to hold the values for command options.
1472
1473 lldb::DescriptionLevel m_level;
1474
1475 bool m_internal;
Jim Ingham33df7cd2014-12-06 01:28:03 +00001476 bool m_use_dummy;
Jim Ingham5a988412012-06-08 21:56:10 +00001477 };
1478
1479protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001480 bool
1481 DoExecute (Args& command, CommandReturnObject &result) override
Jim Ingham5a988412012-06-08 21:56:10 +00001482 {
Jim Ingham33df7cd2014-12-06 01:28:03 +00001483 Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
1484
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00001485 if (target == nullptr)
Jim Ingham5a988412012-06-08 21:56:10 +00001486 {
1487 result.AppendError ("Invalid target. No current target or breakpoints.");
1488 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1489 return true;
1490 }
1491
1492 const BreakpointList &breakpoints = target->GetBreakpointList(m_options.m_internal);
1493 Mutex::Locker locker;
1494 target->GetBreakpointList(m_options.m_internal).GetListMutex(locker);
1495
1496 size_t num_breakpoints = breakpoints.GetSize();
1497
1498 if (num_breakpoints == 0)
1499 {
1500 result.AppendMessage ("No breakpoints currently set.");
1501 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1502 return true;
1503 }
1504
Jim Ingham85e8b812011-02-19 02:53:09 +00001505 Stream &output_stream = result.GetOutputStream();
Jim Ingham5a988412012-06-08 21:56:10 +00001506
1507 if (command.GetArgumentCount() == 0)
1508 {
1509 // No breakpoint selected; show info about all currently set breakpoints.
1510 result.AppendMessage ("Current breakpoints:");
1511 for (size_t i = 0; i < num_breakpoints; ++i)
1512 {
1513 Breakpoint *breakpoint = breakpoints.GetBreakpointAtIndex (i).get();
1514 AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
1515 }
1516 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1517 }
1518 else
1519 {
1520 // Particular breakpoints selected; show info about that breakpoint.
1521 BreakpointIDList valid_bp_ids;
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001522 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
Jim Ingham5a988412012-06-08 21:56:10 +00001523
1524 if (result.Succeeded())
1525 {
1526 for (size_t i = 0; i < valid_bp_ids.GetSize(); ++i)
1527 {
1528 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1529 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1530 AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
1531 }
1532 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1533 }
1534 else
1535 {
1536 result.AppendError ("Invalid breakpoint id.");
1537 result.SetStatus (eReturnStatusFailed);
1538 }
1539 }
1540
1541 return result.Succeeded();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001542 }
1543
Jim Ingham5a988412012-06-08 21:56:10 +00001544private:
1545 CommandOptions m_options;
1546};
1547
1548#pragma mark List::CommandOptions
1549OptionDefinition
1550CommandObjectBreakpointList::CommandOptions::g_option_table[] =
1551{
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00001552 { LLDB_OPT_SET_ALL, false, "internal", 'i', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
Jim Ingham5a988412012-06-08 21:56:10 +00001553 "Show debugger internal breakpoints" },
1554
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00001555 { LLDB_OPT_SET_1, false, "brief", 'b', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
Jim Ingham5a988412012-06-08 21:56:10 +00001556 "Give a brief description of the breakpoint (no location info)."},
1557
1558 // FIXME: We need to add an "internal" command, and then add this sort of thing to it.
1559 // But I need to see it for now, and don't want to wait.
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00001560 { LLDB_OPT_SET_2, false, "full", 'f', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
Jim Ingham5a988412012-06-08 21:56:10 +00001561 "Give a full description of the breakpoint and its locations."},
1562
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00001563 { LLDB_OPT_SET_3, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
Jim Ingham5a988412012-06-08 21:56:10 +00001564 "Explain everything we know about the breakpoint (for debugging debugger bugs)." },
1565
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00001566 { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
Jim Ingham33df7cd2014-12-06 01:28:03 +00001567 "List Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
1568
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00001569 { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
Jim Ingham5a988412012-06-08 21:56:10 +00001570};
1571
1572//-------------------------------------------------------------------------
1573// CommandObjectBreakpointClear
1574//-------------------------------------------------------------------------
1575#pragma mark Clear
1576
1577class CommandObjectBreakpointClear : public CommandObjectParsed
1578{
1579public:
Jim Ingham5a988412012-06-08 21:56:10 +00001580 typedef enum BreakpointClearType
1581 {
1582 eClearTypeInvalid,
1583 eClearTypeFileAndLine
1584 } BreakpointClearType;
1585
1586 CommandObjectBreakpointClear (CommandInterpreter &interpreter) :
1587 CommandObjectParsed (interpreter,
1588 "breakpoint clear",
1589 "Clears a breakpoint or set of breakpoints in the executable.",
1590 "breakpoint clear <cmd-options>"),
1591 m_options (interpreter)
1592 {
1593 }
1594
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00001595 ~CommandObjectBreakpointClear() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +00001596
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001597 Options *
1598 GetOptions () override
Jim Ingham5a988412012-06-08 21:56:10 +00001599 {
1600 return &m_options;
1601 }
1602
1603 class CommandOptions : public Options
1604 {
1605 public:
Jim Ingham5a988412012-06-08 21:56:10 +00001606 CommandOptions (CommandInterpreter &interpreter) :
1607 Options (interpreter),
1608 m_filename (),
1609 m_line_num (0)
1610 {
1611 }
1612
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00001613 ~CommandOptions() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +00001614
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001615 Error
1616 SetOptionValue (uint32_t option_idx, const char *option_arg) override
Jim Ingham5a988412012-06-08 21:56:10 +00001617 {
1618 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +00001619 const int short_option = m_getopt_table[option_idx].val;
Jim Ingham5a988412012-06-08 21:56:10 +00001620
1621 switch (short_option)
1622 {
1623 case 'f':
1624 m_filename.assign (option_arg);
1625 break;
1626
1627 case 'l':
Vince Harron5275aaa2015-01-15 20:08:35 +00001628 m_line_num = StringConvert::ToUInt32 (option_arg, 0);
Jim Ingham5a988412012-06-08 21:56:10 +00001629 break;
1630
1631 default:
1632 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1633 break;
1634 }
1635
1636 return error;
1637 }
1638
1639 void
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001640 OptionParsingStarting () override
Jim Ingham5a988412012-06-08 21:56:10 +00001641 {
1642 m_filename.clear();
1643 m_line_num = 0;
1644 }
1645
1646 const OptionDefinition*
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001647 GetDefinitions () override
Jim Ingham5a988412012-06-08 21:56:10 +00001648 {
1649 return g_option_table;
1650 }
1651
1652 // Options table: Required for subclasses of Options.
1653
1654 static OptionDefinition g_option_table[];
1655
1656 // Instance variables to hold the values for command options.
1657
1658 std::string m_filename;
1659 uint32_t m_line_num;
1660
1661 };
1662
1663protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001664 bool
1665 DoExecute (Args& command, CommandReturnObject &result) override
Jim Ingham5a988412012-06-08 21:56:10 +00001666 {
Jim Ingham893c9322014-11-22 01:42:44 +00001667 Target *target = GetSelectedOrDummyTarget();
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00001668 if (target == nullptr)
Jim Ingham5a988412012-06-08 21:56:10 +00001669 {
1670 result.AppendError ("Invalid target. No existing target or breakpoints.");
1671 result.SetStatus (eReturnStatusFailed);
1672 return false;
1673 }
1674
1675 // The following are the various types of breakpoints that could be cleared:
1676 // 1). -f -l (clearing breakpoint by source location)
1677
1678 BreakpointClearType break_type = eClearTypeInvalid;
1679
1680 if (m_options.m_line_num != 0)
1681 break_type = eClearTypeFileAndLine;
1682
1683 Mutex::Locker locker;
1684 target->GetBreakpointList().GetListMutex(locker);
1685
1686 BreakpointList &breakpoints = target->GetBreakpointList();
1687 size_t num_breakpoints = breakpoints.GetSize();
1688
1689 // Early return if there's no breakpoint at all.
1690 if (num_breakpoints == 0)
1691 {
1692 result.AppendError ("Breakpoint clear: No breakpoint cleared.");
1693 result.SetStatus (eReturnStatusFailed);
1694 return result.Succeeded();
1695 }
1696
1697 // Find matching breakpoints and delete them.
1698
1699 // First create a copy of all the IDs.
1700 std::vector<break_id_t> BreakIDs;
1701 for (size_t i = 0; i < num_breakpoints; ++i)
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00001702 BreakIDs.push_back(breakpoints.GetBreakpointAtIndex(i)->GetID());
Jim Ingham5a988412012-06-08 21:56:10 +00001703
1704 int num_cleared = 0;
1705 StreamString ss;
1706 switch (break_type)
1707 {
1708 case eClearTypeFileAndLine: // Breakpoint by source position
1709 {
1710 const ConstString filename(m_options.m_filename.c_str());
1711 BreakpointLocationCollection loc_coll;
1712
1713 for (size_t i = 0; i < num_breakpoints; ++i)
1714 {
1715 Breakpoint *bp = breakpoints.FindBreakpointByID(BreakIDs[i]).get();
1716
1717 if (bp->GetMatchingFileLine(filename, m_options.m_line_num, loc_coll))
1718 {
1719 // If the collection size is 0, it's a full match and we can just remove the breakpoint.
1720 if (loc_coll.GetSize() == 0)
1721 {
1722 bp->GetDescription(&ss, lldb::eDescriptionLevelBrief);
1723 ss.EOL();
1724 target->RemoveBreakpointByID (bp->GetID());
1725 ++num_cleared;
1726 }
1727 }
1728 }
1729 }
1730 break;
1731
1732 default:
1733 break;
1734 }
1735
1736 if (num_cleared > 0)
1737 {
1738 Stream &output_stream = result.GetOutputStream();
1739 output_stream.Printf ("%d breakpoints cleared:\n", num_cleared);
1740 output_stream << ss.GetData();
1741 output_stream.EOL();
1742 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1743 }
1744 else
1745 {
1746 result.AppendError ("Breakpoint clear: No breakpoint cleared.");
1747 result.SetStatus (eReturnStatusFailed);
1748 }
1749
1750 return result.Succeeded();
1751 }
1752
1753private:
1754 CommandOptions m_options;
1755};
1756
1757#pragma mark Clear::CommandOptions
1758
1759OptionDefinition
1760CommandObjectBreakpointClear::CommandOptions::g_option_table[] =
1761{
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00001762 { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
Jim Ingham5a988412012-06-08 21:56:10 +00001763 "Specify the breakpoint by source location in this particular file."},
1764
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00001765 { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum,
Jim Ingham5a988412012-06-08 21:56:10 +00001766 "Specify the breakpoint by source location at this particular line."},
1767
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00001768 { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
Jim Ingham5a988412012-06-08 21:56:10 +00001769};
1770
1771//-------------------------------------------------------------------------
1772// CommandObjectBreakpointDelete
1773//-------------------------------------------------------------------------
1774#pragma mark Delete
1775
1776class CommandObjectBreakpointDelete : public CommandObjectParsed
1777{
1778public:
1779 CommandObjectBreakpointDelete (CommandInterpreter &interpreter) :
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00001780 CommandObjectParsed(interpreter,
1781 "breakpoint delete",
1782 "Delete the specified breakpoint(s). If no breakpoints are specified, delete them all.",
1783 nullptr),
Jim Ingham33df7cd2014-12-06 01:28:03 +00001784 m_options (interpreter)
Jim Ingham5a988412012-06-08 21:56:10 +00001785 {
1786 CommandArgumentEntry arg;
1787 CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
1788 // Add the entry for the first argument for this command to the object's arguments vector.
1789 m_arguments.push_back (arg);
1790 }
1791
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00001792 ~CommandObjectBreakpointDelete() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +00001793
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001794 Options *
1795 GetOptions () override
Jim Ingham33df7cd2014-12-06 01:28:03 +00001796 {
1797 return &m_options;
1798 }
1799
1800 class CommandOptions : public Options
1801 {
1802 public:
Jim Ingham33df7cd2014-12-06 01:28:03 +00001803 CommandOptions (CommandInterpreter &interpreter) :
1804 Options (interpreter),
1805 m_use_dummy (false),
1806 m_force (false)
1807 {
1808 }
1809
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00001810 ~CommandOptions() override = default;
Jim Ingham33df7cd2014-12-06 01:28:03 +00001811
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001812 Error
1813 SetOptionValue (uint32_t option_idx, const char *option_arg) override
Jim Ingham33df7cd2014-12-06 01:28:03 +00001814 {
1815 Error error;
1816 const int short_option = m_getopt_table[option_idx].val;
1817
1818 switch (short_option)
1819 {
1820 case 'f':
1821 m_force = true;
1822 break;
1823
1824 case 'D':
1825 m_use_dummy = true;
1826 break;
1827
1828 default:
1829 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1830 break;
1831 }
1832
1833 return error;
1834 }
1835
1836 void
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001837 OptionParsingStarting () override
Jim Ingham33df7cd2014-12-06 01:28:03 +00001838 {
1839 m_use_dummy = false;
1840 m_force = false;
1841 }
1842
1843 const OptionDefinition*
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001844 GetDefinitions () override
Jim Ingham33df7cd2014-12-06 01:28:03 +00001845 {
1846 return g_option_table;
1847 }
1848
1849 // Options table: Required for subclasses of Options.
1850
1851 static OptionDefinition g_option_table[];
1852
1853 // Instance variables to hold the values for command options.
1854 bool m_use_dummy;
1855 bool m_force;
1856 };
1857
Jim Ingham5a988412012-06-08 21:56:10 +00001858protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001859 bool
1860 DoExecute (Args& command, CommandReturnObject &result) override
Jim Ingham5a988412012-06-08 21:56:10 +00001861 {
Jim Ingham33df7cd2014-12-06 01:28:03 +00001862 Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
1863
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00001864 if (target == nullptr)
Jim Ingham5a988412012-06-08 21:56:10 +00001865 {
1866 result.AppendError ("Invalid target. No existing target or breakpoints.");
1867 result.SetStatus (eReturnStatusFailed);
1868 return false;
1869 }
1870
1871 Mutex::Locker locker;
1872 target->GetBreakpointList().GetListMutex(locker);
1873
1874 const BreakpointList &breakpoints = target->GetBreakpointList();
1875
1876 size_t num_breakpoints = breakpoints.GetSize();
1877
1878 if (num_breakpoints == 0)
1879 {
1880 result.AppendError ("No breakpoints exist to be deleted.");
1881 result.SetStatus (eReturnStatusFailed);
1882 return false;
1883 }
1884
1885 if (command.GetArgumentCount() == 0)
1886 {
Jim Ingham33df7cd2014-12-06 01:28:03 +00001887 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 +00001888 {
1889 result.AppendMessage("Operation cancelled...");
1890 }
1891 else
1892 {
1893 target->RemoveAllBreakpoints ();
Greg Clayton6fea17e2014-03-03 19:15:20 +00001894 result.AppendMessageWithFormat ("All breakpoints removed. (%" PRIu64 " breakpoint%s)\n", (uint64_t)num_breakpoints, num_breakpoints > 1 ? "s" : "");
Jim Ingham5a988412012-06-08 21:56:10 +00001895 }
1896 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1897 }
1898 else
1899 {
1900 // Particular breakpoint selected; disable that breakpoint.
1901 BreakpointIDList valid_bp_ids;
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001902 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
Jim Ingham5a988412012-06-08 21:56:10 +00001903
1904 if (result.Succeeded())
1905 {
1906 int delete_count = 0;
1907 int disable_count = 0;
1908 const size_t count = valid_bp_ids.GetSize();
1909 for (size_t i = 0; i < count; ++i)
1910 {
1911 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1912
1913 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
1914 {
1915 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
1916 {
1917 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1918 BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
1919 // It makes no sense to try to delete individual locations, so we disable them instead.
1920 if (location)
1921 {
1922 location->SetEnabled (false);
1923 ++disable_count;
1924 }
1925 }
1926 else
1927 {
1928 target->RemoveBreakpointByID (cur_bp_id.GetBreakpointID());
1929 ++delete_count;
1930 }
1931 }
1932 }
1933 result.AppendMessageWithFormat ("%d breakpoints deleted; %d breakpoint locations disabled.\n",
1934 delete_count, disable_count);
1935 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1936 }
1937 }
1938 return result.Succeeded();
1939 }
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00001940
Jim Ingham33df7cd2014-12-06 01:28:03 +00001941private:
1942 CommandOptions m_options;
1943};
1944
1945OptionDefinition
1946CommandObjectBreakpointDelete::CommandOptions::g_option_table[] =
1947{
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00001948 { LLDB_OPT_SET_1, false, "force", 'f', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
Jim Ingham33df7cd2014-12-06 01:28:03 +00001949 "Delete all breakpoints without querying for confirmation."},
1950
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00001951 { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
Jim Ingham33df7cd2014-12-06 01:28:03 +00001952 "Delete Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
1953
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00001954 { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
Jim Ingham5a988412012-06-08 21:56:10 +00001955};
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001956
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001957//-------------------------------------------------------------------------
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001958// CommandObjectBreakpointName
1959//-------------------------------------------------------------------------
1960
1961static OptionDefinition
1962g_breakpoint_name_options[] =
1963{
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00001964 { LLDB_OPT_SET_1, false, "name", 'N', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBreakpointName, "Specifies a breakpoint name to use."},
1965 { LLDB_OPT_SET_2, false, "breakpoint-id", 'B', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBreakpointID, "Specify a breakpoint id to use."},
1966 { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001967 "Operate on Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
1968};
1969class BreakpointNameOptionGroup : public OptionGroup
1970{
1971public:
1972 BreakpointNameOptionGroup() :
1973 OptionGroup(),
1974 m_breakpoint(LLDB_INVALID_BREAK_ID),
1975 m_use_dummy (false)
1976 {
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001977 }
1978
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00001979 ~BreakpointNameOptionGroup() override = default;
1980
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001981 uint32_t
1982 GetNumDefinitions () override
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001983 {
1984 return sizeof (g_breakpoint_name_options) / sizeof (OptionDefinition);
1985 }
1986
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001987 const OptionDefinition*
1988 GetDefinitions () override
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001989 {
1990 return g_breakpoint_name_options;
1991 }
1992
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001993 Error
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001994 SetOptionValue (CommandInterpreter &interpreter,
1995 uint32_t option_idx,
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001996 const char *option_value) override
Jim Ingham5e09c8c2014-12-16 23:40:14 +00001997 {
1998 Error error;
1999 const int short_option = g_breakpoint_name_options[option_idx].short_option;
2000
2001 switch (short_option)
2002 {
2003 case 'N':
2004 if (BreakpointID::StringIsBreakpointName(option_value, error) && error.Success())
Pavel Labathc95f7e22015-02-20 11:14:59 +00002005 m_name.SetValueFromString(option_value);
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002006 break;
2007
2008 case 'B':
Pavel Labathc95f7e22015-02-20 11:14:59 +00002009 if (m_breakpoint.SetValueFromString(option_value).Fail())
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002010 error.SetErrorStringWithFormat ("unrecognized value \"%s\" for breakpoint", option_value);
2011 break;
2012 case 'D':
Pavel Labathc95f7e22015-02-20 11:14:59 +00002013 if (m_use_dummy.SetValueFromString(option_value).Fail())
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002014 error.SetErrorStringWithFormat ("unrecognized value \"%s\" for use-dummy", option_value);
2015 break;
2016
2017 default:
2018 error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option);
2019 break;
2020 }
2021 return error;
2022 }
2023
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002024 void
2025 OptionParsingStarting (CommandInterpreter &interpreter) override
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002026 {
2027 m_name.Clear();
2028 m_breakpoint.Clear();
2029 m_use_dummy.Clear();
2030 m_use_dummy.SetDefaultValue(false);
2031 }
2032
2033 OptionValueString m_name;
2034 OptionValueUInt64 m_breakpoint;
2035 OptionValueBoolean m_use_dummy;
2036};
2037
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002038class CommandObjectBreakpointNameAdd : public CommandObjectParsed
2039{
2040public:
2041 CommandObjectBreakpointNameAdd (CommandInterpreter &interpreter) :
2042 CommandObjectParsed (interpreter,
2043 "add",
2044 "Add a name to the breakpoints provided.",
2045 "breakpoint name add <command-options> <breakpoint-id-list>"),
2046 m_name_options(),
2047 m_option_group(interpreter)
2048 {
2049 // Create the first variant for the first (and only) argument for this command.
2050 CommandArgumentEntry arg1;
2051 CommandArgumentData id_arg;
2052 id_arg.arg_type = eArgTypeBreakpointID;
2053 id_arg.arg_repetition = eArgRepeatOptional;
2054 arg1.push_back(id_arg);
2055 m_arguments.push_back (arg1);
2056
2057 m_option_group.Append (&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
2058 m_option_group.Finalize();
2059 }
2060
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00002061 ~CommandObjectBreakpointNameAdd() override = default;
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002062
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00002063 Options *
2064 GetOptions() override
2065 {
2066 return &m_option_group;
2067 }
2068
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002069protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002070 bool
2071 DoExecute (Args& command, CommandReturnObject &result) override
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002072 {
2073 if (!m_name_options.m_name.OptionWasSet())
2074 {
2075 result.SetError("No name option provided.");
2076 return false;
2077 }
2078
2079 Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
2080
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00002081 if (target == nullptr)
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002082 {
2083 result.AppendError ("Invalid target. No existing target or breakpoints.");
2084 result.SetStatus (eReturnStatusFailed);
2085 return false;
2086 }
2087
2088 Mutex::Locker locker;
2089 target->GetBreakpointList().GetListMutex(locker);
2090
2091 const BreakpointList &breakpoints = target->GetBreakpointList();
2092
2093 size_t num_breakpoints = breakpoints.GetSize();
2094 if (num_breakpoints == 0)
2095 {
2096 result.SetError("No breakpoints, cannot add names.");
2097 result.SetStatus (eReturnStatusFailed);
2098 return false;
2099 }
2100
2101 // Particular breakpoint selected; disable that breakpoint.
2102 BreakpointIDList valid_bp_ids;
2103 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
2104
2105 if (result.Succeeded())
2106 {
2107 if (valid_bp_ids.GetSize() == 0)
2108 {
2109 result.SetError("No breakpoints specified, cannot add names.");
2110 result.SetStatus (eReturnStatusFailed);
2111 return false;
2112 }
2113 size_t num_valid_ids = valid_bp_ids.GetSize();
2114 for (size_t index = 0; index < num_valid_ids; index++)
2115 {
2116 lldb::break_id_t bp_id = valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
2117 BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
2118 Error error; // We don't need to check the error here, since the option parser checked it...
2119 bp_sp->AddName(m_name_options.m_name.GetCurrentValue(), error);
2120 }
2121 }
2122
2123 return true;
2124 }
2125
2126private:
2127 BreakpointNameOptionGroup m_name_options;
2128 OptionGroupOptions m_option_group;
2129};
2130
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002131class CommandObjectBreakpointNameDelete : public CommandObjectParsed
2132{
2133public:
2134 CommandObjectBreakpointNameDelete (CommandInterpreter &interpreter) :
2135 CommandObjectParsed (interpreter,
2136 "delete",
2137 "Delete a name from the breakpoints provided.",
2138 "breakpoint name delete <command-options> <breakpoint-id-list>"),
2139 m_name_options(),
2140 m_option_group(interpreter)
2141 {
2142 // Create the first variant for the first (and only) argument for this command.
2143 CommandArgumentEntry arg1;
2144 CommandArgumentData id_arg;
2145 id_arg.arg_type = eArgTypeBreakpointID;
2146 id_arg.arg_repetition = eArgRepeatOptional;
2147 arg1.push_back(id_arg);
2148 m_arguments.push_back (arg1);
2149
2150 m_option_group.Append (&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
2151 m_option_group.Finalize();
2152 }
2153
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00002154 ~CommandObjectBreakpointNameDelete() override = default;
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002155
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00002156 Options *
2157 GetOptions() override
2158 {
2159 return &m_option_group;
2160 }
2161
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002162protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002163 bool
2164 DoExecute (Args& command, CommandReturnObject &result) override
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002165 {
2166 if (!m_name_options.m_name.OptionWasSet())
2167 {
2168 result.SetError("No name option provided.");
2169 return false;
2170 }
2171
2172 Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
2173
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00002174 if (target == nullptr)
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002175 {
2176 result.AppendError ("Invalid target. No existing target or breakpoints.");
2177 result.SetStatus (eReturnStatusFailed);
2178 return false;
2179 }
2180
2181 Mutex::Locker locker;
2182 target->GetBreakpointList().GetListMutex(locker);
2183
2184 const BreakpointList &breakpoints = target->GetBreakpointList();
2185
2186 size_t num_breakpoints = breakpoints.GetSize();
2187 if (num_breakpoints == 0)
2188 {
2189 result.SetError("No breakpoints, cannot delete names.");
2190 result.SetStatus (eReturnStatusFailed);
2191 return false;
2192 }
2193
2194 // Particular breakpoint selected; disable that breakpoint.
2195 BreakpointIDList valid_bp_ids;
2196 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
2197
2198 if (result.Succeeded())
2199 {
2200 if (valid_bp_ids.GetSize() == 0)
2201 {
2202 result.SetError("No breakpoints specified, cannot delete names.");
2203 result.SetStatus (eReturnStatusFailed);
2204 return false;
2205 }
2206 size_t num_valid_ids = valid_bp_ids.GetSize();
2207 for (size_t index = 0; index < num_valid_ids; index++)
2208 {
2209 lldb::break_id_t bp_id = valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
2210 BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
2211 bp_sp->RemoveName(m_name_options.m_name.GetCurrentValue());
2212 }
2213 }
2214
2215 return true;
2216 }
2217
2218private:
2219 BreakpointNameOptionGroup m_name_options;
2220 OptionGroupOptions m_option_group;
2221};
2222
2223class CommandObjectBreakpointNameList : public CommandObjectParsed
2224{
2225public:
2226 CommandObjectBreakpointNameList (CommandInterpreter &interpreter) :
2227 CommandObjectParsed (interpreter,
2228 "list",
2229 "List either the names for a breakpoint or the breakpoints for a given name.",
2230 "breakpoint name list <command-options>"),
2231 m_name_options(),
2232 m_option_group(interpreter)
2233 {
2234 m_option_group.Append (&m_name_options);
2235 m_option_group.Finalize();
2236 }
2237
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00002238 ~CommandObjectBreakpointNameList() override = default;
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002239
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00002240 Options *
2241 GetOptions() override
2242 {
2243 return &m_option_group;
2244 }
2245
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002246protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002247 bool
2248 DoExecute (Args& command, CommandReturnObject &result) override
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002249 {
2250 Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
2251
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00002252 if (target == nullptr)
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002253 {
2254 result.AppendError ("Invalid target. No existing target or breakpoints.");
2255 result.SetStatus (eReturnStatusFailed);
2256 return false;
2257 }
2258
2259 if (m_name_options.m_name.OptionWasSet())
2260 {
2261 const char *name = m_name_options.m_name.GetCurrentValue();
2262 Mutex::Locker locker;
2263 target->GetBreakpointList().GetListMutex(locker);
2264
2265 BreakpointList &breakpoints = target->GetBreakpointList();
2266 for (BreakpointSP bp_sp : breakpoints.Breakpoints())
2267 {
2268 if (bp_sp->MatchesName(name))
2269 {
2270 StreamString s;
2271 bp_sp->GetDescription(&s, eDescriptionLevelBrief);
2272 s.EOL();
2273 result.AppendMessage(s.GetData());
2274 }
2275 }
2276
2277 }
2278 else if (m_name_options.m_breakpoint.OptionWasSet())
2279 {
2280 BreakpointSP bp_sp = target->GetBreakpointList().FindBreakpointByID(m_name_options.m_breakpoint.GetCurrentValue());
2281 if (bp_sp)
2282 {
2283 std::vector<std::string> names;
2284 bp_sp->GetNames (names);
2285 result.AppendMessage ("Names:");
2286 for (auto name : names)
2287 result.AppendMessageWithFormat (" %s\n", name.c_str());
2288 }
2289 else
2290 {
2291 result.AppendErrorWithFormat ("Could not find breakpoint %" PRId64 ".\n",
2292 m_name_options.m_breakpoint.GetCurrentValue());
2293 result.SetStatus (eReturnStatusFailed);
2294 return false;
2295 }
2296 }
2297 else
2298 {
2299 result.SetError ("Must specify -N or -B option to list.");
2300 result.SetStatus (eReturnStatusFailed);
2301 return false;
2302 }
2303 return true;
2304 }
2305
2306private:
2307 BreakpointNameOptionGroup m_name_options;
2308 OptionGroupOptions m_option_group;
2309};
2310
2311//-------------------------------------------------------------------------
2312// CommandObjectMultiwordBreakpoint
2313//-------------------------------------------------------------------------
2314class CommandObjectBreakpointName : public CommandObjectMultiword
2315{
2316public:
2317 CommandObjectBreakpointName (CommandInterpreter &interpreter) :
2318 CommandObjectMultiword(interpreter,
2319 "name",
2320 "A set of commands to manage name tags for breakpoints",
2321 "breakpoint name <command> [<command-options>]")
2322 {
2323 CommandObjectSP add_command_object (new CommandObjectBreakpointNameAdd (interpreter));
2324 CommandObjectSP delete_command_object (new CommandObjectBreakpointNameDelete (interpreter));
2325 CommandObjectSP list_command_object (new CommandObjectBreakpointNameList (interpreter));
2326
2327 LoadSubCommand ("add", add_command_object);
2328 LoadSubCommand ("delete", delete_command_object);
2329 LoadSubCommand ("list", list_command_object);
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002330 }
2331
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00002332 ~CommandObjectBreakpointName() override = default;
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002333};
2334
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002335//-------------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002336// CommandObjectMultiwordBreakpoint
2337//-------------------------------------------------------------------------
Jim Inghamae1c4cf2010-06-18 00:58:52 +00002338#pragma mark MultiwordBreakpoint
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002339
Greg Clayton66111032010-06-23 01:19:29 +00002340CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint (CommandInterpreter &interpreter) :
Greg Claytona7015092010-09-18 01:14:36 +00002341 CommandObjectMultiword (interpreter,
2342 "breakpoint",
Jim Ingham46fbc602011-05-26 20:39:01 +00002343 "A set of commands for operating on breakpoints. Also see _regexp-break.",
Greg Claytona7015092010-09-18 01:14:36 +00002344 "breakpoint <command> [<command-options>]")
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002345{
Greg Claytona7015092010-09-18 01:14:36 +00002346 CommandObjectSP list_command_object (new CommandObjectBreakpointList (interpreter));
Greg Claytona7015092010-09-18 01:14:36 +00002347 CommandObjectSP enable_command_object (new CommandObjectBreakpointEnable (interpreter));
2348 CommandObjectSP disable_command_object (new CommandObjectBreakpointDisable (interpreter));
Johnny Chenb7234e42010-10-28 17:27:46 +00002349 CommandObjectSP clear_command_object (new CommandObjectBreakpointClear (interpreter));
2350 CommandObjectSP delete_command_object (new CommandObjectBreakpointDelete (interpreter));
Greg Claytona7015092010-09-18 01:14:36 +00002351 CommandObjectSP set_command_object (new CommandObjectBreakpointSet (interpreter));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002352 CommandObjectSP command_command_object (new CommandObjectBreakpointCommand (interpreter));
Greg Claytona7015092010-09-18 01:14:36 +00002353 CommandObjectSP modify_command_object (new CommandObjectBreakpointModify(interpreter));
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002354 CommandObjectSP name_command_object (new CommandObjectBreakpointName(interpreter));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002355
Johnny Chenb7234e42010-10-28 17:27:46 +00002356 list_command_object->SetCommandName ("breakpoint list");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002357 enable_command_object->SetCommandName("breakpoint enable");
2358 disable_command_object->SetCommandName("breakpoint disable");
Johnny Chenb7234e42010-10-28 17:27:46 +00002359 clear_command_object->SetCommandName("breakpoint clear");
2360 delete_command_object->SetCommandName("breakpoint delete");
Jim Inghamae1c4cf2010-06-18 00:58:52 +00002361 set_command_object->SetCommandName("breakpoint set");
Johnny Chenb7234e42010-10-28 17:27:46 +00002362 command_command_object->SetCommandName ("breakpoint command");
2363 modify_command_object->SetCommandName ("breakpoint modify");
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002364 name_command_object->SetCommandName ("breakpoint name");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002365
Greg Clayton23f59502012-07-17 03:23:13 +00002366 LoadSubCommand ("list", list_command_object);
2367 LoadSubCommand ("enable", enable_command_object);
2368 LoadSubCommand ("disable", disable_command_object);
2369 LoadSubCommand ("clear", clear_command_object);
2370 LoadSubCommand ("delete", delete_command_object);
2371 LoadSubCommand ("set", set_command_object);
2372 LoadSubCommand ("command", command_command_object);
2373 LoadSubCommand ("modify", modify_command_object);
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002374 LoadSubCommand ("name", name_command_object);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002375}
2376
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00002377CommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint() = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002378
2379void
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002380CommandObjectMultiwordBreakpoint::VerifyIDs (Args &args,
2381 Target *target,
2382 bool allow_locations,
2383 CommandReturnObject &result,
2384 BreakpointIDList *valid_ids)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002385{
2386 // args can be strings representing 1). integers (for breakpoint ids)
2387 // 2). the full breakpoint & location canonical representation
2388 // 3). the word "to" or a hyphen, representing a range (in which case there
2389 // had *better* be an entry both before & after of one of the first two types.
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002390 // 4). A breakpoint name
Jim Ingham36f3b362010-10-14 23:45:03 +00002391 // If args is empty, we will use the last created breakpoint (if there is one.)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002392
2393 Args temp_args;
2394
Jim Ingham36f3b362010-10-14 23:45:03 +00002395 if (args.GetArgumentCount() == 0)
2396 {
Greg Clayton4d122c42011-09-17 08:33:22 +00002397 if (target->GetLastCreatedBreakpoint())
Jim Ingham36f3b362010-10-14 23:45:03 +00002398 {
2399 valid_ids->AddBreakpointID (BreakpointID(target->GetLastCreatedBreakpoint()->GetID(), LLDB_INVALID_BREAK_ID));
2400 result.SetStatus (eReturnStatusSuccessFinishNoResult);
2401 }
2402 else
2403 {
2404 result.AppendError("No breakpoint specified and no last created breakpoint.");
2405 result.SetStatus (eReturnStatusFailed);
2406 }
2407 return;
2408 }
2409
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002410 // Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff directly from the old ARGS to
2411 // the new TEMP_ARGS. Do not copy breakpoint id range strings over; instead generate a list of strings for
2412 // all the breakpoint ids in the range, and shove all of those breakpoint id strings into TEMP_ARGS.
2413
Jim Ingham5e09c8c2014-12-16 23:40:14 +00002414 BreakpointIDList::FindAndReplaceIDRanges (args, target, allow_locations, result, temp_args);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002415
2416 // NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual BreakpointIDList:
2417
Greg Claytonc982c762010-07-09 20:39:50 +00002418 valid_ids->InsertStringArray (temp_args.GetConstArgumentVector(), temp_args.GetArgumentCount(), result);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002419
2420 // At this point, all of the breakpoint ids that the user passed in have been converted to breakpoint IDs
2421 // and put into valid_ids.
2422
2423 if (result.Succeeded())
2424 {
2425 // Now that we've converted everything from args into a list of breakpoint ids, go through our tentative list
2426 // of breakpoint id's and verify that they correspond to valid/currently set breakpoints.
2427
Greg Claytonc982c762010-07-09 20:39:50 +00002428 const size_t count = valid_ids->GetSize();
2429 for (size_t i = 0; i < count; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002430 {
2431 BreakpointID cur_bp_id = valid_ids->GetBreakpointIDAtIndex (i);
2432 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
Eugene Zelenko9e85e5a2016-02-18 22:39:14 +00002433 if (breakpoint != nullptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002434 {
Greg Claytonc7bece562013-01-25 18:06:21 +00002435 const size_t num_locations = breakpoint->GetNumLocations();
Saleem Abdulrasool3985c8c2014-04-02 03:51:35 +00002436 if (static_cast<size_t>(cur_bp_id.GetLocationID()) > num_locations)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002437 {
2438 StreamString id_str;
Greg Claytonc982c762010-07-09 20:39:50 +00002439 BreakpointID::GetCanonicalReference (&id_str,
2440 cur_bp_id.GetBreakpointID(),
2441 cur_bp_id.GetLocationID());
2442 i = valid_ids->GetSize() + 1;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002443 result.AppendErrorWithFormat ("'%s' is not a currently valid breakpoint/location id.\n",
2444 id_str.GetData());
2445 result.SetStatus (eReturnStatusFailed);
2446 }
2447 }
2448 else
2449 {
Greg Claytonc982c762010-07-09 20:39:50 +00002450 i = valid_ids->GetSize() + 1;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002451 result.AppendErrorWithFormat ("'%d' is not a currently valid breakpoint id.\n", cur_bp_id.GetBreakpointID());
2452 result.SetStatus (eReturnStatusFailed);
2453 }
2454 }
2455 }
2456}