blob: 6bfd753a3d90e5e9de5e4dd6c4cc473e767ee51d [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
31using namespace lldb;
32using namespace lldb_private;
33
34static void
Greg Clayton63094e02010-06-23 01:19:29 +000035AddBreakpointDescription (StreamString *s, Breakpoint *bp, lldb::DescriptionLevel level)
Chris Lattner24943d22010-06-08 16:52:24 +000036{
37 s->IndentMore();
38 bp->GetDescription (s, level, true);
39 s->IndentLess();
40 s->EOL();
41}
42
43//-------------------------------------------------------------------------
44// CommandObjectBreakpointSet::CommandOptions
45//-------------------------------------------------------------------------
Jim Ingham10622a22010-06-18 00:58:52 +000046#pragma mark Set::CommandOptions
Chris Lattner24943d22010-06-08 16:52:24 +000047
48CommandObjectBreakpointSet::CommandOptions::CommandOptions() :
49 Options (),
50 m_filename (),
51 m_line_num (0),
52 m_column (0),
53 m_ignore_inlines (false),
54 m_func_name (),
Greg Clayton12bec712010-06-28 21:30:43 +000055 m_func_name_type_mask (0),
Chris Lattner24943d22010-06-08 16:52:24 +000056 m_func_regexp (),
57 m_modules (),
Jim Ingham3c7b5b92010-06-16 02:00:15 +000058 m_load_addr(),
Greg Clayton54e7afa2010-07-09 20:39:50 +000059 m_ignore_count (0),
Jim Ingham3c7b5b92010-06-16 02:00:15 +000060 m_thread_id(LLDB_INVALID_THREAD_ID),
Greg Clayton54e7afa2010-07-09 20:39:50 +000061 m_thread_index (UINT32_MAX),
Jim Ingham3c7b5b92010-06-16 02:00:15 +000062 m_thread_name(),
Greg Clayton54e7afa2010-07-09 20:39:50 +000063 m_queue_name()
Chris Lattner24943d22010-06-08 16:52:24 +000064{
Chris Lattner24943d22010-06-08 16:52:24 +000065}
66
67CommandObjectBreakpointSet::CommandOptions::~CommandOptions ()
68{
69}
70
71lldb::OptionDefinition
72CommandObjectBreakpointSet::CommandOptions::g_option_table[] =
73{
Greg Clayton12bec712010-06-28 21:30:43 +000074 { LLDB_OPT_SET_ALL, false, "shlib", 's', required_argument, NULL, CommandCompletions::eModuleCompletion, "<shlib-name>",
Jim Ingham34e9a982010-06-15 18:47:14 +000075 "Set the breakpoint only in this shared library (can use this option multiple times for multiple shlibs)."},
76
Greg Clayton12bec712010-06-28 21:30:43 +000077 { LLDB_OPT_SET_ALL, false, "ignore_count", 'k', required_argument, NULL, 0, "<n>",
Jim Ingham3c7b5b92010-06-16 02:00:15 +000078 "Set the number of times this breakpoint is sKipped before stopping." },
79
Greg Clayton12bec712010-06-28 21:30:43 +000080 { LLDB_OPT_SET_ALL, false, "thread_index", 'x', required_argument, NULL, NULL, "<thread_index>",
Jim Ingham3c7b5b92010-06-16 02:00:15 +000081 "The breakpoint stops only for the thread whose indeX matches this argument."},
82
Greg Clayton12bec712010-06-28 21:30:43 +000083 { LLDB_OPT_SET_ALL, false, "thread_id", 't', required_argument, NULL, NULL, "<thread_id>",
Jim Ingham3c7b5b92010-06-16 02:00:15 +000084 "The breakpoint stops only for the thread whose TID matches this argument."},
85
Greg Clayton12bec712010-06-28 21:30:43 +000086 { LLDB_OPT_SET_ALL, false, "thread_name", 'T', required_argument, NULL, NULL, "<thread_name>",
Jim Ingham3c7b5b92010-06-16 02:00:15 +000087 "The breakpoint stops only for the thread whose thread name matches this argument."},
88
Greg Clayton12bec712010-06-28 21:30:43 +000089 { LLDB_OPT_SET_ALL, false, "queue_name", 'q', required_argument, NULL, NULL, "<queue_name>",
Jim Ingham3c7b5b92010-06-16 02:00:15 +000090 "The breakpoint stops only for threads in the queue whose name is given by this argument."},
91
Greg Clayton12bec712010-06-28 21:30:43 +000092 { LLDB_OPT_SET_1, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, "<filename>",
Chris Lattner24943d22010-06-08 16:52:24 +000093 "Set the breakpoint by source location in this particular file."},
94
Greg Clayton12bec712010-06-28 21:30:43 +000095 { LLDB_OPT_SET_1, true, "line", 'l', required_argument, NULL, 0, "<linenum>",
Chris Lattner24943d22010-06-08 16:52:24 +000096 "Set the breakpoint by source location at this particular line."},
97
Chris Lattner24943d22010-06-08 16:52:24 +000098 // Comment out this option for the moment, as we don't actually use it, but will in the future.
99 // This way users won't see it, but the infrastructure is left in place.
100 // { 0, false, "column", 'c', required_argument, NULL, "<column>",
101 // "Set the breakpoint by source location at this particular column."},
102
Greg Clayton12bec712010-06-28 21:30:43 +0000103 { LLDB_OPT_SET_2, true, "address", 'a', required_argument, NULL, 0, "<address>",
Chris Lattner24943d22010-06-08 16:52:24 +0000104 "Set the breakpoint by address, at the specified address."},
105
Greg Clayton12bec712010-06-28 21:30:43 +0000106 { LLDB_OPT_SET_3, true, "name", 'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, "<name>",
Jim Inghamd9e2b762010-08-26 23:56:11 +0000107 "Set the breakpoint by function name - for C++ this means namespaces and arguments will be ignored." },
Chris Lattner24943d22010-06-08 16:52:24 +0000108
Jim Inghamd9e2b762010-08-26 23:56:11 +0000109 { LLDB_OPT_SET_4, true, "fullname", 'F', required_argument, NULL, 0, "<fullname>",
110 "Set the breakpoint by fully qualified function names. For C++ this means namespaces and all arguemnts, and "
111 "for Objective C this means a full function prototype with class and selector." },
Greg Clayton12bec712010-06-28 21:30:43 +0000112
Jim Inghamd9e2b762010-08-26 23:56:11 +0000113 { LLDB_OPT_SET_5, true, "selector", 'S', required_argument, NULL, 0, "<selector>",
114 "Set the breakpoint by ObjC selector name." },
Greg Clayton12bec712010-06-28 21:30:43 +0000115
Jim Inghamd9e2b762010-08-26 23:56:11 +0000116 { LLDB_OPT_SET_6, true, "method", 'M', required_argument, NULL, 0, "<method>",
117 "Set the breakpoint by C++ method names." },
Greg Clayton12bec712010-06-28 21:30:43 +0000118
Jim Inghamd9e2b762010-08-26 23:56:11 +0000119 { LLDB_OPT_SET_7, true, "func_regex", 'r', required_argument, NULL, 0, "<regular-expression>",
Chris Lattner24943d22010-06-08 16:52:24 +0000120 "Set the breakpoint by function name, evaluating a regular-expression to find the function name(s)." },
121
Chris Lattner24943d22010-06-08 16:52:24 +0000122 { 0, false, NULL, 0, 0, NULL, 0, NULL, NULL }
123};
124
125const lldb::OptionDefinition*
126CommandObjectBreakpointSet::CommandOptions::GetDefinitions ()
127{
128 return g_option_table;
129}
130
131Error
132CommandObjectBreakpointSet::CommandOptions::SetOptionValue (int option_idx, const char *option_arg)
133{
134 Error error;
135 char short_option = (char) m_getopt_table[option_idx].val;
136
137 switch (short_option)
138 {
139 case 'a':
140 m_load_addr = Args::StringToUInt64(optarg, LLDB_INVALID_ADDRESS, 0);
141 if (m_load_addr == LLDB_INVALID_ADDRESS)
142 m_load_addr = Args::StringToUInt64(optarg, LLDB_INVALID_ADDRESS, 16);
143
144 if (m_load_addr == LLDB_INVALID_ADDRESS)
145 error.SetErrorStringWithFormat ("Invalid address string '%s'.\n", optarg);
146 break;
147
148 case 'c':
149 m_column = Args::StringToUInt32 (option_arg, 0);
150 break;
Greg Clayton12bec712010-06-28 21:30:43 +0000151
Chris Lattner24943d22010-06-08 16:52:24 +0000152 case 'f':
153 m_filename = option_arg;
154 break;
Greg Clayton12bec712010-06-28 21:30:43 +0000155
Chris Lattner24943d22010-06-08 16:52:24 +0000156 case 'l':
157 m_line_num = Args::StringToUInt32 (option_arg, 0);
158 break;
Greg Clayton12bec712010-06-28 21:30:43 +0000159
Chris Lattner24943d22010-06-08 16:52:24 +0000160 case 'n':
161 m_func_name = option_arg;
Greg Clayton12bec712010-06-28 21:30:43 +0000162 m_func_name_type_mask |= eFunctionNameTypeBase;
163 break;
164
165 case 'F':
Jim Inghamd9e2b762010-08-26 23:56:11 +0000166 m_func_name = option_arg;
Greg Clayton12bec712010-06-28 21:30:43 +0000167 m_func_name_type_mask |= eFunctionNameTypeFull;
168 break;
169
170 case 'S':
Jim Inghamd9e2b762010-08-26 23:56:11 +0000171 m_func_name = option_arg;
Greg Clayton12bec712010-06-28 21:30:43 +0000172 m_func_name_type_mask |= eFunctionNameTypeSelector;
173 break;
174
Jim Inghamd9e2b762010-08-26 23:56:11 +0000175 case 'M':
176 m_func_name = option_arg;
Greg Clayton12bec712010-06-28 21:30:43 +0000177 m_func_name_type_mask |= eFunctionNameTypeMethod;
178 break;
179
Chris Lattner24943d22010-06-08 16:52:24 +0000180 case 'r':
181 m_func_regexp = option_arg;
182 break;
Greg Clayton12bec712010-06-28 21:30:43 +0000183
Chris Lattner24943d22010-06-08 16:52:24 +0000184 case 's':
185 {
186 m_modules.push_back (std::string (option_arg));
187 break;
188 }
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000189 case 'k':
190 {
Greg Clayton54e7afa2010-07-09 20:39:50 +0000191 m_ignore_count = Args::StringToUInt32(optarg, UINT32_MAX, 0);
192 if (m_ignore_count == UINT32_MAX)
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000193 error.SetErrorStringWithFormat ("Invalid ignore count '%s'.\n", optarg);
194 }
Jim Ingham10622a22010-06-18 00:58:52 +0000195 break;
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000196 case 't' :
197 {
198 m_thread_id = Args::StringToUInt64(optarg, LLDB_INVALID_THREAD_ID, 0);
199 if (m_thread_id == LLDB_INVALID_THREAD_ID)
200 error.SetErrorStringWithFormat ("Invalid thread id string '%s'.\n", optarg);
201 }
202 break;
203 case 'T':
204 m_thread_name = option_arg;
205 break;
206 case 'q':
207 m_queue_name = option_arg;
208 break;
209 case 'x':
210 {
Greg Clayton54e7afa2010-07-09 20:39:50 +0000211 m_thread_index = Args::StringToUInt32(optarg, UINT32_MAX, 0);
212 if (m_thread_id == UINT32_MAX)
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000213 error.SetErrorStringWithFormat ("Invalid thread index string '%s'.\n", optarg);
214
215 }
216 break;
Chris Lattner24943d22010-06-08 16:52:24 +0000217 default:
218 error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
219 break;
220 }
221
222 return error;
223}
224
225void
226CommandObjectBreakpointSet::CommandOptions::ResetOptionValues ()
227{
228 Options::ResetOptionValues();
229
230 m_filename.clear();
231 m_line_num = 0;
232 m_column = 0;
Chris Lattner24943d22010-06-08 16:52:24 +0000233 m_func_name.clear();
Greg Clayton12bec712010-06-28 21:30:43 +0000234 m_func_name_type_mask = 0;
Chris Lattner24943d22010-06-08 16:52:24 +0000235 m_func_regexp.clear();
236 m_load_addr = LLDB_INVALID_ADDRESS;
237 m_modules.clear();
Greg Clayton54e7afa2010-07-09 20:39:50 +0000238 m_ignore_count = 0;
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000239 m_thread_id = LLDB_INVALID_THREAD_ID;
Greg Clayton54e7afa2010-07-09 20:39:50 +0000240 m_thread_index = UINT32_MAX;
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000241 m_thread_name.clear();
242 m_queue_name.clear();
Chris Lattner24943d22010-06-08 16:52:24 +0000243}
244
245//-------------------------------------------------------------------------
246// CommandObjectBreakpointSet
247//-------------------------------------------------------------------------
Jim Ingham10622a22010-06-18 00:58:52 +0000248#pragma mark Set
Chris Lattner24943d22010-06-08 16:52:24 +0000249
250CommandObjectBreakpointSet::CommandObjectBreakpointSet () :
251 CommandObject ("breakpoint set", "Sets a breakpoint or set of breakpoints in the executable.",
252 "breakpoint set <cmd-options>")
253{
254}
255
256CommandObjectBreakpointSet::~CommandObjectBreakpointSet ()
257{
258}
259
260Options *
261CommandObjectBreakpointSet::GetOptions ()
262{
263 return &m_options;
264}
265
266bool
267CommandObjectBreakpointSet::Execute
268(
Greg Clayton63094e02010-06-23 01:19:29 +0000269 CommandInterpreter &interpreter,
Chris Lattner24943d22010-06-08 16:52:24 +0000270 Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000271 CommandReturnObject &result
272)
273{
Jim Inghamc8332952010-08-26 21:32:51 +0000274 Target *target = interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000275 if (target == NULL)
276 {
277 result.AppendError ("Invalid target, set executable file using 'file' command.");
278 result.SetStatus (eReturnStatusFailed);
279 return false;
280 }
281
282 // The following are the various types of breakpoints that could be set:
283 // 1). -f -l -p [-s -g] (setting breakpoint by source location)
284 // 2). -a [-s -g] (setting breakpoint by address)
285 // 3). -n [-s -g] (setting breakpoint by function name)
286 // 4). -r [-s -g] (setting breakpoint by function name regular expression)
287
288 BreakpointSetType break_type = eSetTypeInvalid;
289
290 if (m_options.m_line_num != 0)
291 break_type = eSetTypeFileAndLine;
292 else if (m_options.m_load_addr != LLDB_INVALID_ADDRESS)
293 break_type = eSetTypeAddress;
294 else if (!m_options.m_func_name.empty())
295 break_type = eSetTypeFunctionName;
296 else if (!m_options.m_func_regexp.empty())
297 break_type = eSetTypeFunctionRegexp;
298
299 ModuleSP module_sp = target->GetExecutableModule();
300 Breakpoint *bp = NULL;
301 FileSpec module;
302 bool use_module = false;
303 int num_modules = m_options.m_modules.size();
304
305 if ((num_modules > 0) && (break_type != eSetTypeAddress))
306 use_module = true;
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000307
Chris Lattner24943d22010-06-08 16:52:24 +0000308 switch (break_type)
309 {
310 case eSetTypeFileAndLine: // Breakpoint by source position
311 {
312 FileSpec file;
313 if (m_options.m_filename.empty())
314 {
Greg Clayton63094e02010-06-23 01:19:29 +0000315 StackFrame *cur_frame = interpreter.GetDebugger().GetExecutionContext().frame;
Chris Lattner24943d22010-06-08 16:52:24 +0000316 if (cur_frame == NULL)
317 {
318 result.AppendError ("Attempting to set breakpoint by line number alone with no selected frame.");
319 result.SetStatus (eReturnStatusFailed);
320 break;
321 }
322 else if (!cur_frame->HasDebugInformation())
323 {
324 result.AppendError ("Attempting to set breakpoint by line number alone but selected frame has no debug info.");
325 result.SetStatus (eReturnStatusFailed);
326 break;
327 }
328 else
329 {
330 const SymbolContext &context = cur_frame->GetSymbolContext(true);
331 if (context.line_entry.file)
332 {
333 file = context.line_entry.file;
334 }
335 else if (context.comp_unit != NULL)
336 { file = context.comp_unit;
337 }
338 else
339 {
340 result.AppendError ("Attempting to set breakpoint by line number alone but can't find the file for the selected frame.");
341 result.SetStatus (eReturnStatusFailed);
342 break;
343 }
344 }
345 }
346 else
347 {
348 file.SetFile(m_options.m_filename.c_str());
349 }
350
351 if (use_module)
352 {
353 for (int i = 0; i < num_modules; ++i)
354 {
355 module.SetFile(m_options.m_modules[i].c_str());
356 bp = target->CreateBreakpoint (&module,
357 file,
358 m_options.m_line_num,
359 m_options.m_ignore_inlines).get();
360 if (bp)
361 {
362 StreamString &output_stream = result.GetOutputStream();
363 output_stream.Printf ("Breakpoint created: ");
364 bp->GetDescription(&output_stream, lldb::eDescriptionLevelBrief);
365 output_stream.EOL();
366 result.SetStatus (eReturnStatusSuccessFinishResult);
367 }
368 else
369 {
370 result.AppendErrorWithFormat("Breakpoint creation failed: No breakpoint created in module '%s'.\n",
371 m_options.m_modules[i].c_str());
372 result.SetStatus (eReturnStatusFailed);
373 }
374 }
375 }
376 else
377 bp = target->CreateBreakpoint (NULL,
378 file,
379 m_options.m_line_num,
380 m_options.m_ignore_inlines).get();
381 }
382 break;
383 case eSetTypeAddress: // Breakpoint by address
384 bp = target->CreateBreakpoint (m_options.m_load_addr, false).get();
385 break;
Greg Clayton12bec712010-06-28 21:30:43 +0000386
Chris Lattner24943d22010-06-08 16:52:24 +0000387 case eSetTypeFunctionName: // Breakpoint by function name
Chris Lattner24943d22010-06-08 16:52:24 +0000388 {
Greg Clayton12bec712010-06-28 21:30:43 +0000389 uint32_t name_type_mask = m_options.m_func_name_type_mask;
390
391 if (name_type_mask == 0)
Chris Lattner24943d22010-06-08 16:52:24 +0000392 {
Greg Clayton12bec712010-06-28 21:30:43 +0000393
394 if (m_options.m_func_name.find('(') != std::string::npos ||
395 m_options.m_func_name.find("-[") == 0 ||
396 m_options.m_func_name.find("+[") == 0)
397 name_type_mask |= eFunctionNameTypeFull;
Chris Lattner24943d22010-06-08 16:52:24 +0000398 else
Greg Clayton12bec712010-06-28 21:30:43 +0000399 name_type_mask |= eFunctionNameTypeBase;
400 }
401
402
403 if (use_module)
404 {
405 for (int i = 0; i < num_modules; ++i)
Chris Lattner24943d22010-06-08 16:52:24 +0000406 {
Greg Clayton12bec712010-06-28 21:30:43 +0000407 module.SetFile(m_options.m_modules[i].c_str());
408 bp = target->CreateBreakpoint (&module, m_options.m_func_name.c_str(), name_type_mask, Breakpoint::Exact).get();
409 if (bp)
410 {
411 StreamString &output_stream = result.GetOutputStream();
412 output_stream.Printf ("Breakpoint created: ");
413 bp->GetDescription(&output_stream, lldb::eDescriptionLevelBrief);
414 output_stream.EOL();
415 result.SetStatus (eReturnStatusSuccessFinishResult);
416 }
417 else
418 {
419 result.AppendErrorWithFormat("Breakpoint creation failed: No breakpoint created in module '%s'.\n",
420 m_options.m_modules[i].c_str());
421 result.SetStatus (eReturnStatusFailed);
422 }
Chris Lattner24943d22010-06-08 16:52:24 +0000423 }
424 }
Greg Clayton12bec712010-06-28 21:30:43 +0000425 else
426 bp = target->CreateBreakpoint (NULL, m_options.m_func_name.c_str(), name_type_mask, Breakpoint::Exact).get();
Chris Lattner24943d22010-06-08 16:52:24 +0000427 }
Chris Lattner24943d22010-06-08 16:52:24 +0000428 break;
Greg Clayton12bec712010-06-28 21:30:43 +0000429
Chris Lattner24943d22010-06-08 16:52:24 +0000430 case eSetTypeFunctionRegexp: // Breakpoint by regular expression function name
431 {
432 RegularExpression regexp(m_options.m_func_regexp.c_str());
433 if (use_module)
434 {
435 for (int i = 0; i < num_modules; ++i)
436 {
437 module.SetFile(m_options.m_modules[i].c_str());
438 bp = target->CreateBreakpoint (&module, regexp).get();
439 if (bp)
440 {
441 StreamString &output_stream = result.GetOutputStream();
442 output_stream.Printf ("Breakpoint created: ");
443 bp->GetDescription(&output_stream, lldb::eDescriptionLevelBrief);
444 output_stream.EOL();
445 result.SetStatus (eReturnStatusSuccessFinishResult);
446 }
447 else
448 {
449 result.AppendErrorWithFormat("Breakpoint creation failed: No breakpoint created in module '%s'.\n",
450 m_options.m_modules[i].c_str());
451 result.SetStatus (eReturnStatusFailed);
452 }
453 }
454 }
455 else
456 bp = target->CreateBreakpoint (NULL, regexp).get();
457 }
458 break;
Greg Clayton12bec712010-06-28 21:30:43 +0000459
Chris Lattner24943d22010-06-08 16:52:24 +0000460 default:
461 break;
462 }
463
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000464 // Now set the various options that were passed in:
465 if (bp)
466 {
467 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
468 bp->SetThreadID (m_options.m_thread_id);
469
Greg Clayton54e7afa2010-07-09 20:39:50 +0000470 if (m_options.m_thread_index != UINT32_MAX)
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000471 bp->GetOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index);
472
473 if (!m_options.m_thread_name.empty())
474 bp->GetOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str());
475
476 if (!m_options.m_queue_name.empty())
477 bp->GetOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str());
478
Greg Clayton54e7afa2010-07-09 20:39:50 +0000479 if (m_options.m_ignore_count != 0)
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000480 bp->GetOptions()->SetIgnoreCount(m_options.m_ignore_count);
481 }
482
Chris Lattner24943d22010-06-08 16:52:24 +0000483 if (bp && !use_module)
484 {
485 StreamString &output_stream = result.GetOutputStream();
486 output_stream.Printf ("Breakpoint created: ");
487 bp->GetDescription(&output_stream, lldb::eDescriptionLevelBrief);
488 output_stream.EOL();
489 result.SetStatus (eReturnStatusSuccessFinishResult);
490 }
491 else if (!bp)
492 {
493 result.AppendError ("Breakpoint creation failed: No breakpoint created.");
494 result.SetStatus (eReturnStatusFailed);
495 }
496
497 return result.Succeeded();
498}
499
Chris Lattner24943d22010-06-08 16:52:24 +0000500//-------------------------------------------------------------------------
501// CommandObjectMultiwordBreakpoint
502//-------------------------------------------------------------------------
Jim Ingham10622a22010-06-18 00:58:52 +0000503#pragma mark MultiwordBreakpoint
Chris Lattner24943d22010-06-08 16:52:24 +0000504
Greg Clayton63094e02010-06-23 01:19:29 +0000505CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint (CommandInterpreter &interpreter) :
Chris Lattner24943d22010-06-08 16:52:24 +0000506 CommandObjectMultiword ("breakpoint",
Caroline Ticec1ad82e2010-09-07 22:38:08 +0000507 "A set of commands for operating on breakpoints. Also see regexp-break.",
Chris Lattner24943d22010-06-08 16:52:24 +0000508 "breakpoint <command> [<command-options>]")
509{
510 bool status;
511
512 CommandObjectSP list_command_object (new CommandObjectBreakpointList ());
513 CommandObjectSP delete_command_object (new CommandObjectBreakpointDelete ());
514 CommandObjectSP enable_command_object (new CommandObjectBreakpointEnable ());
515 CommandObjectSP disable_command_object (new CommandObjectBreakpointDisable ());
516 CommandObjectSP set_command_object (new CommandObjectBreakpointSet ());
517 CommandObjectSP command_command_object (new CommandObjectBreakpointCommand (interpreter));
Jim Ingham10622a22010-06-18 00:58:52 +0000518 CommandObjectSP modify_command_object (new CommandObjectBreakpointModify());
Chris Lattner24943d22010-06-08 16:52:24 +0000519
Jim Ingham10622a22010-06-18 00:58:52 +0000520 command_command_object->SetCommandName ("breakpoint command");
Chris Lattner24943d22010-06-08 16:52:24 +0000521 enable_command_object->SetCommandName("breakpoint enable");
522 disable_command_object->SetCommandName("breakpoint disable");
Chris Lattner24943d22010-06-08 16:52:24 +0000523 list_command_object->SetCommandName ("breakpoint list");
Jim Ingham10622a22010-06-18 00:58:52 +0000524 modify_command_object->SetCommandName ("breakpoint modify");
525 set_command_object->SetCommandName("breakpoint set");
Chris Lattner24943d22010-06-08 16:52:24 +0000526
Greg Clayton63094e02010-06-23 01:19:29 +0000527 status = LoadSubCommand (interpreter, "list", list_command_object);
528 status = LoadSubCommand (interpreter, "enable", enable_command_object);
529 status = LoadSubCommand (interpreter, "disable", disable_command_object);
530 status = LoadSubCommand (interpreter, "delete", delete_command_object);
531 status = LoadSubCommand (interpreter, "set", set_command_object);
532 status = LoadSubCommand (interpreter, "command", command_command_object);
533 status = LoadSubCommand (interpreter, "modify", modify_command_object);
Chris Lattner24943d22010-06-08 16:52:24 +0000534}
535
536CommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint ()
537{
538}
539
540void
541CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (Args &args, Target *target, CommandReturnObject &result,
542 BreakpointIDList *valid_ids)
543{
544 // args can be strings representing 1). integers (for breakpoint ids)
545 // 2). the full breakpoint & location canonical representation
546 // 3). the word "to" or a hyphen, representing a range (in which case there
547 // had *better* be an entry both before & after of one of the first two types.
548
549 Args temp_args;
550
551 // Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff directly from the old ARGS to
552 // the new TEMP_ARGS. Do not copy breakpoint id range strings over; instead generate a list of strings for
553 // all the breakpoint ids in the range, and shove all of those breakpoint id strings into TEMP_ARGS.
554
555 BreakpointIDList::FindAndReplaceIDRanges (args, target, result, temp_args);
556
557 // NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual BreakpointIDList:
558
Greg Clayton54e7afa2010-07-09 20:39:50 +0000559 valid_ids->InsertStringArray (temp_args.GetConstArgumentVector(), temp_args.GetArgumentCount(), result);
Chris Lattner24943d22010-06-08 16:52:24 +0000560
561 // At this point, all of the breakpoint ids that the user passed in have been converted to breakpoint IDs
562 // and put into valid_ids.
563
564 if (result.Succeeded())
565 {
566 // Now that we've converted everything from args into a list of breakpoint ids, go through our tentative list
567 // of breakpoint id's and verify that they correspond to valid/currently set breakpoints.
568
Greg Clayton54e7afa2010-07-09 20:39:50 +0000569 const size_t count = valid_ids->GetSize();
570 for (size_t i = 0; i < count; ++i)
Chris Lattner24943d22010-06-08 16:52:24 +0000571 {
572 BreakpointID cur_bp_id = valid_ids->GetBreakpointIDAtIndex (i);
573 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
574 if (breakpoint != NULL)
575 {
576 int num_locations = breakpoint->GetNumLocations();
577 if (cur_bp_id.GetLocationID() > num_locations)
578 {
579 StreamString id_str;
Greg Clayton54e7afa2010-07-09 20:39:50 +0000580 BreakpointID::GetCanonicalReference (&id_str,
581 cur_bp_id.GetBreakpointID(),
582 cur_bp_id.GetLocationID());
583 i = valid_ids->GetSize() + 1;
Chris Lattner24943d22010-06-08 16:52:24 +0000584 result.AppendErrorWithFormat ("'%s' is not a currently valid breakpoint/location id.\n",
585 id_str.GetData());
586 result.SetStatus (eReturnStatusFailed);
587 }
588 }
589 else
590 {
Greg Clayton54e7afa2010-07-09 20:39:50 +0000591 i = valid_ids->GetSize() + 1;
Chris Lattner24943d22010-06-08 16:52:24 +0000592 result.AppendErrorWithFormat ("'%d' is not a currently valid breakpoint id.\n", cur_bp_id.GetBreakpointID());
593 result.SetStatus (eReturnStatusFailed);
594 }
595 }
596 }
597}
598
599//-------------------------------------------------------------------------
600// CommandObjectBreakpointList::Options
601//-------------------------------------------------------------------------
Jim Ingham10622a22010-06-18 00:58:52 +0000602#pragma mark List::CommandOptions
Chris Lattner24943d22010-06-08 16:52:24 +0000603
604CommandObjectBreakpointList::CommandOptions::CommandOptions() :
605 Options (),
606 m_level (lldb::eDescriptionLevelFull) // Breakpoint List defaults to brief descriptions
607{
Chris Lattner24943d22010-06-08 16:52:24 +0000608}
609
610CommandObjectBreakpointList::CommandOptions::~CommandOptions ()
611{
612}
613
614lldb::OptionDefinition
615CommandObjectBreakpointList::CommandOptions::g_option_table[] =
616{
Jim Ingham34e9a982010-06-15 18:47:14 +0000617 { LLDB_OPT_SET_ALL, false, "internal", 'i', no_argument, NULL, 0, NULL,
618 "Show debugger internal breakpoints" },
619
620 { LLDB_OPT_SET_1, false, "brief", 'b', no_argument, NULL, 0, NULL,
Chris Lattner24943d22010-06-08 16:52:24 +0000621 "Give a brief description of the breakpoint (no location info)."},
622
623 // FIXME: We need to add an "internal" command, and then add this sort of thing to it.
624 // But I need to see it for now, and don't want to wait.
Jim Ingham34e9a982010-06-15 18:47:14 +0000625 { LLDB_OPT_SET_2, false, "full", 'f', no_argument, NULL, 0, NULL,
Chris Lattner24943d22010-06-08 16:52:24 +0000626 "Give a full description of the breakpoint and its locations."},
Chris Lattner24943d22010-06-08 16:52:24 +0000627
Jim Ingham34e9a982010-06-15 18:47:14 +0000628 { LLDB_OPT_SET_3, false, "verbose", 'v', no_argument, NULL, 0, NULL,
Chris Lattner24943d22010-06-08 16:52:24 +0000629 "Explain everything we know about the breakpoint (for debugging debugger bugs)." },
Chris Lattner24943d22010-06-08 16:52:24 +0000630
631 { 0, false, NULL, 0, 0, NULL, 0, NULL, NULL }
632};
633
634const lldb::OptionDefinition*
635CommandObjectBreakpointList::CommandOptions::GetDefinitions ()
636{
637 return g_option_table;
638}
639
640Error
641CommandObjectBreakpointList::CommandOptions::SetOptionValue (int option_idx, const char *option_arg)
642{
643 Error error;
644 char short_option = (char) m_getopt_table[option_idx].val;
645
646 switch (short_option)
647 {
648 case 'b':
649 m_level = lldb::eDescriptionLevelBrief;
650 break;
651 case 'f':
652 m_level = lldb::eDescriptionLevelFull;
653 break;
654 case 'v':
655 m_level = lldb::eDescriptionLevelVerbose;
656 break;
657 case 'i':
658 m_internal = true;
659 break;
660 default:
661 error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
662 break;
663 }
664
665 return error;
666}
667
668void
669CommandObjectBreakpointList::CommandOptions::ResetOptionValues ()
670{
671 Options::ResetOptionValues();
672
673 m_level = lldb::eDescriptionLevelFull;
674 m_internal = false;
675}
676
677//-------------------------------------------------------------------------
678// CommandObjectBreakpointList
679//-------------------------------------------------------------------------
Jim Ingham10622a22010-06-18 00:58:52 +0000680#pragma mark List
Chris Lattner24943d22010-06-08 16:52:24 +0000681
682CommandObjectBreakpointList::CommandObjectBreakpointList () :
683 CommandObject ("breakpoint list",
684 "List some or all breakpoints at configurable levels of detail.",
685 "breakpoint list [<breakpoint-id>]")
686{
687}
688
689CommandObjectBreakpointList::~CommandObjectBreakpointList ()
690{
691}
692
693Options *
694CommandObjectBreakpointList::GetOptions ()
695{
696 return &m_options;
697}
698
699bool
700CommandObjectBreakpointList::Execute
701(
Greg Clayton63094e02010-06-23 01:19:29 +0000702 CommandInterpreter &interpreter,
Chris Lattner24943d22010-06-08 16:52:24 +0000703 Args& args,
Chris Lattner24943d22010-06-08 16:52:24 +0000704 CommandReturnObject &result
705)
706{
Jim Inghamc8332952010-08-26 21:32:51 +0000707 Target *target = interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000708 if (target == NULL)
709 {
710 result.AppendError ("Invalid target, set executable file using 'file' command.");
711 result.SetStatus (eReturnStatusSuccessFinishNoResult);
712 return true;
713 }
714
715 const BreakpointList &breakpoints = target->GetBreakpointList(m_options.m_internal);
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000716 Mutex::Locker locker;
717 target->GetBreakpointList(m_options.m_internal).GetListMutex(locker);
718
Chris Lattner24943d22010-06-08 16:52:24 +0000719 size_t num_breakpoints = breakpoints.GetSize();
720
721 if (num_breakpoints == 0)
722 {
723 result.AppendMessage ("No breakpoints currently set.");
724 result.SetStatus (eReturnStatusSuccessFinishNoResult);
725 return true;
726 }
727
728 StreamString &output_stream = result.GetOutputStream();
729
730 if (args.GetArgumentCount() == 0)
731 {
732 // No breakpoint selected; show info about all currently set breakpoints.
733 result.AppendMessage ("Current breakpoints:");
Greg Clayton54e7afa2010-07-09 20:39:50 +0000734 for (size_t i = 0; i < num_breakpoints; ++i)
Chris Lattner24943d22010-06-08 16:52:24 +0000735 {
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000736 Breakpoint *breakpoint = breakpoints.GetBreakpointAtIndex (i).get();
Greg Clayton63094e02010-06-23 01:19:29 +0000737 AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
Chris Lattner24943d22010-06-08 16:52:24 +0000738 }
739 result.SetStatus (eReturnStatusSuccessFinishNoResult);
740 }
741 else
742 {
743 // Particular breakpoints selected; show info about that breakpoint.
744 BreakpointIDList valid_bp_ids;
745 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (args, target, result, &valid_bp_ids);
746
747 if (result.Succeeded())
748 {
Greg Clayton54e7afa2010-07-09 20:39:50 +0000749 for (size_t i = 0; i < valid_bp_ids.GetSize(); ++i)
Chris Lattner24943d22010-06-08 16:52:24 +0000750 {
751 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
752 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
Greg Clayton63094e02010-06-23 01:19:29 +0000753 AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
Chris Lattner24943d22010-06-08 16:52:24 +0000754 }
755 result.SetStatus (eReturnStatusSuccessFinishNoResult);
756 }
757 else
758 {
759 result.AppendError ("Invalid breakpoint id.");
760 result.SetStatus (eReturnStatusFailed);
761 }
762 }
763
764 return result.Succeeded();
765}
766
767//-------------------------------------------------------------------------
768// CommandObjectBreakpointEnable
769//-------------------------------------------------------------------------
Jim Ingham10622a22010-06-18 00:58:52 +0000770#pragma mark Enable
Chris Lattner24943d22010-06-08 16:52:24 +0000771
772CommandObjectBreakpointEnable::CommandObjectBreakpointEnable () :
773 CommandObject ("enable",
774 "Enables the specified disabled breakpoint(s). If no breakpoints are specified, enables all of them.",
775 "breakpoint enable [<breakpoint-id> | <breakpoint-id-list>]")
776{
777 // This command object can either be called via 'enable' or 'breakpoint enable'. Because it has two different
778 // potential invocation methods, we need to be a little tricky about generating the syntax string.
779 //StreamString tmp_string;
780 //tmp_string.Printf ("%s <breakpoint-id>", GetCommandName());
781 //m_cmd_syntax.assign (tmp_string.GetData(), tmp_string.GetSize());
782}
783
784
785CommandObjectBreakpointEnable::~CommandObjectBreakpointEnable ()
786{
787}
788
789
790bool
Greg Clayton63094e02010-06-23 01:19:29 +0000791CommandObjectBreakpointEnable::Execute
792(
793 CommandInterpreter &interpreter,
794 Args& args,
795 CommandReturnObject &result
796)
Chris Lattner24943d22010-06-08 16:52:24 +0000797{
Jim Inghamc8332952010-08-26 21:32:51 +0000798 Target *target = interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000799 if (target == NULL)
800 {
801 result.AppendError ("Invalid target, set executable file using 'file' command.");
802 result.SetStatus (eReturnStatusFailed);
803 return false;
804 }
805
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000806 Mutex::Locker locker;
807 target->GetBreakpointList().GetListMutex(locker);
808
Chris Lattner24943d22010-06-08 16:52:24 +0000809 const BreakpointList &breakpoints = target->GetBreakpointList();
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000810
Chris Lattner24943d22010-06-08 16:52:24 +0000811 size_t num_breakpoints = breakpoints.GetSize();
812
813 if (num_breakpoints == 0)
814 {
815 result.AppendError ("No breakpoints exist to be enabled.");
816 result.SetStatus (eReturnStatusFailed);
817 return false;
818 }
819
820 if (args.GetArgumentCount() == 0)
821 {
822 // No breakpoint selected; enable all currently set breakpoints.
823 target->EnableAllBreakpoints ();
824 result.AppendMessageWithFormat ("All breakpoints enabled. (%d breakpoints)\n", num_breakpoints);
825 result.SetStatus (eReturnStatusSuccessFinishNoResult);
826 }
827 else
828 {
829 // Particular breakpoint selected; enable that breakpoint.
830 BreakpointIDList valid_bp_ids;
831 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (args, target, result, &valid_bp_ids);
832
833 if (result.Succeeded())
834 {
835 int enable_count = 0;
836 int loc_count = 0;
Greg Clayton54e7afa2010-07-09 20:39:50 +0000837 const size_t count = valid_bp_ids.GetSize();
838 for (size_t i = 0; i < count; ++i)
Chris Lattner24943d22010-06-08 16:52:24 +0000839 {
840 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
841
842 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
843 {
844 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
845 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
846 {
847 BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
848 if (location)
849 {
850 location->SetEnabled (true);
Chris Lattner24943d22010-06-08 16:52:24 +0000851 ++loc_count;
852 }
853 }
854 else
855 {
Jim Ingham10622a22010-06-18 00:58:52 +0000856 breakpoint->SetEnabled (true);
Chris Lattner24943d22010-06-08 16:52:24 +0000857 ++enable_count;
Chris Lattner24943d22010-06-08 16:52:24 +0000858 }
859 }
860 }
861 result.AppendMessageWithFormat ("%d breakpoints enabled.\n", enable_count + loc_count);
862 result.SetStatus (eReturnStatusSuccessFinishNoResult);
863 }
864 }
865
866 return result.Succeeded();
867}
868
869//-------------------------------------------------------------------------
870// CommandObjectBreakpointDisable
871//-------------------------------------------------------------------------
Jim Ingham10622a22010-06-18 00:58:52 +0000872#pragma mark Disable
Chris Lattner24943d22010-06-08 16:52:24 +0000873
874CommandObjectBreakpointDisable::CommandObjectBreakpointDisable () :
875 CommandObject ("disable",
876 "Disables the specified breakpoint(s) without removing it/them. If no breakpoints are specified, disables them all.",
877 "disable [<breakpoint-id> | <breakpoint-id-list>]")
878{
879 // This command object can either be called via 'enable' or 'breakpoint enable'. Because it has two different
880 // potential invocation methods, we need to be a little tricky about generating the syntax string.
881 //StreamString tmp_string;
882 //tmp_string.Printf ("%s <breakpoint-id>", GetCommandName());
883 //m_cmd_syntax.assign(tmp_string.GetData(), tmp_string.GetSize());
884}
885
886CommandObjectBreakpointDisable::~CommandObjectBreakpointDisable ()
887{
888}
889
890bool
Greg Clayton63094e02010-06-23 01:19:29 +0000891CommandObjectBreakpointDisable::Execute
892(
893 CommandInterpreter &interpreter,
894 Args& args,
895 CommandReturnObject &result
896)
Chris Lattner24943d22010-06-08 16:52:24 +0000897{
Jim Inghamc8332952010-08-26 21:32:51 +0000898 Target *target = interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000899 if (target == NULL)
900 {
901 result.AppendError ("Invalid target, set executable file using 'file' command.");
902 result.SetStatus (eReturnStatusFailed);
903 return false;
904 }
905
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000906 Mutex::Locker locker;
907 target->GetBreakpointList().GetListMutex(locker);
908
Chris Lattner24943d22010-06-08 16:52:24 +0000909 const BreakpointList &breakpoints = target->GetBreakpointList();
910 size_t num_breakpoints = breakpoints.GetSize();
911
912 if (num_breakpoints == 0)
913 {
914 result.AppendError ("No breakpoints exist to be disabled.");
915 result.SetStatus (eReturnStatusFailed);
916 return false;
917 }
918
919 if (args.GetArgumentCount() == 0)
920 {
921 // No breakpoint selected; disable all currently set breakpoints.
922 target->DisableAllBreakpoints ();
923 result.AppendMessageWithFormat ("All breakpoints disabled. (%d breakpoints)\n", num_breakpoints);
924 result.SetStatus (eReturnStatusSuccessFinishNoResult);
925 }
926 else
927 {
928 // Particular breakpoint selected; disable that breakpoint.
929 BreakpointIDList valid_bp_ids;
930
931 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (args, target, result, &valid_bp_ids);
932
933 if (result.Succeeded())
934 {
935 int disable_count = 0;
936 int loc_count = 0;
Greg Clayton54e7afa2010-07-09 20:39:50 +0000937 const size_t count = valid_bp_ids.GetSize();
938 for (size_t i = 0; i < count; ++i)
Chris Lattner24943d22010-06-08 16:52:24 +0000939 {
940 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
941
942 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
943 {
944 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
945 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
946 {
947 BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
948 if (location)
949 {
950 location->SetEnabled (false);
951 ++loc_count;
952 }
953 }
954 else
955 {
Jim Ingham10622a22010-06-18 00:58:52 +0000956 breakpoint->SetEnabled (false);
Chris Lattner24943d22010-06-08 16:52:24 +0000957 ++disable_count;
Chris Lattner24943d22010-06-08 16:52:24 +0000958 }
959 }
960 }
961 result.AppendMessageWithFormat ("%d breakpoints disabled.\n", disable_count + loc_count);
962 result.SetStatus (eReturnStatusSuccessFinishNoResult);
963 }
964 }
965
966 return result.Succeeded();
967}
968
969//-------------------------------------------------------------------------
970// CommandObjectBreakpointDelete
971//-------------------------------------------------------------------------
Jim Ingham10622a22010-06-18 00:58:52 +0000972#pragma mark Delete
Chris Lattner24943d22010-06-08 16:52:24 +0000973
974CommandObjectBreakpointDelete::CommandObjectBreakpointDelete() :
975 CommandObject ("breakpoint delete",
976 "Delete the specified breakpoint(s). If no breakpoints are specified, deletes them all.",
977 "breakpoint delete [<breakpoint-id> | <breakpoint-id-list>]")
978{
979}
980
981
982CommandObjectBreakpointDelete::~CommandObjectBreakpointDelete ()
983{
984}
985
986bool
Greg Clayton63094e02010-06-23 01:19:29 +0000987CommandObjectBreakpointDelete::Execute
988(
989 CommandInterpreter &interpreter,
990 Args& args,
991 CommandReturnObject &result
992)
Chris Lattner24943d22010-06-08 16:52:24 +0000993{
Jim Inghamc8332952010-08-26 21:32:51 +0000994 Target *target = interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000995 if (target == NULL)
996 {
997 result.AppendError ("Invalid target, set executable file using 'file' command.");
998 result.SetStatus (eReturnStatusFailed);
999 return false;
1000 }
1001
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001002 Mutex::Locker locker;
1003 target->GetBreakpointList().GetListMutex(locker);
1004
Chris Lattner24943d22010-06-08 16:52:24 +00001005 const BreakpointList &breakpoints = target->GetBreakpointList();
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001006
Chris Lattner24943d22010-06-08 16:52:24 +00001007 size_t num_breakpoints = breakpoints.GetSize();
1008
1009 if (num_breakpoints == 0)
1010 {
1011 result.AppendError ("No breakpoints exist to be deleted.");
1012 result.SetStatus (eReturnStatusFailed);
1013 return false;
1014 }
1015
1016 if (args.GetArgumentCount() == 0)
1017 {
1018 // No breakpoint selected; disable all currently set breakpoints.
1019 if (args.GetArgumentCount() != 0)
1020 {
1021 result.AppendErrorWithFormat ("Specify breakpoints to delete with the -i option.\n");
1022 result.SetStatus (eReturnStatusFailed);
1023 return false;
1024 }
1025
1026 target->RemoveAllBreakpoints ();
1027 result.AppendMessageWithFormat ("All breakpoints removed. (%d breakpoints)\n", num_breakpoints);
1028 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1029 }
1030 else
1031 {
1032 // Particular breakpoint selected; disable that breakpoint.
1033 BreakpointIDList valid_bp_ids;
1034 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (args, target, result, &valid_bp_ids);
1035
1036 if (result.Succeeded())
1037 {
1038 int delete_count = 0;
1039 int disable_count = 0;
Greg Clayton54e7afa2010-07-09 20:39:50 +00001040 const size_t count = valid_bp_ids.GetSize();
1041 for (size_t i = 0; i < count; ++i)
Chris Lattner24943d22010-06-08 16:52:24 +00001042 {
1043 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1044
1045 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
1046 {
1047 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
1048 {
1049 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1050 BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
1051 // It makes no sense to try to delete individual locations, so we disable them instead.
1052 if (location)
1053 {
1054 location->SetEnabled (false);
1055 ++disable_count;
1056 }
1057 }
1058 else
1059 {
1060 target->RemoveBreakpointByID (cur_bp_id.GetBreakpointID());
1061 ++delete_count;
1062 }
1063 }
1064 }
1065 result.AppendMessageWithFormat ("%d breakpoints deleted; %d breakpoint locations disabled.\n",
1066 delete_count, disable_count);
1067 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1068 }
1069 }
1070 return result.Succeeded();
1071}
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001072
1073//-------------------------------------------------------------------------
Jim Ingham10622a22010-06-18 00:58:52 +00001074// CommandObjectBreakpointModify::CommandOptions
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001075//-------------------------------------------------------------------------
Jim Ingham10622a22010-06-18 00:58:52 +00001076#pragma mark Modify::CommandOptions
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001077
Jim Ingham10622a22010-06-18 00:58:52 +00001078CommandObjectBreakpointModify::CommandOptions::CommandOptions() :
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001079 Options (),
Greg Clayton54e7afa2010-07-09 20:39:50 +00001080 m_ignore_count (0),
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001081 m_thread_id(LLDB_INVALID_THREAD_ID),
Greg Clayton54e7afa2010-07-09 20:39:50 +00001082 m_thread_index (UINT32_MAX),
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001083 m_thread_name(),
1084 m_queue_name(),
Greg Clayton54e7afa2010-07-09 20:39:50 +00001085 m_enable_passed (false),
1086 m_enable_value (false),
1087 m_name_passed (false),
1088 m_queue_passed (false)
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001089{
1090}
1091
Jim Ingham10622a22010-06-18 00:58:52 +00001092CommandObjectBreakpointModify::CommandOptions::~CommandOptions ()
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001093{
1094}
1095
1096lldb::OptionDefinition
Jim Ingham10622a22010-06-18 00:58:52 +00001097CommandObjectBreakpointModify::CommandOptions::g_option_table[] =
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001098{
1099 { LLDB_OPT_SET_ALL, false, "ignore_count", 'k', required_argument, NULL, 0, NULL,
1100 "Set the number of times this breakpoint is sKipped before stopping." },
1101
1102 { LLDB_OPT_SET_ALL, false, "thread_index", 'x', required_argument, NULL, NULL, "<thread_index>",
1103 "The breakpoint stops only for the thread whose indeX matches this argument."},
1104
1105 { LLDB_OPT_SET_ALL, false, "thread_id", 't', required_argument, NULL, NULL, "<thread_id>",
1106 "The breakpoint stops only for the thread whose TID matches this argument."},
1107
1108 { LLDB_OPT_SET_ALL, false, "thread_name", 'T', required_argument, NULL, NULL, "<thread_name>",
1109 "The breakpoint stops only for the thread whose thread name matches this argument."},
1110
1111 { LLDB_OPT_SET_ALL, false, "queue_name", 'q', required_argument, NULL, NULL, "<queue_name>",
1112 "The breakpoint stops only for threads in the queue whose name is given by this argument."},
1113
Jim Ingham10622a22010-06-18 00:58:52 +00001114 { LLDB_OPT_SET_1, false, "enable", 'e', no_argument, NULL, NULL, NULL,
1115 "Enable the breakpoint."},
1116
1117 { LLDB_OPT_SET_2, false, "disable", 'd', no_argument, NULL, NULL, NULL,
1118 "Disable the breakpoint."},
1119
1120
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001121 { 0, false, NULL, 0, 0, NULL, 0, NULL, NULL }
1122};
1123
1124const lldb::OptionDefinition*
Jim Ingham10622a22010-06-18 00:58:52 +00001125CommandObjectBreakpointModify::CommandOptions::GetDefinitions ()
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001126{
1127 return g_option_table;
1128}
1129
1130Error
Jim Ingham10622a22010-06-18 00:58:52 +00001131CommandObjectBreakpointModify::CommandOptions::SetOptionValue (int option_idx, const char *option_arg)
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001132{
1133 Error error;
1134 char short_option = (char) m_getopt_table[option_idx].val;
1135
1136 switch (short_option)
1137 {
Jim Ingham10622a22010-06-18 00:58:52 +00001138 case 'd':
1139 m_enable_passed = true;
1140 m_enable_value = false;
1141 break;
1142 case 'e':
1143 m_enable_passed = true;
1144 m_enable_value = true;
1145 break;
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001146 case 'k':
1147 {
Greg Clayton54e7afa2010-07-09 20:39:50 +00001148 m_ignore_count = Args::StringToUInt32(optarg, UINT32_MAX, 0);
1149 if (m_ignore_count == UINT32_MAX)
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001150 error.SetErrorStringWithFormat ("Invalid ignore count '%s'.\n", optarg);
1151 }
Jim Ingham10622a22010-06-18 00:58:52 +00001152 break;
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001153 case 't' :
1154 {
1155 m_thread_id = Args::StringToUInt64(optarg, LLDB_INVALID_THREAD_ID, 0);
1156 if (m_thread_id == LLDB_INVALID_THREAD_ID)
1157 error.SetErrorStringWithFormat ("Invalid thread id string '%s'.\n", optarg);
1158 }
1159 break;
1160 case 'T':
Jim Inghamd4571222010-06-19 04:35:20 +00001161 if (option_arg != NULL)
1162 m_thread_name = option_arg;
1163 else
1164 m_thread_name.clear();
1165 m_name_passed = true;
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001166 break;
1167 case 'q':
Jim Inghamd4571222010-06-19 04:35:20 +00001168 if (option_arg != NULL)
1169 m_queue_name = option_arg;
1170 else
1171 m_queue_name.clear();
1172 m_queue_passed = true;
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001173 break;
1174 case 'x':
1175 {
Greg Clayton54e7afa2010-07-09 20:39:50 +00001176 m_thread_index = Args::StringToUInt32 (optarg, UINT32_MAX, 0);
1177 if (m_thread_id == UINT32_MAX)
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001178 error.SetErrorStringWithFormat ("Invalid thread index string '%s'.\n", optarg);
1179
1180 }
1181 break;
1182 default:
1183 error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
1184 break;
1185 }
1186
1187 return error;
1188}
1189
1190void
Jim Ingham10622a22010-06-18 00:58:52 +00001191CommandObjectBreakpointModify::CommandOptions::ResetOptionValues ()
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001192{
1193 Options::ResetOptionValues();
1194
Greg Clayton54e7afa2010-07-09 20:39:50 +00001195 m_ignore_count = 0;
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001196 m_thread_id = LLDB_INVALID_THREAD_ID;
Greg Clayton54e7afa2010-07-09 20:39:50 +00001197 m_thread_index = UINT32_MAX;
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001198 m_thread_name.clear();
1199 m_queue_name.clear();
Jim Ingham10622a22010-06-18 00:58:52 +00001200 m_enable_passed = false;
Jim Inghamd4571222010-06-19 04:35:20 +00001201 m_queue_passed = false;
1202 m_name_passed = false;
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001203}
1204
1205//-------------------------------------------------------------------------
Jim Ingham10622a22010-06-18 00:58:52 +00001206// CommandObjectBreakpointModify
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001207//-------------------------------------------------------------------------
Jim Ingham10622a22010-06-18 00:58:52 +00001208#pragma mark Modify
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001209
Jim Ingham10622a22010-06-18 00:58:52 +00001210CommandObjectBreakpointModify::CommandObjectBreakpointModify () :
1211 CommandObject ("breakpoint modify", "Modifys the options on a breakpoint or set of breakpoints in the executable.",
1212 "breakpoint modify <cmd-options> break-id [break-id ...]")
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001213{
1214}
1215
Jim Ingham10622a22010-06-18 00:58:52 +00001216CommandObjectBreakpointModify::~CommandObjectBreakpointModify ()
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001217{
1218}
1219
1220Options *
Jim Ingham10622a22010-06-18 00:58:52 +00001221CommandObjectBreakpointModify::GetOptions ()
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001222{
1223 return &m_options;
1224}
1225
1226bool
Jim Ingham10622a22010-06-18 00:58:52 +00001227CommandObjectBreakpointModify::Execute
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001228(
Greg Clayton63094e02010-06-23 01:19:29 +00001229 CommandInterpreter &interpreter,
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001230 Args& command,
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001231 CommandReturnObject &result
1232)
1233{
1234 if (command.GetArgumentCount() == 0)
1235 {
1236 result.AppendError ("No breakpoints specified.");
1237 result.SetStatus (eReturnStatusFailed);
1238 return false;
1239 }
1240
Jim Inghamc8332952010-08-26 21:32:51 +00001241 Target *target = interpreter.GetDebugger().GetSelectedTarget().get();
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001242 if (target == NULL)
1243 {
1244 result.AppendError ("Invalid target, set executable file using 'file' command.");
1245 result.SetStatus (eReturnStatusFailed);
1246 return false;
1247 }
1248
1249 Mutex::Locker locker;
1250 target->GetBreakpointList().GetListMutex(locker);
1251
1252 BreakpointIDList valid_bp_ids;
1253
1254 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
1255
1256 if (result.Succeeded())
1257 {
Greg Clayton54e7afa2010-07-09 20:39:50 +00001258 const size_t count = valid_bp_ids.GetSize();
1259 for (size_t i = 0; i < count; ++i)
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001260 {
1261 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1262
1263 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
1264 {
1265 Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1266 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
1267 {
1268 BreakpointLocation *location = bp->FindLocationByID (cur_bp_id.GetLocationID()).get();
1269 if (location)
1270 {
1271 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
1272 location->SetThreadID (m_options.m_thread_id);
1273
Greg Clayton54e7afa2010-07-09 20:39:50 +00001274 if (m_options.m_thread_index != UINT32_MAX)
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001275 location->GetLocationOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index);
1276
Jim Inghamd4571222010-06-19 04:35:20 +00001277 if (m_options.m_name_passed)
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001278 location->GetLocationOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str());
1279
Jim Inghamd4571222010-06-19 04:35:20 +00001280 if (m_options.m_queue_passed)
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001281 location->GetLocationOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str());
1282
Greg Clayton54e7afa2010-07-09 20:39:50 +00001283 if (m_options.m_ignore_count != 0)
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001284 location->GetLocationOptions()->SetIgnoreCount(m_options.m_ignore_count);
Jim Ingham10622a22010-06-18 00:58:52 +00001285
1286 if (m_options.m_enable_passed)
1287 location->SetEnabled (m_options.m_enable_value);
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001288 }
1289 }
1290 else
1291 {
1292 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
1293 bp->SetThreadID (m_options.m_thread_id);
1294
Greg Clayton54e7afa2010-07-09 20:39:50 +00001295 if (m_options.m_thread_index != UINT32_MAX)
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001296 bp->GetOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index);
1297
Jim Inghamd4571222010-06-19 04:35:20 +00001298 if (m_options.m_name_passed)
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001299 bp->GetOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str());
1300
Jim Inghamd4571222010-06-19 04:35:20 +00001301 if (m_options.m_queue_passed)
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001302 bp->GetOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str());
1303
Greg Clayton54e7afa2010-07-09 20:39:50 +00001304 if (m_options.m_ignore_count != 0)
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001305 bp->GetOptions()->SetIgnoreCount(m_options.m_ignore_count);
Jim Ingham10622a22010-06-18 00:58:52 +00001306
1307 if (m_options.m_enable_passed)
1308 bp->SetEnabled (m_options.m_enable_value);
1309
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001310 }
1311 }
1312 }
1313 }
1314
1315 return result.Succeeded();
1316}
1317
1318