1*30fdc8d8SChris Lattner //===-- CommandObjectBreakpoint.cpp -----------------------------*- C++ -*-===//
2*30fdc8d8SChris Lattner //
3*30fdc8d8SChris Lattner //                     The LLVM Compiler Infrastructure
4*30fdc8d8SChris Lattner //
5*30fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source
6*30fdc8d8SChris Lattner // License. See LICENSE.TXT for details.
7*30fdc8d8SChris Lattner //
8*30fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
9*30fdc8d8SChris Lattner 
10*30fdc8d8SChris Lattner #include "CommandObjectBreakpoint.h"
11*30fdc8d8SChris Lattner #include "CommandObjectBreakpointCommand.h"
12*30fdc8d8SChris Lattner 
13*30fdc8d8SChris Lattner // C Includes
14*30fdc8d8SChris Lattner // C++ Includes
15*30fdc8d8SChris Lattner // Other libraries and framework includes
16*30fdc8d8SChris Lattner // Project includes
17*30fdc8d8SChris Lattner #include "lldb/Breakpoint/Breakpoint.h"
18*30fdc8d8SChris Lattner #include "lldb/Breakpoint/BreakpointIDList.h"
19*30fdc8d8SChris Lattner #include "lldb/Breakpoint/BreakpointLocation.h"
20*30fdc8d8SChris Lattner #include "lldb/Core/RegularExpression.h"
21*30fdc8d8SChris Lattner #include "lldb/Core/StreamString.h"
22*30fdc8d8SChris Lattner #include "lldb/Interpreter/CommandInterpreter.h"
23*30fdc8d8SChris Lattner #include "lldb/Interpreter/CommandReturnObject.h"
24*30fdc8d8SChris Lattner #include "lldb/Target/Target.h"
25*30fdc8d8SChris Lattner #include "lldb/Interpreter/CommandCompletions.h"
26*30fdc8d8SChris Lattner #include "lldb/Target/StackFrame.h"
27*30fdc8d8SChris Lattner 
28*30fdc8d8SChris Lattner using namespace lldb;
29*30fdc8d8SChris Lattner using namespace lldb_private;
30*30fdc8d8SChris Lattner 
31*30fdc8d8SChris Lattner static void
32*30fdc8d8SChris Lattner AddBreakpointDescription (CommandContext *context, StreamString *s, Breakpoint *bp, lldb::DescriptionLevel level)
33*30fdc8d8SChris Lattner {
34*30fdc8d8SChris Lattner     s->IndentMore();
35*30fdc8d8SChris Lattner     bp->GetDescription (s, level, true);
36*30fdc8d8SChris Lattner     s->IndentLess();
37*30fdc8d8SChris Lattner     s->EOL();
38*30fdc8d8SChris Lattner }
39*30fdc8d8SChris Lattner 
40*30fdc8d8SChris Lattner //-------------------------------------------------------------------------
41*30fdc8d8SChris Lattner // CommandObjectBreakpointSet::CommandOptions
42*30fdc8d8SChris Lattner //-------------------------------------------------------------------------
43*30fdc8d8SChris Lattner 
44*30fdc8d8SChris Lattner CommandObjectBreakpointSet::CommandOptions::CommandOptions() :
45*30fdc8d8SChris Lattner     Options (),
46*30fdc8d8SChris Lattner     m_filename (),
47*30fdc8d8SChris Lattner     m_line_num (0),
48*30fdc8d8SChris Lattner     m_column (0),
49*30fdc8d8SChris Lattner     m_ignore_inlines (false),
50*30fdc8d8SChris Lattner     m_func_name (),
51*30fdc8d8SChris Lattner     m_func_regexp (),
52*30fdc8d8SChris Lattner     m_modules (),
53*30fdc8d8SChris Lattner     m_load_addr()
54*30fdc8d8SChris Lattner {
55*30fdc8d8SChris Lattner     BuildValidOptionSets();
56*30fdc8d8SChris Lattner }
57*30fdc8d8SChris Lattner 
58*30fdc8d8SChris Lattner CommandObjectBreakpointSet::CommandOptions::~CommandOptions ()
59*30fdc8d8SChris Lattner {
60*30fdc8d8SChris Lattner }
61*30fdc8d8SChris Lattner 
62*30fdc8d8SChris Lattner lldb::OptionDefinition
63*30fdc8d8SChris Lattner CommandObjectBreakpointSet::CommandOptions::g_option_table[] =
64*30fdc8d8SChris Lattner {
65*30fdc8d8SChris Lattner     { 0, false, "file",       'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, "<filename>",
66*30fdc8d8SChris Lattner         "Set the breakpoint by source location in this particular file."},
67*30fdc8d8SChris Lattner 
68*30fdc8d8SChris Lattner     { 0, true, "line",       'l', required_argument, NULL, 0, "<linenum>",
69*30fdc8d8SChris Lattner         "Set the breakpoint by source location at this particular line."},
70*30fdc8d8SChris Lattner 
71*30fdc8d8SChris Lattner     { 0, false, "shlib",       's', required_argument, NULL, CommandCompletions::eModuleCompletion, "<shlib-name>",
72*30fdc8d8SChris Lattner         "Set the breakpoint only in this shared library (can use this option multiple times for multiple shlibs)."},
73*30fdc8d8SChris Lattner 
74*30fdc8d8SChris Lattner     // Comment out this option for the moment, as we don't actually use it, but will in the future.
75*30fdc8d8SChris Lattner     // This way users won't see it, but the infrastructure is left in place.
76*30fdc8d8SChris Lattner     //    { 0, false, "column",     'c', required_argument, NULL, "<column>",
77*30fdc8d8SChris Lattner     //    "Set the breakpoint by source location at this particular column."},
78*30fdc8d8SChris Lattner 
79*30fdc8d8SChris Lattner     { 0, false, "ignore_inlines", 'i', no_argument,   NULL, 0, NULL,
80*30fdc8d8SChris Lattner         "Ignore inlined subroutines when setting the breakppoint." },
81*30fdc8d8SChris Lattner 
82*30fdc8d8SChris Lattner     { 1, true, "address",    'a', required_argument, NULL, 0, "<address>",
83*30fdc8d8SChris Lattner         "Set the breakpoint by address, at the specified address."},
84*30fdc8d8SChris Lattner 
85*30fdc8d8SChris Lattner     { 1, false, "ignore_inlines", 'i', no_argument,   NULL, 0, NULL,
86*30fdc8d8SChris Lattner         "Ignore inlined subroutines when setting the breakppoint." },
87*30fdc8d8SChris Lattner 
88*30fdc8d8SChris Lattner     { 2, true, "name",       'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, "<function-name>",
89*30fdc8d8SChris Lattner         "Set the breakpoint by function name." },
90*30fdc8d8SChris Lattner 
91*30fdc8d8SChris Lattner     { 2, false, "shlib",       's', required_argument, NULL, CommandCompletions::eModuleCompletion, "<shlib-name>",
92*30fdc8d8SChris Lattner         "Set the breakpoint only in this shared library (can use this option multiple times for multiple shlibs)."},
93*30fdc8d8SChris Lattner 
94*30fdc8d8SChris Lattner     { 2, false, "ignore_inlines", 'i', no_argument,   NULL, 0, NULL,
95*30fdc8d8SChris Lattner         "Ignore inlined subroutines when setting the breakpoint." },
96*30fdc8d8SChris Lattner 
97*30fdc8d8SChris Lattner     { 3, true, "func_regex", 'r', required_argument, NULL, 0, "<regular-expression>",
98*30fdc8d8SChris Lattner         "Set the breakpoint by function name, evaluating a regular-expression to find the function name(s)." },
99*30fdc8d8SChris Lattner 
100*30fdc8d8SChris Lattner     { 3, false, "shlib",       's', required_argument, NULL, CommandCompletions::eModuleCompletion, "<shlib-name>",
101*30fdc8d8SChris Lattner         "Set the breakpoint only in this shared library (can use this option multiple times for multiple shlibs)."},
102*30fdc8d8SChris Lattner 
103*30fdc8d8SChris Lattner     { 3, false, "ignore_inlines", 'i', no_argument,   NULL, 0, NULL,
104*30fdc8d8SChris Lattner         "Ignore inlined subroutines when setting the breakpoint." },
105*30fdc8d8SChris Lattner 
106*30fdc8d8SChris Lattner     { 0, false, NULL, 0, 0, NULL, 0, NULL, NULL }
107*30fdc8d8SChris Lattner };
108*30fdc8d8SChris Lattner 
109*30fdc8d8SChris Lattner const lldb::OptionDefinition*
110*30fdc8d8SChris Lattner CommandObjectBreakpointSet::CommandOptions::GetDefinitions ()
111*30fdc8d8SChris Lattner {
112*30fdc8d8SChris Lattner     return g_option_table;
113*30fdc8d8SChris Lattner }
114*30fdc8d8SChris Lattner 
115*30fdc8d8SChris Lattner Error
116*30fdc8d8SChris Lattner CommandObjectBreakpointSet::CommandOptions::SetOptionValue (int option_idx, const char *option_arg)
117*30fdc8d8SChris Lattner {
118*30fdc8d8SChris Lattner     Error error;
119*30fdc8d8SChris Lattner     char short_option = (char) m_getopt_table[option_idx].val;
120*30fdc8d8SChris Lattner 
121*30fdc8d8SChris Lattner     switch (short_option)
122*30fdc8d8SChris Lattner     {
123*30fdc8d8SChris Lattner         case 'a':
124*30fdc8d8SChris Lattner             m_load_addr = Args::StringToUInt64(optarg, LLDB_INVALID_ADDRESS, 0);
125*30fdc8d8SChris Lattner             if (m_load_addr == LLDB_INVALID_ADDRESS)
126*30fdc8d8SChris Lattner                 m_load_addr = Args::StringToUInt64(optarg, LLDB_INVALID_ADDRESS, 16);
127*30fdc8d8SChris Lattner 
128*30fdc8d8SChris Lattner             if (m_load_addr == LLDB_INVALID_ADDRESS)
129*30fdc8d8SChris Lattner                 error.SetErrorStringWithFormat ("Invalid address string '%s'.\n", optarg);
130*30fdc8d8SChris Lattner             break;
131*30fdc8d8SChris Lattner 
132*30fdc8d8SChris Lattner         case 'c':
133*30fdc8d8SChris Lattner             m_column = Args::StringToUInt32 (option_arg, 0);
134*30fdc8d8SChris Lattner             break;
135*30fdc8d8SChris Lattner         case 'f':
136*30fdc8d8SChris Lattner             m_filename = option_arg;
137*30fdc8d8SChris Lattner             break;
138*30fdc8d8SChris Lattner         case 'i':
139*30fdc8d8SChris Lattner             m_ignore_inlines = true;
140*30fdc8d8SChris Lattner             break;
141*30fdc8d8SChris Lattner         case 'l':
142*30fdc8d8SChris Lattner             m_line_num = Args::StringToUInt32 (option_arg, 0);
143*30fdc8d8SChris Lattner             break;
144*30fdc8d8SChris Lattner         case 'n':
145*30fdc8d8SChris Lattner             m_func_name = option_arg;
146*30fdc8d8SChris Lattner             break;
147*30fdc8d8SChris Lattner         case 'r':
148*30fdc8d8SChris Lattner             m_func_regexp = option_arg;
149*30fdc8d8SChris Lattner             break;
150*30fdc8d8SChris Lattner         case 's':
151*30fdc8d8SChris Lattner             {
152*30fdc8d8SChris Lattner                 m_modules.push_back (std::string (option_arg));
153*30fdc8d8SChris Lattner                 break;
154*30fdc8d8SChris Lattner             }
155*30fdc8d8SChris Lattner         default:
156*30fdc8d8SChris Lattner             error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
157*30fdc8d8SChris Lattner             break;
158*30fdc8d8SChris Lattner     }
159*30fdc8d8SChris Lattner 
160*30fdc8d8SChris Lattner     return error;
161*30fdc8d8SChris Lattner }
162*30fdc8d8SChris Lattner 
163*30fdc8d8SChris Lattner void
164*30fdc8d8SChris Lattner CommandObjectBreakpointSet::CommandOptions::ResetOptionValues ()
165*30fdc8d8SChris Lattner {
166*30fdc8d8SChris Lattner     Options::ResetOptionValues();
167*30fdc8d8SChris Lattner 
168*30fdc8d8SChris Lattner     m_filename.clear();
169*30fdc8d8SChris Lattner     m_line_num = 0;
170*30fdc8d8SChris Lattner     m_column = 0;
171*30fdc8d8SChris Lattner     m_ignore_inlines = false;
172*30fdc8d8SChris Lattner     m_func_name.clear();
173*30fdc8d8SChris Lattner     m_func_regexp.clear();
174*30fdc8d8SChris Lattner     m_load_addr = LLDB_INVALID_ADDRESS;
175*30fdc8d8SChris Lattner     m_modules.clear();
176*30fdc8d8SChris Lattner }
177*30fdc8d8SChris Lattner 
178*30fdc8d8SChris Lattner //-------------------------------------------------------------------------
179*30fdc8d8SChris Lattner // CommandObjectBreakpointSet
180*30fdc8d8SChris Lattner //-------------------------------------------------------------------------
181*30fdc8d8SChris Lattner 
182*30fdc8d8SChris Lattner CommandObjectBreakpointSet::CommandObjectBreakpointSet () :
183*30fdc8d8SChris Lattner     CommandObject ("breakpoint set", "Sets a breakpoint or set of breakpoints in the executable.",
184*30fdc8d8SChris Lattner                    "breakpoint set <cmd-options>")
185*30fdc8d8SChris Lattner {
186*30fdc8d8SChris Lattner }
187*30fdc8d8SChris Lattner 
188*30fdc8d8SChris Lattner CommandObjectBreakpointSet::~CommandObjectBreakpointSet ()
189*30fdc8d8SChris Lattner {
190*30fdc8d8SChris Lattner }
191*30fdc8d8SChris Lattner 
192*30fdc8d8SChris Lattner Options *
193*30fdc8d8SChris Lattner CommandObjectBreakpointSet::GetOptions ()
194*30fdc8d8SChris Lattner {
195*30fdc8d8SChris Lattner     return &m_options;
196*30fdc8d8SChris Lattner }
197*30fdc8d8SChris Lattner 
198*30fdc8d8SChris Lattner bool
199*30fdc8d8SChris Lattner CommandObjectBreakpointSet::Execute
200*30fdc8d8SChris Lattner (
201*30fdc8d8SChris Lattner     Args& command,
202*30fdc8d8SChris Lattner     CommandContext *context,
203*30fdc8d8SChris Lattner     CommandInterpreter *interpreter,
204*30fdc8d8SChris Lattner     CommandReturnObject &result
205*30fdc8d8SChris Lattner )
206*30fdc8d8SChris Lattner {
207*30fdc8d8SChris Lattner     Target *target = context->GetTarget();
208*30fdc8d8SChris Lattner     if (target == NULL)
209*30fdc8d8SChris Lattner     {
210*30fdc8d8SChris Lattner         result.AppendError ("Invalid target, set executable file using 'file' command.");
211*30fdc8d8SChris Lattner         result.SetStatus (eReturnStatusFailed);
212*30fdc8d8SChris Lattner         return false;
213*30fdc8d8SChris Lattner     }
214*30fdc8d8SChris Lattner 
215*30fdc8d8SChris Lattner     // The following are the various types of breakpoints that could be set:
216*30fdc8d8SChris Lattner     //   1).  -f -l -p  [-s -g]   (setting breakpoint by source location)
217*30fdc8d8SChris Lattner     //   2).  -a  [-s -g]         (setting breakpoint by address)
218*30fdc8d8SChris Lattner     //   3).  -n  [-s -g]         (setting breakpoint by function name)
219*30fdc8d8SChris Lattner     //   4).  -r  [-s -g]         (setting breakpoint by function name regular expression)
220*30fdc8d8SChris Lattner 
221*30fdc8d8SChris Lattner     BreakpointSetType break_type = eSetTypeInvalid;
222*30fdc8d8SChris Lattner 
223*30fdc8d8SChris Lattner     if (m_options.m_line_num != 0)
224*30fdc8d8SChris Lattner         break_type = eSetTypeFileAndLine;
225*30fdc8d8SChris Lattner     else if (m_options.m_load_addr != LLDB_INVALID_ADDRESS)
226*30fdc8d8SChris Lattner         break_type = eSetTypeAddress;
227*30fdc8d8SChris Lattner     else if (!m_options.m_func_name.empty())
228*30fdc8d8SChris Lattner         break_type = eSetTypeFunctionName;
229*30fdc8d8SChris Lattner     else if  (!m_options.m_func_regexp.empty())
230*30fdc8d8SChris Lattner         break_type = eSetTypeFunctionRegexp;
231*30fdc8d8SChris Lattner 
232*30fdc8d8SChris Lattner     ModuleSP module_sp = target->GetExecutableModule();
233*30fdc8d8SChris Lattner     Breakpoint *bp = NULL;
234*30fdc8d8SChris Lattner     FileSpec module;
235*30fdc8d8SChris Lattner     bool use_module = false;
236*30fdc8d8SChris Lattner     int num_modules = m_options.m_modules.size();
237*30fdc8d8SChris Lattner 
238*30fdc8d8SChris Lattner     if ((num_modules > 0) && (break_type != eSetTypeAddress))
239*30fdc8d8SChris Lattner         use_module = true;
240*30fdc8d8SChris Lattner 
241*30fdc8d8SChris Lattner     switch (break_type)
242*30fdc8d8SChris Lattner     {
243*30fdc8d8SChris Lattner         case eSetTypeFileAndLine: // Breakpoint by source position
244*30fdc8d8SChris Lattner         {
245*30fdc8d8SChris Lattner             FileSpec file;
246*30fdc8d8SChris Lattner             if (m_options.m_filename.empty())
247*30fdc8d8SChris Lattner             {
248*30fdc8d8SChris Lattner                 StackFrame *cur_frame = context->GetExecutionContext().frame;
249*30fdc8d8SChris Lattner                 if (cur_frame == NULL)
250*30fdc8d8SChris Lattner                 {
251*30fdc8d8SChris Lattner                     result.AppendError ("Attempting to set breakpoint by line number alone with no selected frame.");
252*30fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusFailed);
253*30fdc8d8SChris Lattner                     break;
254*30fdc8d8SChris Lattner                 }
255*30fdc8d8SChris Lattner                 else if (!cur_frame->HasDebugInformation())
256*30fdc8d8SChris Lattner                 {
257*30fdc8d8SChris Lattner                     result.AppendError ("Attempting to set breakpoint by line number alone but selected frame has no debug info.");
258*30fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusFailed);
259*30fdc8d8SChris Lattner                     break;
260*30fdc8d8SChris Lattner                 }
261*30fdc8d8SChris Lattner                 else
262*30fdc8d8SChris Lattner                 {
263*30fdc8d8SChris Lattner                     const SymbolContext &context = cur_frame->GetSymbolContext(true);
264*30fdc8d8SChris Lattner                     if (context.line_entry.file)
265*30fdc8d8SChris Lattner                     {
266*30fdc8d8SChris Lattner                         file = context.line_entry.file;
267*30fdc8d8SChris Lattner                     }
268*30fdc8d8SChris Lattner                     else if (context.comp_unit != NULL)
269*30fdc8d8SChris Lattner                     {    file = context.comp_unit;
270*30fdc8d8SChris Lattner                     }
271*30fdc8d8SChris Lattner                     else
272*30fdc8d8SChris Lattner                     {
273*30fdc8d8SChris Lattner                         result.AppendError ("Attempting to set breakpoint by line number alone but can't find the file for the selected frame.");
274*30fdc8d8SChris Lattner                         result.SetStatus (eReturnStatusFailed);
275*30fdc8d8SChris Lattner                         break;
276*30fdc8d8SChris Lattner                     }
277*30fdc8d8SChris Lattner                 }
278*30fdc8d8SChris Lattner             }
279*30fdc8d8SChris Lattner             else
280*30fdc8d8SChris Lattner             {
281*30fdc8d8SChris Lattner                 file.SetFile(m_options.m_filename.c_str());
282*30fdc8d8SChris Lattner             }
283*30fdc8d8SChris Lattner 
284*30fdc8d8SChris Lattner             if (use_module)
285*30fdc8d8SChris Lattner             {
286*30fdc8d8SChris Lattner                 for (int i = 0; i < num_modules; ++i)
287*30fdc8d8SChris Lattner                 {
288*30fdc8d8SChris Lattner                     module.SetFile(m_options.m_modules[i].c_str());
289*30fdc8d8SChris Lattner                     bp = target->CreateBreakpoint (&module,
290*30fdc8d8SChris Lattner                                                    file,
291*30fdc8d8SChris Lattner                                                    m_options.m_line_num,
292*30fdc8d8SChris Lattner                                                    m_options.m_ignore_inlines).get();
293*30fdc8d8SChris Lattner                     if (bp)
294*30fdc8d8SChris Lattner                     {
295*30fdc8d8SChris Lattner                         StreamString &output_stream = result.GetOutputStream();
296*30fdc8d8SChris Lattner                         output_stream.Printf ("Breakpoint created: ");
297*30fdc8d8SChris Lattner                         bp->GetDescription(&output_stream, lldb::eDescriptionLevelBrief);
298*30fdc8d8SChris Lattner                         output_stream.EOL();
299*30fdc8d8SChris Lattner                         result.SetStatus (eReturnStatusSuccessFinishResult);
300*30fdc8d8SChris Lattner                     }
301*30fdc8d8SChris Lattner                     else
302*30fdc8d8SChris Lattner                     {
303*30fdc8d8SChris Lattner                         result.AppendErrorWithFormat("Breakpoint creation failed: No breakpoint created in module '%s'.\n",
304*30fdc8d8SChris Lattner                                                     m_options.m_modules[i].c_str());
305*30fdc8d8SChris Lattner                         result.SetStatus (eReturnStatusFailed);
306*30fdc8d8SChris Lattner                     }
307*30fdc8d8SChris Lattner                 }
308*30fdc8d8SChris Lattner             }
309*30fdc8d8SChris Lattner             else
310*30fdc8d8SChris Lattner                 bp = target->CreateBreakpoint (NULL,
311*30fdc8d8SChris Lattner                                                file,
312*30fdc8d8SChris Lattner                                                m_options.m_line_num,
313*30fdc8d8SChris Lattner                                                m_options.m_ignore_inlines).get();
314*30fdc8d8SChris Lattner         }
315*30fdc8d8SChris Lattner         break;
316*30fdc8d8SChris Lattner         case eSetTypeAddress: // Breakpoint by address
317*30fdc8d8SChris Lattner             bp = target->CreateBreakpoint (m_options.m_load_addr, false).get();
318*30fdc8d8SChris Lattner             break;
319*30fdc8d8SChris Lattner         case eSetTypeFunctionName: // Breakpoint by function name
320*30fdc8d8SChris Lattner             if (use_module)
321*30fdc8d8SChris Lattner             {
322*30fdc8d8SChris Lattner                 for (int i = 0; i < num_modules; ++i)
323*30fdc8d8SChris Lattner                 {
324*30fdc8d8SChris Lattner                     module.SetFile(m_options.m_modules[i].c_str());
325*30fdc8d8SChris Lattner                     bp = target->CreateBreakpoint (&module, m_options.m_func_name.c_str()).get();
326*30fdc8d8SChris Lattner                     if (bp)
327*30fdc8d8SChris Lattner                     {
328*30fdc8d8SChris Lattner                         StreamString &output_stream = result.GetOutputStream();
329*30fdc8d8SChris Lattner                         output_stream.Printf ("Breakpoint created: ");
330*30fdc8d8SChris Lattner                         bp->GetDescription(&output_stream, lldb::eDescriptionLevelBrief);
331*30fdc8d8SChris Lattner                         output_stream.EOL();
332*30fdc8d8SChris Lattner                         result.SetStatus (eReturnStatusSuccessFinishResult);
333*30fdc8d8SChris Lattner                     }
334*30fdc8d8SChris Lattner                     else
335*30fdc8d8SChris Lattner                     {
336*30fdc8d8SChris Lattner                         result.AppendErrorWithFormat("Breakpoint creation failed: No breakpoint created in module '%s'.\n",
337*30fdc8d8SChris Lattner                                                     m_options.m_modules[i].c_str());
338*30fdc8d8SChris Lattner                         result.SetStatus (eReturnStatusFailed);
339*30fdc8d8SChris Lattner                     }
340*30fdc8d8SChris Lattner                 }
341*30fdc8d8SChris Lattner             }
342*30fdc8d8SChris Lattner             else
343*30fdc8d8SChris Lattner                 bp = target->CreateBreakpoint (NULL, m_options.m_func_name.c_str()).get();
344*30fdc8d8SChris Lattner             break;
345*30fdc8d8SChris Lattner         case eSetTypeFunctionRegexp: // Breakpoint by regular expression function name
346*30fdc8d8SChris Lattner             {
347*30fdc8d8SChris Lattner                 RegularExpression regexp(m_options.m_func_regexp.c_str());
348*30fdc8d8SChris Lattner                 if (use_module)
349*30fdc8d8SChris Lattner                 {
350*30fdc8d8SChris Lattner                     for (int i = 0; i < num_modules; ++i)
351*30fdc8d8SChris Lattner                     {
352*30fdc8d8SChris Lattner                         module.SetFile(m_options.m_modules[i].c_str());
353*30fdc8d8SChris Lattner                         bp = target->CreateBreakpoint (&module, regexp).get();
354*30fdc8d8SChris Lattner                         if (bp)
355*30fdc8d8SChris Lattner                         {
356*30fdc8d8SChris Lattner                             StreamString &output_stream = result.GetOutputStream();
357*30fdc8d8SChris Lattner                             output_stream.Printf ("Breakpoint created: ");
358*30fdc8d8SChris Lattner                             bp->GetDescription(&output_stream, lldb::eDescriptionLevelBrief);
359*30fdc8d8SChris Lattner                             output_stream.EOL();
360*30fdc8d8SChris Lattner                             result.SetStatus (eReturnStatusSuccessFinishResult);
361*30fdc8d8SChris Lattner                         }
362*30fdc8d8SChris Lattner                         else
363*30fdc8d8SChris Lattner                         {
364*30fdc8d8SChris Lattner                             result.AppendErrorWithFormat("Breakpoint creation failed: No breakpoint created in module '%s'.\n",
365*30fdc8d8SChris Lattner                                                         m_options.m_modules[i].c_str());
366*30fdc8d8SChris Lattner                             result.SetStatus (eReturnStatusFailed);
367*30fdc8d8SChris Lattner                         }
368*30fdc8d8SChris Lattner                     }
369*30fdc8d8SChris Lattner                 }
370*30fdc8d8SChris Lattner                 else
371*30fdc8d8SChris Lattner                     bp = target->CreateBreakpoint (NULL, regexp).get();
372*30fdc8d8SChris Lattner             }
373*30fdc8d8SChris Lattner             break;
374*30fdc8d8SChris Lattner         default:
375*30fdc8d8SChris Lattner             break;
376*30fdc8d8SChris Lattner     }
377*30fdc8d8SChris Lattner 
378*30fdc8d8SChris Lattner     if (bp && !use_module)
379*30fdc8d8SChris Lattner     {
380*30fdc8d8SChris Lattner         StreamString &output_stream = result.GetOutputStream();
381*30fdc8d8SChris Lattner         output_stream.Printf ("Breakpoint created: ");
382*30fdc8d8SChris Lattner         bp->GetDescription(&output_stream, lldb::eDescriptionLevelBrief);
383*30fdc8d8SChris Lattner         output_stream.EOL();
384*30fdc8d8SChris Lattner         result.SetStatus (eReturnStatusSuccessFinishResult);
385*30fdc8d8SChris Lattner     }
386*30fdc8d8SChris Lattner     else if (!bp)
387*30fdc8d8SChris Lattner     {
388*30fdc8d8SChris Lattner         result.AppendError ("Breakpoint creation failed: No breakpoint created.");
389*30fdc8d8SChris Lattner         result.SetStatus (eReturnStatusFailed);
390*30fdc8d8SChris Lattner     }
391*30fdc8d8SChris Lattner 
392*30fdc8d8SChris Lattner     return result.Succeeded();
393*30fdc8d8SChris Lattner }
394*30fdc8d8SChris Lattner 
395*30fdc8d8SChris Lattner 
396*30fdc8d8SChris Lattner 
397*30fdc8d8SChris Lattner //-------------------------------------------------------------------------
398*30fdc8d8SChris Lattner // CommandObjectMultiwordBreakpoint
399*30fdc8d8SChris Lattner //-------------------------------------------------------------------------
400*30fdc8d8SChris Lattner 
401*30fdc8d8SChris Lattner CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint (CommandInterpreter *interpreter) :
402*30fdc8d8SChris Lattner     CommandObjectMultiword ("breakpoint",
403*30fdc8d8SChris Lattner                               "A set of commands for operating on breakpoints.",
404*30fdc8d8SChris Lattner                               "breakpoint <command> [<command-options>]")
405*30fdc8d8SChris Lattner {
406*30fdc8d8SChris Lattner     bool status;
407*30fdc8d8SChris Lattner 
408*30fdc8d8SChris Lattner     CommandObjectSP list_command_object (new CommandObjectBreakpointList ());
409*30fdc8d8SChris Lattner     CommandObjectSP delete_command_object (new CommandObjectBreakpointDelete ());
410*30fdc8d8SChris Lattner     CommandObjectSP enable_command_object (new CommandObjectBreakpointEnable ());
411*30fdc8d8SChris Lattner     CommandObjectSP disable_command_object (new CommandObjectBreakpointDisable ());
412*30fdc8d8SChris Lattner     CommandObjectSP set_command_object (new CommandObjectBreakpointSet ());
413*30fdc8d8SChris Lattner     CommandObjectSP command_command_object (new CommandObjectBreakpointCommand (interpreter));
414*30fdc8d8SChris Lattner 
415*30fdc8d8SChris Lattner     enable_command_object->SetCommandName("breakpoint enable");
416*30fdc8d8SChris Lattner     disable_command_object->SetCommandName("breakpoint disable");
417*30fdc8d8SChris Lattner     set_command_object->SetCommandName("breakpoint set");
418*30fdc8d8SChris Lattner     command_command_object->SetCommandName ("breakpoint command");
419*30fdc8d8SChris Lattner     list_command_object->SetCommandName ("breakpoint list");
420*30fdc8d8SChris Lattner 
421*30fdc8d8SChris Lattner     status = LoadSubCommand (list_command_object, "list", interpreter);
422*30fdc8d8SChris Lattner     status = LoadSubCommand (enable_command_object, "enable", interpreter);
423*30fdc8d8SChris Lattner     status = LoadSubCommand (disable_command_object, "disable", interpreter);
424*30fdc8d8SChris Lattner     status = LoadSubCommand (delete_command_object, "delete", interpreter);
425*30fdc8d8SChris Lattner     status = LoadSubCommand (set_command_object, "set", interpreter);
426*30fdc8d8SChris Lattner     status = LoadSubCommand (command_command_object, "command", interpreter);
427*30fdc8d8SChris Lattner }
428*30fdc8d8SChris Lattner 
429*30fdc8d8SChris Lattner CommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint ()
430*30fdc8d8SChris Lattner {
431*30fdc8d8SChris Lattner }
432*30fdc8d8SChris Lattner 
433*30fdc8d8SChris Lattner void
434*30fdc8d8SChris Lattner CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (Args &args, Target *target, CommandReturnObject &result,
435*30fdc8d8SChris Lattner                                                          BreakpointIDList *valid_ids)
436*30fdc8d8SChris Lattner {
437*30fdc8d8SChris Lattner     // args can be strings representing 1). integers (for breakpoint ids)
438*30fdc8d8SChris Lattner     //                                  2). the full breakpoint & location canonical representation
439*30fdc8d8SChris Lattner     //                                  3). the word "to" or a hyphen, representing a range (in which case there
440*30fdc8d8SChris Lattner     //                                      had *better* be an entry both before & after of one of the first two types.
441*30fdc8d8SChris Lattner 
442*30fdc8d8SChris Lattner     Args temp_args;
443*30fdc8d8SChris Lattner 
444*30fdc8d8SChris Lattner     // Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff directly from the old ARGS to
445*30fdc8d8SChris Lattner     // the new TEMP_ARGS.  Do not copy breakpoint id range strings over; instead generate a list of strings for
446*30fdc8d8SChris Lattner     // all the breakpoint ids in the range, and shove all of those breakpoint id strings into TEMP_ARGS.
447*30fdc8d8SChris Lattner 
448*30fdc8d8SChris Lattner     BreakpointIDList::FindAndReplaceIDRanges (args, target, result, temp_args);
449*30fdc8d8SChris Lattner 
450*30fdc8d8SChris Lattner     // NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual BreakpointIDList:
451*30fdc8d8SChris Lattner 
452*30fdc8d8SChris Lattner     valid_ids->InsertStringArray ((const char **) temp_args.GetArgumentVector(), temp_args.GetArgumentCount(), result);
453*30fdc8d8SChris Lattner 
454*30fdc8d8SChris Lattner     // At this point,  all of the breakpoint ids that the user passed in have been converted to breakpoint IDs
455*30fdc8d8SChris Lattner     // and put into valid_ids.
456*30fdc8d8SChris Lattner 
457*30fdc8d8SChris Lattner     if (result.Succeeded())
458*30fdc8d8SChris Lattner     {
459*30fdc8d8SChris Lattner         // Now that we've converted everything from args into a list of breakpoint ids, go through our tentative list
460*30fdc8d8SChris Lattner         // of breakpoint id's and verify that they correspond to valid/currently set breakpoints.
461*30fdc8d8SChris Lattner 
462*30fdc8d8SChris Lattner         for (int i = 0; i < valid_ids->Size(); ++i)
463*30fdc8d8SChris Lattner         {
464*30fdc8d8SChris Lattner             BreakpointID cur_bp_id = valid_ids->GetBreakpointIDAtIndex (i);
465*30fdc8d8SChris Lattner             Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
466*30fdc8d8SChris Lattner             if (breakpoint != NULL)
467*30fdc8d8SChris Lattner             {
468*30fdc8d8SChris Lattner                 int num_locations = breakpoint->GetNumLocations();
469*30fdc8d8SChris Lattner                 if (cur_bp_id.GetLocationID() > num_locations)
470*30fdc8d8SChris Lattner                 {
471*30fdc8d8SChris Lattner                     StreamString id_str;
472*30fdc8d8SChris Lattner                     BreakpointID::GetCanonicalReference (&id_str, cur_bp_id.GetBreakpointID(),
473*30fdc8d8SChris Lattner                                                            cur_bp_id.GetLocationID());
474*30fdc8d8SChris Lattner                     i = valid_ids->Size() + 1;
475*30fdc8d8SChris Lattner                     result.AppendErrorWithFormat ("'%s' is not a currently valid breakpoint/location id.\n",
476*30fdc8d8SChris Lattner                                                  id_str.GetData());
477*30fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusFailed);
478*30fdc8d8SChris Lattner                 }
479*30fdc8d8SChris Lattner             }
480*30fdc8d8SChris Lattner             else
481*30fdc8d8SChris Lattner             {
482*30fdc8d8SChris Lattner                 i = valid_ids->Size() + 1;
483*30fdc8d8SChris Lattner                 result.AppendErrorWithFormat ("'%d' is not a currently valid breakpoint id.\n", cur_bp_id.GetBreakpointID());
484*30fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
485*30fdc8d8SChris Lattner             }
486*30fdc8d8SChris Lattner         }
487*30fdc8d8SChris Lattner     }
488*30fdc8d8SChris Lattner }
489*30fdc8d8SChris Lattner 
490*30fdc8d8SChris Lattner //-------------------------------------------------------------------------
491*30fdc8d8SChris Lattner // CommandObjectBreakpointList::Options
492*30fdc8d8SChris Lattner //-------------------------------------------------------------------------
493*30fdc8d8SChris Lattner 
494*30fdc8d8SChris Lattner CommandObjectBreakpointList::CommandOptions::CommandOptions() :
495*30fdc8d8SChris Lattner     Options (),
496*30fdc8d8SChris Lattner     m_level (lldb::eDescriptionLevelFull)  // Breakpoint List defaults to brief descriptions
497*30fdc8d8SChris Lattner {
498*30fdc8d8SChris Lattner     BuildValidOptionSets();
499*30fdc8d8SChris Lattner }
500*30fdc8d8SChris Lattner 
501*30fdc8d8SChris Lattner CommandObjectBreakpointList::CommandOptions::~CommandOptions ()
502*30fdc8d8SChris Lattner {
503*30fdc8d8SChris Lattner }
504*30fdc8d8SChris Lattner 
505*30fdc8d8SChris Lattner lldb::OptionDefinition
506*30fdc8d8SChris Lattner CommandObjectBreakpointList::CommandOptions::g_option_table[] =
507*30fdc8d8SChris Lattner {
508*30fdc8d8SChris Lattner     { 0, false, "brief",    'b', no_argument, NULL, 0, NULL,
509*30fdc8d8SChris Lattner         "Give a brief description of the breakpoint (no location info)."},
510*30fdc8d8SChris Lattner 
511*30fdc8d8SChris Lattner     // FIXME: We need to add an "internal" command, and then add this sort of thing to it.
512*30fdc8d8SChris Lattner     // But I need to see it for now, and don't want to wait.
513*30fdc8d8SChris Lattner     { 0, false, "internal", 'i', no_argument, NULL, 0, NULL,
514*30fdc8d8SChris Lattner         "Show debugger internal breakpoints" },
515*30fdc8d8SChris Lattner 
516*30fdc8d8SChris Lattner     { 1, false, "full",    'f', no_argument, NULL, 0, NULL,
517*30fdc8d8SChris Lattner         "Give a full description of the breakpoint and its locations."},
518*30fdc8d8SChris Lattner     // DITTO FIXME
519*30fdc8d8SChris Lattner     { 1, false, "internal", 'i', no_argument, NULL, 0, NULL,
520*30fdc8d8SChris Lattner         "Show debugger internal breakpoints" },
521*30fdc8d8SChris Lattner 
522*30fdc8d8SChris Lattner     { 2, false, "verbose", 'v', no_argument, NULL, 0, NULL,
523*30fdc8d8SChris Lattner         "Explain everything we know about the breakpoint (for debugging debugger bugs)." },
524*30fdc8d8SChris Lattner     // DITTO FIXME
525*30fdc8d8SChris Lattner     { 2, false, "internal", 'i', no_argument, NULL, 0, NULL,
526*30fdc8d8SChris Lattner         "Show debugger internal breakpoints" },
527*30fdc8d8SChris Lattner 
528*30fdc8d8SChris Lattner     { 0, false, NULL, 0, 0, NULL, 0, NULL, NULL }
529*30fdc8d8SChris Lattner };
530*30fdc8d8SChris Lattner 
531*30fdc8d8SChris Lattner const lldb::OptionDefinition*
532*30fdc8d8SChris Lattner CommandObjectBreakpointList::CommandOptions::GetDefinitions ()
533*30fdc8d8SChris Lattner {
534*30fdc8d8SChris Lattner     return g_option_table;
535*30fdc8d8SChris Lattner }
536*30fdc8d8SChris Lattner 
537*30fdc8d8SChris Lattner Error
538*30fdc8d8SChris Lattner CommandObjectBreakpointList::CommandOptions::SetOptionValue (int option_idx, const char *option_arg)
539*30fdc8d8SChris Lattner {
540*30fdc8d8SChris Lattner     Error error;
541*30fdc8d8SChris Lattner     char short_option = (char) m_getopt_table[option_idx].val;
542*30fdc8d8SChris Lattner 
543*30fdc8d8SChris Lattner     switch (short_option)
544*30fdc8d8SChris Lattner     {
545*30fdc8d8SChris Lattner         case 'b':
546*30fdc8d8SChris Lattner             m_level = lldb::eDescriptionLevelBrief;
547*30fdc8d8SChris Lattner             break;
548*30fdc8d8SChris Lattner         case 'f':
549*30fdc8d8SChris Lattner             m_level = lldb::eDescriptionLevelFull;
550*30fdc8d8SChris Lattner             break;
551*30fdc8d8SChris Lattner         case 'v':
552*30fdc8d8SChris Lattner             m_level = lldb::eDescriptionLevelVerbose;
553*30fdc8d8SChris Lattner             break;
554*30fdc8d8SChris Lattner         case 'i':
555*30fdc8d8SChris Lattner             m_internal = true;
556*30fdc8d8SChris Lattner             break;
557*30fdc8d8SChris Lattner         default:
558*30fdc8d8SChris Lattner             error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
559*30fdc8d8SChris Lattner             break;
560*30fdc8d8SChris Lattner     }
561*30fdc8d8SChris Lattner 
562*30fdc8d8SChris Lattner     return error;
563*30fdc8d8SChris Lattner }
564*30fdc8d8SChris Lattner 
565*30fdc8d8SChris Lattner void
566*30fdc8d8SChris Lattner CommandObjectBreakpointList::CommandOptions::ResetOptionValues ()
567*30fdc8d8SChris Lattner {
568*30fdc8d8SChris Lattner     Options::ResetOptionValues();
569*30fdc8d8SChris Lattner 
570*30fdc8d8SChris Lattner     m_level = lldb::eDescriptionLevelFull;
571*30fdc8d8SChris Lattner     m_internal = false;
572*30fdc8d8SChris Lattner }
573*30fdc8d8SChris Lattner 
574*30fdc8d8SChris Lattner //-------------------------------------------------------------------------
575*30fdc8d8SChris Lattner // CommandObjectBreakpointList
576*30fdc8d8SChris Lattner //-------------------------------------------------------------------------
577*30fdc8d8SChris Lattner 
578*30fdc8d8SChris Lattner CommandObjectBreakpointList::CommandObjectBreakpointList () :
579*30fdc8d8SChris Lattner     CommandObject ("breakpoint list",
580*30fdc8d8SChris Lattner                      "List some or all breakpoints at configurable levels of detail.",
581*30fdc8d8SChris Lattner                      "breakpoint list [<breakpoint-id>]")
582*30fdc8d8SChris Lattner {
583*30fdc8d8SChris Lattner }
584*30fdc8d8SChris Lattner 
585*30fdc8d8SChris Lattner CommandObjectBreakpointList::~CommandObjectBreakpointList ()
586*30fdc8d8SChris Lattner {
587*30fdc8d8SChris Lattner }
588*30fdc8d8SChris Lattner 
589*30fdc8d8SChris Lattner Options *
590*30fdc8d8SChris Lattner CommandObjectBreakpointList::GetOptions ()
591*30fdc8d8SChris Lattner {
592*30fdc8d8SChris Lattner     return &m_options;
593*30fdc8d8SChris Lattner }
594*30fdc8d8SChris Lattner 
595*30fdc8d8SChris Lattner bool
596*30fdc8d8SChris Lattner CommandObjectBreakpointList::Execute
597*30fdc8d8SChris Lattner (
598*30fdc8d8SChris Lattner     Args& args,
599*30fdc8d8SChris Lattner     CommandContext *context,
600*30fdc8d8SChris Lattner     CommandInterpreter *interpreter,
601*30fdc8d8SChris Lattner     CommandReturnObject &result
602*30fdc8d8SChris Lattner )
603*30fdc8d8SChris Lattner {
604*30fdc8d8SChris Lattner     Target *target = context->GetTarget();
605*30fdc8d8SChris Lattner     if (target == NULL)
606*30fdc8d8SChris Lattner     {
607*30fdc8d8SChris Lattner         result.AppendError ("Invalid target, set executable file using 'file' command.");
608*30fdc8d8SChris Lattner         result.SetStatus (eReturnStatusSuccessFinishNoResult);
609*30fdc8d8SChris Lattner         return true;
610*30fdc8d8SChris Lattner     }
611*30fdc8d8SChris Lattner 
612*30fdc8d8SChris Lattner     const BreakpointList &breakpoints = target->GetBreakpointList(m_options.m_internal);
613*30fdc8d8SChris Lattner     size_t num_breakpoints = breakpoints.GetSize();
614*30fdc8d8SChris Lattner 
615*30fdc8d8SChris Lattner     if (num_breakpoints == 0)
616*30fdc8d8SChris Lattner     {
617*30fdc8d8SChris Lattner         result.AppendMessage ("No breakpoints currently set.");
618*30fdc8d8SChris Lattner         result.SetStatus (eReturnStatusSuccessFinishNoResult);
619*30fdc8d8SChris Lattner         return true;
620*30fdc8d8SChris Lattner     }
621*30fdc8d8SChris Lattner 
622*30fdc8d8SChris Lattner     StreamString &output_stream = result.GetOutputStream();
623*30fdc8d8SChris Lattner 
624*30fdc8d8SChris Lattner     if (args.GetArgumentCount() == 0)
625*30fdc8d8SChris Lattner     {
626*30fdc8d8SChris Lattner         // No breakpoint selected; show info about all currently set breakpoints.
627*30fdc8d8SChris Lattner         result.AppendMessage ("Current breakpoints:");
628*30fdc8d8SChris Lattner         for (int i = 0; i < num_breakpoints; ++i)
629*30fdc8d8SChris Lattner         {
630*30fdc8d8SChris Lattner             Breakpoint *breakpoint = breakpoints.GetBreakpointByIndex (i).get();
631*30fdc8d8SChris Lattner             AddBreakpointDescription (context, &output_stream, breakpoint, m_options.m_level);
632*30fdc8d8SChris Lattner         }
633*30fdc8d8SChris Lattner         result.SetStatus (eReturnStatusSuccessFinishNoResult);
634*30fdc8d8SChris Lattner     }
635*30fdc8d8SChris Lattner     else
636*30fdc8d8SChris Lattner     {
637*30fdc8d8SChris Lattner         // Particular breakpoints selected; show info about that breakpoint.
638*30fdc8d8SChris Lattner         BreakpointIDList valid_bp_ids;
639*30fdc8d8SChris Lattner         CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (args, target, result, &valid_bp_ids);
640*30fdc8d8SChris Lattner 
641*30fdc8d8SChris Lattner         if (result.Succeeded())
642*30fdc8d8SChris Lattner         {
643*30fdc8d8SChris Lattner             for (int i = 0; i < valid_bp_ids.Size(); ++i)
644*30fdc8d8SChris Lattner             {
645*30fdc8d8SChris Lattner                 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
646*30fdc8d8SChris Lattner                 Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
647*30fdc8d8SChris Lattner                 AddBreakpointDescription (context, &output_stream, breakpoint, m_options.m_level);
648*30fdc8d8SChris Lattner             }
649*30fdc8d8SChris Lattner             result.SetStatus (eReturnStatusSuccessFinishNoResult);
650*30fdc8d8SChris Lattner         }
651*30fdc8d8SChris Lattner         else
652*30fdc8d8SChris Lattner         {
653*30fdc8d8SChris Lattner             result.AppendError ("Invalid breakpoint id.");
654*30fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
655*30fdc8d8SChris Lattner         }
656*30fdc8d8SChris Lattner     }
657*30fdc8d8SChris Lattner 
658*30fdc8d8SChris Lattner     return result.Succeeded();
659*30fdc8d8SChris Lattner }
660*30fdc8d8SChris Lattner 
661*30fdc8d8SChris Lattner //-------------------------------------------------------------------------
662*30fdc8d8SChris Lattner // CommandObjectBreakpointEnable
663*30fdc8d8SChris Lattner //-------------------------------------------------------------------------
664*30fdc8d8SChris Lattner 
665*30fdc8d8SChris Lattner CommandObjectBreakpointEnable::CommandObjectBreakpointEnable () :
666*30fdc8d8SChris Lattner     CommandObject ("enable",
667*30fdc8d8SChris Lattner                      "Enables the specified disabled breakpoint(s).  If no breakpoints are specified, enables all of them.",
668*30fdc8d8SChris Lattner                      "breakpoint enable [<breakpoint-id> | <breakpoint-id-list>]")
669*30fdc8d8SChris Lattner {
670*30fdc8d8SChris Lattner     // This command object can either be called via 'enable' or 'breakpoint enable'.  Because it has two different
671*30fdc8d8SChris Lattner     // potential invocation methods, we need to be a little tricky about generating the syntax string.
672*30fdc8d8SChris Lattner     //StreamString tmp_string;
673*30fdc8d8SChris Lattner     //tmp_string.Printf ("%s <breakpoint-id>", GetCommandName());
674*30fdc8d8SChris Lattner     //m_cmd_syntax.assign (tmp_string.GetData(), tmp_string.GetSize());
675*30fdc8d8SChris Lattner }
676*30fdc8d8SChris Lattner 
677*30fdc8d8SChris Lattner 
678*30fdc8d8SChris Lattner CommandObjectBreakpointEnable::~CommandObjectBreakpointEnable ()
679*30fdc8d8SChris Lattner {
680*30fdc8d8SChris Lattner }
681*30fdc8d8SChris Lattner 
682*30fdc8d8SChris Lattner 
683*30fdc8d8SChris Lattner bool
684*30fdc8d8SChris Lattner CommandObjectBreakpointEnable::Execute (Args& args, CommandContext *context,
685*30fdc8d8SChris Lattner                                           CommandInterpreter *interpreter, CommandReturnObject &result)
686*30fdc8d8SChris Lattner {
687*30fdc8d8SChris Lattner     Target *target = context->GetTarget();
688*30fdc8d8SChris Lattner     if (target == NULL)
689*30fdc8d8SChris Lattner     {
690*30fdc8d8SChris Lattner         result.AppendError ("Invalid target, set executable file using 'file' command.");
691*30fdc8d8SChris Lattner         result.SetStatus (eReturnStatusFailed);
692*30fdc8d8SChris Lattner         return false;
693*30fdc8d8SChris Lattner     }
694*30fdc8d8SChris Lattner 
695*30fdc8d8SChris Lattner     const BreakpointList &breakpoints = target->GetBreakpointList();
696*30fdc8d8SChris Lattner     size_t num_breakpoints = breakpoints.GetSize();
697*30fdc8d8SChris Lattner 
698*30fdc8d8SChris Lattner     if (num_breakpoints == 0)
699*30fdc8d8SChris Lattner     {
700*30fdc8d8SChris Lattner         result.AppendError ("No breakpoints exist to be enabled.");
701*30fdc8d8SChris Lattner         result.SetStatus (eReturnStatusFailed);
702*30fdc8d8SChris Lattner         return false;
703*30fdc8d8SChris Lattner     }
704*30fdc8d8SChris Lattner 
705*30fdc8d8SChris Lattner     if (args.GetArgumentCount() == 0)
706*30fdc8d8SChris Lattner     {
707*30fdc8d8SChris Lattner         // No breakpoint selected; enable all currently set breakpoints.
708*30fdc8d8SChris Lattner         target->EnableAllBreakpoints ();
709*30fdc8d8SChris Lattner         result.AppendMessageWithFormat ("All breakpoints enabled. (%d breakpoints)\n", num_breakpoints);
710*30fdc8d8SChris Lattner         result.SetStatus (eReturnStatusSuccessFinishNoResult);
711*30fdc8d8SChris Lattner     }
712*30fdc8d8SChris Lattner     else
713*30fdc8d8SChris Lattner     {
714*30fdc8d8SChris Lattner         // Particular breakpoint selected; enable that breakpoint.
715*30fdc8d8SChris Lattner         BreakpointIDList valid_bp_ids;
716*30fdc8d8SChris Lattner         CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (args, target, result, &valid_bp_ids);
717*30fdc8d8SChris Lattner 
718*30fdc8d8SChris Lattner         if (result.Succeeded())
719*30fdc8d8SChris Lattner         {
720*30fdc8d8SChris Lattner             int enable_count = 0;
721*30fdc8d8SChris Lattner             int loc_count = 0;
722*30fdc8d8SChris Lattner             for (int i = 0; i < valid_bp_ids.Size(); ++i)
723*30fdc8d8SChris Lattner             {
724*30fdc8d8SChris Lattner                 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
725*30fdc8d8SChris Lattner 
726*30fdc8d8SChris Lattner                 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
727*30fdc8d8SChris Lattner                 {
728*30fdc8d8SChris Lattner                     Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
729*30fdc8d8SChris Lattner                     if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
730*30fdc8d8SChris Lattner                     {
731*30fdc8d8SChris Lattner                         BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
732*30fdc8d8SChris Lattner                         if (location)
733*30fdc8d8SChris Lattner                         {
734*30fdc8d8SChris Lattner                             location->SetEnabled (true);
735*30fdc8d8SChris Lattner                             breakpoint->SetEnabled (true);
736*30fdc8d8SChris Lattner                             ++loc_count;
737*30fdc8d8SChris Lattner                         }
738*30fdc8d8SChris Lattner                     }
739*30fdc8d8SChris Lattner                     else
740*30fdc8d8SChris Lattner                     {
741*30fdc8d8SChris Lattner                         target->EnableBreakpointByID (cur_bp_id.GetBreakpointID());
742*30fdc8d8SChris Lattner                         ++enable_count;
743*30fdc8d8SChris Lattner 
744*30fdc8d8SChris Lattner                         int num_locations = breakpoint->GetNumLocations ();
745*30fdc8d8SChris Lattner                         for (int j = 0; j < num_locations; ++j)
746*30fdc8d8SChris Lattner                         {
747*30fdc8d8SChris Lattner                             BreakpointLocation *cur_loc = breakpoint->GetLocationAtIndex(j).get();
748*30fdc8d8SChris Lattner                             if (cur_loc)
749*30fdc8d8SChris Lattner                                 cur_loc->SetEnabled (true);
750*30fdc8d8SChris Lattner                         }
751*30fdc8d8SChris Lattner                     }
752*30fdc8d8SChris Lattner                 }
753*30fdc8d8SChris Lattner             }
754*30fdc8d8SChris Lattner             result.AppendMessageWithFormat ("%d breakpoints enabled.\n", enable_count + loc_count);
755*30fdc8d8SChris Lattner             result.SetStatus (eReturnStatusSuccessFinishNoResult);
756*30fdc8d8SChris Lattner         }
757*30fdc8d8SChris Lattner     }
758*30fdc8d8SChris Lattner 
759*30fdc8d8SChris Lattner     return result.Succeeded();
760*30fdc8d8SChris Lattner }
761*30fdc8d8SChris Lattner 
762*30fdc8d8SChris Lattner //-------------------------------------------------------------------------
763*30fdc8d8SChris Lattner // CommandObjectBreakpointDisable
764*30fdc8d8SChris Lattner //-------------------------------------------------------------------------
765*30fdc8d8SChris Lattner 
766*30fdc8d8SChris Lattner CommandObjectBreakpointDisable::CommandObjectBreakpointDisable () :
767*30fdc8d8SChris Lattner     CommandObject ("disable",
768*30fdc8d8SChris Lattner                    "Disables the specified breakpoint(s) without removing it/them.  If no breakpoints are specified, disables them all.",
769*30fdc8d8SChris Lattner                    "disable [<breakpoint-id> | <breakpoint-id-list>]")
770*30fdc8d8SChris Lattner {
771*30fdc8d8SChris Lattner     // This command object can either be called via 'enable' or 'breakpoint enable'.  Because it has two different
772*30fdc8d8SChris Lattner     // potential invocation methods, we need to be a little tricky about generating the syntax string.
773*30fdc8d8SChris Lattner     //StreamString tmp_string;
774*30fdc8d8SChris Lattner     //tmp_string.Printf ("%s <breakpoint-id>", GetCommandName());
775*30fdc8d8SChris Lattner     //m_cmd_syntax.assign(tmp_string.GetData(), tmp_string.GetSize());
776*30fdc8d8SChris Lattner }
777*30fdc8d8SChris Lattner 
778*30fdc8d8SChris Lattner CommandObjectBreakpointDisable::~CommandObjectBreakpointDisable ()
779*30fdc8d8SChris Lattner {
780*30fdc8d8SChris Lattner }
781*30fdc8d8SChris Lattner 
782*30fdc8d8SChris Lattner bool
783*30fdc8d8SChris Lattner CommandObjectBreakpointDisable::Execute (Args& args, CommandContext *context,
784*30fdc8d8SChris Lattner                                            CommandInterpreter *interpreter, CommandReturnObject &result)
785*30fdc8d8SChris Lattner {
786*30fdc8d8SChris Lattner     Target *target = context->GetTarget();
787*30fdc8d8SChris Lattner     if (target == NULL)
788*30fdc8d8SChris Lattner     {
789*30fdc8d8SChris Lattner         result.AppendError ("Invalid target, set executable file using 'file' command.");
790*30fdc8d8SChris Lattner         result.SetStatus (eReturnStatusFailed);
791*30fdc8d8SChris Lattner         return false;
792*30fdc8d8SChris Lattner     }
793*30fdc8d8SChris Lattner 
794*30fdc8d8SChris Lattner     const BreakpointList &breakpoints = target->GetBreakpointList();
795*30fdc8d8SChris Lattner     size_t num_breakpoints = breakpoints.GetSize();
796*30fdc8d8SChris Lattner 
797*30fdc8d8SChris Lattner     if (num_breakpoints == 0)
798*30fdc8d8SChris Lattner     {
799*30fdc8d8SChris Lattner         result.AppendError ("No breakpoints exist to be disabled.");
800*30fdc8d8SChris Lattner         result.SetStatus (eReturnStatusFailed);
801*30fdc8d8SChris Lattner         return false;
802*30fdc8d8SChris Lattner     }
803*30fdc8d8SChris Lattner 
804*30fdc8d8SChris Lattner     if (args.GetArgumentCount() == 0)
805*30fdc8d8SChris Lattner     {
806*30fdc8d8SChris Lattner         // No breakpoint selected; disable all currently set breakpoints.
807*30fdc8d8SChris Lattner         target->DisableAllBreakpoints ();
808*30fdc8d8SChris Lattner         result.AppendMessageWithFormat ("All breakpoints disabled. (%d breakpoints)\n", num_breakpoints);
809*30fdc8d8SChris Lattner         result.SetStatus (eReturnStatusSuccessFinishNoResult);
810*30fdc8d8SChris Lattner     }
811*30fdc8d8SChris Lattner     else
812*30fdc8d8SChris Lattner     {
813*30fdc8d8SChris Lattner         // Particular breakpoint selected; disable that breakpoint.
814*30fdc8d8SChris Lattner         BreakpointIDList valid_bp_ids;
815*30fdc8d8SChris Lattner 
816*30fdc8d8SChris Lattner         CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (args, target, result, &valid_bp_ids);
817*30fdc8d8SChris Lattner 
818*30fdc8d8SChris Lattner         if (result.Succeeded())
819*30fdc8d8SChris Lattner         {
820*30fdc8d8SChris Lattner             int disable_count = 0;
821*30fdc8d8SChris Lattner             int loc_count = 0;
822*30fdc8d8SChris Lattner             for (int i = 0; i < valid_bp_ids.Size(); ++i)
823*30fdc8d8SChris Lattner             {
824*30fdc8d8SChris Lattner                 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
825*30fdc8d8SChris Lattner 
826*30fdc8d8SChris Lattner                 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
827*30fdc8d8SChris Lattner                 {
828*30fdc8d8SChris Lattner                     Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
829*30fdc8d8SChris Lattner                     if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
830*30fdc8d8SChris Lattner                     {
831*30fdc8d8SChris Lattner                         BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
832*30fdc8d8SChris Lattner                         if (location)
833*30fdc8d8SChris Lattner                         {
834*30fdc8d8SChris Lattner                             location->SetEnabled (false);
835*30fdc8d8SChris Lattner                             ++loc_count;
836*30fdc8d8SChris Lattner                         }
837*30fdc8d8SChris Lattner                     }
838*30fdc8d8SChris Lattner                     else
839*30fdc8d8SChris Lattner                     {
840*30fdc8d8SChris Lattner                         target->DisableBreakpointByID (cur_bp_id.GetBreakpointID());
841*30fdc8d8SChris Lattner                         ++disable_count;
842*30fdc8d8SChris Lattner 
843*30fdc8d8SChris Lattner                         int num_locations = breakpoint->GetNumLocations();
844*30fdc8d8SChris Lattner                         for (int j = 0; j < num_locations; ++j)
845*30fdc8d8SChris Lattner                         {
846*30fdc8d8SChris Lattner                             BreakpointLocation *cur_loc = breakpoint->GetLocationAtIndex(j).get();
847*30fdc8d8SChris Lattner                             if (cur_loc)
848*30fdc8d8SChris Lattner                                 cur_loc->SetEnabled (false);
849*30fdc8d8SChris Lattner                         }
850*30fdc8d8SChris Lattner                     }
851*30fdc8d8SChris Lattner                 }
852*30fdc8d8SChris Lattner             }
853*30fdc8d8SChris Lattner             result.AppendMessageWithFormat ("%d breakpoints disabled.\n", disable_count + loc_count);
854*30fdc8d8SChris Lattner             result.SetStatus (eReturnStatusSuccessFinishNoResult);
855*30fdc8d8SChris Lattner         }
856*30fdc8d8SChris Lattner     }
857*30fdc8d8SChris Lattner 
858*30fdc8d8SChris Lattner     return result.Succeeded();
859*30fdc8d8SChris Lattner }
860*30fdc8d8SChris Lattner 
861*30fdc8d8SChris Lattner //-------------------------------------------------------------------------
862*30fdc8d8SChris Lattner // CommandObjectBreakpointDelete
863*30fdc8d8SChris Lattner //-------------------------------------------------------------------------
864*30fdc8d8SChris Lattner 
865*30fdc8d8SChris Lattner CommandObjectBreakpointDelete::CommandObjectBreakpointDelete() :
866*30fdc8d8SChris Lattner     CommandObject ("breakpoint delete",
867*30fdc8d8SChris Lattner                    "Delete the specified breakpoint(s).  If no breakpoints are specified, deletes them all.",
868*30fdc8d8SChris Lattner                    "breakpoint delete [<breakpoint-id> | <breakpoint-id-list>]")
869*30fdc8d8SChris Lattner {
870*30fdc8d8SChris Lattner }
871*30fdc8d8SChris Lattner 
872*30fdc8d8SChris Lattner 
873*30fdc8d8SChris Lattner CommandObjectBreakpointDelete::~CommandObjectBreakpointDelete ()
874*30fdc8d8SChris Lattner {
875*30fdc8d8SChris Lattner }
876*30fdc8d8SChris Lattner 
877*30fdc8d8SChris Lattner bool
878*30fdc8d8SChris Lattner CommandObjectBreakpointDelete::Execute (Args& args, CommandContext *context,
879*30fdc8d8SChris Lattner                                           CommandInterpreter *interpreter, CommandReturnObject &result)
880*30fdc8d8SChris Lattner {
881*30fdc8d8SChris Lattner     Target *target = context->GetTarget();
882*30fdc8d8SChris Lattner     if (target == NULL)
883*30fdc8d8SChris Lattner     {
884*30fdc8d8SChris Lattner         result.AppendError ("Invalid target, set executable file using 'file' command.");
885*30fdc8d8SChris Lattner         result.SetStatus (eReturnStatusFailed);
886*30fdc8d8SChris Lattner         return false;
887*30fdc8d8SChris Lattner     }
888*30fdc8d8SChris Lattner 
889*30fdc8d8SChris Lattner     const BreakpointList &breakpoints = target->GetBreakpointList();
890*30fdc8d8SChris Lattner     size_t num_breakpoints = breakpoints.GetSize();
891*30fdc8d8SChris Lattner 
892*30fdc8d8SChris Lattner     if (num_breakpoints == 0)
893*30fdc8d8SChris Lattner     {
894*30fdc8d8SChris Lattner         result.AppendError ("No breakpoints exist to be deleted.");
895*30fdc8d8SChris Lattner         result.SetStatus (eReturnStatusFailed);
896*30fdc8d8SChris Lattner         return false;
897*30fdc8d8SChris Lattner     }
898*30fdc8d8SChris Lattner 
899*30fdc8d8SChris Lattner     if (args.GetArgumentCount() == 0)
900*30fdc8d8SChris Lattner     {
901*30fdc8d8SChris Lattner         // No breakpoint selected; disable all currently set breakpoints.
902*30fdc8d8SChris Lattner         if (args.GetArgumentCount() != 0)
903*30fdc8d8SChris Lattner         {
904*30fdc8d8SChris Lattner             result.AppendErrorWithFormat ("Specify breakpoints to delete with the -i option.\n");
905*30fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
906*30fdc8d8SChris Lattner             return false;
907*30fdc8d8SChris Lattner         }
908*30fdc8d8SChris Lattner 
909*30fdc8d8SChris Lattner         target->RemoveAllBreakpoints ();
910*30fdc8d8SChris Lattner         result.AppendMessageWithFormat ("All breakpoints removed. (%d breakpoints)\n", num_breakpoints);
911*30fdc8d8SChris Lattner         result.SetStatus (eReturnStatusSuccessFinishNoResult);
912*30fdc8d8SChris Lattner     }
913*30fdc8d8SChris Lattner     else
914*30fdc8d8SChris Lattner     {
915*30fdc8d8SChris Lattner         // Particular breakpoint selected; disable that breakpoint.
916*30fdc8d8SChris Lattner         BreakpointIDList valid_bp_ids;
917*30fdc8d8SChris Lattner         CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (args, target, result, &valid_bp_ids);
918*30fdc8d8SChris Lattner 
919*30fdc8d8SChris Lattner         if (result.Succeeded())
920*30fdc8d8SChris Lattner         {
921*30fdc8d8SChris Lattner             int delete_count = 0;
922*30fdc8d8SChris Lattner             int disable_count = 0;
923*30fdc8d8SChris Lattner             for (int i = 0; i < valid_bp_ids.Size(); ++i)
924*30fdc8d8SChris Lattner             {
925*30fdc8d8SChris Lattner                 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
926*30fdc8d8SChris Lattner 
927*30fdc8d8SChris Lattner                 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
928*30fdc8d8SChris Lattner                 {
929*30fdc8d8SChris Lattner                     if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
930*30fdc8d8SChris Lattner                     {
931*30fdc8d8SChris Lattner                         Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
932*30fdc8d8SChris Lattner                         BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
933*30fdc8d8SChris Lattner                         // It makes no sense to try to delete individual locations, so we disable them instead.
934*30fdc8d8SChris Lattner                         if (location)
935*30fdc8d8SChris Lattner                         {
936*30fdc8d8SChris Lattner                             location->SetEnabled (false);
937*30fdc8d8SChris Lattner                             ++disable_count;
938*30fdc8d8SChris Lattner                         }
939*30fdc8d8SChris Lattner                     }
940*30fdc8d8SChris Lattner                     else
941*30fdc8d8SChris Lattner                     {
942*30fdc8d8SChris Lattner                         target->RemoveBreakpointByID (cur_bp_id.GetBreakpointID());
943*30fdc8d8SChris Lattner                         ++delete_count;
944*30fdc8d8SChris Lattner                     }
945*30fdc8d8SChris Lattner                 }
946*30fdc8d8SChris Lattner             }
947*30fdc8d8SChris Lattner             result.AppendMessageWithFormat ("%d breakpoints deleted; %d breakpoint locations disabled.\n",
948*30fdc8d8SChris Lattner                                            delete_count, disable_count);
949*30fdc8d8SChris Lattner             result.SetStatus (eReturnStatusSuccessFinishNoResult);
950*30fdc8d8SChris Lattner         }
951*30fdc8d8SChris Lattner     }
952*30fdc8d8SChris Lattner     return result.Succeeded();
953*30fdc8d8SChris Lattner }
954