blob: 01d29fbd81bffde67228b0a6f8c8dca36f39ade4 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- CommandObjectBreakpoint.cpp -----------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
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 Ingham40af72e2010-06-15 19:49:27 +000020#include "lldb/Interpreter/Options.h"
Chris Lattner30fdc8d2010-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 Ingham1b54c882010-06-16 02:00:15 +000028#include "lldb/Target/Thread.h"
29#include "lldb/Target/ThreadSpec.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000030
31using namespace lldb;
32using namespace lldb_private;
33
34static void
Greg Clayton66111032010-06-23 01:19:29 +000035AddBreakpointDescription (StreamString *s, Breakpoint *bp, lldb::DescriptionLevel level)
Chris Lattner30fdc8d2010-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 Inghamae1c4cf2010-06-18 00:58:52 +000046#pragma mark Set::CommandOptions
Chris Lattner30fdc8d2010-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 (),
55 m_func_regexp (),
56 m_modules (),
Jim Ingham1b54c882010-06-16 02:00:15 +000057 m_load_addr(),
58 m_thread_id(LLDB_INVALID_THREAD_ID),
59 m_thread_index (-1),
60 m_thread_name(),
61 m_queue_name(),
62 m_ignore_count (-1)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000063{
Chris Lattner30fdc8d2010-06-08 16:52:24 +000064}
65
66CommandObjectBreakpointSet::CommandOptions::~CommandOptions ()
67{
68}
69
70lldb::OptionDefinition
71CommandObjectBreakpointSet::CommandOptions::g_option_table[] =
72{
Jim Ingham86511212010-06-15 18:47:14 +000073 { LLDB_OPT_SET_ALL, false, "shlib", 's', required_argument, NULL, CommandCompletions::eModuleCompletion, "<shlib-name>",
74 "Set the breakpoint only in this shared library (can use this option multiple times for multiple shlibs)."},
75
76 { LLDB_OPT_SET_ALL, false, "ignore_inlines", 'i', no_argument, NULL, 0, NULL,
77 "Ignore inlined subroutines when setting the breakppoint." },
78
Jim Ingham1b54c882010-06-16 02:00:15 +000079 { LLDB_OPT_SET_ALL, false, "ignore_count", 'k', required_argument, NULL, 0, NULL,
80 "Set the number of times this breakpoint is sKipped before stopping." },
81
82 { LLDB_OPT_SET_ALL, false, "thread_index", 'x', required_argument, NULL, NULL, "<thread_index>",
83 "The breakpoint stops only for the thread whose indeX matches this argument."},
84
85 { LLDB_OPT_SET_ALL, false, "thread_id", 't', required_argument, NULL, NULL, "<thread_id>",
86 "The breakpoint stops only for the thread whose TID matches this argument."},
87
88 { LLDB_OPT_SET_ALL, false, "thread_name", 'T', required_argument, NULL, NULL, "<thread_name>",
89 "The breakpoint stops only for the thread whose thread name matches this argument."},
90
91 { LLDB_OPT_SET_ALL, false, "queue_name", 'q', required_argument, NULL, NULL, "<queue_name>",
92 "The breakpoint stops only for threads in the queue whose name is given by this argument."},
93
Jim Ingham86511212010-06-15 18:47:14 +000094 { LLDB_OPT_SET_1, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, "<filename>",
Chris Lattner30fdc8d2010-06-08 16:52:24 +000095 "Set the breakpoint by source location in this particular file."},
96
Jim Ingham86511212010-06-15 18:47:14 +000097 { LLDB_OPT_SET_1, true, "line", 'l', required_argument, NULL, 0, "<linenum>",
Chris Lattner30fdc8d2010-06-08 16:52:24 +000098 "Set the breakpoint by source location at this particular line."},
99
Chris Lattner30fdc8d2010-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
Jim Ingham86511212010-06-15 18:47:14 +0000105 { LLDB_OPT_SET_2, true, "address", 'a', required_argument, NULL, 0, "<address>",
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000106 "Set the breakpoint by address, at the specified address."},
107
Jim Ingham86511212010-06-15 18:47:14 +0000108 { LLDB_OPT_SET_3, true, "name", 'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, "<function-name>",
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000109 "Set the breakpoint by function name." },
110
Jim Ingham86511212010-06-15 18:47:14 +0000111 { LLDB_OPT_SET_4, true, "func_regex", 'r', required_argument, NULL, 0, "<regular-expression>",
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000112 "Set the breakpoint by function name, evaluating a regular-expression to find the function name(s)." },
113
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000114 { 0, false, NULL, 0, 0, NULL, 0, NULL, NULL }
115};
116
117const lldb::OptionDefinition*
118CommandObjectBreakpointSet::CommandOptions::GetDefinitions ()
119{
120 return g_option_table;
121}
122
123Error
124CommandObjectBreakpointSet::CommandOptions::SetOptionValue (int option_idx, const char *option_arg)
125{
126 Error error;
127 char short_option = (char) m_getopt_table[option_idx].val;
128
129 switch (short_option)
130 {
131 case 'a':
132 m_load_addr = Args::StringToUInt64(optarg, LLDB_INVALID_ADDRESS, 0);
133 if (m_load_addr == LLDB_INVALID_ADDRESS)
134 m_load_addr = Args::StringToUInt64(optarg, LLDB_INVALID_ADDRESS, 16);
135
136 if (m_load_addr == LLDB_INVALID_ADDRESS)
137 error.SetErrorStringWithFormat ("Invalid address string '%s'.\n", optarg);
138 break;
139
140 case 'c':
141 m_column = Args::StringToUInt32 (option_arg, 0);
142 break;
143 case 'f':
144 m_filename = option_arg;
145 break;
146 case 'i':
147 m_ignore_inlines = true;
148 break;
149 case 'l':
150 m_line_num = Args::StringToUInt32 (option_arg, 0);
151 break;
152 case 'n':
153 m_func_name = option_arg;
154 break;
155 case 'r':
156 m_func_regexp = option_arg;
157 break;
158 case 's':
159 {
160 m_modules.push_back (std::string (option_arg));
161 break;
162 }
Jim Ingham1b54c882010-06-16 02:00:15 +0000163 case 'k':
164 {
165 m_ignore_count = Args::StringToSInt32(optarg, -1, 0);
166 if (m_ignore_count == -1)
167 error.SetErrorStringWithFormat ("Invalid ignore count '%s'.\n", optarg);
168 }
Jim Inghamae1c4cf2010-06-18 00:58:52 +0000169 break;
Jim Ingham1b54c882010-06-16 02:00:15 +0000170 case 't' :
171 {
172 m_thread_id = Args::StringToUInt64(optarg, LLDB_INVALID_THREAD_ID, 0);
173 if (m_thread_id == LLDB_INVALID_THREAD_ID)
174 error.SetErrorStringWithFormat ("Invalid thread id string '%s'.\n", optarg);
175 }
176 break;
177 case 'T':
178 m_thread_name = option_arg;
179 break;
180 case 'q':
181 m_queue_name = option_arg;
182 break;
183 case 'x':
184 {
185 m_thread_index = Args::StringToUInt64(optarg, -1, 0);
186 if (m_thread_id == -1)
187 error.SetErrorStringWithFormat ("Invalid thread index string '%s'.\n", optarg);
188
189 }
190 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000191 default:
192 error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
193 break;
194 }
195
196 return error;
197}
198
199void
200CommandObjectBreakpointSet::CommandOptions::ResetOptionValues ()
201{
202 Options::ResetOptionValues();
203
204 m_filename.clear();
205 m_line_num = 0;
206 m_column = 0;
207 m_ignore_inlines = false;
208 m_func_name.clear();
209 m_func_regexp.clear();
210 m_load_addr = LLDB_INVALID_ADDRESS;
211 m_modules.clear();
Jim Ingham1b54c882010-06-16 02:00:15 +0000212 m_ignore_count = -1;
213 m_thread_id = LLDB_INVALID_THREAD_ID;
214 m_thread_index = -1;
215 m_thread_name.clear();
216 m_queue_name.clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000217}
218
219//-------------------------------------------------------------------------
220// CommandObjectBreakpointSet
221//-------------------------------------------------------------------------
Jim Inghamae1c4cf2010-06-18 00:58:52 +0000222#pragma mark Set
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000223
224CommandObjectBreakpointSet::CommandObjectBreakpointSet () :
225 CommandObject ("breakpoint set", "Sets a breakpoint or set of breakpoints in the executable.",
226 "breakpoint set <cmd-options>")
227{
228}
229
230CommandObjectBreakpointSet::~CommandObjectBreakpointSet ()
231{
232}
233
234Options *
235CommandObjectBreakpointSet::GetOptions ()
236{
237 return &m_options;
238}
239
240bool
241CommandObjectBreakpointSet::Execute
242(
Greg Clayton66111032010-06-23 01:19:29 +0000243 CommandInterpreter &interpreter,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000244 Args& command,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000245 CommandReturnObject &result
246)
247{
Greg Clayton66111032010-06-23 01:19:29 +0000248 Target *target = interpreter.GetDebugger().GetCurrentTarget().get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000249 if (target == NULL)
250 {
251 result.AppendError ("Invalid target, set executable file using 'file' command.");
252 result.SetStatus (eReturnStatusFailed);
253 return false;
254 }
255
256 // The following are the various types of breakpoints that could be set:
257 // 1). -f -l -p [-s -g] (setting breakpoint by source location)
258 // 2). -a [-s -g] (setting breakpoint by address)
259 // 3). -n [-s -g] (setting breakpoint by function name)
260 // 4). -r [-s -g] (setting breakpoint by function name regular expression)
261
262 BreakpointSetType break_type = eSetTypeInvalid;
263
264 if (m_options.m_line_num != 0)
265 break_type = eSetTypeFileAndLine;
266 else if (m_options.m_load_addr != LLDB_INVALID_ADDRESS)
267 break_type = eSetTypeAddress;
268 else if (!m_options.m_func_name.empty())
269 break_type = eSetTypeFunctionName;
270 else if (!m_options.m_func_regexp.empty())
271 break_type = eSetTypeFunctionRegexp;
272
273 ModuleSP module_sp = target->GetExecutableModule();
274 Breakpoint *bp = NULL;
275 FileSpec module;
276 bool use_module = false;
277 int num_modules = m_options.m_modules.size();
278
279 if ((num_modules > 0) && (break_type != eSetTypeAddress))
280 use_module = true;
Jim Ingham1b54c882010-06-16 02:00:15 +0000281
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000282 switch (break_type)
283 {
284 case eSetTypeFileAndLine: // Breakpoint by source position
285 {
286 FileSpec file;
287 if (m_options.m_filename.empty())
288 {
Greg Clayton66111032010-06-23 01:19:29 +0000289 StackFrame *cur_frame = interpreter.GetDebugger().GetExecutionContext().frame;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000290 if (cur_frame == NULL)
291 {
292 result.AppendError ("Attempting to set breakpoint by line number alone with no selected frame.");
293 result.SetStatus (eReturnStatusFailed);
294 break;
295 }
296 else if (!cur_frame->HasDebugInformation())
297 {
298 result.AppendError ("Attempting to set breakpoint by line number alone but selected frame has no debug info.");
299 result.SetStatus (eReturnStatusFailed);
300 break;
301 }
302 else
303 {
304 const SymbolContext &context = cur_frame->GetSymbolContext(true);
305 if (context.line_entry.file)
306 {
307 file = context.line_entry.file;
308 }
309 else if (context.comp_unit != NULL)
310 { file = context.comp_unit;
311 }
312 else
313 {
314 result.AppendError ("Attempting to set breakpoint by line number alone but can't find the file for the selected frame.");
315 result.SetStatus (eReturnStatusFailed);
316 break;
317 }
318 }
319 }
320 else
321 {
322 file.SetFile(m_options.m_filename.c_str());
323 }
324
325 if (use_module)
326 {
327 for (int i = 0; i < num_modules; ++i)
328 {
329 module.SetFile(m_options.m_modules[i].c_str());
330 bp = target->CreateBreakpoint (&module,
331 file,
332 m_options.m_line_num,
333 m_options.m_ignore_inlines).get();
334 if (bp)
335 {
336 StreamString &output_stream = result.GetOutputStream();
337 output_stream.Printf ("Breakpoint created: ");
338 bp->GetDescription(&output_stream, lldb::eDescriptionLevelBrief);
339 output_stream.EOL();
340 result.SetStatus (eReturnStatusSuccessFinishResult);
341 }
342 else
343 {
344 result.AppendErrorWithFormat("Breakpoint creation failed: No breakpoint created in module '%s'.\n",
345 m_options.m_modules[i].c_str());
346 result.SetStatus (eReturnStatusFailed);
347 }
348 }
349 }
350 else
351 bp = target->CreateBreakpoint (NULL,
352 file,
353 m_options.m_line_num,
354 m_options.m_ignore_inlines).get();
355 }
356 break;
357 case eSetTypeAddress: // Breakpoint by address
358 bp = target->CreateBreakpoint (m_options.m_load_addr, false).get();
359 break;
360 case eSetTypeFunctionName: // Breakpoint by function name
361 if (use_module)
362 {
363 for (int i = 0; i < num_modules; ++i)
364 {
365 module.SetFile(m_options.m_modules[i].c_str());
366 bp = target->CreateBreakpoint (&module, m_options.m_func_name.c_str()).get();
367 if (bp)
368 {
369 StreamString &output_stream = result.GetOutputStream();
370 output_stream.Printf ("Breakpoint created: ");
371 bp->GetDescription(&output_stream, lldb::eDescriptionLevelBrief);
372 output_stream.EOL();
373 result.SetStatus (eReturnStatusSuccessFinishResult);
374 }
375 else
376 {
377 result.AppendErrorWithFormat("Breakpoint creation failed: No breakpoint created in module '%s'.\n",
378 m_options.m_modules[i].c_str());
379 result.SetStatus (eReturnStatusFailed);
380 }
381 }
382 }
383 else
384 bp = target->CreateBreakpoint (NULL, m_options.m_func_name.c_str()).get();
385 break;
386 case eSetTypeFunctionRegexp: // Breakpoint by regular expression function name
387 {
388 RegularExpression regexp(m_options.m_func_regexp.c_str());
389 if (use_module)
390 {
391 for (int i = 0; i < num_modules; ++i)
392 {
393 module.SetFile(m_options.m_modules[i].c_str());
394 bp = target->CreateBreakpoint (&module, regexp).get();
395 if (bp)
396 {
397 StreamString &output_stream = result.GetOutputStream();
398 output_stream.Printf ("Breakpoint created: ");
399 bp->GetDescription(&output_stream, lldb::eDescriptionLevelBrief);
400 output_stream.EOL();
401 result.SetStatus (eReturnStatusSuccessFinishResult);
402 }
403 else
404 {
405 result.AppendErrorWithFormat("Breakpoint creation failed: No breakpoint created in module '%s'.\n",
406 m_options.m_modules[i].c_str());
407 result.SetStatus (eReturnStatusFailed);
408 }
409 }
410 }
411 else
412 bp = target->CreateBreakpoint (NULL, regexp).get();
413 }
414 break;
415 default:
416 break;
417 }
418
Jim Ingham1b54c882010-06-16 02:00:15 +0000419 // Now set the various options that were passed in:
420 if (bp)
421 {
422 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
423 bp->SetThreadID (m_options.m_thread_id);
424
425 if (m_options.m_thread_index != -1)
426 bp->GetOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index);
427
428 if (!m_options.m_thread_name.empty())
429 bp->GetOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str());
430
431 if (!m_options.m_queue_name.empty())
432 bp->GetOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str());
433
434 if (m_options.m_ignore_count != -1)
435 bp->GetOptions()->SetIgnoreCount(m_options.m_ignore_count);
436 }
437
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000438 if (bp && !use_module)
439 {
440 StreamString &output_stream = result.GetOutputStream();
441 output_stream.Printf ("Breakpoint created: ");
442 bp->GetDescription(&output_stream, lldb::eDescriptionLevelBrief);
443 output_stream.EOL();
444 result.SetStatus (eReturnStatusSuccessFinishResult);
445 }
446 else if (!bp)
447 {
448 result.AppendError ("Breakpoint creation failed: No breakpoint created.");
449 result.SetStatus (eReturnStatusFailed);
450 }
451
452 return result.Succeeded();
453}
454
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000455//-------------------------------------------------------------------------
456// CommandObjectMultiwordBreakpoint
457//-------------------------------------------------------------------------
Jim Inghamae1c4cf2010-06-18 00:58:52 +0000458#pragma mark MultiwordBreakpoint
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000459
Greg Clayton66111032010-06-23 01:19:29 +0000460CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint (CommandInterpreter &interpreter) :
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000461 CommandObjectMultiword ("breakpoint",
462 "A set of commands for operating on breakpoints.",
463 "breakpoint <command> [<command-options>]")
464{
465 bool status;
466
467 CommandObjectSP list_command_object (new CommandObjectBreakpointList ());
468 CommandObjectSP delete_command_object (new CommandObjectBreakpointDelete ());
469 CommandObjectSP enable_command_object (new CommandObjectBreakpointEnable ());
470 CommandObjectSP disable_command_object (new CommandObjectBreakpointDisable ());
471 CommandObjectSP set_command_object (new CommandObjectBreakpointSet ());
472 CommandObjectSP command_command_object (new CommandObjectBreakpointCommand (interpreter));
Jim Inghamae1c4cf2010-06-18 00:58:52 +0000473 CommandObjectSP modify_command_object (new CommandObjectBreakpointModify());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000474
Jim Inghamae1c4cf2010-06-18 00:58:52 +0000475 command_command_object->SetCommandName ("breakpoint command");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000476 enable_command_object->SetCommandName("breakpoint enable");
477 disable_command_object->SetCommandName("breakpoint disable");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000478 list_command_object->SetCommandName ("breakpoint list");
Jim Inghamae1c4cf2010-06-18 00:58:52 +0000479 modify_command_object->SetCommandName ("breakpoint modify");
480 set_command_object->SetCommandName("breakpoint set");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000481
Greg Clayton66111032010-06-23 01:19:29 +0000482 status = LoadSubCommand (interpreter, "list", list_command_object);
483 status = LoadSubCommand (interpreter, "enable", enable_command_object);
484 status = LoadSubCommand (interpreter, "disable", disable_command_object);
485 status = LoadSubCommand (interpreter, "delete", delete_command_object);
486 status = LoadSubCommand (interpreter, "set", set_command_object);
487 status = LoadSubCommand (interpreter, "command", command_command_object);
488 status = LoadSubCommand (interpreter, "modify", modify_command_object);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000489}
490
491CommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint ()
492{
493}
494
495void
496CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (Args &args, Target *target, CommandReturnObject &result,
497 BreakpointIDList *valid_ids)
498{
499 // args can be strings representing 1). integers (for breakpoint ids)
500 // 2). the full breakpoint & location canonical representation
501 // 3). the word "to" or a hyphen, representing a range (in which case there
502 // had *better* be an entry both before & after of one of the first two types.
503
504 Args temp_args;
505
506 // Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff directly from the old ARGS to
507 // the new TEMP_ARGS. Do not copy breakpoint id range strings over; instead generate a list of strings for
508 // all the breakpoint ids in the range, and shove all of those breakpoint id strings into TEMP_ARGS.
509
510 BreakpointIDList::FindAndReplaceIDRanges (args, target, result, temp_args);
511
512 // NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual BreakpointIDList:
513
514 valid_ids->InsertStringArray ((const char **) temp_args.GetArgumentVector(), temp_args.GetArgumentCount(), result);
515
516 // At this point, all of the breakpoint ids that the user passed in have been converted to breakpoint IDs
517 // and put into valid_ids.
518
519 if (result.Succeeded())
520 {
521 // Now that we've converted everything from args into a list of breakpoint ids, go through our tentative list
522 // of breakpoint id's and verify that they correspond to valid/currently set breakpoints.
523
524 for (int i = 0; i < valid_ids->Size(); ++i)
525 {
526 BreakpointID cur_bp_id = valid_ids->GetBreakpointIDAtIndex (i);
527 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
528 if (breakpoint != NULL)
529 {
530 int num_locations = breakpoint->GetNumLocations();
531 if (cur_bp_id.GetLocationID() > num_locations)
532 {
533 StreamString id_str;
534 BreakpointID::GetCanonicalReference (&id_str, cur_bp_id.GetBreakpointID(),
535 cur_bp_id.GetLocationID());
536 i = valid_ids->Size() + 1;
537 result.AppendErrorWithFormat ("'%s' is not a currently valid breakpoint/location id.\n",
538 id_str.GetData());
539 result.SetStatus (eReturnStatusFailed);
540 }
541 }
542 else
543 {
544 i = valid_ids->Size() + 1;
545 result.AppendErrorWithFormat ("'%d' is not a currently valid breakpoint id.\n", cur_bp_id.GetBreakpointID());
546 result.SetStatus (eReturnStatusFailed);
547 }
548 }
549 }
550}
551
552//-------------------------------------------------------------------------
553// CommandObjectBreakpointList::Options
554//-------------------------------------------------------------------------
Jim Inghamae1c4cf2010-06-18 00:58:52 +0000555#pragma mark List::CommandOptions
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000556
557CommandObjectBreakpointList::CommandOptions::CommandOptions() :
558 Options (),
559 m_level (lldb::eDescriptionLevelFull) // Breakpoint List defaults to brief descriptions
560{
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000561}
562
563CommandObjectBreakpointList::CommandOptions::~CommandOptions ()
564{
565}
566
567lldb::OptionDefinition
568CommandObjectBreakpointList::CommandOptions::g_option_table[] =
569{
Jim Ingham86511212010-06-15 18:47:14 +0000570 { LLDB_OPT_SET_ALL, false, "internal", 'i', no_argument, NULL, 0, NULL,
571 "Show debugger internal breakpoints" },
572
573 { LLDB_OPT_SET_1, false, "brief", 'b', no_argument, NULL, 0, NULL,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000574 "Give a brief description of the breakpoint (no location info)."},
575
576 // FIXME: We need to add an "internal" command, and then add this sort of thing to it.
577 // But I need to see it for now, and don't want to wait.
Jim Ingham86511212010-06-15 18:47:14 +0000578 { LLDB_OPT_SET_2, false, "full", 'f', no_argument, NULL, 0, NULL,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000579 "Give a full description of the breakpoint and its locations."},
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000580
Jim Ingham86511212010-06-15 18:47:14 +0000581 { LLDB_OPT_SET_3, false, "verbose", 'v', no_argument, NULL, 0, NULL,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000582 "Explain everything we know about the breakpoint (for debugging debugger bugs)." },
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000583
584 { 0, false, NULL, 0, 0, NULL, 0, NULL, NULL }
585};
586
587const lldb::OptionDefinition*
588CommandObjectBreakpointList::CommandOptions::GetDefinitions ()
589{
590 return g_option_table;
591}
592
593Error
594CommandObjectBreakpointList::CommandOptions::SetOptionValue (int option_idx, const char *option_arg)
595{
596 Error error;
597 char short_option = (char) m_getopt_table[option_idx].val;
598
599 switch (short_option)
600 {
601 case 'b':
602 m_level = lldb::eDescriptionLevelBrief;
603 break;
604 case 'f':
605 m_level = lldb::eDescriptionLevelFull;
606 break;
607 case 'v':
608 m_level = lldb::eDescriptionLevelVerbose;
609 break;
610 case 'i':
611 m_internal = true;
612 break;
613 default:
614 error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
615 break;
616 }
617
618 return error;
619}
620
621void
622CommandObjectBreakpointList::CommandOptions::ResetOptionValues ()
623{
624 Options::ResetOptionValues();
625
626 m_level = lldb::eDescriptionLevelFull;
627 m_internal = false;
628}
629
630//-------------------------------------------------------------------------
631// CommandObjectBreakpointList
632//-------------------------------------------------------------------------
Jim Inghamae1c4cf2010-06-18 00:58:52 +0000633#pragma mark List
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000634
635CommandObjectBreakpointList::CommandObjectBreakpointList () :
636 CommandObject ("breakpoint list",
637 "List some or all breakpoints at configurable levels of detail.",
638 "breakpoint list [<breakpoint-id>]")
639{
640}
641
642CommandObjectBreakpointList::~CommandObjectBreakpointList ()
643{
644}
645
646Options *
647CommandObjectBreakpointList::GetOptions ()
648{
649 return &m_options;
650}
651
652bool
653CommandObjectBreakpointList::Execute
654(
Greg Clayton66111032010-06-23 01:19:29 +0000655 CommandInterpreter &interpreter,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000656 Args& args,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000657 CommandReturnObject &result
658)
659{
Greg Clayton66111032010-06-23 01:19:29 +0000660 Target *target = interpreter.GetDebugger().GetCurrentTarget().get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000661 if (target == NULL)
662 {
663 result.AppendError ("Invalid target, set executable file using 'file' command.");
664 result.SetStatus (eReturnStatusSuccessFinishNoResult);
665 return true;
666 }
667
668 const BreakpointList &breakpoints = target->GetBreakpointList(m_options.m_internal);
Jim Ingham1b54c882010-06-16 02:00:15 +0000669 Mutex::Locker locker;
670 target->GetBreakpointList(m_options.m_internal).GetListMutex(locker);
671
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000672 size_t num_breakpoints = breakpoints.GetSize();
673
674 if (num_breakpoints == 0)
675 {
676 result.AppendMessage ("No breakpoints currently set.");
677 result.SetStatus (eReturnStatusSuccessFinishNoResult);
678 return true;
679 }
680
681 StreamString &output_stream = result.GetOutputStream();
682
683 if (args.GetArgumentCount() == 0)
684 {
685 // No breakpoint selected; show info about all currently set breakpoints.
686 result.AppendMessage ("Current breakpoints:");
687 for (int i = 0; i < num_breakpoints; ++i)
688 {
689 Breakpoint *breakpoint = breakpoints.GetBreakpointByIndex (i).get();
Greg Clayton66111032010-06-23 01:19:29 +0000690 AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000691 }
692 result.SetStatus (eReturnStatusSuccessFinishNoResult);
693 }
694 else
695 {
696 // Particular breakpoints selected; show info about that breakpoint.
697 BreakpointIDList valid_bp_ids;
698 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (args, target, result, &valid_bp_ids);
699
700 if (result.Succeeded())
701 {
702 for (int i = 0; i < valid_bp_ids.Size(); ++i)
703 {
704 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
705 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
Greg Clayton66111032010-06-23 01:19:29 +0000706 AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000707 }
708 result.SetStatus (eReturnStatusSuccessFinishNoResult);
709 }
710 else
711 {
712 result.AppendError ("Invalid breakpoint id.");
713 result.SetStatus (eReturnStatusFailed);
714 }
715 }
716
717 return result.Succeeded();
718}
719
720//-------------------------------------------------------------------------
721// CommandObjectBreakpointEnable
722//-------------------------------------------------------------------------
Jim Inghamae1c4cf2010-06-18 00:58:52 +0000723#pragma mark Enable
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000724
725CommandObjectBreakpointEnable::CommandObjectBreakpointEnable () :
726 CommandObject ("enable",
727 "Enables the specified disabled breakpoint(s). If no breakpoints are specified, enables all of them.",
728 "breakpoint enable [<breakpoint-id> | <breakpoint-id-list>]")
729{
730 // This command object can either be called via 'enable' or 'breakpoint enable'. Because it has two different
731 // potential invocation methods, we need to be a little tricky about generating the syntax string.
732 //StreamString tmp_string;
733 //tmp_string.Printf ("%s <breakpoint-id>", GetCommandName());
734 //m_cmd_syntax.assign (tmp_string.GetData(), tmp_string.GetSize());
735}
736
737
738CommandObjectBreakpointEnable::~CommandObjectBreakpointEnable ()
739{
740}
741
742
743bool
Greg Clayton66111032010-06-23 01:19:29 +0000744CommandObjectBreakpointEnable::Execute
745(
746 CommandInterpreter &interpreter,
747 Args& args,
748 CommandReturnObject &result
749)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000750{
Greg Clayton66111032010-06-23 01:19:29 +0000751 Target *target = interpreter.GetDebugger().GetCurrentTarget().get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000752 if (target == NULL)
753 {
754 result.AppendError ("Invalid target, set executable file using 'file' command.");
755 result.SetStatus (eReturnStatusFailed);
756 return false;
757 }
758
Jim Ingham1b54c882010-06-16 02:00:15 +0000759 Mutex::Locker locker;
760 target->GetBreakpointList().GetListMutex(locker);
761
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000762 const BreakpointList &breakpoints = target->GetBreakpointList();
Jim Ingham1b54c882010-06-16 02:00:15 +0000763
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000764 size_t num_breakpoints = breakpoints.GetSize();
765
766 if (num_breakpoints == 0)
767 {
768 result.AppendError ("No breakpoints exist to be enabled.");
769 result.SetStatus (eReturnStatusFailed);
770 return false;
771 }
772
773 if (args.GetArgumentCount() == 0)
774 {
775 // No breakpoint selected; enable all currently set breakpoints.
776 target->EnableAllBreakpoints ();
777 result.AppendMessageWithFormat ("All breakpoints enabled. (%d breakpoints)\n", num_breakpoints);
778 result.SetStatus (eReturnStatusSuccessFinishNoResult);
779 }
780 else
781 {
782 // Particular breakpoint selected; enable that breakpoint.
783 BreakpointIDList valid_bp_ids;
784 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (args, target, result, &valid_bp_ids);
785
786 if (result.Succeeded())
787 {
788 int enable_count = 0;
789 int loc_count = 0;
790 for (int i = 0; i < valid_bp_ids.Size(); ++i)
791 {
792 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
793
794 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
795 {
796 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
797 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
798 {
799 BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
800 if (location)
801 {
802 location->SetEnabled (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000803 ++loc_count;
804 }
805 }
806 else
807 {
Jim Inghamae1c4cf2010-06-18 00:58:52 +0000808 breakpoint->SetEnabled (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000809 ++enable_count;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000810 }
811 }
812 }
813 result.AppendMessageWithFormat ("%d breakpoints enabled.\n", enable_count + loc_count);
814 result.SetStatus (eReturnStatusSuccessFinishNoResult);
815 }
816 }
817
818 return result.Succeeded();
819}
820
821//-------------------------------------------------------------------------
822// CommandObjectBreakpointDisable
823//-------------------------------------------------------------------------
Jim Inghamae1c4cf2010-06-18 00:58:52 +0000824#pragma mark Disable
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000825
826CommandObjectBreakpointDisable::CommandObjectBreakpointDisable () :
827 CommandObject ("disable",
828 "Disables the specified breakpoint(s) without removing it/them. If no breakpoints are specified, disables them all.",
829 "disable [<breakpoint-id> | <breakpoint-id-list>]")
830{
831 // This command object can either be called via 'enable' or 'breakpoint enable'. Because it has two different
832 // potential invocation methods, we need to be a little tricky about generating the syntax string.
833 //StreamString tmp_string;
834 //tmp_string.Printf ("%s <breakpoint-id>", GetCommandName());
835 //m_cmd_syntax.assign(tmp_string.GetData(), tmp_string.GetSize());
836}
837
838CommandObjectBreakpointDisable::~CommandObjectBreakpointDisable ()
839{
840}
841
842bool
Greg Clayton66111032010-06-23 01:19:29 +0000843CommandObjectBreakpointDisable::Execute
844(
845 CommandInterpreter &interpreter,
846 Args& args,
847 CommandReturnObject &result
848)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000849{
Greg Clayton66111032010-06-23 01:19:29 +0000850 Target *target = interpreter.GetDebugger().GetCurrentTarget().get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000851 if (target == NULL)
852 {
853 result.AppendError ("Invalid target, set executable file using 'file' command.");
854 result.SetStatus (eReturnStatusFailed);
855 return false;
856 }
857
Jim Ingham1b54c882010-06-16 02:00:15 +0000858 Mutex::Locker locker;
859 target->GetBreakpointList().GetListMutex(locker);
860
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000861 const BreakpointList &breakpoints = target->GetBreakpointList();
862 size_t num_breakpoints = breakpoints.GetSize();
863
864 if (num_breakpoints == 0)
865 {
866 result.AppendError ("No breakpoints exist to be disabled.");
867 result.SetStatus (eReturnStatusFailed);
868 return false;
869 }
870
871 if (args.GetArgumentCount() == 0)
872 {
873 // No breakpoint selected; disable all currently set breakpoints.
874 target->DisableAllBreakpoints ();
875 result.AppendMessageWithFormat ("All breakpoints disabled. (%d breakpoints)\n", num_breakpoints);
876 result.SetStatus (eReturnStatusSuccessFinishNoResult);
877 }
878 else
879 {
880 // Particular breakpoint selected; disable that breakpoint.
881 BreakpointIDList valid_bp_ids;
882
883 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (args, target, result, &valid_bp_ids);
884
885 if (result.Succeeded())
886 {
887 int disable_count = 0;
888 int loc_count = 0;
889 for (int i = 0; i < valid_bp_ids.Size(); ++i)
890 {
891 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
892
893 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
894 {
895 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
896 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
897 {
898 BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
899 if (location)
900 {
901 location->SetEnabled (false);
902 ++loc_count;
903 }
904 }
905 else
906 {
Jim Inghamae1c4cf2010-06-18 00:58:52 +0000907 breakpoint->SetEnabled (false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000908 ++disable_count;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000909 }
910 }
911 }
912 result.AppendMessageWithFormat ("%d breakpoints disabled.\n", disable_count + loc_count);
913 result.SetStatus (eReturnStatusSuccessFinishNoResult);
914 }
915 }
916
917 return result.Succeeded();
918}
919
920//-------------------------------------------------------------------------
921// CommandObjectBreakpointDelete
922//-------------------------------------------------------------------------
Jim Inghamae1c4cf2010-06-18 00:58:52 +0000923#pragma mark Delete
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000924
925CommandObjectBreakpointDelete::CommandObjectBreakpointDelete() :
926 CommandObject ("breakpoint delete",
927 "Delete the specified breakpoint(s). If no breakpoints are specified, deletes them all.",
928 "breakpoint delete [<breakpoint-id> | <breakpoint-id-list>]")
929{
930}
931
932
933CommandObjectBreakpointDelete::~CommandObjectBreakpointDelete ()
934{
935}
936
937bool
Greg Clayton66111032010-06-23 01:19:29 +0000938CommandObjectBreakpointDelete::Execute
939(
940 CommandInterpreter &interpreter,
941 Args& args,
942 CommandReturnObject &result
943)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000944{
Greg Clayton66111032010-06-23 01:19:29 +0000945 Target *target = interpreter.GetDebugger().GetCurrentTarget().get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000946 if (target == NULL)
947 {
948 result.AppendError ("Invalid target, set executable file using 'file' command.");
949 result.SetStatus (eReturnStatusFailed);
950 return false;
951 }
952
Jim Ingham1b54c882010-06-16 02:00:15 +0000953 Mutex::Locker locker;
954 target->GetBreakpointList().GetListMutex(locker);
955
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000956 const BreakpointList &breakpoints = target->GetBreakpointList();
Jim Ingham1b54c882010-06-16 02:00:15 +0000957
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000958 size_t num_breakpoints = breakpoints.GetSize();
959
960 if (num_breakpoints == 0)
961 {
962 result.AppendError ("No breakpoints exist to be deleted.");
963 result.SetStatus (eReturnStatusFailed);
964 return false;
965 }
966
967 if (args.GetArgumentCount() == 0)
968 {
969 // No breakpoint selected; disable all currently set breakpoints.
970 if (args.GetArgumentCount() != 0)
971 {
972 result.AppendErrorWithFormat ("Specify breakpoints to delete with the -i option.\n");
973 result.SetStatus (eReturnStatusFailed);
974 return false;
975 }
976
977 target->RemoveAllBreakpoints ();
978 result.AppendMessageWithFormat ("All breakpoints removed. (%d breakpoints)\n", num_breakpoints);
979 result.SetStatus (eReturnStatusSuccessFinishNoResult);
980 }
981 else
982 {
983 // Particular breakpoint selected; disable that breakpoint.
984 BreakpointIDList valid_bp_ids;
985 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (args, target, result, &valid_bp_ids);
986
987 if (result.Succeeded())
988 {
989 int delete_count = 0;
990 int disable_count = 0;
991 for (int i = 0; i < valid_bp_ids.Size(); ++i)
992 {
993 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
994
995 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
996 {
997 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
998 {
999 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1000 BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
1001 // It makes no sense to try to delete individual locations, so we disable them instead.
1002 if (location)
1003 {
1004 location->SetEnabled (false);
1005 ++disable_count;
1006 }
1007 }
1008 else
1009 {
1010 target->RemoveBreakpointByID (cur_bp_id.GetBreakpointID());
1011 ++delete_count;
1012 }
1013 }
1014 }
1015 result.AppendMessageWithFormat ("%d breakpoints deleted; %d breakpoint locations disabled.\n",
1016 delete_count, disable_count);
1017 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1018 }
1019 }
1020 return result.Succeeded();
1021}
Jim Ingham1b54c882010-06-16 02:00:15 +00001022
1023//-------------------------------------------------------------------------
Jim Inghamae1c4cf2010-06-18 00:58:52 +00001024// CommandObjectBreakpointModify::CommandOptions
Jim Ingham1b54c882010-06-16 02:00:15 +00001025//-------------------------------------------------------------------------
Jim Inghamae1c4cf2010-06-18 00:58:52 +00001026#pragma mark Modify::CommandOptions
Jim Ingham1b54c882010-06-16 02:00:15 +00001027
Jim Inghamae1c4cf2010-06-18 00:58:52 +00001028CommandObjectBreakpointModify::CommandOptions::CommandOptions() :
Jim Ingham1b54c882010-06-16 02:00:15 +00001029 Options (),
1030 m_thread_id(LLDB_INVALID_THREAD_ID),
1031 m_thread_index (-1),
1032 m_thread_name(),
1033 m_queue_name(),
Jim Inghamae1c4cf2010-06-18 00:58:52 +00001034 m_ignore_count (-1),
1035 m_enable_passed (false)
Jim Ingham1b54c882010-06-16 02:00:15 +00001036{
1037}
1038
Jim Inghamae1c4cf2010-06-18 00:58:52 +00001039CommandObjectBreakpointModify::CommandOptions::~CommandOptions ()
Jim Ingham1b54c882010-06-16 02:00:15 +00001040{
1041}
1042
1043lldb::OptionDefinition
Jim Inghamae1c4cf2010-06-18 00:58:52 +00001044CommandObjectBreakpointModify::CommandOptions::g_option_table[] =
Jim Ingham1b54c882010-06-16 02:00:15 +00001045{
1046 { LLDB_OPT_SET_ALL, false, "ignore_count", 'k', required_argument, NULL, 0, NULL,
1047 "Set the number of times this breakpoint is sKipped before stopping." },
1048
1049 { LLDB_OPT_SET_ALL, false, "thread_index", 'x', required_argument, NULL, NULL, "<thread_index>",
1050 "The breakpoint stops only for the thread whose indeX matches this argument."},
1051
1052 { LLDB_OPT_SET_ALL, false, "thread_id", 't', required_argument, NULL, NULL, "<thread_id>",
1053 "The breakpoint stops only for the thread whose TID matches this argument."},
1054
1055 { LLDB_OPT_SET_ALL, false, "thread_name", 'T', required_argument, NULL, NULL, "<thread_name>",
1056 "The breakpoint stops only for the thread whose thread name matches this argument."},
1057
1058 { LLDB_OPT_SET_ALL, false, "queue_name", 'q', required_argument, NULL, NULL, "<queue_name>",
1059 "The breakpoint stops only for threads in the queue whose name is given by this argument."},
1060
Jim Inghamae1c4cf2010-06-18 00:58:52 +00001061 { LLDB_OPT_SET_1, false, "enable", 'e', no_argument, NULL, NULL, NULL,
1062 "Enable the breakpoint."},
1063
1064 { LLDB_OPT_SET_2, false, "disable", 'd', no_argument, NULL, NULL, NULL,
1065 "Disable the breakpoint."},
1066
1067
Jim Ingham1b54c882010-06-16 02:00:15 +00001068 { 0, false, NULL, 0, 0, NULL, 0, NULL, NULL }
1069};
1070
1071const lldb::OptionDefinition*
Jim Inghamae1c4cf2010-06-18 00:58:52 +00001072CommandObjectBreakpointModify::CommandOptions::GetDefinitions ()
Jim Ingham1b54c882010-06-16 02:00:15 +00001073{
1074 return g_option_table;
1075}
1076
1077Error
Jim Inghamae1c4cf2010-06-18 00:58:52 +00001078CommandObjectBreakpointModify::CommandOptions::SetOptionValue (int option_idx, const char *option_arg)
Jim Ingham1b54c882010-06-16 02:00:15 +00001079{
1080 Error error;
1081 char short_option = (char) m_getopt_table[option_idx].val;
1082
1083 switch (short_option)
1084 {
Jim Inghamae1c4cf2010-06-18 00:58:52 +00001085 case 'd':
1086 m_enable_passed = true;
1087 m_enable_value = false;
1088 break;
1089 case 'e':
1090 m_enable_passed = true;
1091 m_enable_value = true;
1092 break;
Jim Ingham1b54c882010-06-16 02:00:15 +00001093 case 'k':
1094 {
1095 m_ignore_count = Args::StringToSInt32(optarg, -1, 0);
1096 if (m_ignore_count == -1)
1097 error.SetErrorStringWithFormat ("Invalid ignore count '%s'.\n", optarg);
1098 }
Jim Inghamae1c4cf2010-06-18 00:58:52 +00001099 break;
Jim Ingham1b54c882010-06-16 02:00:15 +00001100 case 't' :
1101 {
1102 m_thread_id = Args::StringToUInt64(optarg, LLDB_INVALID_THREAD_ID, 0);
1103 if (m_thread_id == LLDB_INVALID_THREAD_ID)
1104 error.SetErrorStringWithFormat ("Invalid thread id string '%s'.\n", optarg);
1105 }
1106 break;
1107 case 'T':
Jim Inghamb2a38a72010-06-19 04:35:20 +00001108 if (option_arg != NULL)
1109 m_thread_name = option_arg;
1110 else
1111 m_thread_name.clear();
1112 m_name_passed = true;
Jim Ingham1b54c882010-06-16 02:00:15 +00001113 break;
1114 case 'q':
Jim Inghamb2a38a72010-06-19 04:35:20 +00001115 if (option_arg != NULL)
1116 m_queue_name = option_arg;
1117 else
1118 m_queue_name.clear();
1119 m_queue_passed = true;
Jim Ingham1b54c882010-06-16 02:00:15 +00001120 break;
1121 case 'x':
1122 {
1123 m_thread_index = Args::StringToUInt64(optarg, -1, 0);
1124 if (m_thread_id == -1)
1125 error.SetErrorStringWithFormat ("Invalid thread index string '%s'.\n", optarg);
1126
1127 }
1128 break;
1129 default:
1130 error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
1131 break;
1132 }
1133
1134 return error;
1135}
1136
1137void
Jim Inghamae1c4cf2010-06-18 00:58:52 +00001138CommandObjectBreakpointModify::CommandOptions::ResetOptionValues ()
Jim Ingham1b54c882010-06-16 02:00:15 +00001139{
1140 Options::ResetOptionValues();
1141
1142 m_ignore_count = -1;
1143 m_thread_id = LLDB_INVALID_THREAD_ID;
1144 m_thread_index = -1;
1145 m_thread_name.clear();
1146 m_queue_name.clear();
Jim Inghamae1c4cf2010-06-18 00:58:52 +00001147 m_enable_passed = false;
Jim Inghamb2a38a72010-06-19 04:35:20 +00001148 m_queue_passed = false;
1149 m_name_passed = false;
Jim Ingham1b54c882010-06-16 02:00:15 +00001150}
1151
1152//-------------------------------------------------------------------------
Jim Inghamae1c4cf2010-06-18 00:58:52 +00001153// CommandObjectBreakpointModify
Jim Ingham1b54c882010-06-16 02:00:15 +00001154//-------------------------------------------------------------------------
Jim Inghamae1c4cf2010-06-18 00:58:52 +00001155#pragma mark Modify
Jim Ingham1b54c882010-06-16 02:00:15 +00001156
Jim Inghamae1c4cf2010-06-18 00:58:52 +00001157CommandObjectBreakpointModify::CommandObjectBreakpointModify () :
1158 CommandObject ("breakpoint modify", "Modifys the options on a breakpoint or set of breakpoints in the executable.",
1159 "breakpoint modify <cmd-options> break-id [break-id ...]")
Jim Ingham1b54c882010-06-16 02:00:15 +00001160{
1161}
1162
Jim Inghamae1c4cf2010-06-18 00:58:52 +00001163CommandObjectBreakpointModify::~CommandObjectBreakpointModify ()
Jim Ingham1b54c882010-06-16 02:00:15 +00001164{
1165}
1166
1167Options *
Jim Inghamae1c4cf2010-06-18 00:58:52 +00001168CommandObjectBreakpointModify::GetOptions ()
Jim Ingham1b54c882010-06-16 02:00:15 +00001169{
1170 return &m_options;
1171}
1172
1173bool
Jim Inghamae1c4cf2010-06-18 00:58:52 +00001174CommandObjectBreakpointModify::Execute
Jim Ingham1b54c882010-06-16 02:00:15 +00001175(
Greg Clayton66111032010-06-23 01:19:29 +00001176 CommandInterpreter &interpreter,
Jim Ingham1b54c882010-06-16 02:00:15 +00001177 Args& command,
Jim Ingham1b54c882010-06-16 02:00:15 +00001178 CommandReturnObject &result
1179)
1180{
1181 if (command.GetArgumentCount() == 0)
1182 {
1183 result.AppendError ("No breakpoints specified.");
1184 result.SetStatus (eReturnStatusFailed);
1185 return false;
1186 }
1187
Greg Clayton66111032010-06-23 01:19:29 +00001188 Target *target = interpreter.GetDebugger().GetCurrentTarget().get();
Jim Ingham1b54c882010-06-16 02:00:15 +00001189 if (target == NULL)
1190 {
1191 result.AppendError ("Invalid target, set executable file using 'file' command.");
1192 result.SetStatus (eReturnStatusFailed);
1193 return false;
1194 }
1195
1196 Mutex::Locker locker;
1197 target->GetBreakpointList().GetListMutex(locker);
1198
1199 BreakpointIDList valid_bp_ids;
1200
1201 CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
1202
1203 if (result.Succeeded())
1204 {
1205 for (int i = 0; i < valid_bp_ids.Size(); ++i)
1206 {
1207 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
1208
1209 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
1210 {
1211 Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
1212 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
1213 {
1214 BreakpointLocation *location = bp->FindLocationByID (cur_bp_id.GetLocationID()).get();
1215 if (location)
1216 {
1217 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
1218 location->SetThreadID (m_options.m_thread_id);
1219
1220 if (m_options.m_thread_index != -1)
1221 location->GetLocationOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index);
1222
Jim Inghamb2a38a72010-06-19 04:35:20 +00001223 if (m_options.m_name_passed)
Jim Ingham1b54c882010-06-16 02:00:15 +00001224 location->GetLocationOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str());
1225
Jim Inghamb2a38a72010-06-19 04:35:20 +00001226 if (m_options.m_queue_passed)
Jim Ingham1b54c882010-06-16 02:00:15 +00001227 location->GetLocationOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str());
1228
1229 if (m_options.m_ignore_count != -1)
1230 location->GetLocationOptions()->SetIgnoreCount(m_options.m_ignore_count);
Jim Inghamae1c4cf2010-06-18 00:58:52 +00001231
1232 if (m_options.m_enable_passed)
1233 location->SetEnabled (m_options.m_enable_value);
Jim Ingham1b54c882010-06-16 02:00:15 +00001234 }
1235 }
1236 else
1237 {
1238 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
1239 bp->SetThreadID (m_options.m_thread_id);
1240
1241 if (m_options.m_thread_index != -1)
1242 bp->GetOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index);
1243
Jim Inghamb2a38a72010-06-19 04:35:20 +00001244 if (m_options.m_name_passed)
Jim Ingham1b54c882010-06-16 02:00:15 +00001245 bp->GetOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str());
1246
Jim Inghamb2a38a72010-06-19 04:35:20 +00001247 if (m_options.m_queue_passed)
Jim Ingham1b54c882010-06-16 02:00:15 +00001248 bp->GetOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str());
1249
1250 if (m_options.m_ignore_count != -1)
1251 bp->GetOptions()->SetIgnoreCount(m_options.m_ignore_count);
Jim Inghamae1c4cf2010-06-18 00:58:52 +00001252
1253 if (m_options.m_enable_passed)
1254 bp->SetEnabled (m_options.m_enable_value);
1255
Jim Ingham1b54c882010-06-16 02:00:15 +00001256 }
1257 }
1258 }
1259 }
1260
1261 return result.Succeeded();
1262}
1263
1264