130fdc8d8SChris Lattner //===-- CommandObjectBreakpoint.cpp -----------------------------*- C++ -*-===//
230fdc8d8SChris Lattner //
330fdc8d8SChris Lattner //                     The LLVM Compiler Infrastructure
430fdc8d8SChris Lattner //
530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source
630fdc8d8SChris Lattner // License. See LICENSE.TXT for details.
730fdc8d8SChris Lattner //
830fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
930fdc8d8SChris Lattner 
1030fdc8d8SChris Lattner #include "CommandObjectBreakpoint.h"
1130fdc8d8SChris Lattner #include "CommandObjectBreakpointCommand.h"
1230fdc8d8SChris Lattner 
1330fdc8d8SChris Lattner // C Includes
1430fdc8d8SChris Lattner // C++ Includes
1530fdc8d8SChris Lattner // Other libraries and framework includes
1630fdc8d8SChris Lattner // Project includes
1730fdc8d8SChris Lattner #include "lldb/Breakpoint/Breakpoint.h"
1830fdc8d8SChris Lattner #include "lldb/Breakpoint/BreakpointIDList.h"
1930fdc8d8SChris Lattner #include "lldb/Breakpoint/BreakpointLocation.h"
2040af72e1SJim Ingham #include "lldb/Interpreter/Options.h"
2130fdc8d8SChris Lattner #include "lldb/Core/RegularExpression.h"
2230fdc8d8SChris Lattner #include "lldb/Core/StreamString.h"
2330fdc8d8SChris Lattner #include "lldb/Interpreter/CommandInterpreter.h"
2430fdc8d8SChris Lattner #include "lldb/Interpreter/CommandReturnObject.h"
2530fdc8d8SChris Lattner #include "lldb/Target/Target.h"
2630fdc8d8SChris Lattner #include "lldb/Interpreter/CommandCompletions.h"
2730fdc8d8SChris Lattner #include "lldb/Target/StackFrame.h"
281b54c88cSJim Ingham #include "lldb/Target/Thread.h"
291b54c88cSJim Ingham #include "lldb/Target/ThreadSpec.h"
3030fdc8d8SChris Lattner 
3130fdc8d8SChris Lattner using namespace lldb;
3230fdc8d8SChris Lattner using namespace lldb_private;
3330fdc8d8SChris Lattner 
3430fdc8d8SChris Lattner static void
3530fdc8d8SChris Lattner AddBreakpointDescription (CommandContext *context, StreamString *s, Breakpoint *bp, lldb::DescriptionLevel level)
3630fdc8d8SChris Lattner {
3730fdc8d8SChris Lattner     s->IndentMore();
3830fdc8d8SChris Lattner     bp->GetDescription (s, level, true);
3930fdc8d8SChris Lattner     s->IndentLess();
4030fdc8d8SChris Lattner     s->EOL();
4130fdc8d8SChris Lattner }
4230fdc8d8SChris Lattner 
4330fdc8d8SChris Lattner //-------------------------------------------------------------------------
4430fdc8d8SChris Lattner // CommandObjectBreakpointSet::CommandOptions
4530fdc8d8SChris Lattner //-------------------------------------------------------------------------
46*ae1c4cf5SJim Ingham #pragma mark Set::CommandOptions
4730fdc8d8SChris Lattner 
4830fdc8d8SChris Lattner CommandObjectBreakpointSet::CommandOptions::CommandOptions() :
4930fdc8d8SChris Lattner     Options (),
5030fdc8d8SChris Lattner     m_filename (),
5130fdc8d8SChris Lattner     m_line_num (0),
5230fdc8d8SChris Lattner     m_column (0),
5330fdc8d8SChris Lattner     m_ignore_inlines (false),
5430fdc8d8SChris Lattner     m_func_name (),
5530fdc8d8SChris Lattner     m_func_regexp (),
5630fdc8d8SChris Lattner     m_modules (),
571b54c88cSJim Ingham     m_load_addr(),
581b54c88cSJim Ingham     m_thread_id(LLDB_INVALID_THREAD_ID),
591b54c88cSJim Ingham     m_thread_index (-1),
601b54c88cSJim Ingham     m_thread_name(),
611b54c88cSJim Ingham     m_queue_name(),
621b54c88cSJim Ingham     m_ignore_count (-1)
6330fdc8d8SChris Lattner {
6430fdc8d8SChris Lattner }
6530fdc8d8SChris Lattner 
6630fdc8d8SChris Lattner CommandObjectBreakpointSet::CommandOptions::~CommandOptions ()
6730fdc8d8SChris Lattner {
6830fdc8d8SChris Lattner }
6930fdc8d8SChris Lattner 
7030fdc8d8SChris Lattner lldb::OptionDefinition
7130fdc8d8SChris Lattner CommandObjectBreakpointSet::CommandOptions::g_option_table[] =
7230fdc8d8SChris Lattner {
738651121cSJim Ingham     { LLDB_OPT_SET_ALL, false, "shlib",       's', required_argument, NULL, CommandCompletions::eModuleCompletion, "<shlib-name>",
748651121cSJim Ingham         "Set the breakpoint only in this shared library (can use this option multiple times for multiple shlibs)."},
758651121cSJim Ingham 
768651121cSJim Ingham     { LLDB_OPT_SET_ALL, false, "ignore_inlines", 'i', no_argument,   NULL, 0, NULL,
778651121cSJim Ingham         "Ignore inlined subroutines when setting the breakppoint." },
788651121cSJim Ingham 
791b54c88cSJim Ingham     { LLDB_OPT_SET_ALL, false, "ignore_count", 'k', required_argument,   NULL, 0, NULL,
801b54c88cSJim Ingham         "Set the number of times this breakpoint is sKipped before stopping." },
811b54c88cSJim Ingham 
821b54c88cSJim Ingham     { LLDB_OPT_SET_ALL, false, "thread_index",       'x', required_argument, NULL, NULL, "<thread_index>",
831b54c88cSJim Ingham         "The breakpoint stops only for the thread whose indeX matches this argument."},
841b54c88cSJim Ingham 
851b54c88cSJim Ingham     { LLDB_OPT_SET_ALL, false, "thread_id",       't', required_argument, NULL, NULL, "<thread_id>",
861b54c88cSJim Ingham         "The breakpoint stops only for the thread whose TID matches this argument."},
871b54c88cSJim Ingham 
881b54c88cSJim Ingham     { LLDB_OPT_SET_ALL, false, "thread_name",       'T', required_argument, NULL, NULL, "<thread_name>",
891b54c88cSJim Ingham         "The breakpoint stops only for the thread whose thread name matches this argument."},
901b54c88cSJim Ingham 
911b54c88cSJim Ingham     { LLDB_OPT_SET_ALL, false, "queue_name",       'q', required_argument, NULL, NULL, "<queue_name>",
921b54c88cSJim Ingham         "The breakpoint stops only for threads in the queue whose name is given by this argument."},
931b54c88cSJim Ingham 
948651121cSJim Ingham     { LLDB_OPT_SET_1, false, "file",       'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, "<filename>",
9530fdc8d8SChris Lattner         "Set the breakpoint by source location in this particular file."},
9630fdc8d8SChris Lattner 
978651121cSJim Ingham     { LLDB_OPT_SET_1, true, "line",       'l', required_argument, NULL, 0, "<linenum>",
9830fdc8d8SChris Lattner         "Set the breakpoint by source location at this particular line."},
9930fdc8d8SChris Lattner 
10030fdc8d8SChris Lattner     // Comment out this option for the moment, as we don't actually use it, but will in the future.
10130fdc8d8SChris Lattner     // This way users won't see it, but the infrastructure is left in place.
10230fdc8d8SChris Lattner     //    { 0, false, "column",     'c', required_argument, NULL, "<column>",
10330fdc8d8SChris Lattner     //    "Set the breakpoint by source location at this particular column."},
10430fdc8d8SChris Lattner 
1058651121cSJim Ingham     { LLDB_OPT_SET_2, true, "address",    'a', required_argument, NULL, 0, "<address>",
10630fdc8d8SChris Lattner         "Set the breakpoint by address, at the specified address."},
10730fdc8d8SChris Lattner 
1088651121cSJim Ingham     { LLDB_OPT_SET_3, true, "name",       'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, "<function-name>",
10930fdc8d8SChris Lattner         "Set the breakpoint by function name." },
11030fdc8d8SChris Lattner 
1118651121cSJim Ingham     { LLDB_OPT_SET_4, true, "func_regex", 'r', required_argument, NULL, 0, "<regular-expression>",
11230fdc8d8SChris Lattner         "Set the breakpoint by function name, evaluating a regular-expression to find the function name(s)." },
11330fdc8d8SChris Lattner 
11430fdc8d8SChris Lattner     { 0, false, NULL, 0, 0, NULL, 0, NULL, NULL }
11530fdc8d8SChris Lattner };
11630fdc8d8SChris Lattner 
11730fdc8d8SChris Lattner const lldb::OptionDefinition*
11830fdc8d8SChris Lattner CommandObjectBreakpointSet::CommandOptions::GetDefinitions ()
11930fdc8d8SChris Lattner {
12030fdc8d8SChris Lattner     return g_option_table;
12130fdc8d8SChris Lattner }
12230fdc8d8SChris Lattner 
12330fdc8d8SChris Lattner Error
12430fdc8d8SChris Lattner CommandObjectBreakpointSet::CommandOptions::SetOptionValue (int option_idx, const char *option_arg)
12530fdc8d8SChris Lattner {
12630fdc8d8SChris Lattner     Error error;
12730fdc8d8SChris Lattner     char short_option = (char) m_getopt_table[option_idx].val;
12830fdc8d8SChris Lattner 
12930fdc8d8SChris Lattner     switch (short_option)
13030fdc8d8SChris Lattner     {
13130fdc8d8SChris Lattner         case 'a':
13230fdc8d8SChris Lattner             m_load_addr = Args::StringToUInt64(optarg, LLDB_INVALID_ADDRESS, 0);
13330fdc8d8SChris Lattner             if (m_load_addr == LLDB_INVALID_ADDRESS)
13430fdc8d8SChris Lattner                 m_load_addr = Args::StringToUInt64(optarg, LLDB_INVALID_ADDRESS, 16);
13530fdc8d8SChris Lattner 
13630fdc8d8SChris Lattner             if (m_load_addr == LLDB_INVALID_ADDRESS)
13730fdc8d8SChris Lattner                 error.SetErrorStringWithFormat ("Invalid address string '%s'.\n", optarg);
13830fdc8d8SChris Lattner             break;
13930fdc8d8SChris Lattner 
14030fdc8d8SChris Lattner         case 'c':
14130fdc8d8SChris Lattner             m_column = Args::StringToUInt32 (option_arg, 0);
14230fdc8d8SChris Lattner             break;
14330fdc8d8SChris Lattner         case 'f':
14430fdc8d8SChris Lattner             m_filename = option_arg;
14530fdc8d8SChris Lattner             break;
14630fdc8d8SChris Lattner         case 'i':
14730fdc8d8SChris Lattner             m_ignore_inlines = true;
14830fdc8d8SChris Lattner             break;
14930fdc8d8SChris Lattner         case 'l':
15030fdc8d8SChris Lattner             m_line_num = Args::StringToUInt32 (option_arg, 0);
15130fdc8d8SChris Lattner             break;
15230fdc8d8SChris Lattner         case 'n':
15330fdc8d8SChris Lattner             m_func_name = option_arg;
15430fdc8d8SChris Lattner             break;
15530fdc8d8SChris Lattner         case 'r':
15630fdc8d8SChris Lattner             m_func_regexp = option_arg;
15730fdc8d8SChris Lattner             break;
15830fdc8d8SChris Lattner         case 's':
15930fdc8d8SChris Lattner             {
16030fdc8d8SChris Lattner                 m_modules.push_back (std::string (option_arg));
16130fdc8d8SChris Lattner                 break;
16230fdc8d8SChris Lattner             }
1631b54c88cSJim Ingham         case 'k':
1641b54c88cSJim Ingham         {
1651b54c88cSJim Ingham             m_ignore_count = Args::StringToSInt32(optarg, -1, 0);
1661b54c88cSJim Ingham             if (m_ignore_count == -1)
1671b54c88cSJim Ingham                error.SetErrorStringWithFormat ("Invalid ignore count '%s'.\n", optarg);
1681b54c88cSJim Ingham         }
169*ae1c4cf5SJim Ingham         break;
1701b54c88cSJim Ingham         case 't' :
1711b54c88cSJim Ingham         {
1721b54c88cSJim Ingham             m_thread_id = Args::StringToUInt64(optarg, LLDB_INVALID_THREAD_ID, 0);
1731b54c88cSJim Ingham             if (m_thread_id == LLDB_INVALID_THREAD_ID)
1741b54c88cSJim Ingham                error.SetErrorStringWithFormat ("Invalid thread id string '%s'.\n", optarg);
1751b54c88cSJim Ingham         }
1761b54c88cSJim Ingham         break;
1771b54c88cSJim Ingham         case 'T':
1781b54c88cSJim Ingham             m_thread_name = option_arg;
1791b54c88cSJim Ingham             break;
1801b54c88cSJim Ingham         case 'q':
1811b54c88cSJim Ingham             m_queue_name = option_arg;
1821b54c88cSJim Ingham             break;
1831b54c88cSJim Ingham         case 'x':
1841b54c88cSJim Ingham         {
1851b54c88cSJim Ingham             m_thread_index = Args::StringToUInt64(optarg, -1, 0);
1861b54c88cSJim Ingham             if (m_thread_id == -1)
1871b54c88cSJim Ingham                error.SetErrorStringWithFormat ("Invalid thread index string '%s'.\n", optarg);
1881b54c88cSJim Ingham 
1891b54c88cSJim Ingham         }
1901b54c88cSJim Ingham         break;
19130fdc8d8SChris Lattner         default:
19230fdc8d8SChris Lattner             error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
19330fdc8d8SChris Lattner             break;
19430fdc8d8SChris Lattner     }
19530fdc8d8SChris Lattner 
19630fdc8d8SChris Lattner     return error;
19730fdc8d8SChris Lattner }
19830fdc8d8SChris Lattner 
19930fdc8d8SChris Lattner void
20030fdc8d8SChris Lattner CommandObjectBreakpointSet::CommandOptions::ResetOptionValues ()
20130fdc8d8SChris Lattner {
20230fdc8d8SChris Lattner     Options::ResetOptionValues();
20330fdc8d8SChris Lattner 
20430fdc8d8SChris Lattner     m_filename.clear();
20530fdc8d8SChris Lattner     m_line_num = 0;
20630fdc8d8SChris Lattner     m_column = 0;
20730fdc8d8SChris Lattner     m_ignore_inlines = false;
20830fdc8d8SChris Lattner     m_func_name.clear();
20930fdc8d8SChris Lattner     m_func_regexp.clear();
21030fdc8d8SChris Lattner     m_load_addr = LLDB_INVALID_ADDRESS;
21130fdc8d8SChris Lattner     m_modules.clear();
2121b54c88cSJim Ingham     m_ignore_count = -1;
2131b54c88cSJim Ingham     m_thread_id = LLDB_INVALID_THREAD_ID;
2141b54c88cSJim Ingham     m_thread_index = -1;
2151b54c88cSJim Ingham     m_thread_name.clear();
2161b54c88cSJim Ingham     m_queue_name.clear();
21730fdc8d8SChris Lattner }
21830fdc8d8SChris Lattner 
21930fdc8d8SChris Lattner //-------------------------------------------------------------------------
22030fdc8d8SChris Lattner // CommandObjectBreakpointSet
22130fdc8d8SChris Lattner //-------------------------------------------------------------------------
222*ae1c4cf5SJim Ingham #pragma mark Set
22330fdc8d8SChris Lattner 
22430fdc8d8SChris Lattner CommandObjectBreakpointSet::CommandObjectBreakpointSet () :
22530fdc8d8SChris Lattner     CommandObject ("breakpoint set", "Sets a breakpoint or set of breakpoints in the executable.",
22630fdc8d8SChris Lattner                    "breakpoint set <cmd-options>")
22730fdc8d8SChris Lattner {
22830fdc8d8SChris Lattner }
22930fdc8d8SChris Lattner 
23030fdc8d8SChris Lattner CommandObjectBreakpointSet::~CommandObjectBreakpointSet ()
23130fdc8d8SChris Lattner {
23230fdc8d8SChris Lattner }
23330fdc8d8SChris Lattner 
23430fdc8d8SChris Lattner Options *
23530fdc8d8SChris Lattner CommandObjectBreakpointSet::GetOptions ()
23630fdc8d8SChris Lattner {
23730fdc8d8SChris Lattner     return &m_options;
23830fdc8d8SChris Lattner }
23930fdc8d8SChris Lattner 
24030fdc8d8SChris Lattner bool
24130fdc8d8SChris Lattner CommandObjectBreakpointSet::Execute
24230fdc8d8SChris Lattner (
24330fdc8d8SChris Lattner     Args& command,
24430fdc8d8SChris Lattner     CommandContext *context,
24530fdc8d8SChris Lattner     CommandInterpreter *interpreter,
24630fdc8d8SChris Lattner     CommandReturnObject &result
24730fdc8d8SChris Lattner )
24830fdc8d8SChris Lattner {
24930fdc8d8SChris Lattner     Target *target = context->GetTarget();
25030fdc8d8SChris Lattner     if (target == NULL)
25130fdc8d8SChris Lattner     {
25230fdc8d8SChris Lattner         result.AppendError ("Invalid target, set executable file using 'file' command.");
25330fdc8d8SChris Lattner         result.SetStatus (eReturnStatusFailed);
25430fdc8d8SChris Lattner         return false;
25530fdc8d8SChris Lattner     }
25630fdc8d8SChris Lattner 
25730fdc8d8SChris Lattner     // The following are the various types of breakpoints that could be set:
25830fdc8d8SChris Lattner     //   1).  -f -l -p  [-s -g]   (setting breakpoint by source location)
25930fdc8d8SChris Lattner     //   2).  -a  [-s -g]         (setting breakpoint by address)
26030fdc8d8SChris Lattner     //   3).  -n  [-s -g]         (setting breakpoint by function name)
26130fdc8d8SChris Lattner     //   4).  -r  [-s -g]         (setting breakpoint by function name regular expression)
26230fdc8d8SChris Lattner 
26330fdc8d8SChris Lattner     BreakpointSetType break_type = eSetTypeInvalid;
26430fdc8d8SChris Lattner 
26530fdc8d8SChris Lattner     if (m_options.m_line_num != 0)
26630fdc8d8SChris Lattner         break_type = eSetTypeFileAndLine;
26730fdc8d8SChris Lattner     else if (m_options.m_load_addr != LLDB_INVALID_ADDRESS)
26830fdc8d8SChris Lattner         break_type = eSetTypeAddress;
26930fdc8d8SChris Lattner     else if (!m_options.m_func_name.empty())
27030fdc8d8SChris Lattner         break_type = eSetTypeFunctionName;
27130fdc8d8SChris Lattner     else if  (!m_options.m_func_regexp.empty())
27230fdc8d8SChris Lattner         break_type = eSetTypeFunctionRegexp;
27330fdc8d8SChris Lattner 
27430fdc8d8SChris Lattner     ModuleSP module_sp = target->GetExecutableModule();
27530fdc8d8SChris Lattner     Breakpoint *bp = NULL;
27630fdc8d8SChris Lattner     FileSpec module;
27730fdc8d8SChris Lattner     bool use_module = false;
27830fdc8d8SChris Lattner     int num_modules = m_options.m_modules.size();
27930fdc8d8SChris Lattner 
28030fdc8d8SChris Lattner     if ((num_modules > 0) && (break_type != eSetTypeAddress))
28130fdc8d8SChris Lattner         use_module = true;
28230fdc8d8SChris Lattner 
28330fdc8d8SChris Lattner     switch (break_type)
28430fdc8d8SChris Lattner     {
28530fdc8d8SChris Lattner         case eSetTypeFileAndLine: // Breakpoint by source position
28630fdc8d8SChris Lattner         {
28730fdc8d8SChris Lattner             FileSpec file;
28830fdc8d8SChris Lattner             if (m_options.m_filename.empty())
28930fdc8d8SChris Lattner             {
29030fdc8d8SChris Lattner                 StackFrame *cur_frame = context->GetExecutionContext().frame;
29130fdc8d8SChris Lattner                 if (cur_frame == NULL)
29230fdc8d8SChris Lattner                 {
29330fdc8d8SChris Lattner                     result.AppendError ("Attempting to set breakpoint by line number alone with no selected frame.");
29430fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusFailed);
29530fdc8d8SChris Lattner                     break;
29630fdc8d8SChris Lattner                 }
29730fdc8d8SChris Lattner                 else if (!cur_frame->HasDebugInformation())
29830fdc8d8SChris Lattner                 {
29930fdc8d8SChris Lattner                     result.AppendError ("Attempting to set breakpoint by line number alone but selected frame has no debug info.");
30030fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusFailed);
30130fdc8d8SChris Lattner                     break;
30230fdc8d8SChris Lattner                 }
30330fdc8d8SChris Lattner                 else
30430fdc8d8SChris Lattner                 {
30530fdc8d8SChris Lattner                     const SymbolContext &context = cur_frame->GetSymbolContext(true);
30630fdc8d8SChris Lattner                     if (context.line_entry.file)
30730fdc8d8SChris Lattner                     {
30830fdc8d8SChris Lattner                         file = context.line_entry.file;
30930fdc8d8SChris Lattner                     }
31030fdc8d8SChris Lattner                     else if (context.comp_unit != NULL)
31130fdc8d8SChris Lattner                     {    file = context.comp_unit;
31230fdc8d8SChris Lattner                     }
31330fdc8d8SChris Lattner                     else
31430fdc8d8SChris Lattner                     {
31530fdc8d8SChris Lattner                         result.AppendError ("Attempting to set breakpoint by line number alone but can't find the file for the selected frame.");
31630fdc8d8SChris Lattner                         result.SetStatus (eReturnStatusFailed);
31730fdc8d8SChris Lattner                         break;
31830fdc8d8SChris Lattner                     }
31930fdc8d8SChris Lattner                 }
32030fdc8d8SChris Lattner             }
32130fdc8d8SChris Lattner             else
32230fdc8d8SChris Lattner             {
32330fdc8d8SChris Lattner                 file.SetFile(m_options.m_filename.c_str());
32430fdc8d8SChris Lattner             }
32530fdc8d8SChris Lattner 
32630fdc8d8SChris Lattner             if (use_module)
32730fdc8d8SChris Lattner             {
32830fdc8d8SChris Lattner                 for (int i = 0; i < num_modules; ++i)
32930fdc8d8SChris Lattner                 {
33030fdc8d8SChris Lattner                     module.SetFile(m_options.m_modules[i].c_str());
33130fdc8d8SChris Lattner                     bp = target->CreateBreakpoint (&module,
33230fdc8d8SChris Lattner                                                    file,
33330fdc8d8SChris Lattner                                                    m_options.m_line_num,
33430fdc8d8SChris Lattner                                                    m_options.m_ignore_inlines).get();
33530fdc8d8SChris Lattner                     if (bp)
33630fdc8d8SChris Lattner                     {
33730fdc8d8SChris Lattner                         StreamString &output_stream = result.GetOutputStream();
33830fdc8d8SChris Lattner                         output_stream.Printf ("Breakpoint created: ");
33930fdc8d8SChris Lattner                         bp->GetDescription(&output_stream, lldb::eDescriptionLevelBrief);
34030fdc8d8SChris Lattner                         output_stream.EOL();
34130fdc8d8SChris Lattner                         result.SetStatus (eReturnStatusSuccessFinishResult);
34230fdc8d8SChris Lattner                     }
34330fdc8d8SChris Lattner                     else
34430fdc8d8SChris Lattner                     {
34530fdc8d8SChris Lattner                         result.AppendErrorWithFormat("Breakpoint creation failed: No breakpoint created in module '%s'.\n",
34630fdc8d8SChris Lattner                                                     m_options.m_modules[i].c_str());
34730fdc8d8SChris Lattner                         result.SetStatus (eReturnStatusFailed);
34830fdc8d8SChris Lattner                     }
34930fdc8d8SChris Lattner                 }
35030fdc8d8SChris Lattner             }
35130fdc8d8SChris Lattner             else
35230fdc8d8SChris Lattner                 bp = target->CreateBreakpoint (NULL,
35330fdc8d8SChris Lattner                                                file,
35430fdc8d8SChris Lattner                                                m_options.m_line_num,
35530fdc8d8SChris Lattner                                                m_options.m_ignore_inlines).get();
35630fdc8d8SChris Lattner         }
35730fdc8d8SChris Lattner         break;
35830fdc8d8SChris Lattner         case eSetTypeAddress: // Breakpoint by address
35930fdc8d8SChris Lattner             bp = target->CreateBreakpoint (m_options.m_load_addr, false).get();
36030fdc8d8SChris Lattner             break;
36130fdc8d8SChris Lattner         case eSetTypeFunctionName: // Breakpoint by function name
36230fdc8d8SChris Lattner             if (use_module)
36330fdc8d8SChris Lattner             {
36430fdc8d8SChris Lattner                 for (int i = 0; i < num_modules; ++i)
36530fdc8d8SChris Lattner                 {
36630fdc8d8SChris Lattner                     module.SetFile(m_options.m_modules[i].c_str());
36730fdc8d8SChris Lattner                     bp = target->CreateBreakpoint (&module, m_options.m_func_name.c_str()).get();
36830fdc8d8SChris Lattner                     if (bp)
36930fdc8d8SChris Lattner                     {
37030fdc8d8SChris Lattner                         StreamString &output_stream = result.GetOutputStream();
37130fdc8d8SChris Lattner                         output_stream.Printf ("Breakpoint created: ");
37230fdc8d8SChris Lattner                         bp->GetDescription(&output_stream, lldb::eDescriptionLevelBrief);
37330fdc8d8SChris Lattner                         output_stream.EOL();
37430fdc8d8SChris Lattner                         result.SetStatus (eReturnStatusSuccessFinishResult);
37530fdc8d8SChris Lattner                     }
37630fdc8d8SChris Lattner                     else
37730fdc8d8SChris Lattner                     {
37830fdc8d8SChris Lattner                         result.AppendErrorWithFormat("Breakpoint creation failed: No breakpoint created in module '%s'.\n",
37930fdc8d8SChris Lattner                                                     m_options.m_modules[i].c_str());
38030fdc8d8SChris Lattner                         result.SetStatus (eReturnStatusFailed);
38130fdc8d8SChris Lattner                     }
38230fdc8d8SChris Lattner                 }
38330fdc8d8SChris Lattner             }
38430fdc8d8SChris Lattner             else
38530fdc8d8SChris Lattner                 bp = target->CreateBreakpoint (NULL, m_options.m_func_name.c_str()).get();
38630fdc8d8SChris Lattner             break;
38730fdc8d8SChris Lattner         case eSetTypeFunctionRegexp: // Breakpoint by regular expression function name
38830fdc8d8SChris Lattner             {
38930fdc8d8SChris Lattner                 RegularExpression regexp(m_options.m_func_regexp.c_str());
39030fdc8d8SChris Lattner                 if (use_module)
39130fdc8d8SChris Lattner                 {
39230fdc8d8SChris Lattner                     for (int i = 0; i < num_modules; ++i)
39330fdc8d8SChris Lattner                     {
39430fdc8d8SChris Lattner                         module.SetFile(m_options.m_modules[i].c_str());
39530fdc8d8SChris Lattner                         bp = target->CreateBreakpoint (&module, regexp).get();
39630fdc8d8SChris Lattner                         if (bp)
39730fdc8d8SChris Lattner                         {
39830fdc8d8SChris Lattner                             StreamString &output_stream = result.GetOutputStream();
39930fdc8d8SChris Lattner                             output_stream.Printf ("Breakpoint created: ");
40030fdc8d8SChris Lattner                             bp->GetDescription(&output_stream, lldb::eDescriptionLevelBrief);
40130fdc8d8SChris Lattner                             output_stream.EOL();
40230fdc8d8SChris Lattner                             result.SetStatus (eReturnStatusSuccessFinishResult);
40330fdc8d8SChris Lattner                         }
40430fdc8d8SChris Lattner                         else
40530fdc8d8SChris Lattner                         {
40630fdc8d8SChris Lattner                             result.AppendErrorWithFormat("Breakpoint creation failed: No breakpoint created in module '%s'.\n",
40730fdc8d8SChris Lattner                                                         m_options.m_modules[i].c_str());
40830fdc8d8SChris Lattner                             result.SetStatus (eReturnStatusFailed);
40930fdc8d8SChris Lattner                         }
41030fdc8d8SChris Lattner                     }
41130fdc8d8SChris Lattner                 }
41230fdc8d8SChris Lattner                 else
41330fdc8d8SChris Lattner                     bp = target->CreateBreakpoint (NULL, regexp).get();
41430fdc8d8SChris Lattner             }
41530fdc8d8SChris Lattner             break;
41630fdc8d8SChris Lattner         default:
41730fdc8d8SChris Lattner             break;
41830fdc8d8SChris Lattner     }
41930fdc8d8SChris Lattner 
4201b54c88cSJim Ingham     // Now set the various options that were passed in:
4211b54c88cSJim Ingham     if (bp)
4221b54c88cSJim Ingham     {
4231b54c88cSJim Ingham         if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
4241b54c88cSJim Ingham             bp->SetThreadID (m_options.m_thread_id);
4251b54c88cSJim Ingham 
4261b54c88cSJim Ingham         if (m_options.m_thread_index != -1)
4271b54c88cSJim Ingham             bp->GetOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index);
4281b54c88cSJim Ingham 
4291b54c88cSJim Ingham         if (!m_options.m_thread_name.empty())
4301b54c88cSJim Ingham             bp->GetOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str());
4311b54c88cSJim Ingham 
4321b54c88cSJim Ingham         if (!m_options.m_queue_name.empty())
4331b54c88cSJim Ingham             bp->GetOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str());
4341b54c88cSJim Ingham 
4351b54c88cSJim Ingham         if (m_options.m_ignore_count != -1)
4361b54c88cSJim Ingham             bp->GetOptions()->SetIgnoreCount(m_options.m_ignore_count);
4371b54c88cSJim Ingham     }
4381b54c88cSJim Ingham 
43930fdc8d8SChris Lattner     if (bp && !use_module)
44030fdc8d8SChris Lattner     {
44130fdc8d8SChris Lattner         StreamString &output_stream = result.GetOutputStream();
44230fdc8d8SChris Lattner         output_stream.Printf ("Breakpoint created: ");
44330fdc8d8SChris Lattner         bp->GetDescription(&output_stream, lldb::eDescriptionLevelBrief);
44430fdc8d8SChris Lattner         output_stream.EOL();
44530fdc8d8SChris Lattner         result.SetStatus (eReturnStatusSuccessFinishResult);
44630fdc8d8SChris Lattner     }
44730fdc8d8SChris Lattner     else if (!bp)
44830fdc8d8SChris Lattner     {
44930fdc8d8SChris Lattner         result.AppendError ("Breakpoint creation failed: No breakpoint created.");
45030fdc8d8SChris Lattner         result.SetStatus (eReturnStatusFailed);
45130fdc8d8SChris Lattner     }
45230fdc8d8SChris Lattner 
45330fdc8d8SChris Lattner     return result.Succeeded();
45430fdc8d8SChris Lattner }
45530fdc8d8SChris Lattner 
45630fdc8d8SChris Lattner //-------------------------------------------------------------------------
45730fdc8d8SChris Lattner // CommandObjectMultiwordBreakpoint
45830fdc8d8SChris Lattner //-------------------------------------------------------------------------
459*ae1c4cf5SJim Ingham #pragma mark MultiwordBreakpoint
46030fdc8d8SChris Lattner 
46130fdc8d8SChris Lattner CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint (CommandInterpreter *interpreter) :
46230fdc8d8SChris Lattner     CommandObjectMultiword ("breakpoint",
46330fdc8d8SChris Lattner                               "A set of commands for operating on breakpoints.",
46430fdc8d8SChris Lattner                               "breakpoint <command> [<command-options>]")
46530fdc8d8SChris Lattner {
46630fdc8d8SChris Lattner     bool status;
46730fdc8d8SChris Lattner 
46830fdc8d8SChris Lattner     CommandObjectSP list_command_object (new CommandObjectBreakpointList ());
46930fdc8d8SChris Lattner     CommandObjectSP delete_command_object (new CommandObjectBreakpointDelete ());
47030fdc8d8SChris Lattner     CommandObjectSP enable_command_object (new CommandObjectBreakpointEnable ());
47130fdc8d8SChris Lattner     CommandObjectSP disable_command_object (new CommandObjectBreakpointDisable ());
47230fdc8d8SChris Lattner     CommandObjectSP set_command_object (new CommandObjectBreakpointSet ());
47330fdc8d8SChris Lattner     CommandObjectSP command_command_object (new CommandObjectBreakpointCommand (interpreter));
474*ae1c4cf5SJim Ingham     CommandObjectSP modify_command_object (new CommandObjectBreakpointModify());
47530fdc8d8SChris Lattner 
476*ae1c4cf5SJim Ingham     command_command_object->SetCommandName ("breakpoint command");
47730fdc8d8SChris Lattner     enable_command_object->SetCommandName("breakpoint enable");
47830fdc8d8SChris Lattner     disable_command_object->SetCommandName("breakpoint disable");
47930fdc8d8SChris Lattner     list_command_object->SetCommandName ("breakpoint list");
480*ae1c4cf5SJim Ingham     modify_command_object->SetCommandName ("breakpoint modify");
481*ae1c4cf5SJim Ingham     set_command_object->SetCommandName("breakpoint set");
48230fdc8d8SChris Lattner 
48330fdc8d8SChris Lattner     status = LoadSubCommand (list_command_object, "list", interpreter);
48430fdc8d8SChris Lattner     status = LoadSubCommand (enable_command_object, "enable", interpreter);
48530fdc8d8SChris Lattner     status = LoadSubCommand (disable_command_object, "disable", interpreter);
48630fdc8d8SChris Lattner     status = LoadSubCommand (delete_command_object, "delete", interpreter);
48730fdc8d8SChris Lattner     status = LoadSubCommand (set_command_object, "set", interpreter);
48830fdc8d8SChris Lattner     status = LoadSubCommand (command_command_object, "command", interpreter);
489*ae1c4cf5SJim Ingham     status = LoadSubCommand (modify_command_object, "modify", interpreter);
49030fdc8d8SChris Lattner }
49130fdc8d8SChris Lattner 
49230fdc8d8SChris Lattner CommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint ()
49330fdc8d8SChris Lattner {
49430fdc8d8SChris Lattner }
49530fdc8d8SChris Lattner 
49630fdc8d8SChris Lattner void
49730fdc8d8SChris Lattner CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (Args &args, Target *target, CommandReturnObject &result,
49830fdc8d8SChris Lattner                                                          BreakpointIDList *valid_ids)
49930fdc8d8SChris Lattner {
50030fdc8d8SChris Lattner     // args can be strings representing 1). integers (for breakpoint ids)
50130fdc8d8SChris Lattner     //                                  2). the full breakpoint & location canonical representation
50230fdc8d8SChris Lattner     //                                  3). the word "to" or a hyphen, representing a range (in which case there
50330fdc8d8SChris Lattner     //                                      had *better* be an entry both before & after of one of the first two types.
50430fdc8d8SChris Lattner 
50530fdc8d8SChris Lattner     Args temp_args;
50630fdc8d8SChris Lattner 
50730fdc8d8SChris Lattner     // Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff directly from the old ARGS to
50830fdc8d8SChris Lattner     // the new TEMP_ARGS.  Do not copy breakpoint id range strings over; instead generate a list of strings for
50930fdc8d8SChris Lattner     // all the breakpoint ids in the range, and shove all of those breakpoint id strings into TEMP_ARGS.
51030fdc8d8SChris Lattner 
51130fdc8d8SChris Lattner     BreakpointIDList::FindAndReplaceIDRanges (args, target, result, temp_args);
51230fdc8d8SChris Lattner 
51330fdc8d8SChris Lattner     // NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual BreakpointIDList:
51430fdc8d8SChris Lattner 
51530fdc8d8SChris Lattner     valid_ids->InsertStringArray ((const char **) temp_args.GetArgumentVector(), temp_args.GetArgumentCount(), result);
51630fdc8d8SChris Lattner 
51730fdc8d8SChris Lattner     // At this point,  all of the breakpoint ids that the user passed in have been converted to breakpoint IDs
51830fdc8d8SChris Lattner     // and put into valid_ids.
51930fdc8d8SChris Lattner 
52030fdc8d8SChris Lattner     if (result.Succeeded())
52130fdc8d8SChris Lattner     {
52230fdc8d8SChris Lattner         // Now that we've converted everything from args into a list of breakpoint ids, go through our tentative list
52330fdc8d8SChris Lattner         // of breakpoint id's and verify that they correspond to valid/currently set breakpoints.
52430fdc8d8SChris Lattner 
52530fdc8d8SChris Lattner         for (int i = 0; i < valid_ids->Size(); ++i)
52630fdc8d8SChris Lattner         {
52730fdc8d8SChris Lattner             BreakpointID cur_bp_id = valid_ids->GetBreakpointIDAtIndex (i);
52830fdc8d8SChris Lattner             Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
52930fdc8d8SChris Lattner             if (breakpoint != NULL)
53030fdc8d8SChris Lattner             {
53130fdc8d8SChris Lattner                 int num_locations = breakpoint->GetNumLocations();
53230fdc8d8SChris Lattner                 if (cur_bp_id.GetLocationID() > num_locations)
53330fdc8d8SChris Lattner                 {
53430fdc8d8SChris Lattner                     StreamString id_str;
53530fdc8d8SChris Lattner                     BreakpointID::GetCanonicalReference (&id_str, cur_bp_id.GetBreakpointID(),
53630fdc8d8SChris Lattner                                                            cur_bp_id.GetLocationID());
53730fdc8d8SChris Lattner                     i = valid_ids->Size() + 1;
53830fdc8d8SChris Lattner                     result.AppendErrorWithFormat ("'%s' is not a currently valid breakpoint/location id.\n",
53930fdc8d8SChris Lattner                                                  id_str.GetData());
54030fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusFailed);
54130fdc8d8SChris Lattner                 }
54230fdc8d8SChris Lattner             }
54330fdc8d8SChris Lattner             else
54430fdc8d8SChris Lattner             {
54530fdc8d8SChris Lattner                 i = valid_ids->Size() + 1;
54630fdc8d8SChris Lattner                 result.AppendErrorWithFormat ("'%d' is not a currently valid breakpoint id.\n", cur_bp_id.GetBreakpointID());
54730fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
54830fdc8d8SChris Lattner             }
54930fdc8d8SChris Lattner         }
55030fdc8d8SChris Lattner     }
55130fdc8d8SChris Lattner }
55230fdc8d8SChris Lattner 
55330fdc8d8SChris Lattner //-------------------------------------------------------------------------
55430fdc8d8SChris Lattner // CommandObjectBreakpointList::Options
55530fdc8d8SChris Lattner //-------------------------------------------------------------------------
556*ae1c4cf5SJim Ingham #pragma mark List::CommandOptions
55730fdc8d8SChris Lattner 
55830fdc8d8SChris Lattner CommandObjectBreakpointList::CommandOptions::CommandOptions() :
55930fdc8d8SChris Lattner     Options (),
56030fdc8d8SChris Lattner     m_level (lldb::eDescriptionLevelFull)  // Breakpoint List defaults to brief descriptions
56130fdc8d8SChris Lattner {
56230fdc8d8SChris Lattner }
56330fdc8d8SChris Lattner 
56430fdc8d8SChris Lattner CommandObjectBreakpointList::CommandOptions::~CommandOptions ()
56530fdc8d8SChris Lattner {
56630fdc8d8SChris Lattner }
56730fdc8d8SChris Lattner 
56830fdc8d8SChris Lattner lldb::OptionDefinition
56930fdc8d8SChris Lattner CommandObjectBreakpointList::CommandOptions::g_option_table[] =
57030fdc8d8SChris Lattner {
5718651121cSJim Ingham     { LLDB_OPT_SET_ALL, false, "internal", 'i', no_argument, NULL, 0, NULL,
5728651121cSJim Ingham         "Show debugger internal breakpoints" },
5738651121cSJim Ingham 
5748651121cSJim Ingham     { LLDB_OPT_SET_1, false, "brief",    'b', no_argument, NULL, 0, NULL,
57530fdc8d8SChris Lattner         "Give a brief description of the breakpoint (no location info)."},
57630fdc8d8SChris Lattner 
57730fdc8d8SChris Lattner     // FIXME: We need to add an "internal" command, and then add this sort of thing to it.
57830fdc8d8SChris Lattner     // But I need to see it for now, and don't want to wait.
5798651121cSJim Ingham     { LLDB_OPT_SET_2, false, "full",    'f', no_argument, NULL, 0, NULL,
58030fdc8d8SChris Lattner         "Give a full description of the breakpoint and its locations."},
58130fdc8d8SChris Lattner 
5828651121cSJim Ingham     { LLDB_OPT_SET_3, false, "verbose", 'v', no_argument, NULL, 0, NULL,
58330fdc8d8SChris Lattner         "Explain everything we know about the breakpoint (for debugging debugger bugs)." },
58430fdc8d8SChris Lattner 
58530fdc8d8SChris Lattner     { 0, false, NULL, 0, 0, NULL, 0, NULL, NULL }
58630fdc8d8SChris Lattner };
58730fdc8d8SChris Lattner 
58830fdc8d8SChris Lattner const lldb::OptionDefinition*
58930fdc8d8SChris Lattner CommandObjectBreakpointList::CommandOptions::GetDefinitions ()
59030fdc8d8SChris Lattner {
59130fdc8d8SChris Lattner     return g_option_table;
59230fdc8d8SChris Lattner }
59330fdc8d8SChris Lattner 
59430fdc8d8SChris Lattner Error
59530fdc8d8SChris Lattner CommandObjectBreakpointList::CommandOptions::SetOptionValue (int option_idx, const char *option_arg)
59630fdc8d8SChris Lattner {
59730fdc8d8SChris Lattner     Error error;
59830fdc8d8SChris Lattner     char short_option = (char) m_getopt_table[option_idx].val;
59930fdc8d8SChris Lattner 
60030fdc8d8SChris Lattner     switch (short_option)
60130fdc8d8SChris Lattner     {
60230fdc8d8SChris Lattner         case 'b':
60330fdc8d8SChris Lattner             m_level = lldb::eDescriptionLevelBrief;
60430fdc8d8SChris Lattner             break;
60530fdc8d8SChris Lattner         case 'f':
60630fdc8d8SChris Lattner             m_level = lldb::eDescriptionLevelFull;
60730fdc8d8SChris Lattner             break;
60830fdc8d8SChris Lattner         case 'v':
60930fdc8d8SChris Lattner             m_level = lldb::eDescriptionLevelVerbose;
61030fdc8d8SChris Lattner             break;
61130fdc8d8SChris Lattner         case 'i':
61230fdc8d8SChris Lattner             m_internal = true;
61330fdc8d8SChris Lattner             break;
61430fdc8d8SChris Lattner         default:
61530fdc8d8SChris Lattner             error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
61630fdc8d8SChris Lattner             break;
61730fdc8d8SChris Lattner     }
61830fdc8d8SChris Lattner 
61930fdc8d8SChris Lattner     return error;
62030fdc8d8SChris Lattner }
62130fdc8d8SChris Lattner 
62230fdc8d8SChris Lattner void
62330fdc8d8SChris Lattner CommandObjectBreakpointList::CommandOptions::ResetOptionValues ()
62430fdc8d8SChris Lattner {
62530fdc8d8SChris Lattner     Options::ResetOptionValues();
62630fdc8d8SChris Lattner 
62730fdc8d8SChris Lattner     m_level = lldb::eDescriptionLevelFull;
62830fdc8d8SChris Lattner     m_internal = false;
62930fdc8d8SChris Lattner }
63030fdc8d8SChris Lattner 
63130fdc8d8SChris Lattner //-------------------------------------------------------------------------
63230fdc8d8SChris Lattner // CommandObjectBreakpointList
63330fdc8d8SChris Lattner //-------------------------------------------------------------------------
634*ae1c4cf5SJim Ingham #pragma mark List
63530fdc8d8SChris Lattner 
63630fdc8d8SChris Lattner CommandObjectBreakpointList::CommandObjectBreakpointList () :
63730fdc8d8SChris Lattner     CommandObject ("breakpoint list",
63830fdc8d8SChris Lattner                      "List some or all breakpoints at configurable levels of detail.",
63930fdc8d8SChris Lattner                      "breakpoint list [<breakpoint-id>]")
64030fdc8d8SChris Lattner {
64130fdc8d8SChris Lattner }
64230fdc8d8SChris Lattner 
64330fdc8d8SChris Lattner CommandObjectBreakpointList::~CommandObjectBreakpointList ()
64430fdc8d8SChris Lattner {
64530fdc8d8SChris Lattner }
64630fdc8d8SChris Lattner 
64730fdc8d8SChris Lattner Options *
64830fdc8d8SChris Lattner CommandObjectBreakpointList::GetOptions ()
64930fdc8d8SChris Lattner {
65030fdc8d8SChris Lattner     return &m_options;
65130fdc8d8SChris Lattner }
65230fdc8d8SChris Lattner 
65330fdc8d8SChris Lattner bool
65430fdc8d8SChris Lattner CommandObjectBreakpointList::Execute
65530fdc8d8SChris Lattner (
65630fdc8d8SChris Lattner     Args& args,
65730fdc8d8SChris Lattner     CommandContext *context,
65830fdc8d8SChris Lattner     CommandInterpreter *interpreter,
65930fdc8d8SChris Lattner     CommandReturnObject &result
66030fdc8d8SChris Lattner )
66130fdc8d8SChris Lattner {
66230fdc8d8SChris Lattner     Target *target = context->GetTarget();
66330fdc8d8SChris Lattner     if (target == NULL)
66430fdc8d8SChris Lattner     {
66530fdc8d8SChris Lattner         result.AppendError ("Invalid target, set executable file using 'file' command.");
66630fdc8d8SChris Lattner         result.SetStatus (eReturnStatusSuccessFinishNoResult);
66730fdc8d8SChris Lattner         return true;
66830fdc8d8SChris Lattner     }
66930fdc8d8SChris Lattner 
67030fdc8d8SChris Lattner     const BreakpointList &breakpoints = target->GetBreakpointList(m_options.m_internal);
6711b54c88cSJim Ingham     Mutex::Locker locker;
6721b54c88cSJim Ingham     target->GetBreakpointList(m_options.m_internal).GetListMutex(locker);
6731b54c88cSJim Ingham 
67430fdc8d8SChris Lattner     size_t num_breakpoints = breakpoints.GetSize();
67530fdc8d8SChris Lattner 
67630fdc8d8SChris Lattner     if (num_breakpoints == 0)
67730fdc8d8SChris Lattner     {
67830fdc8d8SChris Lattner         result.AppendMessage ("No breakpoints currently set.");
67930fdc8d8SChris Lattner         result.SetStatus (eReturnStatusSuccessFinishNoResult);
68030fdc8d8SChris Lattner         return true;
68130fdc8d8SChris Lattner     }
68230fdc8d8SChris Lattner 
68330fdc8d8SChris Lattner     StreamString &output_stream = result.GetOutputStream();
68430fdc8d8SChris Lattner 
68530fdc8d8SChris Lattner     if (args.GetArgumentCount() == 0)
68630fdc8d8SChris Lattner     {
68730fdc8d8SChris Lattner         // No breakpoint selected; show info about all currently set breakpoints.
68830fdc8d8SChris Lattner         result.AppendMessage ("Current breakpoints:");
68930fdc8d8SChris Lattner         for (int i = 0; i < num_breakpoints; ++i)
69030fdc8d8SChris Lattner         {
69130fdc8d8SChris Lattner             Breakpoint *breakpoint = breakpoints.GetBreakpointByIndex (i).get();
69230fdc8d8SChris Lattner             AddBreakpointDescription (context, &output_stream, breakpoint, m_options.m_level);
69330fdc8d8SChris Lattner         }
69430fdc8d8SChris Lattner         result.SetStatus (eReturnStatusSuccessFinishNoResult);
69530fdc8d8SChris Lattner     }
69630fdc8d8SChris Lattner     else
69730fdc8d8SChris Lattner     {
69830fdc8d8SChris Lattner         // Particular breakpoints selected; show info about that breakpoint.
69930fdc8d8SChris Lattner         BreakpointIDList valid_bp_ids;
70030fdc8d8SChris Lattner         CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (args, target, result, &valid_bp_ids);
70130fdc8d8SChris Lattner 
70230fdc8d8SChris Lattner         if (result.Succeeded())
70330fdc8d8SChris Lattner         {
70430fdc8d8SChris Lattner             for (int i = 0; i < valid_bp_ids.Size(); ++i)
70530fdc8d8SChris Lattner             {
70630fdc8d8SChris Lattner                 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
70730fdc8d8SChris Lattner                 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
70830fdc8d8SChris Lattner                 AddBreakpointDescription (context, &output_stream, breakpoint, m_options.m_level);
70930fdc8d8SChris Lattner             }
71030fdc8d8SChris Lattner             result.SetStatus (eReturnStatusSuccessFinishNoResult);
71130fdc8d8SChris Lattner         }
71230fdc8d8SChris Lattner         else
71330fdc8d8SChris Lattner         {
71430fdc8d8SChris Lattner             result.AppendError ("Invalid breakpoint id.");
71530fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
71630fdc8d8SChris Lattner         }
71730fdc8d8SChris Lattner     }
71830fdc8d8SChris Lattner 
71930fdc8d8SChris Lattner     return result.Succeeded();
72030fdc8d8SChris Lattner }
72130fdc8d8SChris Lattner 
72230fdc8d8SChris Lattner //-------------------------------------------------------------------------
72330fdc8d8SChris Lattner // CommandObjectBreakpointEnable
72430fdc8d8SChris Lattner //-------------------------------------------------------------------------
725*ae1c4cf5SJim Ingham #pragma mark Enable
72630fdc8d8SChris Lattner 
72730fdc8d8SChris Lattner CommandObjectBreakpointEnable::CommandObjectBreakpointEnable () :
72830fdc8d8SChris Lattner     CommandObject ("enable",
72930fdc8d8SChris Lattner                      "Enables the specified disabled breakpoint(s).  If no breakpoints are specified, enables all of them.",
73030fdc8d8SChris Lattner                      "breakpoint enable [<breakpoint-id> | <breakpoint-id-list>]")
73130fdc8d8SChris Lattner {
73230fdc8d8SChris Lattner     // This command object can either be called via 'enable' or 'breakpoint enable'.  Because it has two different
73330fdc8d8SChris Lattner     // potential invocation methods, we need to be a little tricky about generating the syntax string.
73430fdc8d8SChris Lattner     //StreamString tmp_string;
73530fdc8d8SChris Lattner     //tmp_string.Printf ("%s <breakpoint-id>", GetCommandName());
73630fdc8d8SChris Lattner     //m_cmd_syntax.assign (tmp_string.GetData(), tmp_string.GetSize());
73730fdc8d8SChris Lattner }
73830fdc8d8SChris Lattner 
73930fdc8d8SChris Lattner 
74030fdc8d8SChris Lattner CommandObjectBreakpointEnable::~CommandObjectBreakpointEnable ()
74130fdc8d8SChris Lattner {
74230fdc8d8SChris Lattner }
74330fdc8d8SChris Lattner 
74430fdc8d8SChris Lattner 
74530fdc8d8SChris Lattner bool
74630fdc8d8SChris Lattner CommandObjectBreakpointEnable::Execute (Args& args, CommandContext *context,
74730fdc8d8SChris Lattner                                           CommandInterpreter *interpreter, CommandReturnObject &result)
74830fdc8d8SChris Lattner {
74930fdc8d8SChris Lattner     Target *target = context->GetTarget();
75030fdc8d8SChris Lattner     if (target == NULL)
75130fdc8d8SChris Lattner     {
75230fdc8d8SChris Lattner         result.AppendError ("Invalid target, set executable file using 'file' command.");
75330fdc8d8SChris Lattner         result.SetStatus (eReturnStatusFailed);
75430fdc8d8SChris Lattner         return false;
75530fdc8d8SChris Lattner     }
75630fdc8d8SChris Lattner 
7571b54c88cSJim Ingham     Mutex::Locker locker;
7581b54c88cSJim Ingham     target->GetBreakpointList().GetListMutex(locker);
7591b54c88cSJim Ingham 
76030fdc8d8SChris Lattner     const BreakpointList &breakpoints = target->GetBreakpointList();
7611b54c88cSJim Ingham 
76230fdc8d8SChris Lattner     size_t num_breakpoints = breakpoints.GetSize();
76330fdc8d8SChris Lattner 
76430fdc8d8SChris Lattner     if (num_breakpoints == 0)
76530fdc8d8SChris Lattner     {
76630fdc8d8SChris Lattner         result.AppendError ("No breakpoints exist to be enabled.");
76730fdc8d8SChris Lattner         result.SetStatus (eReturnStatusFailed);
76830fdc8d8SChris Lattner         return false;
76930fdc8d8SChris Lattner     }
77030fdc8d8SChris Lattner 
77130fdc8d8SChris Lattner     if (args.GetArgumentCount() == 0)
77230fdc8d8SChris Lattner     {
77330fdc8d8SChris Lattner         // No breakpoint selected; enable all currently set breakpoints.
77430fdc8d8SChris Lattner         target->EnableAllBreakpoints ();
77530fdc8d8SChris Lattner         result.AppendMessageWithFormat ("All breakpoints enabled. (%d breakpoints)\n", num_breakpoints);
77630fdc8d8SChris Lattner         result.SetStatus (eReturnStatusSuccessFinishNoResult);
77730fdc8d8SChris Lattner     }
77830fdc8d8SChris Lattner     else
77930fdc8d8SChris Lattner     {
78030fdc8d8SChris Lattner         // Particular breakpoint selected; enable that breakpoint.
78130fdc8d8SChris Lattner         BreakpointIDList valid_bp_ids;
78230fdc8d8SChris Lattner         CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (args, target, result, &valid_bp_ids);
78330fdc8d8SChris Lattner 
78430fdc8d8SChris Lattner         if (result.Succeeded())
78530fdc8d8SChris Lattner         {
78630fdc8d8SChris Lattner             int enable_count = 0;
78730fdc8d8SChris Lattner             int loc_count = 0;
78830fdc8d8SChris Lattner             for (int i = 0; i < valid_bp_ids.Size(); ++i)
78930fdc8d8SChris Lattner             {
79030fdc8d8SChris Lattner                 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
79130fdc8d8SChris Lattner 
79230fdc8d8SChris Lattner                 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
79330fdc8d8SChris Lattner                 {
79430fdc8d8SChris Lattner                     Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
79530fdc8d8SChris Lattner                     if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
79630fdc8d8SChris Lattner                     {
79730fdc8d8SChris Lattner                         BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
79830fdc8d8SChris Lattner                         if (location)
79930fdc8d8SChris Lattner                         {
80030fdc8d8SChris Lattner                             location->SetEnabled (true);
80130fdc8d8SChris Lattner                             ++loc_count;
80230fdc8d8SChris Lattner                         }
80330fdc8d8SChris Lattner                     }
80430fdc8d8SChris Lattner                     else
80530fdc8d8SChris Lattner                     {
806*ae1c4cf5SJim Ingham                         breakpoint->SetEnabled (true);
80730fdc8d8SChris Lattner                         ++enable_count;
80830fdc8d8SChris Lattner                     }
80930fdc8d8SChris Lattner                 }
81030fdc8d8SChris Lattner             }
81130fdc8d8SChris Lattner             result.AppendMessageWithFormat ("%d breakpoints enabled.\n", enable_count + loc_count);
81230fdc8d8SChris Lattner             result.SetStatus (eReturnStatusSuccessFinishNoResult);
81330fdc8d8SChris Lattner         }
81430fdc8d8SChris Lattner     }
81530fdc8d8SChris Lattner 
81630fdc8d8SChris Lattner     return result.Succeeded();
81730fdc8d8SChris Lattner }
81830fdc8d8SChris Lattner 
81930fdc8d8SChris Lattner //-------------------------------------------------------------------------
82030fdc8d8SChris Lattner // CommandObjectBreakpointDisable
82130fdc8d8SChris Lattner //-------------------------------------------------------------------------
822*ae1c4cf5SJim Ingham #pragma mark Disable
82330fdc8d8SChris Lattner 
82430fdc8d8SChris Lattner CommandObjectBreakpointDisable::CommandObjectBreakpointDisable () :
82530fdc8d8SChris Lattner     CommandObject ("disable",
82630fdc8d8SChris Lattner                    "Disables the specified breakpoint(s) without removing it/them.  If no breakpoints are specified, disables them all.",
82730fdc8d8SChris Lattner                    "disable [<breakpoint-id> | <breakpoint-id-list>]")
82830fdc8d8SChris Lattner {
82930fdc8d8SChris Lattner     // This command object can either be called via 'enable' or 'breakpoint enable'.  Because it has two different
83030fdc8d8SChris Lattner     // potential invocation methods, we need to be a little tricky about generating the syntax string.
83130fdc8d8SChris Lattner     //StreamString tmp_string;
83230fdc8d8SChris Lattner     //tmp_string.Printf ("%s <breakpoint-id>", GetCommandName());
83330fdc8d8SChris Lattner     //m_cmd_syntax.assign(tmp_string.GetData(), tmp_string.GetSize());
83430fdc8d8SChris Lattner }
83530fdc8d8SChris Lattner 
83630fdc8d8SChris Lattner CommandObjectBreakpointDisable::~CommandObjectBreakpointDisable ()
83730fdc8d8SChris Lattner {
83830fdc8d8SChris Lattner }
83930fdc8d8SChris Lattner 
84030fdc8d8SChris Lattner bool
84130fdc8d8SChris Lattner CommandObjectBreakpointDisable::Execute (Args& args, CommandContext *context,
84230fdc8d8SChris Lattner                                            CommandInterpreter *interpreter, CommandReturnObject &result)
84330fdc8d8SChris Lattner {
84430fdc8d8SChris Lattner     Target *target = context->GetTarget();
84530fdc8d8SChris Lattner     if (target == NULL)
84630fdc8d8SChris Lattner     {
84730fdc8d8SChris Lattner         result.AppendError ("Invalid target, set executable file using 'file' command.");
84830fdc8d8SChris Lattner         result.SetStatus (eReturnStatusFailed);
84930fdc8d8SChris Lattner         return false;
85030fdc8d8SChris Lattner     }
85130fdc8d8SChris Lattner 
8521b54c88cSJim Ingham     Mutex::Locker locker;
8531b54c88cSJim Ingham     target->GetBreakpointList().GetListMutex(locker);
8541b54c88cSJim Ingham 
85530fdc8d8SChris Lattner     const BreakpointList &breakpoints = target->GetBreakpointList();
85630fdc8d8SChris Lattner     size_t num_breakpoints = breakpoints.GetSize();
85730fdc8d8SChris Lattner 
85830fdc8d8SChris Lattner     if (num_breakpoints == 0)
85930fdc8d8SChris Lattner     {
86030fdc8d8SChris Lattner         result.AppendError ("No breakpoints exist to be disabled.");
86130fdc8d8SChris Lattner         result.SetStatus (eReturnStatusFailed);
86230fdc8d8SChris Lattner         return false;
86330fdc8d8SChris Lattner     }
86430fdc8d8SChris Lattner 
86530fdc8d8SChris Lattner     if (args.GetArgumentCount() == 0)
86630fdc8d8SChris Lattner     {
86730fdc8d8SChris Lattner         // No breakpoint selected; disable all currently set breakpoints.
86830fdc8d8SChris Lattner         target->DisableAllBreakpoints ();
86930fdc8d8SChris Lattner         result.AppendMessageWithFormat ("All breakpoints disabled. (%d breakpoints)\n", num_breakpoints);
87030fdc8d8SChris Lattner         result.SetStatus (eReturnStatusSuccessFinishNoResult);
87130fdc8d8SChris Lattner     }
87230fdc8d8SChris Lattner     else
87330fdc8d8SChris Lattner     {
87430fdc8d8SChris Lattner         // Particular breakpoint selected; disable that breakpoint.
87530fdc8d8SChris Lattner         BreakpointIDList valid_bp_ids;
87630fdc8d8SChris Lattner 
87730fdc8d8SChris Lattner         CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (args, target, result, &valid_bp_ids);
87830fdc8d8SChris Lattner 
87930fdc8d8SChris Lattner         if (result.Succeeded())
88030fdc8d8SChris Lattner         {
88130fdc8d8SChris Lattner             int disable_count = 0;
88230fdc8d8SChris Lattner             int loc_count = 0;
88330fdc8d8SChris Lattner             for (int i = 0; i < valid_bp_ids.Size(); ++i)
88430fdc8d8SChris Lattner             {
88530fdc8d8SChris Lattner                 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
88630fdc8d8SChris Lattner 
88730fdc8d8SChris Lattner                 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
88830fdc8d8SChris Lattner                 {
88930fdc8d8SChris Lattner                     Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
89030fdc8d8SChris Lattner                     if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
89130fdc8d8SChris Lattner                     {
89230fdc8d8SChris Lattner                         BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
89330fdc8d8SChris Lattner                         if (location)
89430fdc8d8SChris Lattner                         {
89530fdc8d8SChris Lattner                             location->SetEnabled (false);
89630fdc8d8SChris Lattner                             ++loc_count;
89730fdc8d8SChris Lattner                         }
89830fdc8d8SChris Lattner                     }
89930fdc8d8SChris Lattner                     else
90030fdc8d8SChris Lattner                     {
901*ae1c4cf5SJim Ingham                         breakpoint->SetEnabled (false);
90230fdc8d8SChris Lattner                         ++disable_count;
90330fdc8d8SChris Lattner                     }
90430fdc8d8SChris Lattner                 }
90530fdc8d8SChris Lattner             }
90630fdc8d8SChris Lattner             result.AppendMessageWithFormat ("%d breakpoints disabled.\n", disable_count + loc_count);
90730fdc8d8SChris Lattner             result.SetStatus (eReturnStatusSuccessFinishNoResult);
90830fdc8d8SChris Lattner         }
90930fdc8d8SChris Lattner     }
91030fdc8d8SChris Lattner 
91130fdc8d8SChris Lattner     return result.Succeeded();
91230fdc8d8SChris Lattner }
91330fdc8d8SChris Lattner 
91430fdc8d8SChris Lattner //-------------------------------------------------------------------------
91530fdc8d8SChris Lattner // CommandObjectBreakpointDelete
91630fdc8d8SChris Lattner //-------------------------------------------------------------------------
917*ae1c4cf5SJim Ingham #pragma mark Delete
91830fdc8d8SChris Lattner 
91930fdc8d8SChris Lattner CommandObjectBreakpointDelete::CommandObjectBreakpointDelete() :
92030fdc8d8SChris Lattner     CommandObject ("breakpoint delete",
92130fdc8d8SChris Lattner                    "Delete the specified breakpoint(s).  If no breakpoints are specified, deletes them all.",
92230fdc8d8SChris Lattner                    "breakpoint delete [<breakpoint-id> | <breakpoint-id-list>]")
92330fdc8d8SChris Lattner {
92430fdc8d8SChris Lattner }
92530fdc8d8SChris Lattner 
92630fdc8d8SChris Lattner 
92730fdc8d8SChris Lattner CommandObjectBreakpointDelete::~CommandObjectBreakpointDelete ()
92830fdc8d8SChris Lattner {
92930fdc8d8SChris Lattner }
93030fdc8d8SChris Lattner 
93130fdc8d8SChris Lattner bool
93230fdc8d8SChris Lattner CommandObjectBreakpointDelete::Execute (Args& args, CommandContext *context,
93330fdc8d8SChris Lattner                                           CommandInterpreter *interpreter, CommandReturnObject &result)
93430fdc8d8SChris Lattner {
93530fdc8d8SChris Lattner     Target *target = context->GetTarget();
93630fdc8d8SChris Lattner     if (target == NULL)
93730fdc8d8SChris Lattner     {
93830fdc8d8SChris Lattner         result.AppendError ("Invalid target, set executable file using 'file' command.");
93930fdc8d8SChris Lattner         result.SetStatus (eReturnStatusFailed);
94030fdc8d8SChris Lattner         return false;
94130fdc8d8SChris Lattner     }
94230fdc8d8SChris Lattner 
9431b54c88cSJim Ingham     Mutex::Locker locker;
9441b54c88cSJim Ingham     target->GetBreakpointList().GetListMutex(locker);
9451b54c88cSJim Ingham 
94630fdc8d8SChris Lattner     const BreakpointList &breakpoints = target->GetBreakpointList();
9471b54c88cSJim Ingham 
94830fdc8d8SChris Lattner     size_t num_breakpoints = breakpoints.GetSize();
94930fdc8d8SChris Lattner 
95030fdc8d8SChris Lattner     if (num_breakpoints == 0)
95130fdc8d8SChris Lattner     {
95230fdc8d8SChris Lattner         result.AppendError ("No breakpoints exist to be deleted.");
95330fdc8d8SChris Lattner         result.SetStatus (eReturnStatusFailed);
95430fdc8d8SChris Lattner         return false;
95530fdc8d8SChris Lattner     }
95630fdc8d8SChris Lattner 
95730fdc8d8SChris Lattner     if (args.GetArgumentCount() == 0)
95830fdc8d8SChris Lattner     {
95930fdc8d8SChris Lattner         // No breakpoint selected; disable all currently set breakpoints.
96030fdc8d8SChris Lattner         if (args.GetArgumentCount() != 0)
96130fdc8d8SChris Lattner         {
96230fdc8d8SChris Lattner             result.AppendErrorWithFormat ("Specify breakpoints to delete with the -i option.\n");
96330fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
96430fdc8d8SChris Lattner             return false;
96530fdc8d8SChris Lattner         }
96630fdc8d8SChris Lattner 
96730fdc8d8SChris Lattner         target->RemoveAllBreakpoints ();
96830fdc8d8SChris Lattner         result.AppendMessageWithFormat ("All breakpoints removed. (%d breakpoints)\n", num_breakpoints);
96930fdc8d8SChris Lattner         result.SetStatus (eReturnStatusSuccessFinishNoResult);
97030fdc8d8SChris Lattner     }
97130fdc8d8SChris Lattner     else
97230fdc8d8SChris Lattner     {
97330fdc8d8SChris Lattner         // Particular breakpoint selected; disable that breakpoint.
97430fdc8d8SChris Lattner         BreakpointIDList valid_bp_ids;
97530fdc8d8SChris Lattner         CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (args, target, result, &valid_bp_ids);
97630fdc8d8SChris Lattner 
97730fdc8d8SChris Lattner         if (result.Succeeded())
97830fdc8d8SChris Lattner         {
97930fdc8d8SChris Lattner             int delete_count = 0;
98030fdc8d8SChris Lattner             int disable_count = 0;
98130fdc8d8SChris Lattner             for (int i = 0; i < valid_bp_ids.Size(); ++i)
98230fdc8d8SChris Lattner             {
98330fdc8d8SChris Lattner                 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
98430fdc8d8SChris Lattner 
98530fdc8d8SChris Lattner                 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
98630fdc8d8SChris Lattner                 {
98730fdc8d8SChris Lattner                     if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
98830fdc8d8SChris Lattner                     {
98930fdc8d8SChris Lattner                         Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
99030fdc8d8SChris Lattner                         BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
99130fdc8d8SChris Lattner                         // It makes no sense to try to delete individual locations, so we disable them instead.
99230fdc8d8SChris Lattner                         if (location)
99330fdc8d8SChris Lattner                         {
99430fdc8d8SChris Lattner                             location->SetEnabled (false);
99530fdc8d8SChris Lattner                             ++disable_count;
99630fdc8d8SChris Lattner                         }
99730fdc8d8SChris Lattner                     }
99830fdc8d8SChris Lattner                     else
99930fdc8d8SChris Lattner                     {
100030fdc8d8SChris Lattner                         target->RemoveBreakpointByID (cur_bp_id.GetBreakpointID());
100130fdc8d8SChris Lattner                         ++delete_count;
100230fdc8d8SChris Lattner                     }
100330fdc8d8SChris Lattner                 }
100430fdc8d8SChris Lattner             }
100530fdc8d8SChris Lattner             result.AppendMessageWithFormat ("%d breakpoints deleted; %d breakpoint locations disabled.\n",
100630fdc8d8SChris Lattner                                            delete_count, disable_count);
100730fdc8d8SChris Lattner             result.SetStatus (eReturnStatusSuccessFinishNoResult);
100830fdc8d8SChris Lattner         }
100930fdc8d8SChris Lattner     }
101030fdc8d8SChris Lattner     return result.Succeeded();
101130fdc8d8SChris Lattner }
10121b54c88cSJim Ingham 
10131b54c88cSJim Ingham //-------------------------------------------------------------------------
1014*ae1c4cf5SJim Ingham // CommandObjectBreakpointModify::CommandOptions
10151b54c88cSJim Ingham //-------------------------------------------------------------------------
1016*ae1c4cf5SJim Ingham #pragma mark Modify::CommandOptions
10171b54c88cSJim Ingham 
1018*ae1c4cf5SJim Ingham CommandObjectBreakpointModify::CommandOptions::CommandOptions() :
10191b54c88cSJim Ingham     Options (),
10201b54c88cSJim Ingham     m_thread_id(LLDB_INVALID_THREAD_ID),
10211b54c88cSJim Ingham     m_thread_index (-1),
10221b54c88cSJim Ingham     m_thread_name(),
10231b54c88cSJim Ingham     m_queue_name(),
1024*ae1c4cf5SJim Ingham     m_ignore_count (-1),
1025*ae1c4cf5SJim Ingham     m_enable_passed (false)
10261b54c88cSJim Ingham {
10271b54c88cSJim Ingham }
10281b54c88cSJim Ingham 
1029*ae1c4cf5SJim Ingham CommandObjectBreakpointModify::CommandOptions::~CommandOptions ()
10301b54c88cSJim Ingham {
10311b54c88cSJim Ingham }
10321b54c88cSJim Ingham 
10331b54c88cSJim Ingham lldb::OptionDefinition
1034*ae1c4cf5SJim Ingham CommandObjectBreakpointModify::CommandOptions::g_option_table[] =
10351b54c88cSJim Ingham {
10361b54c88cSJim Ingham     { LLDB_OPT_SET_ALL, false, "ignore_count", 'k', required_argument,   NULL, 0, NULL,
10371b54c88cSJim Ingham         "Set the number of times this breakpoint is sKipped before stopping." },
10381b54c88cSJim Ingham 
10391b54c88cSJim Ingham     { LLDB_OPT_SET_ALL, false, "thread_index",       'x', required_argument, NULL, NULL, "<thread_index>",
10401b54c88cSJim Ingham         "The breakpoint stops only for the thread whose indeX matches this argument."},
10411b54c88cSJim Ingham 
10421b54c88cSJim Ingham     { LLDB_OPT_SET_ALL, false, "thread_id",       't', required_argument, NULL, NULL, "<thread_id>",
10431b54c88cSJim Ingham         "The breakpoint stops only for the thread whose TID matches this argument."},
10441b54c88cSJim Ingham 
10451b54c88cSJim Ingham     { LLDB_OPT_SET_ALL, false, "thread_name",       'T', required_argument, NULL, NULL, "<thread_name>",
10461b54c88cSJim Ingham         "The breakpoint stops only for the thread whose thread name matches this argument."},
10471b54c88cSJim Ingham 
10481b54c88cSJim Ingham     { LLDB_OPT_SET_ALL, false, "queue_name",       'q', required_argument, NULL, NULL, "<queue_name>",
10491b54c88cSJim Ingham         "The breakpoint stops only for threads in the queue whose name is given by this argument."},
10501b54c88cSJim Ingham 
1051*ae1c4cf5SJim Ingham     { LLDB_OPT_SET_1, false, "enable",       'e', no_argument, NULL, NULL, NULL,
1052*ae1c4cf5SJim Ingham         "Enable the breakpoint."},
1053*ae1c4cf5SJim Ingham 
1054*ae1c4cf5SJim Ingham     { LLDB_OPT_SET_2, false, "disable",       'd', no_argument, NULL, NULL, NULL,
1055*ae1c4cf5SJim Ingham         "Disable the breakpoint."},
1056*ae1c4cf5SJim Ingham 
1057*ae1c4cf5SJim Ingham 
10581b54c88cSJim Ingham     { 0, false, NULL, 0, 0, NULL, 0, NULL, NULL }
10591b54c88cSJim Ingham };
10601b54c88cSJim Ingham 
10611b54c88cSJim Ingham const lldb::OptionDefinition*
1062*ae1c4cf5SJim Ingham CommandObjectBreakpointModify::CommandOptions::GetDefinitions ()
10631b54c88cSJim Ingham {
10641b54c88cSJim Ingham     return g_option_table;
10651b54c88cSJim Ingham }
10661b54c88cSJim Ingham 
10671b54c88cSJim Ingham Error
1068*ae1c4cf5SJim Ingham CommandObjectBreakpointModify::CommandOptions::SetOptionValue (int option_idx, const char *option_arg)
10691b54c88cSJim Ingham {
10701b54c88cSJim Ingham     Error error;
10711b54c88cSJim Ingham     char short_option = (char) m_getopt_table[option_idx].val;
10721b54c88cSJim Ingham 
10731b54c88cSJim Ingham     switch (short_option)
10741b54c88cSJim Ingham     {
1075*ae1c4cf5SJim Ingham         case 'd':
1076*ae1c4cf5SJim Ingham             m_enable_passed = true;
1077*ae1c4cf5SJim Ingham             m_enable_value = false;
1078*ae1c4cf5SJim Ingham             break;
1079*ae1c4cf5SJim Ingham         case 'e':
1080*ae1c4cf5SJim Ingham             m_enable_passed = true;
1081*ae1c4cf5SJim Ingham             m_enable_value = true;
1082*ae1c4cf5SJim Ingham             break;
10831b54c88cSJim Ingham         case 'k':
10841b54c88cSJim Ingham         {
10851b54c88cSJim Ingham             m_ignore_count = Args::StringToSInt32(optarg, -1, 0);
10861b54c88cSJim Ingham             if (m_ignore_count == -1)
10871b54c88cSJim Ingham                error.SetErrorStringWithFormat ("Invalid ignore count '%s'.\n", optarg);
10881b54c88cSJim Ingham         }
1089*ae1c4cf5SJim Ingham         break;
10901b54c88cSJim Ingham         case 't' :
10911b54c88cSJim Ingham         {
10921b54c88cSJim Ingham             m_thread_id = Args::StringToUInt64(optarg, LLDB_INVALID_THREAD_ID, 0);
10931b54c88cSJim Ingham             if (m_thread_id == LLDB_INVALID_THREAD_ID)
10941b54c88cSJim Ingham                error.SetErrorStringWithFormat ("Invalid thread id string '%s'.\n", optarg);
10951b54c88cSJim Ingham         }
10961b54c88cSJim Ingham         break;
10971b54c88cSJim Ingham         case 'T':
10981b54c88cSJim Ingham             m_thread_name = option_arg;
10991b54c88cSJim Ingham             break;
11001b54c88cSJim Ingham         case 'q':
11011b54c88cSJim Ingham             m_queue_name = option_arg;
11021b54c88cSJim Ingham             break;
11031b54c88cSJim Ingham         case 'x':
11041b54c88cSJim Ingham         {
11051b54c88cSJim Ingham             m_thread_index = Args::StringToUInt64(optarg, -1, 0);
11061b54c88cSJim Ingham             if (m_thread_id == -1)
11071b54c88cSJim Ingham                error.SetErrorStringWithFormat ("Invalid thread index string '%s'.\n", optarg);
11081b54c88cSJim Ingham 
11091b54c88cSJim Ingham         }
11101b54c88cSJim Ingham         break;
11111b54c88cSJim Ingham         default:
11121b54c88cSJim Ingham             error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
11131b54c88cSJim Ingham             break;
11141b54c88cSJim Ingham     }
11151b54c88cSJim Ingham 
11161b54c88cSJim Ingham     return error;
11171b54c88cSJim Ingham }
11181b54c88cSJim Ingham 
11191b54c88cSJim Ingham void
1120*ae1c4cf5SJim Ingham CommandObjectBreakpointModify::CommandOptions::ResetOptionValues ()
11211b54c88cSJim Ingham {
11221b54c88cSJim Ingham     Options::ResetOptionValues();
11231b54c88cSJim Ingham 
11241b54c88cSJim Ingham     m_ignore_count = -1;
11251b54c88cSJim Ingham     m_thread_id = LLDB_INVALID_THREAD_ID;
11261b54c88cSJim Ingham     m_thread_index = -1;
11271b54c88cSJim Ingham     m_thread_name.clear();
11281b54c88cSJim Ingham     m_queue_name.clear();
1129*ae1c4cf5SJim Ingham     m_enable_passed = false;
11301b54c88cSJim Ingham }
11311b54c88cSJim Ingham 
11321b54c88cSJim Ingham //-------------------------------------------------------------------------
1133*ae1c4cf5SJim Ingham // CommandObjectBreakpointModify
11341b54c88cSJim Ingham //-------------------------------------------------------------------------
1135*ae1c4cf5SJim Ingham #pragma mark Modify
11361b54c88cSJim Ingham 
1137*ae1c4cf5SJim Ingham CommandObjectBreakpointModify::CommandObjectBreakpointModify () :
1138*ae1c4cf5SJim Ingham     CommandObject ("breakpoint modify", "Modifys the options on a breakpoint or set of breakpoints in the executable.",
1139*ae1c4cf5SJim Ingham                    "breakpoint modify <cmd-options> break-id [break-id ...]")
11401b54c88cSJim Ingham {
11411b54c88cSJim Ingham }
11421b54c88cSJim Ingham 
1143*ae1c4cf5SJim Ingham CommandObjectBreakpointModify::~CommandObjectBreakpointModify ()
11441b54c88cSJim Ingham {
11451b54c88cSJim Ingham }
11461b54c88cSJim Ingham 
11471b54c88cSJim Ingham Options *
1148*ae1c4cf5SJim Ingham CommandObjectBreakpointModify::GetOptions ()
11491b54c88cSJim Ingham {
11501b54c88cSJim Ingham     return &m_options;
11511b54c88cSJim Ingham }
11521b54c88cSJim Ingham 
11531b54c88cSJim Ingham bool
1154*ae1c4cf5SJim Ingham CommandObjectBreakpointModify::Execute
11551b54c88cSJim Ingham (
11561b54c88cSJim Ingham     Args& command,
11571b54c88cSJim Ingham     CommandContext *context,
11581b54c88cSJim Ingham     CommandInterpreter *interpreter,
11591b54c88cSJim Ingham     CommandReturnObject &result
11601b54c88cSJim Ingham )
11611b54c88cSJim Ingham {
11621b54c88cSJim Ingham     if (command.GetArgumentCount() == 0)
11631b54c88cSJim Ingham     {
11641b54c88cSJim Ingham         result.AppendError ("No breakpoints specified.");
11651b54c88cSJim Ingham         result.SetStatus (eReturnStatusFailed);
11661b54c88cSJim Ingham         return false;
11671b54c88cSJim Ingham     }
11681b54c88cSJim Ingham 
11691b54c88cSJim Ingham     Target *target = context->GetTarget();
11701b54c88cSJim Ingham     if (target == NULL)
11711b54c88cSJim Ingham     {
11721b54c88cSJim Ingham         result.AppendError ("Invalid target, set executable file using 'file' command.");
11731b54c88cSJim Ingham         result.SetStatus (eReturnStatusFailed);
11741b54c88cSJim Ingham         return false;
11751b54c88cSJim Ingham     }
11761b54c88cSJim Ingham 
11771b54c88cSJim Ingham     Mutex::Locker locker;
11781b54c88cSJim Ingham     target->GetBreakpointList().GetListMutex(locker);
11791b54c88cSJim Ingham 
11801b54c88cSJim Ingham     BreakpointIDList valid_bp_ids;
11811b54c88cSJim Ingham 
11821b54c88cSJim Ingham     CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
11831b54c88cSJim Ingham 
11841b54c88cSJim Ingham     if (result.Succeeded())
11851b54c88cSJim Ingham     {
11861b54c88cSJim Ingham         for (int i = 0; i < valid_bp_ids.Size(); ++i)
11871b54c88cSJim Ingham         {
11881b54c88cSJim Ingham             BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
11891b54c88cSJim Ingham 
11901b54c88cSJim Ingham             if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
11911b54c88cSJim Ingham             {
11921b54c88cSJim Ingham                 Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
11931b54c88cSJim Ingham                 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
11941b54c88cSJim Ingham                 {
11951b54c88cSJim Ingham                     BreakpointLocation *location = bp->FindLocationByID (cur_bp_id.GetLocationID()).get();
11961b54c88cSJim Ingham                     if (location)
11971b54c88cSJim Ingham                     {
11981b54c88cSJim Ingham                         if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
11991b54c88cSJim Ingham                             location->SetThreadID (m_options.m_thread_id);
12001b54c88cSJim Ingham 
12011b54c88cSJim Ingham                         if (m_options.m_thread_index != -1)
12021b54c88cSJim Ingham                             location->GetLocationOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index);
12031b54c88cSJim Ingham 
12041b54c88cSJim Ingham                         if (!m_options.m_thread_name.empty())
12051b54c88cSJim Ingham                             location->GetLocationOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str());
12061b54c88cSJim Ingham 
12071b54c88cSJim Ingham                         if (!m_options.m_queue_name.empty())
12081b54c88cSJim Ingham                             location->GetLocationOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str());
12091b54c88cSJim Ingham 
12101b54c88cSJim Ingham                         if (m_options.m_ignore_count != -1)
12111b54c88cSJim Ingham                             location->GetLocationOptions()->SetIgnoreCount(m_options.m_ignore_count);
1212*ae1c4cf5SJim Ingham 
1213*ae1c4cf5SJim Ingham                         if (m_options.m_enable_passed)
1214*ae1c4cf5SJim Ingham                             location->SetEnabled (m_options.m_enable_value);
12151b54c88cSJim Ingham                     }
12161b54c88cSJim Ingham                 }
12171b54c88cSJim Ingham                 else
12181b54c88cSJim Ingham                 {
12191b54c88cSJim Ingham                     if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
12201b54c88cSJim Ingham                         bp->SetThreadID (m_options.m_thread_id);
12211b54c88cSJim Ingham 
12221b54c88cSJim Ingham                     if (m_options.m_thread_index != -1)
12231b54c88cSJim Ingham                         bp->GetOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index);
12241b54c88cSJim Ingham 
12251b54c88cSJim Ingham                     if (!m_options.m_thread_name.empty())
12261b54c88cSJim Ingham                         bp->GetOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str());
12271b54c88cSJim Ingham 
12281b54c88cSJim Ingham                     if (!m_options.m_queue_name.empty())
12291b54c88cSJim Ingham                         bp->GetOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str());
12301b54c88cSJim Ingham 
12311b54c88cSJim Ingham                     if (m_options.m_ignore_count != -1)
12321b54c88cSJim Ingham                         bp->GetOptions()->SetIgnoreCount(m_options.m_ignore_count);
1233*ae1c4cf5SJim Ingham 
1234*ae1c4cf5SJim Ingham                     if (m_options.m_enable_passed)
1235*ae1c4cf5SJim Ingham                         bp->SetEnabled (m_options.m_enable_value);
1236*ae1c4cf5SJim Ingham 
12371b54c88cSJim Ingham                 }
12381b54c88cSJim Ingham             }
12391b54c88cSJim Ingham         }
12401b54c88cSJim Ingham     }
12411b54c88cSJim Ingham 
12421b54c88cSJim Ingham     return result.Succeeded();
12431b54c88cSJim Ingham }
12441b54c88cSJim Ingham 
12451b54c88cSJim Ingham 
1246