blob: d5a4345ba2ee6e8c14219ad41225d899b73fe7be [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- CommandObjectBreakpoint.cpp -----------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "CommandObjectBreakpoint.h"
11#include "CommandObjectBreakpointCommand.h"
12
13// C Includes
14// C++ Includes
15// Other libraries and framework includes
16// Project includes
17#include "lldb/Breakpoint/Breakpoint.h"
18#include "lldb/Breakpoint/BreakpointIDList.h"
19#include "lldb/Breakpoint/BreakpointLocation.h"
Jim Ingham84cdc152010-06-15 19:49:27 +000020#include "lldb/Interpreter/Options.h"
Chris Lattner24943d22010-06-08 16:52:24 +000021#include "lldb/Core/RegularExpression.h"
22#include "lldb/Core/StreamString.h"
23#include "lldb/Interpreter/CommandInterpreter.h"
24#include "lldb/Interpreter/CommandReturnObject.h"
25#include "lldb/Target/Target.h"
26#include "lldb/Interpreter/CommandCompletions.h"
27#include "lldb/Target/StackFrame.h"
Jim Ingham3c7b5b92010-06-16 02:00:15 +000028#include "lldb/Target/Thread.h"
29#include "lldb/Target/ThreadSpec.h"
Chris Lattner24943d22010-06-08 16:52:24 +000030
Johnny Chena62ad7c2010-10-28 17:27:46 +000031#include <vector>
32
Chris Lattner24943d22010-06-08 16:52:24 +000033using namespace lldb;
34using namespace lldb_private;
35
36static void
Jim Ingham2e8cb8a2011-02-19 02:53:09 +000037AddBreakpointDescription (Stream *s, Breakpoint *bp, lldb::DescriptionLevel level)
Chris Lattner24943d22010-06-08 16:52:24 +000038{
39 s->IndentMore();
40 bp->GetDescription (s, level, true);
41 s->IndentLess();
42 s->EOL();
43}
44
45//-------------------------------------------------------------------------
46// CommandObjectBreakpointSet::CommandOptions
47//-------------------------------------------------------------------------
Jim Ingham10622a22010-06-18 00:58:52 +000048#pragma mark Set::CommandOptions
Chris Lattner24943d22010-06-08 16:52:24 +000049
Greg Claytonf15996e2011-04-07 22:46:35 +000050CommandObjectBreakpointSet::CommandOptions::CommandOptions(CommandInterpreter &interpreter) :
51 Options (interpreter),
Chris Lattner24943d22010-06-08 16:52:24 +000052 m_filename (),
53 m_line_num (0),
54 m_column (0),
Greg Clayton2dfe4c62010-11-02 03:02:38 +000055 m_check_inlines (true),
Chris Lattner24943d22010-06-08 16:52:24 +000056 m_func_name (),
Greg Clayton12bec712010-06-28 21:30:43 +000057 m_func_name_type_mask (0),
Chris Lattner24943d22010-06-08 16:52:24 +000058 m_func_regexp (),
59 m_modules (),
Jim Ingham3c7b5b92010-06-16 02:00:15 +000060 m_load_addr(),
Greg Clayton54e7afa2010-07-09 20:39:50 +000061 m_ignore_count (0),
Jim Ingham3c7b5b92010-06-16 02:00:15 +000062 m_thread_id(LLDB_INVALID_THREAD_ID),
Greg Clayton54e7afa2010-07-09 20:39:50 +000063 m_thread_index (UINT32_MAX),
Jim Ingham3c7b5b92010-06-16 02:00:15 +000064 m_thread_name(),
Greg Clayton54e7afa2010-07-09 20:39:50 +000065 m_queue_name()
Chris Lattner24943d22010-06-08 16:52:24 +000066{
Chris Lattner24943d22010-06-08 16:52:24 +000067}
68
69CommandObjectBreakpointSet::CommandOptions::~CommandOptions ()
70{
71}
72
Greg Claytonb3448432011-03-24 21:19:54 +000073OptionDefinition
Chris Lattner24943d22010-06-08 16:52:24 +000074CommandObjectBreakpointSet::CommandOptions::g_option_table[] =
75{
Caroline Tice4d6675c2010-10-01 19:59:14 +000076 { LLDB_OPT_SET_ALL, false, "shlib", 's', required_argument, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName,
Jim Ingham34e9a982010-06-15 18:47:14 +000077 "Set the breakpoint only in this shared library (can use this option multiple times for multiple shlibs)."},
78
Caroline Tice4d6675c2010-10-01 19:59:14 +000079 { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', required_argument, NULL, 0, eArgTypeCount,
80 "Set the number of times this breakpoint is skipped before stopping." },
Jim Ingham3c7b5b92010-06-16 02:00:15 +000081
Caroline Tice4d6675c2010-10-01 19:59:14 +000082 { LLDB_OPT_SET_ALL, false, "thread-index", 'x', required_argument, NULL, NULL, eArgTypeThreadIndex,
Greg Claytonfe424a92010-09-18 03:37:20 +000083 "The breakpoint stops only for the thread whose index matches this argument."},
Jim Ingham3c7b5b92010-06-16 02:00:15 +000084
Caroline Tice4d6675c2010-10-01 19:59:14 +000085 { LLDB_OPT_SET_ALL, false, "thread-id", 't', required_argument, NULL, NULL, eArgTypeThreadID,
Jim Ingham3c7b5b92010-06-16 02:00:15 +000086 "The breakpoint stops only for the thread whose TID matches this argument."},
87
Caroline Tice4d6675c2010-10-01 19:59:14 +000088 { LLDB_OPT_SET_ALL, false, "thread-name", 'T', required_argument, NULL, NULL, eArgTypeThreadName,
Jim Ingham3c7b5b92010-06-16 02:00:15 +000089 "The breakpoint stops only for the thread whose thread name matches this argument."},
90
Caroline Tice4d6675c2010-10-01 19:59:14 +000091 { LLDB_OPT_SET_ALL, false, "queue-name", 'q', required_argument, NULL, NULL, eArgTypeQueueName,
Jim Ingham3c7b5b92010-06-16 02:00:15 +000092 "The breakpoint stops only for threads in the queue whose name is given by this argument."},
93
Caroline Tice4d6675c2010-10-01 19:59:14 +000094 { LLDB_OPT_SET_1, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
Chris Lattner24943d22010-06-08 16:52:24 +000095 "Set the breakpoint by source location in this particular file."},
96
Caroline Tice4d6675c2010-10-01 19:59:14 +000097 { LLDB_OPT_SET_1, true, "line", 'l', required_argument, NULL, 0, eArgTypeLineNum,
Chris Lattner24943d22010-06-08 16:52:24 +000098 "Set the breakpoint by source location at this particular line."},
99
Chris Lattner24943d22010-06-08 16:52:24 +0000100 // Comment out this option for the moment, as we don't actually use it, but will in the future.
101 // This way users won't see it, but the infrastructure is left in place.
102 // { 0, false, "column", 'c', required_argument, NULL, "<column>",
103 // "Set the breakpoint by source location at this particular column."},
104
Caroline Tice4d6675c2010-10-01 19:59:14 +0000105 { LLDB_OPT_SET_2, true, "address", 'a', required_argument, NULL, 0, eArgTypeAddress,
Chris Lattner24943d22010-06-08 16:52:24 +0000106 "Set the breakpoint by address, at the specified address."},
107
Caroline Tice4d6675c2010-10-01 19:59:14 +0000108 { LLDB_OPT_SET_3, true, "name", 'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
Greg Clayton48fbdf72010-10-12 04:29:14 +0000109 "Set the breakpoint by function name." },
Chris Lattner24943d22010-06-08 16:52:24 +0000110
Caroline Tice4d6675c2010-10-01 19:59:14 +0000111 { LLDB_OPT_SET_4, true, "fullname", 'F', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFullName,
Jim Inghamd9e2b762010-08-26 23:56:11 +0000112 "Set the breakpoint by fully qualified function names. For C++ this means namespaces and all arguemnts, and "
113 "for Objective C this means a full function prototype with class and selector." },
Greg Clayton12bec712010-06-28 21:30:43 +0000114
Caroline Tice4d6675c2010-10-01 19:59:14 +0000115 { LLDB_OPT_SET_5, true, "selector", 'S', required_argument, NULL, 0, eArgTypeSelector,
Jim Inghamd9e2b762010-08-26 23:56:11 +0000116 "Set the breakpoint by ObjC selector name." },
Greg Clayton12bec712010-06-28 21:30:43 +0000117
Caroline Tice4d6675c2010-10-01 19:59:14 +0000118 { LLDB_OPT_SET_6, true, "method", 'M', required_argument, NULL, 0, eArgTypeMethod,
Jim Inghamd9e2b762010-08-26 23:56:11 +0000119 "Set the breakpoint by C++ method names." },
Greg Clayton12bec712010-06-28 21:30:43 +0000120
Caroline Tice4d6675c2010-10-01 19:59:14 +0000121 { LLDB_OPT_SET_7, true, "func-regex", 'r', required_argument, NULL, 0, eArgTypeRegularExpression,
Chris Lattner24943d22010-06-08 16:52:24 +0000122 "Set the breakpoint by function name, evaluating a regular-expression to find the function name(s)." },
123
Greg Clayton48fbdf72010-10-12 04:29:14 +0000124 { LLDB_OPT_SET_8, true, "basename", 'b', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
125 "Set the breakpoint by function basename (C++ namespaces and arguments will be ignored)." },
126
Caroline Tice4d6675c2010-10-01 19:59:14 +0000127 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Chris Lattner24943d22010-06-08 16:52:24 +0000128};
129
Greg Claytonb3448432011-03-24 21:19:54 +0000130const OptionDefinition*
Chris Lattner24943d22010-06-08 16:52:24 +0000131CommandObjectBreakpointSet::CommandOptions::GetDefinitions ()
132{
133 return g_option_table;
134}
135
136Error
137CommandObjectBreakpointSet::CommandOptions::SetOptionValue (int option_idx, const char *option_arg)
138{
139 Error error;
140 char short_option = (char) m_getopt_table[option_idx].val;
141
142 switch (short_option)
143 {
144 case 'a':
Jim Ingham7a4c8ea2011-03-22 01:53:33 +0000145 m_load_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS, 0);
Chris Lattner24943d22010-06-08 16:52:24 +0000146 if (m_load_addr == LLDB_INVALID_ADDRESS)
Jim Ingham7a4c8ea2011-03-22 01:53:33 +0000147 m_load_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS, 16);
Chris Lattner24943d22010-06-08 16:52:24 +0000148
149 if (m_load_addr == LLDB_INVALID_ADDRESS)
Jim Ingham7a4c8ea2011-03-22 01:53:33 +0000150 error.SetErrorStringWithFormat ("Invalid address string '%s'.\n", option_arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000151 break;
152
153 case 'c':
154 m_column = Args::StringToUInt32 (option_arg, 0);
155 break;
Greg Clayton12bec712010-06-28 21:30:43 +0000156
Chris Lattner24943d22010-06-08 16:52:24 +0000157 case 'f':
Greg Clayton889fbd02011-03-26 19:14:58 +0000158 m_filename.assign (option_arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000159 break;
Greg Clayton12bec712010-06-28 21:30:43 +0000160
Chris Lattner24943d22010-06-08 16:52:24 +0000161 case 'l':
162 m_line_num = Args::StringToUInt32 (option_arg, 0);
163 break;
Greg Clayton12bec712010-06-28 21:30:43 +0000164
Greg Clayton48fbdf72010-10-12 04:29:14 +0000165 case 'b':
Greg Clayton889fbd02011-03-26 19:14:58 +0000166 m_func_name.assign (option_arg);
Greg Clayton12bec712010-06-28 21:30:43 +0000167 m_func_name_type_mask |= eFunctionNameTypeBase;
168 break;
169
Greg Clayton48fbdf72010-10-12 04:29:14 +0000170 case 'n':
Greg Clayton889fbd02011-03-26 19:14:58 +0000171 m_func_name.assign (option_arg);
Greg Clayton48fbdf72010-10-12 04:29:14 +0000172 m_func_name_type_mask |= eFunctionNameTypeAuto;
173 break;
174
Greg Clayton12bec712010-06-28 21:30:43 +0000175 case 'F':
Greg Clayton889fbd02011-03-26 19:14:58 +0000176 m_func_name.assign (option_arg);
Greg Clayton12bec712010-06-28 21:30:43 +0000177 m_func_name_type_mask |= eFunctionNameTypeFull;
178 break;
179
180 case 'S':
Greg Clayton889fbd02011-03-26 19:14:58 +0000181 m_func_name.assign (option_arg);
Greg Clayton12bec712010-06-28 21:30:43 +0000182 m_func_name_type_mask |= eFunctionNameTypeSelector;
183 break;
184
Jim Inghamd9e2b762010-08-26 23:56:11 +0000185 case 'M':
Greg Clayton889fbd02011-03-26 19:14:58 +0000186 m_func_name.assign (option_arg);
Greg Clayton12bec712010-06-28 21:30:43 +0000187 m_func_name_type_mask |= eFunctionNameTypeMethod;
188 break;
189
Chris Lattner24943d22010-06-08 16:52:24 +0000190 case 'r':
Greg Clayton889fbd02011-03-26 19:14:58 +0000191 m_func_regexp.assign (option_arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000192 break;
Greg Clayton12bec712010-06-28 21:30:43 +0000193
Chris Lattner24943d22010-06-08 16:52:24 +0000194 case 's':
195 {
196 m_modules.push_back (std::string (option_arg));
197 break;
198 }
Greg Claytonfe424a92010-09-18 03:37:20 +0000199 case 'i':
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000200 {
Jim Ingham7a4c8ea2011-03-22 01:53:33 +0000201 m_ignore_count = Args::StringToUInt32(option_arg, UINT32_MAX, 0);
Greg Clayton54e7afa2010-07-09 20:39:50 +0000202 if (m_ignore_count == UINT32_MAX)
Jim Ingham7a4c8ea2011-03-22 01:53:33 +0000203 error.SetErrorStringWithFormat ("Invalid ignore count '%s'.\n", option_arg);
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000204 }
Jim Ingham10622a22010-06-18 00:58:52 +0000205 break;
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000206 case 't' :
207 {
Jim Ingham7a4c8ea2011-03-22 01:53:33 +0000208 m_thread_id = Args::StringToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000209 if (m_thread_id == LLDB_INVALID_THREAD_ID)
Jim Ingham7a4c8ea2011-03-22 01:53:33 +0000210 error.SetErrorStringWithFormat ("Invalid thread id string '%s'.\n", option_arg);
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000211 }
212 break;
213 case 'T':
Greg Clayton889fbd02011-03-26 19:14:58 +0000214 m_thread_name.assign (option_arg);
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000215 break;
216 case 'q':
Greg Clayton889fbd02011-03-26 19:14:58 +0000217 m_queue_name.assign (option_arg);
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000218 break;
219 case 'x':
220 {
Jim Ingham7a4c8ea2011-03-22 01:53:33 +0000221 m_thread_index = Args::StringToUInt32(option_arg, UINT32_MAX, 0);
Greg Clayton54e7afa2010-07-09 20:39:50 +0000222 if (m_thread_id == UINT32_MAX)
Jim Ingham7a4c8ea2011-03-22 01:53:33 +0000223 error.SetErrorStringWithFormat ("Invalid thread index string '%s'.\n", option_arg);
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000224
225 }
226 break;
Chris Lattner24943d22010-06-08 16:52:24 +0000227 default:
228 error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
229 break;
230 }
231
232 return error;
233}
234
235void
236CommandObjectBreakpointSet::CommandOptions::ResetOptionValues ()
237{
Chris Lattner24943d22010-06-08 16:52:24 +0000238 m_filename.clear();
239 m_line_num = 0;
240 m_column = 0;
Chris Lattner24943d22010-06-08 16:52:24 +0000241 m_func_name.clear();
Greg Clayton12bec712010-06-28 21:30:43 +0000242 m_func_name_type_mask = 0;
Chris Lattner24943d22010-06-08 16:52:24 +0000243 m_func_regexp.clear();
244 m_load_addr = LLDB_INVALID_ADDRESS;
245 m_modules.clear();
Greg Clayton54e7afa2010-07-09 20:39:50 +0000246 m_ignore_count = 0;
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000247 m_thread_id = LLDB_INVALID_THREAD_ID;
Greg Clayton54e7afa2010-07-09 20:39:50 +0000248 m_thread_index = UINT32_MAX;
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000249 m_thread_name.clear();
250 m_queue_name.clear();
Chris Lattner24943d22010-06-08 16:52:24 +0000251}
252
253//-------------------------------------------------------------------------
254// CommandObjectBreakpointSet
255//-------------------------------------------------------------------------
Jim Ingham10622a22010-06-18 00:58:52 +0000256#pragma mark Set
Chris Lattner24943d22010-06-08 16:52:24 +0000257
Greg Clayton238c0a12010-09-18 01:14:36 +0000258CommandObjectBreakpointSet::CommandObjectBreakpointSet (CommandInterpreter &interpreter) :
259 CommandObject (interpreter,
260 "breakpoint set",
261 "Sets a breakpoint or set of breakpoints in the executable.",
Greg Claytonf15996e2011-04-07 22:46:35 +0000262 "breakpoint set <cmd-options>"),
263 m_options (interpreter)
Chris Lattner24943d22010-06-08 16:52:24 +0000264{
265}
266
267CommandObjectBreakpointSet::~CommandObjectBreakpointSet ()
268{
269}
270
271Options *
272CommandObjectBreakpointSet::GetOptions ()
273{
274 return &m_options;
275}
276
277bool
278CommandObjectBreakpointSet::Execute
279(
280 Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000281 CommandReturnObject &result
282)
283{
Greg Clayton238c0a12010-09-18 01:14:36 +0000284 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000285 if (target == NULL)
286 {
Caroline Tice17dce1c2010-09-29 19:42:33 +0000287 result.AppendError ("Invalid target. Must set target before setting breakpoints (see 'file' command).");
Chris Lattner24943d22010-06-08 16:52:24 +0000288 result.SetStatus (eReturnStatusFailed);
289 return false;
290 }
291
292 // The following are the various types of breakpoints that could be set:
293 // 1). -f -l -p [-s -g] (setting breakpoint by source location)
294 // 2). -a [-s -g] (setting breakpoint by address)
295 // 3). -n [-s -g] (setting breakpoint by function name)
296 // 4). -r [-s -g] (setting breakpoint by function name regular expression)
297
298 BreakpointSetType break_type = eSetTypeInvalid;
299
300 if (m_options.m_line_num != 0)
301 break_type = eSetTypeFileAndLine;
302 else if (m_options.m_load_addr != LLDB_INVALID_ADDRESS)
303 break_type = eSetTypeAddress;
304 else if (!m_options.m_func_name.empty())
305 break_type = eSetTypeFunctionName;
306 else if (!m_options.m_func_regexp.empty())
307 break_type = eSetTypeFunctionRegexp;
308
309 ModuleSP module_sp = target->GetExecutableModule();
310 Breakpoint *bp = NULL;
Greg Clayton537a7a82010-10-20 20:54:39 +0000311 FileSpec module_spec;
Chris Lattner24943d22010-06-08 16:52:24 +0000312 bool use_module = false;
313 int num_modules = m_options.m_modules.size();
314
315 if ((num_modules > 0) && (break_type != eSetTypeAddress))
316 use_module = true;
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000317
Chris Lattner24943d22010-06-08 16:52:24 +0000318 switch (break_type)
319 {
320 case eSetTypeFileAndLine: // Breakpoint by source position
Chris Lattner24943d22010-06-08 16:52:24 +0000321 {
Greg Clayton887aa282010-10-11 01:05:37 +0000322 FileSpec file;
323 if (m_options.m_filename.empty())
Chris Lattner24943d22010-06-08 16:52:24 +0000324 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000325 StackFrame *cur_frame = m_interpreter.GetExecutionContext().frame;
Greg Clayton887aa282010-10-11 01:05:37 +0000326 if (cur_frame == NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000327 {
Greg Clayton887aa282010-10-11 01:05:37 +0000328 result.AppendError ("Attempting to set breakpoint by line number alone with no selected frame.");
Chris Lattner24943d22010-06-08 16:52:24 +0000329 result.SetStatus (eReturnStatusFailed);
330 break;
331 }
Greg Clayton887aa282010-10-11 01:05:37 +0000332 else if (!cur_frame->HasDebugInformation())
Chris Lattner24943d22010-06-08 16:52:24 +0000333 {
Greg Clayton887aa282010-10-11 01:05:37 +0000334 result.AppendError ("Attempting to set breakpoint by line number alone but selected frame has no debug info.");
335 result.SetStatus (eReturnStatusFailed);
336 break;
Chris Lattner24943d22010-06-08 16:52:24 +0000337 }
338 else
339 {
Greg Clayton887aa282010-10-11 01:05:37 +0000340 const SymbolContext &context = cur_frame->GetSymbolContext(true);
341 if (context.line_entry.file)
342 {
343 file = context.line_entry.file;
344 }
345 else if (context.comp_unit != NULL)
346 { file = context.comp_unit;
347 }
348 else
349 {
350 result.AppendError ("Attempting to set breakpoint by line number alone but can't find the file for the selected frame.");
351 result.SetStatus (eReturnStatusFailed);
352 break;
353 }
Chris Lattner24943d22010-06-08 16:52:24 +0000354 }
355 }
Greg Clayton887aa282010-10-11 01:05:37 +0000356 else
357 {
Greg Clayton537a7a82010-10-20 20:54:39 +0000358 file.SetFile(m_options.m_filename.c_str(), false);
Greg Clayton887aa282010-10-11 01:05:37 +0000359 }
360
361 if (use_module)
362 {
363 for (int i = 0; i < num_modules; ++i)
364 {
Greg Clayton537a7a82010-10-20 20:54:39 +0000365 module_spec.SetFile(m_options.m_modules[i].c_str(), false);
366 bp = target->CreateBreakpoint (&module_spec,
Greg Clayton887aa282010-10-11 01:05:37 +0000367 file,
368 m_options.m_line_num,
Greg Clayton2dfe4c62010-11-02 03:02:38 +0000369 m_options.m_check_inlines).get();
Greg Clayton887aa282010-10-11 01:05:37 +0000370 if (bp)
371 {
Jim Ingham2e8cb8a2011-02-19 02:53:09 +0000372 Stream &output_stream = result.GetOutputStream();
373 result.AppendMessage ("Breakpoint created: ");
Greg Clayton887aa282010-10-11 01:05:37 +0000374 bp->GetDescription(&output_stream, lldb::eDescriptionLevelBrief);
375 output_stream.EOL();
Caroline Ticecf2f3052010-10-28 16:28:56 +0000376 if (bp->GetNumLocations() == 0)
377 output_stream.Printf ("WARNING: Unable to resolve breakpoint to any actual"
378 " locations.\n");
Greg Clayton887aa282010-10-11 01:05:37 +0000379 result.SetStatus (eReturnStatusSuccessFinishResult);
380 }
381 else
382 {
383 result.AppendErrorWithFormat("Breakpoint creation failed: No breakpoint created in module '%s'.\n",
384 m_options.m_modules[i].c_str());
385 result.SetStatus (eReturnStatusFailed);
386 }
387 }
388 }
389 else
390 bp = target->CreateBreakpoint (NULL,
391 file,
392 m_options.m_line_num,
Greg Clayton2dfe4c62010-11-02 03:02:38 +0000393 m_options.m_check_inlines).get();
Chris Lattner24943d22010-06-08 16:52:24 +0000394 }
Greg Clayton887aa282010-10-11 01:05:37 +0000395 break;
396
Chris Lattner24943d22010-06-08 16:52:24 +0000397 case eSetTypeAddress: // Breakpoint by address
398 bp = target->CreateBreakpoint (m_options.m_load_addr, false).get();
399 break;
Greg Clayton12bec712010-06-28 21:30:43 +0000400
Chris Lattner24943d22010-06-08 16:52:24 +0000401 case eSetTypeFunctionName: // Breakpoint by function name
Chris Lattner24943d22010-06-08 16:52:24 +0000402 {
Greg Clayton12bec712010-06-28 21:30:43 +0000403 uint32_t name_type_mask = m_options.m_func_name_type_mask;
404
405 if (name_type_mask == 0)
Greg Clayton48fbdf72010-10-12 04:29:14 +0000406 name_type_mask = eFunctionNameTypeAuto;
407
Greg Clayton12bec712010-06-28 21:30:43 +0000408 if (use_module)
409 {
410 for (int i = 0; i < num_modules; ++i)
Chris Lattner24943d22010-06-08 16:52:24 +0000411 {
Greg Clayton537a7a82010-10-20 20:54:39 +0000412 module_spec.SetFile(m_options.m_modules[i].c_str(), false);
413 bp = target->CreateBreakpoint (&module_spec,
414 m_options.m_func_name.c_str(),
415 name_type_mask,
416 Breakpoint::Exact).get();
Greg Clayton12bec712010-06-28 21:30:43 +0000417 if (bp)
418 {
Jim Ingham2e8cb8a2011-02-19 02:53:09 +0000419 Stream &output_stream = result.GetOutputStream();
Greg Clayton12bec712010-06-28 21:30:43 +0000420 output_stream.Printf ("Breakpoint created: ");
421 bp->GetDescription(&output_stream, lldb::eDescriptionLevelBrief);
422 output_stream.EOL();
Caroline Ticecf2f3052010-10-28 16:28:56 +0000423 if (bp->GetNumLocations() == 0)
424 output_stream.Printf ("WARNING: Unable to resolve breakpoint to any actual"
425 " locations.\n");
Greg Clayton12bec712010-06-28 21:30:43 +0000426 result.SetStatus (eReturnStatusSuccessFinishResult);
427 }
428 else
429 {
430 result.AppendErrorWithFormat("Breakpoint creation failed: No breakpoint created in module '%s'.\n",
431 m_options.m_modules[i].c_str());
432 result.SetStatus (eReturnStatusFailed);
433 }
Chris Lattner24943d22010-06-08 16:52:24 +0000434 }
435 }
Greg Clayton12bec712010-06-28 21:30:43 +0000436 else
437 bp = target->CreateBreakpoint (NULL, m_options.m_func_name.c_str(), name_type_mask, Breakpoint::Exact).get();
Chris Lattner24943d22010-06-08 16:52:24 +0000438 }
Chris Lattner24943d22010-06-08 16:52:24 +0000439 break;
Greg Clayton12bec712010-06-28 21:30:43 +0000440
Chris Lattner24943d22010-06-08 16:52:24 +0000441 case eSetTypeFunctionRegexp: // Breakpoint by regular expression function name
442 {
443 RegularExpression regexp(m_options.m_func_regexp.c_str());
444 if (use_module)
445 {
446 for (int i = 0; i < num_modules; ++i)
447 {
Greg Clayton537a7a82010-10-20 20:54:39 +0000448 module_spec.SetFile(m_options.m_modules[i].c_str(), false);
449 bp = target->CreateBreakpoint (&module_spec, regexp).get();
Chris Lattner24943d22010-06-08 16:52:24 +0000450 if (bp)
451 {
Jim Ingham2e8cb8a2011-02-19 02:53:09 +0000452 Stream &output_stream = result.GetOutputStream();
Chris Lattner24943d22010-06-08 16:52:24 +0000453 output_stream.Printf ("Breakpoint created: ");
454 bp->GetDescription(&output_stream, lldb::eDescriptionLevelBrief);
455 output_stream.EOL();
Caroline Ticecf2f3052010-10-28 16:28:56 +0000456 if (bp->GetNumLocations() == 0)
457 output_stream.Printf ("WARNING: Unable to resolve breakpoint to any actual"
458 " locations.\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000459 result.SetStatus (eReturnStatusSuccessFinishResult);
460 }
461 else
462 {
463 result.AppendErrorWithFormat("Breakpoint creation failed: No breakpoint created in module '%s'.\n",
464 m_options.m_modules[i].c_str());
465 result.SetStatus (eReturnStatusFailed);
466 }
467 }
468 }
469 else
470 bp = target->CreateBreakpoint (NULL, regexp).get();
471 }
472 break;
Greg Clayton12bec712010-06-28 21:30:43 +0000473
Chris Lattner24943d22010-06-08 16:52:24 +0000474 default:
475 break;
476 }
477
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000478 // Now set the various options that were passed in:
479 if (bp)
480 {
481 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
482 bp->SetThreadID (m_options.m_thread_id);
483
Greg Clayton54e7afa2010-07-09 20:39:50 +0000484 if (m_options.m_thread_index != UINT32_MAX)
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000485 bp->GetOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index);
486
487 if (!m_options.m_thread_name.empty())
488 bp->GetOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str());
489
490 if (!m_options.m_queue_name.empty())
491 bp->GetOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str());
492
Greg Clayton54e7afa2010-07-09 20:39:50 +0000493 if (m_options.m_ignore_count != 0)
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000494 bp->GetOptions()->SetIgnoreCount(m_options.m_ignore_count);
495 }
496
Chris Lattner24943d22010-06-08 16:52:24 +0000497 if (bp && !use_module)
498 {
Jim Ingham2e8cb8a2011-02-19 02:53:09 +0000499 Stream &output_stream = result.GetOutputStream();
Chris Lattner24943d22010-06-08 16:52:24 +0000500 output_stream.Printf ("Breakpoint created: ");
501 bp->GetDescription(&output_stream, lldb::eDescriptionLevelBrief);
502 output_stream.EOL();
Caroline Ticecf2f3052010-10-28 16:28:56 +0000503 if (bp->GetNumLocations() == 0)
504 output_stream.Printf ("WARNING: Unable to resolve breakpoint to any actual locations.\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000505 result.SetStatus (eReturnStatusSuccessFinishResult);
506 }
507 else if (!bp)
508 {
509 result.AppendError ("Breakpoint creation failed: No breakpoint created.");
510 result.SetStatus (eReturnStatusFailed);
511 }
512
513 return result.Succeeded();
514}
515
Chris Lattner24943d22010-06-08 16:52:24 +0000516//-------------------------------------------------------------------------
517// CommandObjectMultiwordBreakpoint
518//-------------------------------------------------------------------------
Jim Ingham10622a22010-06-18 00:58:52 +0000519#pragma mark MultiwordBreakpoint
Chris Lattner24943d22010-06-08 16:52:24 +0000520
Greg Clayton63094e02010-06-23 01:19:29 +0000521CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +0000522 CommandObjectMultiword (interpreter,
523 "breakpoint",
524 "A set of commands for operating on breakpoints. Also see regexp-break.",
525 "breakpoint <command> [<command-options>]")
Chris Lattner24943d22010-06-08 16:52:24 +0000526{
527 bool status;
528
Greg Clayton238c0a12010-09-18 01:14:36 +0000529 CommandObjectSP list_command_object (new CommandObjectBreakpointList (interpreter));
Greg Clayton238c0a12010-09-18 01:14:36 +0000530 CommandObjectSP enable_command_object (new CommandObjectBreakpointEnable (interpreter));
531 CommandObjectSP disable_command_object (new CommandObjectBreakpointDisable (interpreter));
Johnny Chena62ad7c2010-10-28 17:27:46 +0000532 CommandObjectSP clear_command_object (new CommandObjectBreakpointClear (interpreter));
533 CommandObjectSP delete_command_object (new CommandObjectBreakpointDelete (interpreter));
Greg Clayton238c0a12010-09-18 01:14:36 +0000534 CommandObjectSP set_command_object (new CommandObjectBreakpointSet (interpreter));
Chris Lattner24943d22010-06-08 16:52:24 +0000535 CommandObjectSP command_command_object (new CommandObjectBreakpointCommand (interpreter));
Greg Clayton238c0a12010-09-18 01:14:36 +0000536 CommandObjectSP modify_command_object (new CommandObjectBreakpointModify(interpreter));
Chris Lattner24943d22010-06-08 16:52:24 +0000537
Johnny Chena62ad7c2010-10-28 17:27:46 +0000538 list_command_object->SetCommandName ("breakpoint list");
Chris Lattner24943d22010-06-08 16:52:24 +0000539 enable_command_object->SetCommandName("breakpoint enable");
540 disable_command_object->SetCommandName("breakpoint disable");
Johnny Chena62ad7c2010-10-28 17:27:46 +0000541 clear_command_object->SetCommandName("breakpoint clear");
542 delete_command_object->SetCommandName("breakpoint delete");
Jim Ingham10622a22010-06-18 00:58:52 +0000543 set_command_object->SetCommandName("breakpoint set");
Johnny Chena62ad7c2010-10-28 17:27:46 +0000544 command_command_object->SetCommandName ("breakpoint command");
545 modify_command_object->SetCommandName ("breakpoint modify");
Chris Lattner24943d22010-06-08 16:52:24 +0000546
Greg Clayton238c0a12010-09-18 01:14:36 +0000547 status = LoadSubCommand ("list", list_command_object);
548 status = LoadSubCommand ("enable", enable_command_object);
549 status = LoadSubCommand ("disable", disable_command_object);
Johnny Chena62ad7c2010-10-28 17:27:46 +0000550 status = LoadSubCommand ("clear", clear_command_object);
Greg Clayton238c0a12010-09-18 01:14:36 +0000551 status = LoadSubCommand ("delete", delete_command_object);
552 status = LoadSubCommand ("set", set_command_object);
553 status = LoadSubCommand ("command", command_command_object);
554 status = LoadSubCommand ("modify", modify_command_object);
Chris Lattner24943d22010-06-08 16:52:24 +0000555}
556
557CommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint ()
558{
559}
560
561void
562CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (Args &args, Target *target, CommandReturnObject &result,
563 BreakpointIDList *valid_ids)
564{
565 // args can be strings representing 1). integers (for breakpoint ids)
566 // 2). the full breakpoint & location canonical representation
567 // 3). the word "to" or a hyphen, representing a range (in which case there
568 // had *better* be an entry both before & after of one of the first two types.
Jim Inghamd1686902010-10-14 23:45:03 +0000569 // If args is empty, we will use the last created breakpoint (if there is one.)
Chris Lattner24943d22010-06-08 16:52:24 +0000570
571 Args temp_args;
572
Jim Inghamd1686902010-10-14 23:45:03 +0000573 if (args.GetArgumentCount() == 0)
574 {
575 if (target->GetLastCreatedBreakpoint() != NULL)
576 {
577 valid_ids->AddBreakpointID (BreakpointID(target->GetLastCreatedBreakpoint()->GetID(), LLDB_INVALID_BREAK_ID));
578 result.SetStatus (eReturnStatusSuccessFinishNoResult);
579 }
580 else
581 {
582 result.AppendError("No breakpoint specified and no last created breakpoint.");
583 result.SetStatus (eReturnStatusFailed);
584 }
585 return;
586 }
587
Chris Lattner24943d22010-06-08 16:52:24 +0000588 // Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff directly from the old ARGS to
589 // the new TEMP_ARGS. Do not copy breakpoint id range strings over; instead generate a list of strings for
590 // all the breakpoint ids in the range, and shove all of those breakpoint id strings into TEMP_ARGS.
591
592 BreakpointIDList::FindAndReplaceIDRanges (args, target, result, temp_args);
593
594 // NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual BreakpointIDList:
595
Greg Clayton54e7afa2010-07-09 20:39:50 +0000596 valid_ids->InsertStringArray (temp_args.GetConstArgumentVector(), temp_args.GetArgumentCount(), result);
Chris Lattner24943d22010-06-08 16:52:24 +0000597
598 // At this point, all of the breakpoint ids that the user passed in have been converted to breakpoint IDs
599 // and put into valid_ids.
600
601 if (result.Succeeded())
602 {
603 // Now that we've converted everything from args into a list of breakpoint ids, go through our tentative list
604 // of breakpoint id's and verify that they correspond to valid/currently set breakpoints.
605
Greg Clayton54e7afa2010-07-09 20:39:50 +0000606 const size_t count = valid_ids->GetSize();
607 for (size_t i = 0; i < count; ++i)
Chris Lattner24943d22010-06-08 16:52:24 +0000608 {
609 BreakpointID cur_bp_id = valid_ids->GetBreakpointIDAtIndex (i);
610 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
611 if (breakpoint != NULL)
612 {
613 int num_locations = breakpoint->GetNumLocations();
614 if (cur_bp_id.GetLocationID() > num_locations)
615 {
616 StreamString id_str;
Greg Clayton54e7afa2010-07-09 20:39:50 +0000617 BreakpointID::GetCanonicalReference (&id_str,
618 cur_bp_id.GetBreakpointID(),
619 cur_bp_id.GetLocationID());
620 i = valid_ids->GetSize() + 1;
Chris Lattner24943d22010-06-08 16:52:24 +0000621 result.AppendErrorWithFormat ("'%s' is not a currently valid breakpoint/location id.\n",
622 id_str.GetData());
623 result.SetStatus (eReturnStatusFailed);
624 }
625 }
626 else
627 {
Greg Clayton54e7afa2010-07-09 20:39:50 +0000628 i = valid_ids->GetSize() + 1;
Chris Lattner24943d22010-06-08 16:52:24 +0000629 result.AppendErrorWithFormat ("'%d' is not a currently valid breakpoint id.\n", cur_bp_id.GetBreakpointID());
630 result.SetStatus (eReturnStatusFailed);
631 }
632 }
633 }
634}
635
636//-------------------------------------------------------------------------
637// CommandObjectBreakpointList::Options
638//-------------------------------------------------------------------------
Jim Ingham10622a22010-06-18 00:58:52 +0000639#pragma mark List::CommandOptions
Chris Lattner24943d22010-06-08 16:52:24 +0000640
Greg Claytonf15996e2011-04-07 22:46:35 +0000641CommandObjectBreakpointList::CommandOptions::CommandOptions(CommandInterpreter &interpreter) :
642 Options (interpreter),
Caroline Tice41950cc2011-02-04 22:59:41 +0000643 m_level (lldb::eDescriptionLevelBrief) // Breakpoint List defaults to brief descriptions
Chris Lattner24943d22010-06-08 16:52:24 +0000644{
Chris Lattner24943d22010-06-08 16:52:24 +0000645}
646
647CommandObjectBreakpointList::CommandOptions::~CommandOptions ()
648{
649}
650
Greg Claytonb3448432011-03-24 21:19:54 +0000651OptionDefinition
Chris Lattner24943d22010-06-08 16:52:24 +0000652CommandObjectBreakpointList::CommandOptions::g_option_table[] =
653{
Caroline Tice4d6675c2010-10-01 19:59:14 +0000654 { LLDB_OPT_SET_ALL, false, "internal", 'i', no_argument, NULL, 0, eArgTypeNone,
Jim Ingham34e9a982010-06-15 18:47:14 +0000655 "Show debugger internal breakpoints" },
656
Caroline Tice4d6675c2010-10-01 19:59:14 +0000657 { LLDB_OPT_SET_1, false, "brief", 'b', no_argument, NULL, 0, eArgTypeNone,
Chris Lattner24943d22010-06-08 16:52:24 +0000658 "Give a brief description of the breakpoint (no location info)."},
659
660 // FIXME: We need to add an "internal" command, and then add this sort of thing to it.
661 // But I need to see it for now, and don't want to wait.
Caroline Tice4d6675c2010-10-01 19:59:14 +0000662 { LLDB_OPT_SET_2, false, "full", 'f', no_argument, NULL, 0, eArgTypeNone,
Chris Lattner24943d22010-06-08 16:52:24 +0000663 "Give a full description of the breakpoint and its locations."},
Chris Lattner24943d22010-06-08 16:52:24 +0000664
Caroline Tice4d6675c2010-10-01 19:59:14 +0000665 { LLDB_OPT_SET_3, false, "verbose", 'v', no_argument, NULL, 0, eArgTypeNone,
Chris Lattner24943d22010-06-08 16:52:24 +0000666 "Explain everything we know about the breakpoint (for debugging debugger bugs)." },
Chris Lattner24943d22010-06-08 16:52:24 +0000667
Caroline Tice4d6675c2010-10-01 19:59:14 +0000668 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Chris Lattner24943d22010-06-08 16:52:24 +0000669};
670
Greg Claytonb3448432011-03-24 21:19:54 +0000671const OptionDefinition*
Chris Lattner24943d22010-06-08 16:52:24 +0000672CommandObjectBreakpointList::CommandOptions::GetDefinitions ()
673{
674 return g_option_table;
675}
676
677Error
678CommandObjectBreakpointList::CommandOptions::SetOptionValue (int option_idx, const char *option_arg)
679{
680 Error error;
681 char short_option = (char) m_getopt_table[option_idx].val;
682
683 switch (short_option)
684 {
685 case 'b':
686 m_level = lldb::eDescriptionLevelBrief;
687 break;
688 case 'f':
689 m_level = lldb::eDescriptionLevelFull;
690 break;
691 case 'v':
692 m_level = lldb::eDescriptionLevelVerbose;
693 break;
694 case 'i':
695 m_internal = true;
696 break;
697 default:
698 error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
699 break;
700 }
701
702 return error;
703}
704
705void
706CommandObjectBreakpointList::CommandOptions::ResetOptionValues ()
707{
Caroline Tice41950cc2011-02-04 22:59:41 +0000708 m_level = lldb::eDescriptionLevelBrief;
Chris Lattner24943d22010-06-08 16:52:24 +0000709 m_internal = false;
710}
711
712//-------------------------------------------------------------------------
713// CommandObjectBreakpointList
714//-------------------------------------------------------------------------
Jim Ingham10622a22010-06-18 00:58:52 +0000715#pragma mark List
Chris Lattner24943d22010-06-08 16:52:24 +0000716
Greg Clayton238c0a12010-09-18 01:14:36 +0000717CommandObjectBreakpointList::CommandObjectBreakpointList (CommandInterpreter &interpreter) :
718 CommandObject (interpreter,
719 "breakpoint list",
720 "List some or all breakpoints at configurable levels of detail.",
Greg Claytonf15996e2011-04-07 22:46:35 +0000721 NULL),
722 m_options (interpreter)
Chris Lattner24943d22010-06-08 16:52:24 +0000723{
Caroline Ticefb355112010-10-01 17:46:38 +0000724 CommandArgumentEntry arg;
725 CommandArgumentData bp_id_arg;
726
727 // Define the first (and only) variant of this arg.
728 bp_id_arg.arg_type = eArgTypeBreakpointID;
Caroline Tice43b014a2010-10-04 22:28:36 +0000729 bp_id_arg.arg_repetition = eArgRepeatOptional;
Caroline Ticefb355112010-10-01 17:46:38 +0000730
731 // There is only one variant this argument could be; put it into the argument entry.
732 arg.push_back (bp_id_arg);
733
734 // Push the data for the first argument into the m_arguments vector.
735 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000736}
737
738CommandObjectBreakpointList::~CommandObjectBreakpointList ()
739{
740}
741
742Options *
743CommandObjectBreakpointList::GetOptions ()
744{
745 return &m_options;
746}
747
748bool
749CommandObjectBreakpointList::Execute
750(
751 Args& args,
Chris Lattner24943d22010-06-08 16:52:24 +0000752 CommandReturnObject &result
753)
754{
Greg Clayton238c0a12010-09-18 01:14:36 +0000755 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000756 if (target == NULL)
757 {
Caroline Tice17dce1c2010-09-29 19:42:33 +0000758 result.AppendError ("Invalid target. No current target or breakpoints.");
Chris Lattner24943d22010-06-08 16:52:24 +0000759 result.SetStatus (eReturnStatusSuccessFinishNoResult);
760 return true;
761 }
762
763 const BreakpointList &breakpoints = target->GetBreakpointList(m_options.m_internal);
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000764 Mutex::Locker locker;
765 target->GetBreakpointList(m_options.m_internal).GetListMutex(locker);
766
Chris Lattner24943d22010-06-08 16:52:24 +0000767 size_t num_breakpoints = breakpoints.GetSize();
768
769 if (num_breakpoints == 0)
770 {
771 result.AppendMessage ("No breakpoints currently set.");
772 result.SetStatus (eReturnStatusSuccessFinishNoResult);
773 return true;
774 }
775
Jim Ingham2e8cb8a2011-02-19 02:53:09 +0000776 Stream &output_stream = result.GetOutputStream();
Chris Lattner24943d22010-06-08 16:52:24 +0000777
778 if (args.GetArgumentCount() == 0)
779 {
780 // No breakpoint selected; show info about all currently set breakpoints.
781 result.AppendMessage ("Current breakpoints:");
Greg Clayton54e7afa2010-07-09 20:39:50 +0000782 for (size_t i = 0; i < num_breakpoints; ++i)
Chris Lattner24943d22010-06-08 16:52:24 +0000783 {
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000784 Breakpoint *breakpoint = breakpoints.GetBreakpointAtIndex (i).get();
Greg Clayton63094e02010-06-23 01:19:29 +0000785 AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
Chris Lattner24943d22010-06-08 16:52:24 +0000786 }
787 result.SetStatus (eReturnStatusSuccessFinishNoResult);
788 }
789 else
790 {
791 // Particular breakpoints selected; show info about that breakpoint.
792 BreakpointIDList valid_bp_ids;
793 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (args, target, result, &valid_bp_ids);
794
795 if (result.Succeeded())
796 {
Greg Clayton54e7afa2010-07-09 20:39:50 +0000797 for (size_t i = 0; i < valid_bp_ids.GetSize(); ++i)
Chris Lattner24943d22010-06-08 16:52:24 +0000798 {
799 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
800 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
Greg Clayton63094e02010-06-23 01:19:29 +0000801 AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
Chris Lattner24943d22010-06-08 16:52:24 +0000802 }
803 result.SetStatus (eReturnStatusSuccessFinishNoResult);
804 }
805 else
806 {
807 result.AppendError ("Invalid breakpoint id.");
808 result.SetStatus (eReturnStatusFailed);
809 }
810 }
811
812 return result.Succeeded();
813}
814
815//-------------------------------------------------------------------------
816// CommandObjectBreakpointEnable
817//-------------------------------------------------------------------------
Jim Ingham10622a22010-06-18 00:58:52 +0000818#pragma mark Enable
Chris Lattner24943d22010-06-08 16:52:24 +0000819
Greg Clayton238c0a12010-09-18 01:14:36 +0000820CommandObjectBreakpointEnable::CommandObjectBreakpointEnable (CommandInterpreter &interpreter) :
821 CommandObject (interpreter,
822 "enable",
Caroline Ticefb355112010-10-01 17:46:38 +0000823 "Enable the specified disabled breakpoint(s). If no breakpoints are specified, enable all of them.",
824 NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000825{
Caroline Ticefb355112010-10-01 17:46:38 +0000826 CommandArgumentEntry arg;
827 CommandArgumentData bp_id_arg;
828 CommandArgumentData bp_id_range_arg;
829
830 // Create the first variant for the first (and only) argument for this command.
831 bp_id_arg.arg_type = eArgTypeBreakpointID;
Caroline Tice43b014a2010-10-04 22:28:36 +0000832 bp_id_arg.arg_repetition = eArgRepeatOptional;
Caroline Ticefb355112010-10-01 17:46:38 +0000833
834 // Create the second variant for the first (and only) argument for this command.
835 bp_id_range_arg.arg_type = eArgTypeBreakpointIDRange;
Caroline Tice43b014a2010-10-04 22:28:36 +0000836 bp_id_range_arg.arg_repetition = eArgRepeatOptional;
Caroline Ticefb355112010-10-01 17:46:38 +0000837
838 // The first (and only) argument for this command could be either a bp_id or a bp_id_range.
839 // Push both variants into the entry for the first argument for this command.
840 arg.push_back (bp_id_arg);
841 arg.push_back (bp_id_range_arg);
842
843 // Add the entry for the first argument for this command to the object's arguments vector.
844 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000845}
846
847
848CommandObjectBreakpointEnable::~CommandObjectBreakpointEnable ()
849{
850}
851
852
853bool
Greg Clayton63094e02010-06-23 01:19:29 +0000854CommandObjectBreakpointEnable::Execute
855(
Greg Clayton63094e02010-06-23 01:19:29 +0000856 Args& args,
857 CommandReturnObject &result
858)
Chris Lattner24943d22010-06-08 16:52:24 +0000859{
Greg Clayton238c0a12010-09-18 01:14:36 +0000860 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000861 if (target == NULL)
862 {
Caroline Tice17dce1c2010-09-29 19:42:33 +0000863 result.AppendError ("Invalid target. No existing target or breakpoints.");
Chris Lattner24943d22010-06-08 16:52:24 +0000864 result.SetStatus (eReturnStatusFailed);
865 return false;
866 }
867
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000868 Mutex::Locker locker;
869 target->GetBreakpointList().GetListMutex(locker);
870
Chris Lattner24943d22010-06-08 16:52:24 +0000871 const BreakpointList &breakpoints = target->GetBreakpointList();
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000872
Chris Lattner24943d22010-06-08 16:52:24 +0000873 size_t num_breakpoints = breakpoints.GetSize();
874
875 if (num_breakpoints == 0)
876 {
877 result.AppendError ("No breakpoints exist to be enabled.");
878 result.SetStatus (eReturnStatusFailed);
879 return false;
880 }
881
882 if (args.GetArgumentCount() == 0)
883 {
884 // No breakpoint selected; enable all currently set breakpoints.
885 target->EnableAllBreakpoints ();
886 result.AppendMessageWithFormat ("All breakpoints enabled. (%d breakpoints)\n", num_breakpoints);
887 result.SetStatus (eReturnStatusSuccessFinishNoResult);
888 }
889 else
890 {
891 // Particular breakpoint selected; enable that breakpoint.
892 BreakpointIDList valid_bp_ids;
893 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (args, target, result, &valid_bp_ids);
894
895 if (result.Succeeded())
896 {
897 int enable_count = 0;
898 int loc_count = 0;
Greg Clayton54e7afa2010-07-09 20:39:50 +0000899 const size_t count = valid_bp_ids.GetSize();
900 for (size_t i = 0; i < count; ++i)
Chris Lattner24943d22010-06-08 16:52:24 +0000901 {
902 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
903
904 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
905 {
906 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
907 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
908 {
909 BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
910 if (location)
911 {
912 location->SetEnabled (true);
Chris Lattner24943d22010-06-08 16:52:24 +0000913 ++loc_count;
914 }
915 }
916 else
917 {
Jim Ingham10622a22010-06-18 00:58:52 +0000918 breakpoint->SetEnabled (true);
Chris Lattner24943d22010-06-08 16:52:24 +0000919 ++enable_count;
Chris Lattner24943d22010-06-08 16:52:24 +0000920 }
921 }
922 }
923 result.AppendMessageWithFormat ("%d breakpoints enabled.\n", enable_count + loc_count);
924 result.SetStatus (eReturnStatusSuccessFinishNoResult);
925 }
926 }
927
928 return result.Succeeded();
929}
930
931//-------------------------------------------------------------------------
932// CommandObjectBreakpointDisable
933//-------------------------------------------------------------------------
Jim Ingham10622a22010-06-18 00:58:52 +0000934#pragma mark Disable
Chris Lattner24943d22010-06-08 16:52:24 +0000935
Greg Clayton238c0a12010-09-18 01:14:36 +0000936CommandObjectBreakpointDisable::CommandObjectBreakpointDisable (CommandInterpreter &interpreter) :
937 CommandObject (interpreter,
Caroline Ticefb355112010-10-01 17:46:38 +0000938 "breakpoint disable",
Caroline Ticeabb507a2010-09-08 21:06:11 +0000939 "Disable the specified breakpoint(s) without removing it/them. If no breakpoints are specified, disable them all.",
Caroline Ticefb355112010-10-01 17:46:38 +0000940 NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000941{
Caroline Ticefb355112010-10-01 17:46:38 +0000942 CommandArgumentEntry arg;
943 CommandArgumentData bp_id_arg;
944 CommandArgumentData bp_id_range_arg;
945
946 // Create the first variant for the first (and only) argument for this command.
947 bp_id_arg.arg_type = eArgTypeBreakpointID;
Caroline Tice43b014a2010-10-04 22:28:36 +0000948 bp_id_arg.arg_repetition = eArgRepeatOptional;
Caroline Ticefb355112010-10-01 17:46:38 +0000949
950 // Create the second variant for the first (and only) argument for this command.
951 bp_id_range_arg.arg_type = eArgTypeBreakpointIDRange;
Caroline Tice43b014a2010-10-04 22:28:36 +0000952 bp_id_range_arg.arg_repetition = eArgRepeatOptional;
Caroline Ticefb355112010-10-01 17:46:38 +0000953
954 // The first (and only) argument for this command could be either a bp_id or a bp_id_range.
955 // Push both variants into the entry for the first argument for this command.
956 arg.push_back (bp_id_arg);
957 arg.push_back (bp_id_range_arg);
958
959 // Add the entry for the first argument for this command to the object's arguments vector.
960 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000961}
962
963CommandObjectBreakpointDisable::~CommandObjectBreakpointDisable ()
964{
965}
966
967bool
Greg Clayton63094e02010-06-23 01:19:29 +0000968CommandObjectBreakpointDisable::Execute
969(
Greg Clayton63094e02010-06-23 01:19:29 +0000970 Args& args,
971 CommandReturnObject &result
972)
Chris Lattner24943d22010-06-08 16:52:24 +0000973{
Greg Clayton238c0a12010-09-18 01:14:36 +0000974 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000975 if (target == NULL)
976 {
Caroline Tice17dce1c2010-09-29 19:42:33 +0000977 result.AppendError ("Invalid target. No existing target or breakpoints.");
Chris Lattner24943d22010-06-08 16:52:24 +0000978 result.SetStatus (eReturnStatusFailed);
979 return false;
980 }
981
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000982 Mutex::Locker locker;
983 target->GetBreakpointList().GetListMutex(locker);
984
Chris Lattner24943d22010-06-08 16:52:24 +0000985 const BreakpointList &breakpoints = target->GetBreakpointList();
986 size_t num_breakpoints = breakpoints.GetSize();
987
988 if (num_breakpoints == 0)
989 {
990 result.AppendError ("No breakpoints exist to be disabled.");
991 result.SetStatus (eReturnStatusFailed);
992 return false;
993 }
994
995 if (args.GetArgumentCount() == 0)
996 {
997 // No breakpoint selected; disable all currently set breakpoints.
998 target->DisableAllBreakpoints ();
999 result.AppendMessageWithFormat ("All breakpoints disabled. (%d breakpoints)\n", num_breakpoints);
1000 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1001 }
1002 else
1003 {
1004 // Particular breakpoint selected; disable that breakpoint.
1005 BreakpointIDList valid_bp_ids;
1006
1007 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (args, target, result, &valid_bp_ids);
1008
1009 if (result.Succeeded())
1010 {
1011 int disable_count = 0;
1012 int loc_count = 0;
Greg Clayton54e7afa2010-07-09 20:39:50 +00001013 const size_t count = valid_bp_ids.GetSize();
1014 for (size_t i = 0; i < count; ++i)
Chris Lattner24943d22010-06-08 16:52:24 +00001015 {
1016 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1017
1018 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
1019 {
1020 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1021 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
1022 {
1023 BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
1024 if (location)
1025 {
1026 location->SetEnabled (false);
1027 ++loc_count;
1028 }
1029 }
1030 else
1031 {
Jim Ingham10622a22010-06-18 00:58:52 +00001032 breakpoint->SetEnabled (false);
Chris Lattner24943d22010-06-08 16:52:24 +00001033 ++disable_count;
Chris Lattner24943d22010-06-08 16:52:24 +00001034 }
1035 }
1036 }
1037 result.AppendMessageWithFormat ("%d breakpoints disabled.\n", disable_count + loc_count);
1038 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1039 }
1040 }
1041
1042 return result.Succeeded();
1043}
1044
1045//-------------------------------------------------------------------------
Johnny Chena62ad7c2010-10-28 17:27:46 +00001046// CommandObjectBreakpointClear::CommandOptions
1047//-------------------------------------------------------------------------
1048#pragma mark Clear::CommandOptions
1049
Greg Claytonf15996e2011-04-07 22:46:35 +00001050CommandObjectBreakpointClear::CommandOptions::CommandOptions(CommandInterpreter &interpreter) :
1051 Options (interpreter),
Johnny Chena62ad7c2010-10-28 17:27:46 +00001052 m_filename (),
1053 m_line_num (0)
1054{
1055}
1056
1057CommandObjectBreakpointClear::CommandOptions::~CommandOptions ()
1058{
1059}
1060
Greg Claytonb3448432011-03-24 21:19:54 +00001061OptionDefinition
Johnny Chena62ad7c2010-10-28 17:27:46 +00001062CommandObjectBreakpointClear::CommandOptions::g_option_table[] =
1063{
1064 { LLDB_OPT_SET_1, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
1065 "Specify the breakpoint by source location in this particular file."},
1066
1067 { LLDB_OPT_SET_1, true, "line", 'l', required_argument, NULL, 0, eArgTypeLineNum,
1068 "Specify the breakpoint by source location at this particular line."},
1069
1070 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1071};
1072
Greg Claytonb3448432011-03-24 21:19:54 +00001073const OptionDefinition*
Johnny Chena62ad7c2010-10-28 17:27:46 +00001074CommandObjectBreakpointClear::CommandOptions::GetDefinitions ()
1075{
1076 return g_option_table;
1077}
1078
1079Error
1080CommandObjectBreakpointClear::CommandOptions::SetOptionValue (int option_idx, const char *option_arg)
1081{
1082 Error error;
1083 char short_option = (char) m_getopt_table[option_idx].val;
1084
1085 switch (short_option)
1086 {
1087 case 'f':
Greg Clayton889fbd02011-03-26 19:14:58 +00001088 m_filename.assign (option_arg);
Johnny Chena62ad7c2010-10-28 17:27:46 +00001089 break;
1090
1091 case 'l':
1092 m_line_num = Args::StringToUInt32 (option_arg, 0);
1093 break;
1094
1095 default:
1096 error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
1097 break;
1098 }
1099
1100 return error;
1101}
1102
1103void
1104CommandObjectBreakpointClear::CommandOptions::ResetOptionValues ()
1105{
Johnny Chena62ad7c2010-10-28 17:27:46 +00001106 m_filename.clear();
1107 m_line_num = 0;
1108}
1109
1110//-------------------------------------------------------------------------
1111// CommandObjectBreakpointClear
1112//-------------------------------------------------------------------------
1113#pragma mark Clear
1114
1115CommandObjectBreakpointClear::CommandObjectBreakpointClear (CommandInterpreter &interpreter) :
1116 CommandObject (interpreter,
1117 "breakpoint clear",
1118 "Clears a breakpoint or set of breakpoints in the executable.",
Greg Claytonf15996e2011-04-07 22:46:35 +00001119 "breakpoint clear <cmd-options>"),
1120 m_options (interpreter)
Johnny Chena62ad7c2010-10-28 17:27:46 +00001121{
1122}
1123
1124CommandObjectBreakpointClear::~CommandObjectBreakpointClear ()
1125{
1126}
1127
1128Options *
1129CommandObjectBreakpointClear::GetOptions ()
1130{
1131 return &m_options;
1132}
1133
1134bool
1135CommandObjectBreakpointClear::Execute
1136(
1137 Args& command,
1138 CommandReturnObject &result
1139)
1140{
1141 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1142 if (target == NULL)
1143 {
1144 result.AppendError ("Invalid target. No existing target or breakpoints.");
1145 result.SetStatus (eReturnStatusFailed);
1146 return false;
1147 }
1148
1149 // The following are the various types of breakpoints that could be cleared:
1150 // 1). -f -l (clearing breakpoint by source location)
1151
1152 BreakpointClearType break_type = eClearTypeInvalid;
1153
1154 if (m_options.m_line_num != 0)
1155 break_type = eClearTypeFileAndLine;
1156
1157 Mutex::Locker locker;
1158 target->GetBreakpointList().GetListMutex(locker);
1159
1160 BreakpointList &breakpoints = target->GetBreakpointList();
1161 size_t num_breakpoints = breakpoints.GetSize();
1162
1163 // Early return if there's no breakpoint at all.
1164 if (num_breakpoints == 0)
1165 {
1166 result.AppendError ("Breakpoint clear: No breakpoint cleared.");
1167 result.SetStatus (eReturnStatusFailed);
1168 return result.Succeeded();
1169 }
1170
1171 // Find matching breakpoints and delete them.
1172
1173 // First create a copy of all the IDs.
1174 std::vector<break_id_t> BreakIDs;
1175 for (size_t i = 0; i < num_breakpoints; ++i)
1176 BreakIDs.push_back(breakpoints.GetBreakpointAtIndex(i).get()->GetID());
1177
1178 int num_cleared = 0;
1179 StreamString ss;
1180 switch (break_type)
1181 {
1182 case eClearTypeFileAndLine: // Breakpoint by source position
1183 {
1184 const ConstString filename(m_options.m_filename.c_str());
1185 BreakpointLocationCollection loc_coll;
1186
1187 for (size_t i = 0; i < num_breakpoints; ++i)
1188 {
1189 Breakpoint *bp = breakpoints.FindBreakpointByID(BreakIDs[i]).get();
1190
1191 if (bp->GetMatchingFileLine(filename, m_options.m_line_num, loc_coll))
1192 {
1193 // If the collection size is 0, it's a full match and we can just remove the breakpoint.
1194 if (loc_coll.GetSize() == 0)
1195 {
1196 bp->GetDescription(&ss, lldb::eDescriptionLevelBrief);
1197 ss.EOL();
1198 target->RemoveBreakpointByID (bp->GetID());
1199 ++num_cleared;
1200 }
1201 }
1202 }
1203 }
1204 break;
1205
1206 default:
1207 break;
1208 }
1209
1210 if (num_cleared > 0)
1211 {
Jim Ingham2e8cb8a2011-02-19 02:53:09 +00001212 Stream &output_stream = result.GetOutputStream();
Johnny Chena62ad7c2010-10-28 17:27:46 +00001213 output_stream.Printf ("%d breakpoints cleared:\n", num_cleared);
1214 output_stream << ss.GetData();
1215 output_stream.EOL();
1216 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1217 }
1218 else
1219 {
1220 result.AppendError ("Breakpoint clear: No breakpoint cleared.");
1221 result.SetStatus (eReturnStatusFailed);
1222 }
1223
1224 return result.Succeeded();
1225}
1226
1227//-------------------------------------------------------------------------
Chris Lattner24943d22010-06-08 16:52:24 +00001228// CommandObjectBreakpointDelete
1229//-------------------------------------------------------------------------
Jim Ingham10622a22010-06-18 00:58:52 +00001230#pragma mark Delete
Chris Lattner24943d22010-06-08 16:52:24 +00001231
Greg Clayton238c0a12010-09-18 01:14:36 +00001232CommandObjectBreakpointDelete::CommandObjectBreakpointDelete(CommandInterpreter &interpreter) :
1233 CommandObject (interpreter,
1234 "breakpoint delete",
Caroline Ticeabb507a2010-09-08 21:06:11 +00001235 "Delete the specified breakpoint(s). If no breakpoints are specified, delete them all.",
Caroline Ticefb355112010-10-01 17:46:38 +00001236 NULL)
Chris Lattner24943d22010-06-08 16:52:24 +00001237{
Caroline Ticefb355112010-10-01 17:46:38 +00001238 CommandArgumentEntry arg;
1239 CommandArgumentData bp_id_arg;
1240 CommandArgumentData bp_id_range_arg;
1241
1242 // Create the first variant for the first (and only) argument for this command.
1243 bp_id_arg.arg_type = eArgTypeBreakpointID;
Caroline Tice43b014a2010-10-04 22:28:36 +00001244 bp_id_arg.arg_repetition = eArgRepeatOptional;
Caroline Ticefb355112010-10-01 17:46:38 +00001245
1246 // Create the second variant for the first (and only) argument for this command.
1247 bp_id_range_arg.arg_type = eArgTypeBreakpointIDRange;
Caroline Tice43b014a2010-10-04 22:28:36 +00001248 bp_id_range_arg.arg_repetition = eArgRepeatOptional;
Caroline Ticefb355112010-10-01 17:46:38 +00001249
1250 // The first (and only) argument for this command could be either a bp_id or a bp_id_range.
1251 // Push both variants into the entry for the first argument for this command.
1252 arg.push_back (bp_id_arg);
1253 arg.push_back (bp_id_range_arg);
1254
1255 // Add the entry for the first argument for this command to the object's arguments vector.
1256 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +00001257}
1258
1259
1260CommandObjectBreakpointDelete::~CommandObjectBreakpointDelete ()
1261{
1262}
1263
1264bool
Greg Clayton63094e02010-06-23 01:19:29 +00001265CommandObjectBreakpointDelete::Execute
1266(
Greg Clayton63094e02010-06-23 01:19:29 +00001267 Args& args,
1268 CommandReturnObject &result
1269)
Chris Lattner24943d22010-06-08 16:52:24 +00001270{
Greg Clayton238c0a12010-09-18 01:14:36 +00001271 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +00001272 if (target == NULL)
1273 {
Caroline Tice17dce1c2010-09-29 19:42:33 +00001274 result.AppendError ("Invalid target. No existing target or breakpoints.");
Chris Lattner24943d22010-06-08 16:52:24 +00001275 result.SetStatus (eReturnStatusFailed);
1276 return false;
1277 }
1278
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001279 Mutex::Locker locker;
1280 target->GetBreakpointList().GetListMutex(locker);
1281
Chris Lattner24943d22010-06-08 16:52:24 +00001282 const BreakpointList &breakpoints = target->GetBreakpointList();
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001283
Chris Lattner24943d22010-06-08 16:52:24 +00001284 size_t num_breakpoints = breakpoints.GetSize();
1285
1286 if (num_breakpoints == 0)
1287 {
1288 result.AppendError ("No breakpoints exist to be deleted.");
1289 result.SetStatus (eReturnStatusFailed);
1290 return false;
1291 }
1292
1293 if (args.GetArgumentCount() == 0)
1294 {
Jim Inghamd1686902010-10-14 23:45:03 +00001295 if (!m_interpreter.Confirm ("About to delete all breakpoints, do you want to do that?", true))
Chris Lattner24943d22010-06-08 16:52:24 +00001296 {
Jim Inghamd1686902010-10-14 23:45:03 +00001297 result.AppendMessage("Operation cancelled...");
Chris Lattner24943d22010-06-08 16:52:24 +00001298 }
Jim Inghamd1686902010-10-14 23:45:03 +00001299 else
1300 {
1301 target->RemoveAllBreakpoints ();
1302 result.AppendMessageWithFormat ("All breakpoints removed. (%d breakpoints)\n", num_breakpoints);
1303 }
Chris Lattner24943d22010-06-08 16:52:24 +00001304 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1305 }
1306 else
1307 {
1308 // Particular breakpoint selected; disable that breakpoint.
1309 BreakpointIDList valid_bp_ids;
1310 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (args, target, result, &valid_bp_ids);
1311
1312 if (result.Succeeded())
1313 {
1314 int delete_count = 0;
1315 int disable_count = 0;
Greg Clayton54e7afa2010-07-09 20:39:50 +00001316 const size_t count = valid_bp_ids.GetSize();
1317 for (size_t i = 0; i < count; ++i)
Chris Lattner24943d22010-06-08 16:52:24 +00001318 {
1319 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1320
1321 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
1322 {
1323 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
1324 {
1325 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1326 BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
1327 // It makes no sense to try to delete individual locations, so we disable them instead.
1328 if (location)
1329 {
1330 location->SetEnabled (false);
1331 ++disable_count;
1332 }
1333 }
1334 else
1335 {
1336 target->RemoveBreakpointByID (cur_bp_id.GetBreakpointID());
1337 ++delete_count;
1338 }
1339 }
1340 }
1341 result.AppendMessageWithFormat ("%d breakpoints deleted; %d breakpoint locations disabled.\n",
1342 delete_count, disable_count);
1343 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1344 }
1345 }
1346 return result.Succeeded();
1347}
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001348
1349//-------------------------------------------------------------------------
Jim Ingham10622a22010-06-18 00:58:52 +00001350// CommandObjectBreakpointModify::CommandOptions
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001351//-------------------------------------------------------------------------
Jim Ingham10622a22010-06-18 00:58:52 +00001352#pragma mark Modify::CommandOptions
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001353
Greg Claytonf15996e2011-04-07 22:46:35 +00001354CommandObjectBreakpointModify::CommandOptions::CommandOptions(CommandInterpreter &interpreter) :
1355 Options (interpreter),
Greg Clayton54e7afa2010-07-09 20:39:50 +00001356 m_ignore_count (0),
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001357 m_thread_id(LLDB_INVALID_THREAD_ID),
Jim Ingham9a7b2912010-12-03 23:04:19 +00001358 m_thread_id_passed(false),
Greg Clayton54e7afa2010-07-09 20:39:50 +00001359 m_thread_index (UINT32_MAX),
Jim Ingham9a7b2912010-12-03 23:04:19 +00001360 m_thread_index_passed(false),
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001361 m_thread_name(),
1362 m_queue_name(),
Jim Inghamd1686902010-10-14 23:45:03 +00001363 m_condition (),
Greg Clayton54e7afa2010-07-09 20:39:50 +00001364 m_enable_passed (false),
1365 m_enable_value (false),
1366 m_name_passed (false),
Jim Inghamd1686902010-10-14 23:45:03 +00001367 m_queue_passed (false),
1368 m_condition_passed (false)
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001369{
1370}
1371
Jim Ingham10622a22010-06-18 00:58:52 +00001372CommandObjectBreakpointModify::CommandOptions::~CommandOptions ()
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001373{
1374}
1375
Greg Claytonb3448432011-03-24 21:19:54 +00001376OptionDefinition
Jim Ingham10622a22010-06-18 00:58:52 +00001377CommandObjectBreakpointModify::CommandOptions::g_option_table[] =
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001378{
Caroline Tice4d6675c2010-10-01 19:59:14 +00001379{ LLDB_OPT_SET_ALL, false, "ignore-count", 'i', required_argument, NULL, NULL, eArgTypeCount, "Set the number of times this breakpoint is skipped before stopping." },
1380{ LLDB_OPT_SET_ALL, false, "thread-index", 'x', required_argument, NULL, NULL, eArgTypeThreadIndex, "The breakpoint stops only for the thread whose indeX matches this argument."},
1381{ LLDB_OPT_SET_ALL, false, "thread-id", 't', required_argument, NULL, NULL, eArgTypeThreadID, "The breakpoint stops only for the thread whose TID matches this argument."},
1382{ LLDB_OPT_SET_ALL, false, "thread-name", 'T', required_argument, NULL, NULL, eArgTypeThreadName, "The breakpoint stops only for the thread whose thread name matches this argument."},
1383{ LLDB_OPT_SET_ALL, false, "queue-name", 'q', required_argument, NULL, NULL, eArgTypeQueueName, "The breakpoint stops only for threads in the queue whose name is given by this argument."},
Jim Inghamd1686902010-10-14 23:45:03 +00001384{ LLDB_OPT_SET_ALL, false, "condition", 'c', required_argument, NULL, NULL, eArgTypeExpression, "The breakpoint stops only if this condition expression evaluates to true."},
Caroline Tice4d6675c2010-10-01 19:59:14 +00001385{ LLDB_OPT_SET_1, false, "enable", 'e', no_argument, NULL, NULL, eArgTypeNone, "Enable the breakpoint."},
1386{ LLDB_OPT_SET_2, false, "disable", 'd', no_argument, NULL, NULL, eArgTypeNone, "Disable the breakpoint."},
Jim Inghamd1686902010-10-14 23:45:03 +00001387{ 0, false, NULL, 0 , 0, NULL, 0, eArgTypeNone, NULL }
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001388};
1389
Greg Claytonb3448432011-03-24 21:19:54 +00001390const OptionDefinition*
Jim Ingham10622a22010-06-18 00:58:52 +00001391CommandObjectBreakpointModify::CommandOptions::GetDefinitions ()
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001392{
1393 return g_option_table;
1394}
1395
1396Error
Jim Ingham10622a22010-06-18 00:58:52 +00001397CommandObjectBreakpointModify::CommandOptions::SetOptionValue (int option_idx, const char *option_arg)
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001398{
1399 Error error;
1400 char short_option = (char) m_getopt_table[option_idx].val;
1401
1402 switch (short_option)
1403 {
Jim Inghamd1686902010-10-14 23:45:03 +00001404 case 'c':
1405 if (option_arg != NULL)
Greg Clayton889fbd02011-03-26 19:14:58 +00001406 m_condition.assign (option_arg);
Jim Inghamd1686902010-10-14 23:45:03 +00001407 else
1408 m_condition.clear();
1409 m_condition_passed = true;
1410 break;
Jim Ingham10622a22010-06-18 00:58:52 +00001411 case 'd':
1412 m_enable_passed = true;
1413 m_enable_value = false;
1414 break;
1415 case 'e':
1416 m_enable_passed = true;
1417 m_enable_value = true;
1418 break;
Greg Claytonfe424a92010-09-18 03:37:20 +00001419 case 'i':
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001420 {
Jim Ingham7a4c8ea2011-03-22 01:53:33 +00001421 m_ignore_count = Args::StringToUInt32(option_arg, UINT32_MAX, 0);
Greg Clayton54e7afa2010-07-09 20:39:50 +00001422 if (m_ignore_count == UINT32_MAX)
Jim Ingham7a4c8ea2011-03-22 01:53:33 +00001423 error.SetErrorStringWithFormat ("Invalid ignore count '%s'.\n", option_arg);
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001424 }
Jim Ingham10622a22010-06-18 00:58:52 +00001425 break;
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001426 case 't' :
1427 {
Jim Ingham7a4c8ea2011-03-22 01:53:33 +00001428 if (option_arg[0] == '\0')
Jim Ingham9a7b2912010-12-03 23:04:19 +00001429 {
1430 m_thread_id = LLDB_INVALID_THREAD_ID;
1431 m_thread_id_passed = true;
1432 }
1433 else
1434 {
Jim Ingham7a4c8ea2011-03-22 01:53:33 +00001435 m_thread_id = Args::StringToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
Jim Ingham9a7b2912010-12-03 23:04:19 +00001436 if (m_thread_id == LLDB_INVALID_THREAD_ID)
Jim Ingham7a4c8ea2011-03-22 01:53:33 +00001437 error.SetErrorStringWithFormat ("Invalid thread id string '%s'.\n", option_arg);
Jim Ingham9a7b2912010-12-03 23:04:19 +00001438 else
1439 m_thread_id_passed = true;
1440 }
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001441 }
1442 break;
1443 case 'T':
Jim Inghamd4571222010-06-19 04:35:20 +00001444 if (option_arg != NULL)
Greg Clayton889fbd02011-03-26 19:14:58 +00001445 m_thread_name.assign (option_arg);
Jim Inghamd4571222010-06-19 04:35:20 +00001446 else
1447 m_thread_name.clear();
1448 m_name_passed = true;
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001449 break;
1450 case 'q':
Jim Inghamd4571222010-06-19 04:35:20 +00001451 if (option_arg != NULL)
Greg Clayton889fbd02011-03-26 19:14:58 +00001452 m_queue_name.assign (option_arg);
Jim Inghamd4571222010-06-19 04:35:20 +00001453 else
1454 m_queue_name.clear();
1455 m_queue_passed = true;
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001456 break;
1457 case 'x':
1458 {
Jim Ingham7a4c8ea2011-03-22 01:53:33 +00001459 if (option_arg[0] == '\n')
Jim Ingham9a7b2912010-12-03 23:04:19 +00001460 {
1461 m_thread_index = UINT32_MAX;
1462 m_thread_index_passed = true;
1463 }
1464 else
1465 {
Jim Ingham7a4c8ea2011-03-22 01:53:33 +00001466 m_thread_index = Args::StringToUInt32 (option_arg, UINT32_MAX, 0);
Jim Ingham9a7b2912010-12-03 23:04:19 +00001467 if (m_thread_id == UINT32_MAX)
Jim Ingham7a4c8ea2011-03-22 01:53:33 +00001468 error.SetErrorStringWithFormat ("Invalid thread index string '%s'.\n", option_arg);
Jim Ingham9a7b2912010-12-03 23:04:19 +00001469 else
1470 m_thread_index_passed = true;
1471 }
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001472 }
1473 break;
1474 default:
1475 error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
1476 break;
1477 }
1478
1479 return error;
1480}
1481
1482void
Jim Ingham10622a22010-06-18 00:58:52 +00001483CommandObjectBreakpointModify::CommandOptions::ResetOptionValues ()
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001484{
Greg Clayton54e7afa2010-07-09 20:39:50 +00001485 m_ignore_count = 0;
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001486 m_thread_id = LLDB_INVALID_THREAD_ID;
Jim Ingham9a7b2912010-12-03 23:04:19 +00001487 m_thread_id_passed = false;
Greg Clayton54e7afa2010-07-09 20:39:50 +00001488 m_thread_index = UINT32_MAX;
Jim Ingham9a7b2912010-12-03 23:04:19 +00001489 m_thread_index_passed = false;
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001490 m_thread_name.clear();
1491 m_queue_name.clear();
Jim Inghamd1686902010-10-14 23:45:03 +00001492 m_condition.clear();
Jim Ingham10622a22010-06-18 00:58:52 +00001493 m_enable_passed = false;
Jim Inghamd4571222010-06-19 04:35:20 +00001494 m_queue_passed = false;
1495 m_name_passed = false;
Jim Inghamd1686902010-10-14 23:45:03 +00001496 m_condition_passed = false;
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001497}
1498
1499//-------------------------------------------------------------------------
Jim Ingham10622a22010-06-18 00:58:52 +00001500// CommandObjectBreakpointModify
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001501//-------------------------------------------------------------------------
Jim Ingham10622a22010-06-18 00:58:52 +00001502#pragma mark Modify
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001503
Greg Clayton238c0a12010-09-18 01:14:36 +00001504CommandObjectBreakpointModify::CommandObjectBreakpointModify (CommandInterpreter &interpreter) :
1505 CommandObject (interpreter,
1506 "breakpoint modify",
Jim Ingham19ac0bd2010-12-03 22:37:19 +00001507 "Modify the options on a breakpoint or set of breakpoints in the executable. "
Jim Ingham9a7b2912010-12-03 23:04:19 +00001508 "If no breakpoint is specified, acts on the last created breakpoint. "
1509 "With the exception of -e, -d and -i, passing an empty argument clears the modification.",
Greg Claytonf15996e2011-04-07 22:46:35 +00001510 NULL),
1511 m_options (interpreter)
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001512{
Caroline Ticefb355112010-10-01 17:46:38 +00001513 CommandArgumentEntry arg;
1514 CommandArgumentData bp_id_arg;
1515 CommandArgumentData bp_id_range_arg;
1516
1517 // Create the first variant for the first (and only) argument for this command.
1518 bp_id_arg.arg_type = eArgTypeBreakpointID;
Caroline Tice43b014a2010-10-04 22:28:36 +00001519 bp_id_arg.arg_repetition = eArgRepeatPlain;
Caroline Ticefb355112010-10-01 17:46:38 +00001520
1521 // Create the second variant for the first (and only) argument for this command.
1522 bp_id_range_arg.arg_type = eArgTypeBreakpointIDRange;
Caroline Tice43b014a2010-10-04 22:28:36 +00001523 bp_id_range_arg.arg_repetition = eArgRepeatPlain;
Caroline Ticefb355112010-10-01 17:46:38 +00001524
1525 // The first (and only) argument for this command could be either a bp_id or a bp_id_range.
1526 // Push both variants into the entry for the first argument for this command.
1527 arg.push_back (bp_id_arg);
1528 arg.push_back (bp_id_range_arg);
1529
1530 // Add the entry for the first argument for this command to the object's arguments vector.
1531 m_arguments.push_back (arg);
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001532}
1533
Jim Ingham10622a22010-06-18 00:58:52 +00001534CommandObjectBreakpointModify::~CommandObjectBreakpointModify ()
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001535{
1536}
1537
1538Options *
Jim Ingham10622a22010-06-18 00:58:52 +00001539CommandObjectBreakpointModify::GetOptions ()
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001540{
1541 return &m_options;
1542}
1543
1544bool
Jim Ingham10622a22010-06-18 00:58:52 +00001545CommandObjectBreakpointModify::Execute
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001546(
1547 Args& command,
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001548 CommandReturnObject &result
1549)
1550{
Greg Clayton238c0a12010-09-18 01:14:36 +00001551 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001552 if (target == NULL)
1553 {
Caroline Tice17dce1c2010-09-29 19:42:33 +00001554 result.AppendError ("Invalid target. No existing target or breakpoints.");
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001555 result.SetStatus (eReturnStatusFailed);
1556 return false;
1557 }
1558
1559 Mutex::Locker locker;
1560 target->GetBreakpointList().GetListMutex(locker);
1561
1562 BreakpointIDList valid_bp_ids;
1563
1564 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
1565
1566 if (result.Succeeded())
1567 {
Greg Clayton54e7afa2010-07-09 20:39:50 +00001568 const size_t count = valid_bp_ids.GetSize();
1569 for (size_t i = 0; i < count; ++i)
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001570 {
1571 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1572
1573 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
1574 {
1575 Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1576 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
1577 {
1578 BreakpointLocation *location = bp->FindLocationByID (cur_bp_id.GetLocationID()).get();
1579 if (location)
1580 {
Jim Ingham9a7b2912010-12-03 23:04:19 +00001581 if (m_options.m_thread_id_passed)
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001582 location->SetThreadID (m_options.m_thread_id);
1583
Jim Ingham9a7b2912010-12-03 23:04:19 +00001584 if (m_options.m_thread_index_passed)
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001585 location->GetLocationOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index);
1586
Jim Inghamd4571222010-06-19 04:35:20 +00001587 if (m_options.m_name_passed)
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001588 location->GetLocationOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str());
1589
Jim Inghamd4571222010-06-19 04:35:20 +00001590 if (m_options.m_queue_passed)
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001591 location->GetLocationOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str());
1592
Greg Clayton54e7afa2010-07-09 20:39:50 +00001593 if (m_options.m_ignore_count != 0)
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001594 location->GetLocationOptions()->SetIgnoreCount(m_options.m_ignore_count);
Jim Ingham10622a22010-06-18 00:58:52 +00001595
1596 if (m_options.m_enable_passed)
1597 location->SetEnabled (m_options.m_enable_value);
Jim Inghamd1686902010-10-14 23:45:03 +00001598
1599 if (m_options.m_condition_passed)
1600 location->SetCondition (m_options.m_condition.c_str());
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001601 }
1602 }
1603 else
1604 {
Jim Ingham9a7b2912010-12-03 23:04:19 +00001605 if (m_options.m_thread_id_passed)
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001606 bp->SetThreadID (m_options.m_thread_id);
1607
Jim Ingham9a7b2912010-12-03 23:04:19 +00001608 if (m_options.m_thread_index_passed)
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001609 bp->GetOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index);
1610
Jim Inghamd4571222010-06-19 04:35:20 +00001611 if (m_options.m_name_passed)
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001612 bp->GetOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str());
1613
Jim Inghamd4571222010-06-19 04:35:20 +00001614 if (m_options.m_queue_passed)
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001615 bp->GetOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str());
1616
Greg Clayton54e7afa2010-07-09 20:39:50 +00001617 if (m_options.m_ignore_count != 0)
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001618 bp->GetOptions()->SetIgnoreCount(m_options.m_ignore_count);
Jim Ingham10622a22010-06-18 00:58:52 +00001619
1620 if (m_options.m_enable_passed)
1621 bp->SetEnabled (m_options.m_enable_value);
Jim Inghamd1686902010-10-14 23:45:03 +00001622
1623 if (m_options.m_condition_passed)
1624 bp->SetCondition (m_options.m_condition.c_str());
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001625 }
1626 }
1627 }
1628 }
1629
1630 return result.Succeeded();
1631}
1632
1633