blob: 237ac89a35ec7689bd3297b2dd34ec4fa8de722a [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
Greg Clayton63094e02010-06-23 01:19:29 +000037AddBreakpointDescription (StreamString *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
50CommandObjectBreakpointSet::CommandOptions::CommandOptions() :
51 Options (),
52 m_filename (),
53 m_line_num (0),
54 m_column (0),
55 m_ignore_inlines (false),
56 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
73lldb::OptionDefinition
74CommandObjectBreakpointSet::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
130const lldb::OptionDefinition*
131CommandObjectBreakpointSet::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':
145 m_load_addr = Args::StringToUInt64(optarg, LLDB_INVALID_ADDRESS, 0);
146 if (m_load_addr == LLDB_INVALID_ADDRESS)
147 m_load_addr = Args::StringToUInt64(optarg, LLDB_INVALID_ADDRESS, 16);
148
149 if (m_load_addr == LLDB_INVALID_ADDRESS)
150 error.SetErrorStringWithFormat ("Invalid address string '%s'.\n", optarg);
151 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':
158 m_filename = option_arg;
159 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':
Chris Lattner24943d22010-06-08 16:52:24 +0000166 m_func_name = 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':
171 m_func_name = option_arg;
172 m_func_name_type_mask |= eFunctionNameTypeAuto;
173 break;
174
Greg Clayton12bec712010-06-28 21:30:43 +0000175 case 'F':
Jim Inghamd9e2b762010-08-26 23:56:11 +0000176 m_func_name = option_arg;
Greg Clayton12bec712010-06-28 21:30:43 +0000177 m_func_name_type_mask |= eFunctionNameTypeFull;
178 break;
179
180 case 'S':
Jim Inghamd9e2b762010-08-26 23:56:11 +0000181 m_func_name = 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':
186 m_func_name = 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':
191 m_func_regexp = option_arg;
192 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 {
Greg Clayton54e7afa2010-07-09 20:39:50 +0000201 m_ignore_count = Args::StringToUInt32(optarg, UINT32_MAX, 0);
202 if (m_ignore_count == UINT32_MAX)
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000203 error.SetErrorStringWithFormat ("Invalid ignore count '%s'.\n", optarg);
204 }
Jim Ingham10622a22010-06-18 00:58:52 +0000205 break;
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000206 case 't' :
207 {
208 m_thread_id = Args::StringToUInt64(optarg, LLDB_INVALID_THREAD_ID, 0);
209 if (m_thread_id == LLDB_INVALID_THREAD_ID)
210 error.SetErrorStringWithFormat ("Invalid thread id string '%s'.\n", optarg);
211 }
212 break;
213 case 'T':
214 m_thread_name = option_arg;
215 break;
216 case 'q':
217 m_queue_name = option_arg;
218 break;
219 case 'x':
220 {
Greg Clayton54e7afa2010-07-09 20:39:50 +0000221 m_thread_index = Args::StringToUInt32(optarg, UINT32_MAX, 0);
222 if (m_thread_id == UINT32_MAX)
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000223 error.SetErrorStringWithFormat ("Invalid thread index string '%s'.\n", optarg);
224
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{
238 Options::ResetOptionValues();
239
240 m_filename.clear();
241 m_line_num = 0;
242 m_column = 0;
Chris Lattner24943d22010-06-08 16:52:24 +0000243 m_func_name.clear();
Greg Clayton12bec712010-06-28 21:30:43 +0000244 m_func_name_type_mask = 0;
Chris Lattner24943d22010-06-08 16:52:24 +0000245 m_func_regexp.clear();
246 m_load_addr = LLDB_INVALID_ADDRESS;
247 m_modules.clear();
Greg Clayton54e7afa2010-07-09 20:39:50 +0000248 m_ignore_count = 0;
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000249 m_thread_id = LLDB_INVALID_THREAD_ID;
Greg Clayton54e7afa2010-07-09 20:39:50 +0000250 m_thread_index = UINT32_MAX;
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000251 m_thread_name.clear();
252 m_queue_name.clear();
Chris Lattner24943d22010-06-08 16:52:24 +0000253}
254
255//-------------------------------------------------------------------------
256// CommandObjectBreakpointSet
257//-------------------------------------------------------------------------
Jim Ingham10622a22010-06-18 00:58:52 +0000258#pragma mark Set
Chris Lattner24943d22010-06-08 16:52:24 +0000259
Greg Clayton238c0a12010-09-18 01:14:36 +0000260CommandObjectBreakpointSet::CommandObjectBreakpointSet (CommandInterpreter &interpreter) :
261 CommandObject (interpreter,
262 "breakpoint set",
263 "Sets a breakpoint or set of breakpoints in the executable.",
Chris Lattner24943d22010-06-08 16:52:24 +0000264 "breakpoint set <cmd-options>")
265{
266}
267
268CommandObjectBreakpointSet::~CommandObjectBreakpointSet ()
269{
270}
271
272Options *
273CommandObjectBreakpointSet::GetOptions ()
274{
275 return &m_options;
276}
277
278bool
279CommandObjectBreakpointSet::Execute
280(
281 Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000282 CommandReturnObject &result
283)
284{
Greg Clayton238c0a12010-09-18 01:14:36 +0000285 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000286 if (target == NULL)
287 {
Caroline Tice17dce1c2010-09-29 19:42:33 +0000288 result.AppendError ("Invalid target. Must set target before setting breakpoints (see 'file' command).");
Chris Lattner24943d22010-06-08 16:52:24 +0000289 result.SetStatus (eReturnStatusFailed);
290 return false;
291 }
292
293 // The following are the various types of breakpoints that could be set:
294 // 1). -f -l -p [-s -g] (setting breakpoint by source location)
295 // 2). -a [-s -g] (setting breakpoint by address)
296 // 3). -n [-s -g] (setting breakpoint by function name)
297 // 4). -r [-s -g] (setting breakpoint by function name regular expression)
298
299 BreakpointSetType break_type = eSetTypeInvalid;
300
301 if (m_options.m_line_num != 0)
302 break_type = eSetTypeFileAndLine;
303 else if (m_options.m_load_addr != LLDB_INVALID_ADDRESS)
304 break_type = eSetTypeAddress;
305 else if (!m_options.m_func_name.empty())
306 break_type = eSetTypeFunctionName;
307 else if (!m_options.m_func_regexp.empty())
308 break_type = eSetTypeFunctionRegexp;
309
310 ModuleSP module_sp = target->GetExecutableModule();
311 Breakpoint *bp = NULL;
Greg Clayton537a7a82010-10-20 20:54:39 +0000312 FileSpec module_spec;
Chris Lattner24943d22010-06-08 16:52:24 +0000313 bool use_module = false;
314 int num_modules = m_options.m_modules.size();
315
316 if ((num_modules > 0) && (break_type != eSetTypeAddress))
317 use_module = true;
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000318
Chris Lattner24943d22010-06-08 16:52:24 +0000319 switch (break_type)
320 {
321 case eSetTypeFileAndLine: // Breakpoint by source position
Chris Lattner24943d22010-06-08 16:52:24 +0000322 {
Greg Clayton887aa282010-10-11 01:05:37 +0000323 FileSpec file;
324 if (m_options.m_filename.empty())
Chris Lattner24943d22010-06-08 16:52:24 +0000325 {
Greg Clayton887aa282010-10-11 01:05:37 +0000326 StackFrame *cur_frame = m_interpreter.GetDebugger().GetExecutionContext().frame;
327 if (cur_frame == NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000328 {
Greg Clayton887aa282010-10-11 01:05:37 +0000329 result.AppendError ("Attempting to set breakpoint by line number alone with no selected frame.");
Chris Lattner24943d22010-06-08 16:52:24 +0000330 result.SetStatus (eReturnStatusFailed);
331 break;
332 }
Greg Clayton887aa282010-10-11 01:05:37 +0000333 else if (!cur_frame->HasDebugInformation())
Chris Lattner24943d22010-06-08 16:52:24 +0000334 {
Greg Clayton887aa282010-10-11 01:05:37 +0000335 result.AppendError ("Attempting to set breakpoint by line number alone but selected frame has no debug info.");
336 result.SetStatus (eReturnStatusFailed);
337 break;
Chris Lattner24943d22010-06-08 16:52:24 +0000338 }
339 else
340 {
Greg Clayton887aa282010-10-11 01:05:37 +0000341 const SymbolContext &context = cur_frame->GetSymbolContext(true);
342 if (context.line_entry.file)
343 {
344 file = context.line_entry.file;
345 }
346 else if (context.comp_unit != NULL)
347 { file = context.comp_unit;
348 }
349 else
350 {
351 result.AppendError ("Attempting to set breakpoint by line number alone but can't find the file for the selected frame.");
352 result.SetStatus (eReturnStatusFailed);
353 break;
354 }
Chris Lattner24943d22010-06-08 16:52:24 +0000355 }
356 }
Greg Clayton887aa282010-10-11 01:05:37 +0000357 else
358 {
Greg Clayton537a7a82010-10-20 20:54:39 +0000359 file.SetFile(m_options.m_filename.c_str(), false);
Greg Clayton887aa282010-10-11 01:05:37 +0000360 }
361
362 if (use_module)
363 {
364 for (int i = 0; i < num_modules; ++i)
365 {
Greg Clayton537a7a82010-10-20 20:54:39 +0000366 module_spec.SetFile(m_options.m_modules[i].c_str(), false);
367 bp = target->CreateBreakpoint (&module_spec,
Greg Clayton887aa282010-10-11 01:05:37 +0000368 file,
369 m_options.m_line_num,
370 m_options.m_ignore_inlines).get();
371 if (bp)
372 {
373 StreamString &output_stream = result.GetOutputStream();
374 output_stream.Printf ("Breakpoint created: ");
375 bp->GetDescription(&output_stream, lldb::eDescriptionLevelBrief);
376 output_stream.EOL();
Caroline Ticecf2f3052010-10-28 16:28:56 +0000377 if (bp->GetNumLocations() == 0)
378 output_stream.Printf ("WARNING: Unable to resolve breakpoint to any actual"
379 " locations.\n");
Greg Clayton887aa282010-10-11 01:05:37 +0000380 result.SetStatus (eReturnStatusSuccessFinishResult);
381 }
382 else
383 {
384 result.AppendErrorWithFormat("Breakpoint creation failed: No breakpoint created in module '%s'.\n",
385 m_options.m_modules[i].c_str());
386 result.SetStatus (eReturnStatusFailed);
387 }
388 }
389 }
390 else
391 bp = target->CreateBreakpoint (NULL,
392 file,
393 m_options.m_line_num,
394 m_options.m_ignore_inlines).get();
Chris Lattner24943d22010-06-08 16:52:24 +0000395 }
Greg Clayton887aa282010-10-11 01:05:37 +0000396 break;
397
Chris Lattner24943d22010-06-08 16:52:24 +0000398 case eSetTypeAddress: // Breakpoint by address
399 bp = target->CreateBreakpoint (m_options.m_load_addr, false).get();
400 break;
Greg Clayton12bec712010-06-28 21:30:43 +0000401
Chris Lattner24943d22010-06-08 16:52:24 +0000402 case eSetTypeFunctionName: // Breakpoint by function name
Chris Lattner24943d22010-06-08 16:52:24 +0000403 {
Greg Clayton12bec712010-06-28 21:30:43 +0000404 uint32_t name_type_mask = m_options.m_func_name_type_mask;
405
406 if (name_type_mask == 0)
Greg Clayton48fbdf72010-10-12 04:29:14 +0000407 name_type_mask = eFunctionNameTypeAuto;
408
Greg Clayton12bec712010-06-28 21:30:43 +0000409 if (use_module)
410 {
411 for (int i = 0; i < num_modules; ++i)
Chris Lattner24943d22010-06-08 16:52:24 +0000412 {
Greg Clayton537a7a82010-10-20 20:54:39 +0000413 module_spec.SetFile(m_options.m_modules[i].c_str(), false);
414 bp = target->CreateBreakpoint (&module_spec,
415 m_options.m_func_name.c_str(),
416 name_type_mask,
417 Breakpoint::Exact).get();
Greg Clayton12bec712010-06-28 21:30:43 +0000418 if (bp)
419 {
420 StreamString &output_stream = result.GetOutputStream();
421 output_stream.Printf ("Breakpoint created: ");
422 bp->GetDescription(&output_stream, lldb::eDescriptionLevelBrief);
423 output_stream.EOL();
Caroline Ticecf2f3052010-10-28 16:28:56 +0000424 if (bp->GetNumLocations() == 0)
425 output_stream.Printf ("WARNING: Unable to resolve breakpoint to any actual"
426 " locations.\n");
Greg Clayton12bec712010-06-28 21:30:43 +0000427 result.SetStatus (eReturnStatusSuccessFinishResult);
428 }
429 else
430 {
431 result.AppendErrorWithFormat("Breakpoint creation failed: No breakpoint created in module '%s'.\n",
432 m_options.m_modules[i].c_str());
433 result.SetStatus (eReturnStatusFailed);
434 }
Chris Lattner24943d22010-06-08 16:52:24 +0000435 }
436 }
Greg Clayton12bec712010-06-28 21:30:43 +0000437 else
438 bp = target->CreateBreakpoint (NULL, m_options.m_func_name.c_str(), name_type_mask, Breakpoint::Exact).get();
Chris Lattner24943d22010-06-08 16:52:24 +0000439 }
Chris Lattner24943d22010-06-08 16:52:24 +0000440 break;
Greg Clayton12bec712010-06-28 21:30:43 +0000441
Chris Lattner24943d22010-06-08 16:52:24 +0000442 case eSetTypeFunctionRegexp: // Breakpoint by regular expression function name
443 {
444 RegularExpression regexp(m_options.m_func_regexp.c_str());
445 if (use_module)
446 {
447 for (int i = 0; i < num_modules; ++i)
448 {
Greg Clayton537a7a82010-10-20 20:54:39 +0000449 module_spec.SetFile(m_options.m_modules[i].c_str(), false);
450 bp = target->CreateBreakpoint (&module_spec, regexp).get();
Chris Lattner24943d22010-06-08 16:52:24 +0000451 if (bp)
452 {
453 StreamString &output_stream = result.GetOutputStream();
454 output_stream.Printf ("Breakpoint created: ");
455 bp->GetDescription(&output_stream, lldb::eDescriptionLevelBrief);
456 output_stream.EOL();
Caroline Ticecf2f3052010-10-28 16:28:56 +0000457 if (bp->GetNumLocations() == 0)
458 output_stream.Printf ("WARNING: Unable to resolve breakpoint to any actual"
459 " locations.\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000460 result.SetStatus (eReturnStatusSuccessFinishResult);
461 }
462 else
463 {
464 result.AppendErrorWithFormat("Breakpoint creation failed: No breakpoint created in module '%s'.\n",
465 m_options.m_modules[i].c_str());
466 result.SetStatus (eReturnStatusFailed);
467 }
468 }
469 }
470 else
471 bp = target->CreateBreakpoint (NULL, regexp).get();
472 }
473 break;
Greg Clayton12bec712010-06-28 21:30:43 +0000474
Chris Lattner24943d22010-06-08 16:52:24 +0000475 default:
476 break;
477 }
478
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000479 // Now set the various options that were passed in:
480 if (bp)
481 {
482 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
483 bp->SetThreadID (m_options.m_thread_id);
484
Greg Clayton54e7afa2010-07-09 20:39:50 +0000485 if (m_options.m_thread_index != UINT32_MAX)
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000486 bp->GetOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index);
487
488 if (!m_options.m_thread_name.empty())
489 bp->GetOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str());
490
491 if (!m_options.m_queue_name.empty())
492 bp->GetOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str());
493
Greg Clayton54e7afa2010-07-09 20:39:50 +0000494 if (m_options.m_ignore_count != 0)
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000495 bp->GetOptions()->SetIgnoreCount(m_options.m_ignore_count);
496 }
497
Chris Lattner24943d22010-06-08 16:52:24 +0000498 if (bp && !use_module)
499 {
500 StreamString &output_stream = result.GetOutputStream();
501 output_stream.Printf ("Breakpoint created: ");
502 bp->GetDescription(&output_stream, lldb::eDescriptionLevelBrief);
503 output_stream.EOL();
Caroline Ticecf2f3052010-10-28 16:28:56 +0000504 if (bp->GetNumLocations() == 0)
505 output_stream.Printf ("WARNING: Unable to resolve breakpoint to any actual locations.\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000506 result.SetStatus (eReturnStatusSuccessFinishResult);
507 }
508 else if (!bp)
509 {
510 result.AppendError ("Breakpoint creation failed: No breakpoint created.");
511 result.SetStatus (eReturnStatusFailed);
512 }
513
514 return result.Succeeded();
515}
516
Chris Lattner24943d22010-06-08 16:52:24 +0000517//-------------------------------------------------------------------------
518// CommandObjectMultiwordBreakpoint
519//-------------------------------------------------------------------------
Jim Ingham10622a22010-06-18 00:58:52 +0000520#pragma mark MultiwordBreakpoint
Chris Lattner24943d22010-06-08 16:52:24 +0000521
Greg Clayton63094e02010-06-23 01:19:29 +0000522CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +0000523 CommandObjectMultiword (interpreter,
524 "breakpoint",
525 "A set of commands for operating on breakpoints. Also see regexp-break.",
526 "breakpoint <command> [<command-options>]")
Chris Lattner24943d22010-06-08 16:52:24 +0000527{
528 bool status;
529
Greg Clayton238c0a12010-09-18 01:14:36 +0000530 CommandObjectSP list_command_object (new CommandObjectBreakpointList (interpreter));
Greg Clayton238c0a12010-09-18 01:14:36 +0000531 CommandObjectSP enable_command_object (new CommandObjectBreakpointEnable (interpreter));
532 CommandObjectSP disable_command_object (new CommandObjectBreakpointDisable (interpreter));
Johnny Chena62ad7c2010-10-28 17:27:46 +0000533 CommandObjectSP clear_command_object (new CommandObjectBreakpointClear (interpreter));
534 CommandObjectSP delete_command_object (new CommandObjectBreakpointDelete (interpreter));
Greg Clayton238c0a12010-09-18 01:14:36 +0000535 CommandObjectSP set_command_object (new CommandObjectBreakpointSet (interpreter));
Chris Lattner24943d22010-06-08 16:52:24 +0000536 CommandObjectSP command_command_object (new CommandObjectBreakpointCommand (interpreter));
Greg Clayton238c0a12010-09-18 01:14:36 +0000537 CommandObjectSP modify_command_object (new CommandObjectBreakpointModify(interpreter));
Chris Lattner24943d22010-06-08 16:52:24 +0000538
Johnny Chena62ad7c2010-10-28 17:27:46 +0000539 list_command_object->SetCommandName ("breakpoint list");
Chris Lattner24943d22010-06-08 16:52:24 +0000540 enable_command_object->SetCommandName("breakpoint enable");
541 disable_command_object->SetCommandName("breakpoint disable");
Johnny Chena62ad7c2010-10-28 17:27:46 +0000542 clear_command_object->SetCommandName("breakpoint clear");
543 delete_command_object->SetCommandName("breakpoint delete");
Jim Ingham10622a22010-06-18 00:58:52 +0000544 set_command_object->SetCommandName("breakpoint set");
Johnny Chena62ad7c2010-10-28 17:27:46 +0000545 command_command_object->SetCommandName ("breakpoint command");
546 modify_command_object->SetCommandName ("breakpoint modify");
Chris Lattner24943d22010-06-08 16:52:24 +0000547
Greg Clayton238c0a12010-09-18 01:14:36 +0000548 status = LoadSubCommand ("list", list_command_object);
549 status = LoadSubCommand ("enable", enable_command_object);
550 status = LoadSubCommand ("disable", disable_command_object);
Johnny Chena62ad7c2010-10-28 17:27:46 +0000551 status = LoadSubCommand ("clear", clear_command_object);
Greg Clayton238c0a12010-09-18 01:14:36 +0000552 status = LoadSubCommand ("delete", delete_command_object);
553 status = LoadSubCommand ("set", set_command_object);
554 status = LoadSubCommand ("command", command_command_object);
555 status = LoadSubCommand ("modify", modify_command_object);
Chris Lattner24943d22010-06-08 16:52:24 +0000556}
557
558CommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint ()
559{
560}
561
562void
563CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (Args &args, Target *target, CommandReturnObject &result,
564 BreakpointIDList *valid_ids)
565{
566 // args can be strings representing 1). integers (for breakpoint ids)
567 // 2). the full breakpoint & location canonical representation
568 // 3). the word "to" or a hyphen, representing a range (in which case there
569 // had *better* be an entry both before & after of one of the first two types.
Jim Inghamd1686902010-10-14 23:45:03 +0000570 // If args is empty, we will use the last created breakpoint (if there is one.)
Chris Lattner24943d22010-06-08 16:52:24 +0000571
572 Args temp_args;
573
Jim Inghamd1686902010-10-14 23:45:03 +0000574 if (args.GetArgumentCount() == 0)
575 {
576 if (target->GetLastCreatedBreakpoint() != NULL)
577 {
578 valid_ids->AddBreakpointID (BreakpointID(target->GetLastCreatedBreakpoint()->GetID(), LLDB_INVALID_BREAK_ID));
579 result.SetStatus (eReturnStatusSuccessFinishNoResult);
580 }
581 else
582 {
583 result.AppendError("No breakpoint specified and no last created breakpoint.");
584 result.SetStatus (eReturnStatusFailed);
585 }
586 return;
587 }
588
Chris Lattner24943d22010-06-08 16:52:24 +0000589 // Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff directly from the old ARGS to
590 // the new TEMP_ARGS. Do not copy breakpoint id range strings over; instead generate a list of strings for
591 // all the breakpoint ids in the range, and shove all of those breakpoint id strings into TEMP_ARGS.
592
593 BreakpointIDList::FindAndReplaceIDRanges (args, target, result, temp_args);
594
595 // NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual BreakpointIDList:
596
Greg Clayton54e7afa2010-07-09 20:39:50 +0000597 valid_ids->InsertStringArray (temp_args.GetConstArgumentVector(), temp_args.GetArgumentCount(), result);
Chris Lattner24943d22010-06-08 16:52:24 +0000598
599 // At this point, all of the breakpoint ids that the user passed in have been converted to breakpoint IDs
600 // and put into valid_ids.
601
602 if (result.Succeeded())
603 {
604 // Now that we've converted everything from args into a list of breakpoint ids, go through our tentative list
605 // of breakpoint id's and verify that they correspond to valid/currently set breakpoints.
606
Greg Clayton54e7afa2010-07-09 20:39:50 +0000607 const size_t count = valid_ids->GetSize();
608 for (size_t i = 0; i < count; ++i)
Chris Lattner24943d22010-06-08 16:52:24 +0000609 {
610 BreakpointID cur_bp_id = valid_ids->GetBreakpointIDAtIndex (i);
611 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
612 if (breakpoint != NULL)
613 {
614 int num_locations = breakpoint->GetNumLocations();
615 if (cur_bp_id.GetLocationID() > num_locations)
616 {
617 StreamString id_str;
Greg Clayton54e7afa2010-07-09 20:39:50 +0000618 BreakpointID::GetCanonicalReference (&id_str,
619 cur_bp_id.GetBreakpointID(),
620 cur_bp_id.GetLocationID());
621 i = valid_ids->GetSize() + 1;
Chris Lattner24943d22010-06-08 16:52:24 +0000622 result.AppendErrorWithFormat ("'%s' is not a currently valid breakpoint/location id.\n",
623 id_str.GetData());
624 result.SetStatus (eReturnStatusFailed);
625 }
626 }
627 else
628 {
Greg Clayton54e7afa2010-07-09 20:39:50 +0000629 i = valid_ids->GetSize() + 1;
Chris Lattner24943d22010-06-08 16:52:24 +0000630 result.AppendErrorWithFormat ("'%d' is not a currently valid breakpoint id.\n", cur_bp_id.GetBreakpointID());
631 result.SetStatus (eReturnStatusFailed);
632 }
633 }
634 }
635}
636
637//-------------------------------------------------------------------------
638// CommandObjectBreakpointList::Options
639//-------------------------------------------------------------------------
Jim Ingham10622a22010-06-18 00:58:52 +0000640#pragma mark List::CommandOptions
Chris Lattner24943d22010-06-08 16:52:24 +0000641
642CommandObjectBreakpointList::CommandOptions::CommandOptions() :
643 Options (),
644 m_level (lldb::eDescriptionLevelFull) // Breakpoint List defaults to brief descriptions
645{
Chris Lattner24943d22010-06-08 16:52:24 +0000646}
647
648CommandObjectBreakpointList::CommandOptions::~CommandOptions ()
649{
650}
651
652lldb::OptionDefinition
653CommandObjectBreakpointList::CommandOptions::g_option_table[] =
654{
Caroline Tice4d6675c2010-10-01 19:59:14 +0000655 { LLDB_OPT_SET_ALL, false, "internal", 'i', no_argument, NULL, 0, eArgTypeNone,
Jim Ingham34e9a982010-06-15 18:47:14 +0000656 "Show debugger internal breakpoints" },
657
Caroline Tice4d6675c2010-10-01 19:59:14 +0000658 { LLDB_OPT_SET_1, false, "brief", 'b', no_argument, NULL, 0, eArgTypeNone,
Chris Lattner24943d22010-06-08 16:52:24 +0000659 "Give a brief description of the breakpoint (no location info)."},
660
661 // FIXME: We need to add an "internal" command, and then add this sort of thing to it.
662 // But I need to see it for now, and don't want to wait.
Caroline Tice4d6675c2010-10-01 19:59:14 +0000663 { LLDB_OPT_SET_2, false, "full", 'f', no_argument, NULL, 0, eArgTypeNone,
Chris Lattner24943d22010-06-08 16:52:24 +0000664 "Give a full description of the breakpoint and its locations."},
Chris Lattner24943d22010-06-08 16:52:24 +0000665
Caroline Tice4d6675c2010-10-01 19:59:14 +0000666 { LLDB_OPT_SET_3, false, "verbose", 'v', no_argument, NULL, 0, eArgTypeNone,
Chris Lattner24943d22010-06-08 16:52:24 +0000667 "Explain everything we know about the breakpoint (for debugging debugger bugs)." },
Chris Lattner24943d22010-06-08 16:52:24 +0000668
Caroline Tice4d6675c2010-10-01 19:59:14 +0000669 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Chris Lattner24943d22010-06-08 16:52:24 +0000670};
671
672const lldb::OptionDefinition*
673CommandObjectBreakpointList::CommandOptions::GetDefinitions ()
674{
675 return g_option_table;
676}
677
678Error
679CommandObjectBreakpointList::CommandOptions::SetOptionValue (int option_idx, const char *option_arg)
680{
681 Error error;
682 char short_option = (char) m_getopt_table[option_idx].val;
683
684 switch (short_option)
685 {
686 case 'b':
687 m_level = lldb::eDescriptionLevelBrief;
688 break;
689 case 'f':
690 m_level = lldb::eDescriptionLevelFull;
691 break;
692 case 'v':
693 m_level = lldb::eDescriptionLevelVerbose;
694 break;
695 case 'i':
696 m_internal = true;
697 break;
698 default:
699 error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
700 break;
701 }
702
703 return error;
704}
705
706void
707CommandObjectBreakpointList::CommandOptions::ResetOptionValues ()
708{
709 Options::ResetOptionValues();
710
711 m_level = lldb::eDescriptionLevelFull;
712 m_internal = false;
713}
714
715//-------------------------------------------------------------------------
716// CommandObjectBreakpointList
717//-------------------------------------------------------------------------
Jim Ingham10622a22010-06-18 00:58:52 +0000718#pragma mark List
Chris Lattner24943d22010-06-08 16:52:24 +0000719
Greg Clayton238c0a12010-09-18 01:14:36 +0000720CommandObjectBreakpointList::CommandObjectBreakpointList (CommandInterpreter &interpreter) :
721 CommandObject (interpreter,
722 "breakpoint list",
723 "List some or all breakpoints at configurable levels of detail.",
Caroline Ticefb355112010-10-01 17:46:38 +0000724 NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000725{
Caroline Ticefb355112010-10-01 17:46:38 +0000726 CommandArgumentEntry arg;
727 CommandArgumentData bp_id_arg;
728
729 // Define the first (and only) variant of this arg.
730 bp_id_arg.arg_type = eArgTypeBreakpointID;
Caroline Tice43b014a2010-10-04 22:28:36 +0000731 bp_id_arg.arg_repetition = eArgRepeatOptional;
Caroline Ticefb355112010-10-01 17:46:38 +0000732
733 // There is only one variant this argument could be; put it into the argument entry.
734 arg.push_back (bp_id_arg);
735
736 // Push the data for the first argument into the m_arguments vector.
737 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000738}
739
740CommandObjectBreakpointList::~CommandObjectBreakpointList ()
741{
742}
743
744Options *
745CommandObjectBreakpointList::GetOptions ()
746{
747 return &m_options;
748}
749
750bool
751CommandObjectBreakpointList::Execute
752(
753 Args& args,
Chris Lattner24943d22010-06-08 16:52:24 +0000754 CommandReturnObject &result
755)
756{
Greg Clayton238c0a12010-09-18 01:14:36 +0000757 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000758 if (target == NULL)
759 {
Caroline Tice17dce1c2010-09-29 19:42:33 +0000760 result.AppendError ("Invalid target. No current target or breakpoints.");
Chris Lattner24943d22010-06-08 16:52:24 +0000761 result.SetStatus (eReturnStatusSuccessFinishNoResult);
762 return true;
763 }
764
765 const BreakpointList &breakpoints = target->GetBreakpointList(m_options.m_internal);
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000766 Mutex::Locker locker;
767 target->GetBreakpointList(m_options.m_internal).GetListMutex(locker);
768
Chris Lattner24943d22010-06-08 16:52:24 +0000769 size_t num_breakpoints = breakpoints.GetSize();
770
771 if (num_breakpoints == 0)
772 {
773 result.AppendMessage ("No breakpoints currently set.");
774 result.SetStatus (eReturnStatusSuccessFinishNoResult);
775 return true;
776 }
777
778 StreamString &output_stream = result.GetOutputStream();
779
780 if (args.GetArgumentCount() == 0)
781 {
782 // No breakpoint selected; show info about all currently set breakpoints.
783 result.AppendMessage ("Current breakpoints:");
Greg Clayton54e7afa2010-07-09 20:39:50 +0000784 for (size_t i = 0; i < num_breakpoints; ++i)
Chris Lattner24943d22010-06-08 16:52:24 +0000785 {
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000786 Breakpoint *breakpoint = breakpoints.GetBreakpointAtIndex (i).get();
Greg Clayton63094e02010-06-23 01:19:29 +0000787 AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
Chris Lattner24943d22010-06-08 16:52:24 +0000788 }
789 result.SetStatus (eReturnStatusSuccessFinishNoResult);
790 }
791 else
792 {
793 // Particular breakpoints selected; show info about that breakpoint.
794 BreakpointIDList valid_bp_ids;
795 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (args, target, result, &valid_bp_ids);
796
797 if (result.Succeeded())
798 {
Greg Clayton54e7afa2010-07-09 20:39:50 +0000799 for (size_t i = 0; i < valid_bp_ids.GetSize(); ++i)
Chris Lattner24943d22010-06-08 16:52:24 +0000800 {
801 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
802 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
Greg Clayton63094e02010-06-23 01:19:29 +0000803 AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
Chris Lattner24943d22010-06-08 16:52:24 +0000804 }
805 result.SetStatus (eReturnStatusSuccessFinishNoResult);
806 }
807 else
808 {
809 result.AppendError ("Invalid breakpoint id.");
810 result.SetStatus (eReturnStatusFailed);
811 }
812 }
813
814 return result.Succeeded();
815}
816
817//-------------------------------------------------------------------------
818// CommandObjectBreakpointEnable
819//-------------------------------------------------------------------------
Jim Ingham10622a22010-06-18 00:58:52 +0000820#pragma mark Enable
Chris Lattner24943d22010-06-08 16:52:24 +0000821
Greg Clayton238c0a12010-09-18 01:14:36 +0000822CommandObjectBreakpointEnable::CommandObjectBreakpointEnable (CommandInterpreter &interpreter) :
823 CommandObject (interpreter,
824 "enable",
Caroline Ticefb355112010-10-01 17:46:38 +0000825 "Enable the specified disabled breakpoint(s). If no breakpoints are specified, enable all of them.",
826 NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000827{
Caroline Ticefb355112010-10-01 17:46:38 +0000828 CommandArgumentEntry arg;
829 CommandArgumentData bp_id_arg;
830 CommandArgumentData bp_id_range_arg;
831
832 // Create the first variant for the first (and only) argument for this command.
833 bp_id_arg.arg_type = eArgTypeBreakpointID;
Caroline Tice43b014a2010-10-04 22:28:36 +0000834 bp_id_arg.arg_repetition = eArgRepeatOptional;
Caroline Ticefb355112010-10-01 17:46:38 +0000835
836 // Create the second variant for the first (and only) argument for this command.
837 bp_id_range_arg.arg_type = eArgTypeBreakpointIDRange;
Caroline Tice43b014a2010-10-04 22:28:36 +0000838 bp_id_range_arg.arg_repetition = eArgRepeatOptional;
Caroline Ticefb355112010-10-01 17:46:38 +0000839
840 // The first (and only) argument for this command could be either a bp_id or a bp_id_range.
841 // Push both variants into the entry for the first argument for this command.
842 arg.push_back (bp_id_arg);
843 arg.push_back (bp_id_range_arg);
844
845 // Add the entry for the first argument for this command to the object's arguments vector.
846 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000847}
848
849
850CommandObjectBreakpointEnable::~CommandObjectBreakpointEnable ()
851{
852}
853
854
855bool
Greg Clayton63094e02010-06-23 01:19:29 +0000856CommandObjectBreakpointEnable::Execute
857(
Greg Clayton63094e02010-06-23 01:19:29 +0000858 Args& args,
859 CommandReturnObject &result
860)
Chris Lattner24943d22010-06-08 16:52:24 +0000861{
Greg Clayton238c0a12010-09-18 01:14:36 +0000862 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000863 if (target == NULL)
864 {
Caroline Tice17dce1c2010-09-29 19:42:33 +0000865 result.AppendError ("Invalid target. No existing target or breakpoints.");
Chris Lattner24943d22010-06-08 16:52:24 +0000866 result.SetStatus (eReturnStatusFailed);
867 return false;
868 }
869
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000870 Mutex::Locker locker;
871 target->GetBreakpointList().GetListMutex(locker);
872
Chris Lattner24943d22010-06-08 16:52:24 +0000873 const BreakpointList &breakpoints = target->GetBreakpointList();
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000874
Chris Lattner24943d22010-06-08 16:52:24 +0000875 size_t num_breakpoints = breakpoints.GetSize();
876
877 if (num_breakpoints == 0)
878 {
879 result.AppendError ("No breakpoints exist to be enabled.");
880 result.SetStatus (eReturnStatusFailed);
881 return false;
882 }
883
884 if (args.GetArgumentCount() == 0)
885 {
886 // No breakpoint selected; enable all currently set breakpoints.
887 target->EnableAllBreakpoints ();
888 result.AppendMessageWithFormat ("All breakpoints enabled. (%d breakpoints)\n", num_breakpoints);
889 result.SetStatus (eReturnStatusSuccessFinishNoResult);
890 }
891 else
892 {
893 // Particular breakpoint selected; enable that breakpoint.
894 BreakpointIDList valid_bp_ids;
895 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (args, target, result, &valid_bp_ids);
896
897 if (result.Succeeded())
898 {
899 int enable_count = 0;
900 int loc_count = 0;
Greg Clayton54e7afa2010-07-09 20:39:50 +0000901 const size_t count = valid_bp_ids.GetSize();
902 for (size_t i = 0; i < count; ++i)
Chris Lattner24943d22010-06-08 16:52:24 +0000903 {
904 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
905
906 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
907 {
908 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
909 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
910 {
911 BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
912 if (location)
913 {
914 location->SetEnabled (true);
Chris Lattner24943d22010-06-08 16:52:24 +0000915 ++loc_count;
916 }
917 }
918 else
919 {
Jim Ingham10622a22010-06-18 00:58:52 +0000920 breakpoint->SetEnabled (true);
Chris Lattner24943d22010-06-08 16:52:24 +0000921 ++enable_count;
Chris Lattner24943d22010-06-08 16:52:24 +0000922 }
923 }
924 }
925 result.AppendMessageWithFormat ("%d breakpoints enabled.\n", enable_count + loc_count);
926 result.SetStatus (eReturnStatusSuccessFinishNoResult);
927 }
928 }
929
930 return result.Succeeded();
931}
932
933//-------------------------------------------------------------------------
934// CommandObjectBreakpointDisable
935//-------------------------------------------------------------------------
Jim Ingham10622a22010-06-18 00:58:52 +0000936#pragma mark Disable
Chris Lattner24943d22010-06-08 16:52:24 +0000937
Greg Clayton238c0a12010-09-18 01:14:36 +0000938CommandObjectBreakpointDisable::CommandObjectBreakpointDisable (CommandInterpreter &interpreter) :
939 CommandObject (interpreter,
Caroline Ticefb355112010-10-01 17:46:38 +0000940 "breakpoint disable",
Caroline Ticeabb507a2010-09-08 21:06:11 +0000941 "Disable the specified breakpoint(s) without removing it/them. If no breakpoints are specified, disable them all.",
Caroline Ticefb355112010-10-01 17:46:38 +0000942 NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000943{
Caroline Ticefb355112010-10-01 17:46:38 +0000944 CommandArgumentEntry arg;
945 CommandArgumentData bp_id_arg;
946 CommandArgumentData bp_id_range_arg;
947
948 // Create the first variant for the first (and only) argument for this command.
949 bp_id_arg.arg_type = eArgTypeBreakpointID;
Caroline Tice43b014a2010-10-04 22:28:36 +0000950 bp_id_arg.arg_repetition = eArgRepeatOptional;
Caroline Ticefb355112010-10-01 17:46:38 +0000951
952 // Create the second variant for the first (and only) argument for this command.
953 bp_id_range_arg.arg_type = eArgTypeBreakpointIDRange;
Caroline Tice43b014a2010-10-04 22:28:36 +0000954 bp_id_range_arg.arg_repetition = eArgRepeatOptional;
Caroline Ticefb355112010-10-01 17:46:38 +0000955
956 // The first (and only) argument for this command could be either a bp_id or a bp_id_range.
957 // Push both variants into the entry for the first argument for this command.
958 arg.push_back (bp_id_arg);
959 arg.push_back (bp_id_range_arg);
960
961 // Add the entry for the first argument for this command to the object's arguments vector.
962 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000963}
964
965CommandObjectBreakpointDisable::~CommandObjectBreakpointDisable ()
966{
967}
968
969bool
Greg Clayton63094e02010-06-23 01:19:29 +0000970CommandObjectBreakpointDisable::Execute
971(
Greg Clayton63094e02010-06-23 01:19:29 +0000972 Args& args,
973 CommandReturnObject &result
974)
Chris Lattner24943d22010-06-08 16:52:24 +0000975{
Greg Clayton238c0a12010-09-18 01:14:36 +0000976 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000977 if (target == NULL)
978 {
Caroline Tice17dce1c2010-09-29 19:42:33 +0000979 result.AppendError ("Invalid target. No existing target or breakpoints.");
Chris Lattner24943d22010-06-08 16:52:24 +0000980 result.SetStatus (eReturnStatusFailed);
981 return false;
982 }
983
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000984 Mutex::Locker locker;
985 target->GetBreakpointList().GetListMutex(locker);
986
Chris Lattner24943d22010-06-08 16:52:24 +0000987 const BreakpointList &breakpoints = target->GetBreakpointList();
988 size_t num_breakpoints = breakpoints.GetSize();
989
990 if (num_breakpoints == 0)
991 {
992 result.AppendError ("No breakpoints exist to be disabled.");
993 result.SetStatus (eReturnStatusFailed);
994 return false;
995 }
996
997 if (args.GetArgumentCount() == 0)
998 {
999 // No breakpoint selected; disable all currently set breakpoints.
1000 target->DisableAllBreakpoints ();
1001 result.AppendMessageWithFormat ("All breakpoints disabled. (%d breakpoints)\n", num_breakpoints);
1002 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1003 }
1004 else
1005 {
1006 // Particular breakpoint selected; disable that breakpoint.
1007 BreakpointIDList valid_bp_ids;
1008
1009 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (args, target, result, &valid_bp_ids);
1010
1011 if (result.Succeeded())
1012 {
1013 int disable_count = 0;
1014 int loc_count = 0;
Greg Clayton54e7afa2010-07-09 20:39:50 +00001015 const size_t count = valid_bp_ids.GetSize();
1016 for (size_t i = 0; i < count; ++i)
Chris Lattner24943d22010-06-08 16:52:24 +00001017 {
1018 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1019
1020 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
1021 {
1022 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1023 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
1024 {
1025 BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
1026 if (location)
1027 {
1028 location->SetEnabled (false);
1029 ++loc_count;
1030 }
1031 }
1032 else
1033 {
Jim Ingham10622a22010-06-18 00:58:52 +00001034 breakpoint->SetEnabled (false);
Chris Lattner24943d22010-06-08 16:52:24 +00001035 ++disable_count;
Chris Lattner24943d22010-06-08 16:52:24 +00001036 }
1037 }
1038 }
1039 result.AppendMessageWithFormat ("%d breakpoints disabled.\n", disable_count + loc_count);
1040 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1041 }
1042 }
1043
1044 return result.Succeeded();
1045}
1046
1047//-------------------------------------------------------------------------
Johnny Chena62ad7c2010-10-28 17:27:46 +00001048// CommandObjectBreakpointClear::CommandOptions
1049//-------------------------------------------------------------------------
1050#pragma mark Clear::CommandOptions
1051
1052CommandObjectBreakpointClear::CommandOptions::CommandOptions() :
1053 Options (),
1054 m_filename (),
1055 m_line_num (0)
1056{
1057}
1058
1059CommandObjectBreakpointClear::CommandOptions::~CommandOptions ()
1060{
1061}
1062
1063lldb::OptionDefinition
1064CommandObjectBreakpointClear::CommandOptions::g_option_table[] =
1065{
1066 { LLDB_OPT_SET_1, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
1067 "Specify the breakpoint by source location in this particular file."},
1068
1069 { LLDB_OPT_SET_1, true, "line", 'l', required_argument, NULL, 0, eArgTypeLineNum,
1070 "Specify the breakpoint by source location at this particular line."},
1071
1072 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1073};
1074
1075const lldb::OptionDefinition*
1076CommandObjectBreakpointClear::CommandOptions::GetDefinitions ()
1077{
1078 return g_option_table;
1079}
1080
1081Error
1082CommandObjectBreakpointClear::CommandOptions::SetOptionValue (int option_idx, const char *option_arg)
1083{
1084 Error error;
1085 char short_option = (char) m_getopt_table[option_idx].val;
1086
1087 switch (short_option)
1088 {
1089 case 'f':
1090 m_filename = option_arg;
1091 break;
1092
1093 case 'l':
1094 m_line_num = Args::StringToUInt32 (option_arg, 0);
1095 break;
1096
1097 default:
1098 error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
1099 break;
1100 }
1101
1102 return error;
1103}
1104
1105void
1106CommandObjectBreakpointClear::CommandOptions::ResetOptionValues ()
1107{
1108 Options::ResetOptionValues();
1109
1110 m_filename.clear();
1111 m_line_num = 0;
1112}
1113
1114//-------------------------------------------------------------------------
1115// CommandObjectBreakpointClear
1116//-------------------------------------------------------------------------
1117#pragma mark Clear
1118
1119CommandObjectBreakpointClear::CommandObjectBreakpointClear (CommandInterpreter &interpreter) :
1120 CommandObject (interpreter,
1121 "breakpoint clear",
1122 "Clears a breakpoint or set of breakpoints in the executable.",
1123 "breakpoint clear <cmd-options>")
1124{
1125}
1126
1127CommandObjectBreakpointClear::~CommandObjectBreakpointClear ()
1128{
1129}
1130
1131Options *
1132CommandObjectBreakpointClear::GetOptions ()
1133{
1134 return &m_options;
1135}
1136
1137bool
1138CommandObjectBreakpointClear::Execute
1139(
1140 Args& command,
1141 CommandReturnObject &result
1142)
1143{
1144 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1145 if (target == NULL)
1146 {
1147 result.AppendError ("Invalid target. No existing target or breakpoints.");
1148 result.SetStatus (eReturnStatusFailed);
1149 return false;
1150 }
1151
1152 // The following are the various types of breakpoints that could be cleared:
1153 // 1). -f -l (clearing breakpoint by source location)
1154
1155 BreakpointClearType break_type = eClearTypeInvalid;
1156
1157 if (m_options.m_line_num != 0)
1158 break_type = eClearTypeFileAndLine;
1159
1160 Mutex::Locker locker;
1161 target->GetBreakpointList().GetListMutex(locker);
1162
1163 BreakpointList &breakpoints = target->GetBreakpointList();
1164 size_t num_breakpoints = breakpoints.GetSize();
1165
1166 // Early return if there's no breakpoint at all.
1167 if (num_breakpoints == 0)
1168 {
1169 result.AppendError ("Breakpoint clear: No breakpoint cleared.");
1170 result.SetStatus (eReturnStatusFailed);
1171 return result.Succeeded();
1172 }
1173
1174 // Find matching breakpoints and delete them.
1175
1176 // First create a copy of all the IDs.
1177 std::vector<break_id_t> BreakIDs;
1178 for (size_t i = 0; i < num_breakpoints; ++i)
1179 BreakIDs.push_back(breakpoints.GetBreakpointAtIndex(i).get()->GetID());
1180
1181 int num_cleared = 0;
1182 StreamString ss;
1183 switch (break_type)
1184 {
1185 case eClearTypeFileAndLine: // Breakpoint by source position
1186 {
1187 const ConstString filename(m_options.m_filename.c_str());
1188 BreakpointLocationCollection loc_coll;
1189
1190 for (size_t i = 0; i < num_breakpoints; ++i)
1191 {
1192 Breakpoint *bp = breakpoints.FindBreakpointByID(BreakIDs[i]).get();
1193
1194 if (bp->GetMatchingFileLine(filename, m_options.m_line_num, loc_coll))
1195 {
1196 // If the collection size is 0, it's a full match and we can just remove the breakpoint.
1197 if (loc_coll.GetSize() == 0)
1198 {
1199 bp->GetDescription(&ss, lldb::eDescriptionLevelBrief);
1200 ss.EOL();
1201 target->RemoveBreakpointByID (bp->GetID());
1202 ++num_cleared;
1203 }
1204 }
1205 }
1206 }
1207 break;
1208
1209 default:
1210 break;
1211 }
1212
1213 if (num_cleared > 0)
1214 {
1215 StreamString &output_stream = result.GetOutputStream();
1216 output_stream.Printf ("%d breakpoints cleared:\n", num_cleared);
1217 output_stream << ss.GetData();
1218 output_stream.EOL();
1219 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1220 }
1221 else
1222 {
1223 result.AppendError ("Breakpoint clear: No breakpoint cleared.");
1224 result.SetStatus (eReturnStatusFailed);
1225 }
1226
1227 return result.Succeeded();
1228}
1229
1230//-------------------------------------------------------------------------
Chris Lattner24943d22010-06-08 16:52:24 +00001231// CommandObjectBreakpointDelete
1232//-------------------------------------------------------------------------
Jim Ingham10622a22010-06-18 00:58:52 +00001233#pragma mark Delete
Chris Lattner24943d22010-06-08 16:52:24 +00001234
Greg Clayton238c0a12010-09-18 01:14:36 +00001235CommandObjectBreakpointDelete::CommandObjectBreakpointDelete(CommandInterpreter &interpreter) :
1236 CommandObject (interpreter,
1237 "breakpoint delete",
Caroline Ticeabb507a2010-09-08 21:06:11 +00001238 "Delete the specified breakpoint(s). If no breakpoints are specified, delete them all.",
Caroline Ticefb355112010-10-01 17:46:38 +00001239 NULL)
Chris Lattner24943d22010-06-08 16:52:24 +00001240{
Caroline Ticefb355112010-10-01 17:46:38 +00001241 CommandArgumentEntry arg;
1242 CommandArgumentData bp_id_arg;
1243 CommandArgumentData bp_id_range_arg;
1244
1245 // Create the first variant for the first (and only) argument for this command.
1246 bp_id_arg.arg_type = eArgTypeBreakpointID;
Caroline Tice43b014a2010-10-04 22:28:36 +00001247 bp_id_arg.arg_repetition = eArgRepeatOptional;
Caroline Ticefb355112010-10-01 17:46:38 +00001248
1249 // Create the second variant for the first (and only) argument for this command.
1250 bp_id_range_arg.arg_type = eArgTypeBreakpointIDRange;
Caroline Tice43b014a2010-10-04 22:28:36 +00001251 bp_id_range_arg.arg_repetition = eArgRepeatOptional;
Caroline Ticefb355112010-10-01 17:46:38 +00001252
1253 // The first (and only) argument for this command could be either a bp_id or a bp_id_range.
1254 // Push both variants into the entry for the first argument for this command.
1255 arg.push_back (bp_id_arg);
1256 arg.push_back (bp_id_range_arg);
1257
1258 // Add the entry for the first argument for this command to the object's arguments vector.
1259 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +00001260}
1261
1262
1263CommandObjectBreakpointDelete::~CommandObjectBreakpointDelete ()
1264{
1265}
1266
1267bool
Greg Clayton63094e02010-06-23 01:19:29 +00001268CommandObjectBreakpointDelete::Execute
1269(
Greg Clayton63094e02010-06-23 01:19:29 +00001270 Args& args,
1271 CommandReturnObject &result
1272)
Chris Lattner24943d22010-06-08 16:52:24 +00001273{
Greg Clayton238c0a12010-09-18 01:14:36 +00001274 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +00001275 if (target == NULL)
1276 {
Caroline Tice17dce1c2010-09-29 19:42:33 +00001277 result.AppendError ("Invalid target. No existing target or breakpoints.");
Chris Lattner24943d22010-06-08 16:52:24 +00001278 result.SetStatus (eReturnStatusFailed);
1279 return false;
1280 }
1281
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001282 Mutex::Locker locker;
1283 target->GetBreakpointList().GetListMutex(locker);
1284
Chris Lattner24943d22010-06-08 16:52:24 +00001285 const BreakpointList &breakpoints = target->GetBreakpointList();
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001286
Chris Lattner24943d22010-06-08 16:52:24 +00001287 size_t num_breakpoints = breakpoints.GetSize();
1288
1289 if (num_breakpoints == 0)
1290 {
1291 result.AppendError ("No breakpoints exist to be deleted.");
1292 result.SetStatus (eReturnStatusFailed);
1293 return false;
1294 }
1295
1296 if (args.GetArgumentCount() == 0)
1297 {
Jim Inghamd1686902010-10-14 23:45:03 +00001298 if (!m_interpreter.Confirm ("About to delete all breakpoints, do you want to do that?", true))
Chris Lattner24943d22010-06-08 16:52:24 +00001299 {
Jim Inghamd1686902010-10-14 23:45:03 +00001300 result.AppendMessage("Operation cancelled...");
Chris Lattner24943d22010-06-08 16:52:24 +00001301 }
Jim Inghamd1686902010-10-14 23:45:03 +00001302 else
1303 {
1304 target->RemoveAllBreakpoints ();
1305 result.AppendMessageWithFormat ("All breakpoints removed. (%d breakpoints)\n", num_breakpoints);
1306 }
Chris Lattner24943d22010-06-08 16:52:24 +00001307 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1308 }
1309 else
1310 {
1311 // Particular breakpoint selected; disable that breakpoint.
1312 BreakpointIDList valid_bp_ids;
1313 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (args, target, result, &valid_bp_ids);
1314
1315 if (result.Succeeded())
1316 {
1317 int delete_count = 0;
1318 int disable_count = 0;
Greg Clayton54e7afa2010-07-09 20:39:50 +00001319 const size_t count = valid_bp_ids.GetSize();
1320 for (size_t i = 0; i < count; ++i)
Chris Lattner24943d22010-06-08 16:52:24 +00001321 {
1322 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1323
1324 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
1325 {
1326 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
1327 {
1328 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1329 BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
1330 // It makes no sense to try to delete individual locations, so we disable them instead.
1331 if (location)
1332 {
1333 location->SetEnabled (false);
1334 ++disable_count;
1335 }
1336 }
1337 else
1338 {
1339 target->RemoveBreakpointByID (cur_bp_id.GetBreakpointID());
1340 ++delete_count;
1341 }
1342 }
1343 }
1344 result.AppendMessageWithFormat ("%d breakpoints deleted; %d breakpoint locations disabled.\n",
1345 delete_count, disable_count);
1346 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1347 }
1348 }
1349 return result.Succeeded();
1350}
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001351
1352//-------------------------------------------------------------------------
Jim Ingham10622a22010-06-18 00:58:52 +00001353// CommandObjectBreakpointModify::CommandOptions
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001354//-------------------------------------------------------------------------
Jim Ingham10622a22010-06-18 00:58:52 +00001355#pragma mark Modify::CommandOptions
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001356
Jim Ingham10622a22010-06-18 00:58:52 +00001357CommandObjectBreakpointModify::CommandOptions::CommandOptions() :
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001358 Options (),
Greg Clayton54e7afa2010-07-09 20:39:50 +00001359 m_ignore_count (0),
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001360 m_thread_id(LLDB_INVALID_THREAD_ID),
Greg Clayton54e7afa2010-07-09 20:39:50 +00001361 m_thread_index (UINT32_MAX),
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001362 m_thread_name(),
1363 m_queue_name(),
Jim Inghamd1686902010-10-14 23:45:03 +00001364 m_condition (),
Greg Clayton54e7afa2010-07-09 20:39:50 +00001365 m_enable_passed (false),
1366 m_enable_value (false),
1367 m_name_passed (false),
Jim Inghamd1686902010-10-14 23:45:03 +00001368 m_queue_passed (false),
1369 m_condition_passed (false)
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001370{
1371}
1372
Jim Ingham10622a22010-06-18 00:58:52 +00001373CommandObjectBreakpointModify::CommandOptions::~CommandOptions ()
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001374{
1375}
1376
1377lldb::OptionDefinition
Jim Ingham10622a22010-06-18 00:58:52 +00001378CommandObjectBreakpointModify::CommandOptions::g_option_table[] =
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001379{
Caroline Tice4d6675c2010-10-01 19:59:14 +00001380{ LLDB_OPT_SET_ALL, false, "ignore-count", 'i', required_argument, NULL, NULL, eArgTypeCount, "Set the number of times this breakpoint is skipped before stopping." },
1381{ 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."},
1382{ 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."},
1383{ 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."},
1384{ 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 +00001385{ 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 +00001386{ LLDB_OPT_SET_1, false, "enable", 'e', no_argument, NULL, NULL, eArgTypeNone, "Enable the breakpoint."},
1387{ LLDB_OPT_SET_2, false, "disable", 'd', no_argument, NULL, NULL, eArgTypeNone, "Disable the breakpoint."},
Jim Inghamd1686902010-10-14 23:45:03 +00001388{ 0, false, NULL, 0 , 0, NULL, 0, eArgTypeNone, NULL }
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001389};
1390
1391const lldb::OptionDefinition*
Jim Ingham10622a22010-06-18 00:58:52 +00001392CommandObjectBreakpointModify::CommandOptions::GetDefinitions ()
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001393{
1394 return g_option_table;
1395}
1396
1397Error
Jim Ingham10622a22010-06-18 00:58:52 +00001398CommandObjectBreakpointModify::CommandOptions::SetOptionValue (int option_idx, const char *option_arg)
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001399{
1400 Error error;
1401 char short_option = (char) m_getopt_table[option_idx].val;
1402
1403 switch (short_option)
1404 {
Jim Inghamd1686902010-10-14 23:45:03 +00001405 case 'c':
1406 if (option_arg != NULL)
1407 m_condition = option_arg;
1408 else
1409 m_condition.clear();
1410 m_condition_passed = true;
1411 break;
Jim Ingham10622a22010-06-18 00:58:52 +00001412 case 'd':
1413 m_enable_passed = true;
1414 m_enable_value = false;
1415 break;
1416 case 'e':
1417 m_enable_passed = true;
1418 m_enable_value = true;
1419 break;
Greg Claytonfe424a92010-09-18 03:37:20 +00001420 case 'i':
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001421 {
Greg Clayton54e7afa2010-07-09 20:39:50 +00001422 m_ignore_count = Args::StringToUInt32(optarg, UINT32_MAX, 0);
1423 if (m_ignore_count == UINT32_MAX)
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001424 error.SetErrorStringWithFormat ("Invalid ignore count '%s'.\n", optarg);
1425 }
Jim Ingham10622a22010-06-18 00:58:52 +00001426 break;
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001427 case 't' :
1428 {
1429 m_thread_id = Args::StringToUInt64(optarg, LLDB_INVALID_THREAD_ID, 0);
1430 if (m_thread_id == LLDB_INVALID_THREAD_ID)
1431 error.SetErrorStringWithFormat ("Invalid thread id string '%s'.\n", optarg);
1432 }
1433 break;
1434 case 'T':
Jim Inghamd4571222010-06-19 04:35:20 +00001435 if (option_arg != NULL)
1436 m_thread_name = option_arg;
1437 else
1438 m_thread_name.clear();
1439 m_name_passed = true;
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001440 break;
1441 case 'q':
Jim Inghamd4571222010-06-19 04:35:20 +00001442 if (option_arg != NULL)
1443 m_queue_name = option_arg;
1444 else
1445 m_queue_name.clear();
1446 m_queue_passed = true;
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001447 break;
1448 case 'x':
1449 {
Greg Clayton54e7afa2010-07-09 20:39:50 +00001450 m_thread_index = Args::StringToUInt32 (optarg, UINT32_MAX, 0);
1451 if (m_thread_id == UINT32_MAX)
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001452 error.SetErrorStringWithFormat ("Invalid thread index string '%s'.\n", optarg);
1453
1454 }
1455 break;
1456 default:
1457 error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
1458 break;
1459 }
1460
1461 return error;
1462}
1463
1464void
Jim Ingham10622a22010-06-18 00:58:52 +00001465CommandObjectBreakpointModify::CommandOptions::ResetOptionValues ()
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001466{
1467 Options::ResetOptionValues();
1468
Greg Clayton54e7afa2010-07-09 20:39:50 +00001469 m_ignore_count = 0;
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001470 m_thread_id = LLDB_INVALID_THREAD_ID;
Greg Clayton54e7afa2010-07-09 20:39:50 +00001471 m_thread_index = UINT32_MAX;
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001472 m_thread_name.clear();
1473 m_queue_name.clear();
Jim Inghamd1686902010-10-14 23:45:03 +00001474 m_condition.clear();
Jim Ingham10622a22010-06-18 00:58:52 +00001475 m_enable_passed = false;
Jim Inghamd4571222010-06-19 04:35:20 +00001476 m_queue_passed = false;
1477 m_name_passed = false;
Jim Inghamd1686902010-10-14 23:45:03 +00001478 m_condition_passed = false;
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001479}
1480
1481//-------------------------------------------------------------------------
Jim Ingham10622a22010-06-18 00:58:52 +00001482// CommandObjectBreakpointModify
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001483//-------------------------------------------------------------------------
Jim Ingham10622a22010-06-18 00:58:52 +00001484#pragma mark Modify
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001485
Greg Clayton238c0a12010-09-18 01:14:36 +00001486CommandObjectBreakpointModify::CommandObjectBreakpointModify (CommandInterpreter &interpreter) :
1487 CommandObject (interpreter,
1488 "breakpoint modify",
1489 "Modify the options on a breakpoint or set of breakpoints in the executable.",
Caroline Ticefb355112010-10-01 17:46:38 +00001490 NULL)
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001491{
Caroline Ticefb355112010-10-01 17:46:38 +00001492 CommandArgumentEntry arg;
1493 CommandArgumentData bp_id_arg;
1494 CommandArgumentData bp_id_range_arg;
1495
1496 // Create the first variant for the first (and only) argument for this command.
1497 bp_id_arg.arg_type = eArgTypeBreakpointID;
Caroline Tice43b014a2010-10-04 22:28:36 +00001498 bp_id_arg.arg_repetition = eArgRepeatPlain;
Caroline Ticefb355112010-10-01 17:46:38 +00001499
1500 // Create the second variant for the first (and only) argument for this command.
1501 bp_id_range_arg.arg_type = eArgTypeBreakpointIDRange;
Caroline Tice43b014a2010-10-04 22:28:36 +00001502 bp_id_range_arg.arg_repetition = eArgRepeatPlain;
Caroline Ticefb355112010-10-01 17:46:38 +00001503
1504 // The first (and only) argument for this command could be either a bp_id or a bp_id_range.
1505 // Push both variants into the entry for the first argument for this command.
1506 arg.push_back (bp_id_arg);
1507 arg.push_back (bp_id_range_arg);
1508
1509 // Add the entry for the first argument for this command to the object's arguments vector.
1510 m_arguments.push_back (arg);
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001511}
1512
Jim Ingham10622a22010-06-18 00:58:52 +00001513CommandObjectBreakpointModify::~CommandObjectBreakpointModify ()
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001514{
1515}
1516
1517Options *
Jim Ingham10622a22010-06-18 00:58:52 +00001518CommandObjectBreakpointModify::GetOptions ()
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001519{
1520 return &m_options;
1521}
1522
1523bool
Jim Ingham10622a22010-06-18 00:58:52 +00001524CommandObjectBreakpointModify::Execute
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001525(
1526 Args& command,
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001527 CommandReturnObject &result
1528)
1529{
Greg Clayton238c0a12010-09-18 01:14:36 +00001530 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001531 if (target == NULL)
1532 {
Caroline Tice17dce1c2010-09-29 19:42:33 +00001533 result.AppendError ("Invalid target. No existing target or breakpoints.");
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001534 result.SetStatus (eReturnStatusFailed);
1535 return false;
1536 }
1537
1538 Mutex::Locker locker;
1539 target->GetBreakpointList().GetListMutex(locker);
1540
1541 BreakpointIDList valid_bp_ids;
1542
1543 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
1544
1545 if (result.Succeeded())
1546 {
Greg Clayton54e7afa2010-07-09 20:39:50 +00001547 const size_t count = valid_bp_ids.GetSize();
1548 for (size_t i = 0; i < count; ++i)
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001549 {
1550 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1551
1552 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
1553 {
1554 Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1555 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
1556 {
1557 BreakpointLocation *location = bp->FindLocationByID (cur_bp_id.GetLocationID()).get();
1558 if (location)
1559 {
1560 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
1561 location->SetThreadID (m_options.m_thread_id);
1562
Greg Clayton54e7afa2010-07-09 20:39:50 +00001563 if (m_options.m_thread_index != UINT32_MAX)
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001564 location->GetLocationOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index);
1565
Jim Inghamd4571222010-06-19 04:35:20 +00001566 if (m_options.m_name_passed)
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001567 location->GetLocationOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str());
1568
Jim Inghamd4571222010-06-19 04:35:20 +00001569 if (m_options.m_queue_passed)
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001570 location->GetLocationOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str());
1571
Greg Clayton54e7afa2010-07-09 20:39:50 +00001572 if (m_options.m_ignore_count != 0)
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001573 location->GetLocationOptions()->SetIgnoreCount(m_options.m_ignore_count);
Jim Ingham10622a22010-06-18 00:58:52 +00001574
1575 if (m_options.m_enable_passed)
1576 location->SetEnabled (m_options.m_enable_value);
Jim Inghamd1686902010-10-14 23:45:03 +00001577
1578 if (m_options.m_condition_passed)
1579 location->SetCondition (m_options.m_condition.c_str());
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001580 }
1581 }
1582 else
1583 {
1584 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
1585 bp->SetThreadID (m_options.m_thread_id);
1586
Greg Clayton54e7afa2010-07-09 20:39:50 +00001587 if (m_options.m_thread_index != UINT32_MAX)
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001588 bp->GetOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index);
1589
Jim Inghamd4571222010-06-19 04:35:20 +00001590 if (m_options.m_name_passed)
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001591 bp->GetOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str());
1592
Jim Inghamd4571222010-06-19 04:35:20 +00001593 if (m_options.m_queue_passed)
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001594 bp->GetOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str());
1595
Greg Clayton54e7afa2010-07-09 20:39:50 +00001596 if (m_options.m_ignore_count != 0)
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001597 bp->GetOptions()->SetIgnoreCount(m_options.m_ignore_count);
Jim Ingham10622a22010-06-18 00:58:52 +00001598
1599 if (m_options.m_enable_passed)
1600 bp->SetEnabled (m_options.m_enable_value);
Jim Inghamd1686902010-10-14 23:45:03 +00001601
1602 if (m_options.m_condition_passed)
1603 bp->SetCondition (m_options.m_condition.c_str());
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001604 }
1605 }
1606 }
1607 }
1608
1609 return result.Succeeded();
1610}
1611
1612