blob: 15c9fee8d43c232f18a4e68fa49534dfde372cf2 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- CommandObjectBreakpointCommand.cpp ----------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10// C Includes
11// C++ Includes
Eugene Zelenkoc8ecc2a2016-02-19 19:33:46 +000012// Other libraries and framework includes
13// Project includes
Chris Lattner30fdc8d2010-06-08 16:52:24 +000014#include "CommandObjectBreakpointCommand.h"
15#include "CommandObjectBreakpoint.h"
Greg Clayton44d93782014-01-27 23:43:24 +000016#include "lldb/Core/IOHandler.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000017#include "lldb/Interpreter/CommandInterpreter.h"
18#include "lldb/Interpreter/CommandReturnObject.h"
19#include "lldb/Target/Target.h"
20#include "lldb/Target/Thread.h"
21#include "lldb/Breakpoint/BreakpointIDList.h"
22#include "lldb/Breakpoint/Breakpoint.h"
23#include "lldb/Breakpoint/BreakpointLocation.h"
24#include "lldb/Breakpoint/StoppointCallbackContext.h"
25#include "lldb/Core/State.h"
26
27using namespace lldb;
28using namespace lldb_private;
29
30//-------------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +000031// CommandObjectBreakpointCommandAdd
32//-------------------------------------------------------------------------
33
Greg Clayton44d93782014-01-27 23:43:24 +000034class CommandObjectBreakpointCommandAdd :
35 public CommandObjectParsed,
36 public IOHandlerDelegateMultiline
Chris Lattner30fdc8d2010-06-08 16:52:24 +000037{
Jim Ingham5a988412012-06-08 21:56:10 +000038public:
Kate Stone7428a182016-07-14 22:03:10 +000039 CommandObjectBreakpointCommandAdd(CommandInterpreter &interpreter)
40 : CommandObjectParsed(interpreter, "add",
41 "Add LLDB commands to a breakpoint, to be executed whenever the breakpoint is hit."
42 " If no breakpoint is specified, adds the commands to the last created breakpoint.",
43 nullptr),
44 IOHandlerDelegateMultiline("DONE", IOHandlerDelegate::Completion::LLDBCommand),
Todd Fialae1cfbc72016-08-11 23:51:28 +000045 m_options()
Jim Ingham5a988412012-06-08 21:56:10 +000046 {
47 SetHelpLong (
Kate Stoneea671fb2015-07-14 05:48:36 +000048R"(
49General information about entering breakpoint commands
50------------------------------------------------------
51
52)" "This command will prompt for commands to be executed when the specified \
53breakpoint is hit. Each command is typed on its own line following the '> ' \
54prompt until 'DONE' is entered." R"(
55
56)" "Syntactic errors may not be detected when initially entered, and many \
57malformed commands can silently fail when executed. If your breakpoint commands \
58do not appear to be executing, double-check the command syntax." R"(
59
60)" "Note: You may enter any debugger command exactly as you would at the debugger \
61prompt. There is no limit to the number of commands supplied, but do NOT enter \
62more than one command per line." R"(
63
64Special information about PYTHON breakpoint commands
65----------------------------------------------------
66
67)" "You may enter either one or more lines of Python, including function \
68definitions or calls to functions that will have been imported by the time \
69the code executes. Single line breakpoint commands will be interpreted 'as is' \
70when the breakpoint is hit. Multiple lines of Python will be wrapped in a \
71generated function, and a call to the function will be attached to the breakpoint." R"(
72
73This auto-generated function is passed in three arguments:
74
75 frame: an lldb.SBFrame object for the frame which hit breakpoint.
76
77 bp_loc: an lldb.SBBreakpointLocation object that represents the breakpoint location that was hit.
78
79 dict: the python session dictionary hit.
80
81)" "When specifying a python function with the --python-function option, you need \
82to supply the function name prepended by the module name:" R"(
83
84 --python-function myutils.breakpoint_callback
85
86The function itself must have the following prototype:
87
88def breakpoint_callback(frame, bp_loc, dict):
89 # Your code goes here
90
91)" "The arguments are the same as the arguments passed to generated functions as \
92described above. Note that the global variable 'lldb.frame' will NOT be updated when \
93this function is called, so be sure to use the 'frame' argument. The 'frame' argument \
94can get you to the thread via frame.GetThread(), the thread can get you to the \
95process via thread.GetProcess(), and the process can get you back to the target \
96via process.GetTarget()." R"(
97
98)" "Important Note: As Python code gets collected into functions, access to global \
99variables requires explicit scoping using the 'global' keyword. Be sure to use correct \
100Python syntax, including indentation, when entering Python breakpoint commands." R"(
101
102Example Python one-line breakpoint command:
103
104(lldb) breakpoint command add -s python 1
105Enter your Python command(s). Type 'DONE' to end.
106> print "Hit this breakpoint!"
107> DONE
108
109As a convenience, this also works for a short Python one-liner:
110
111(lldb) breakpoint command add -s python 1 -o 'import time; print time.asctime()'
112(lldb) run
113Launching '.../a.out' (x86_64)
114(lldb) Fri Sep 10 12:17:45 2010
115Process 21778 Stopped
116* thread #1: tid = 0x2e03, 0x0000000100000de8 a.out`c + 7 at main.c:39, stop reason = breakpoint 1.1, queue = com.apple.main-thread
117 36
118 37 int c(int val)
119 38 {
120 39 -> return val + 3;
121 40 }
122 41
123 42 int main (int argc, char const *argv[])
124
125Example multiple line Python breakpoint command:
126
127(lldb) breakpoint command add -s p 1
128Enter your Python command(s). Type 'DONE' to end.
129> global bp_count
130> bp_count = bp_count + 1
131> print "Hit this breakpoint " + repr(bp_count) + " times!"
132> DONE
133
134Example multiple line Python breakpoint command, using function definition:
135
136(lldb) breakpoint command add -s python 1
137Enter your Python command(s). Type 'DONE' to end.
138> def breakpoint_output (bp_no):
139> out_string = "Hit breakpoint number " + repr (bp_no)
140> print out_string
141> return True
142> breakpoint_output (1)
143> DONE
144
145)" "In this case, since there is a reference to a global variable, \
146'bp_count', you will also need to make sure 'bp_count' exists and is \
147initialized:" R"(
148
149(lldb) script
150>>> bp_count = 0
151>>> quit()
152
153)" "Your Python code, however organized, can optionally return a value. \
154If the returned value is False, that tells LLDB not to stop at the breakpoint \
155to which the code is associated. Returning anything other than False, or even \
156returning None, or even omitting a return statement entirely, will cause \
157LLDB to stop." R"(
158
159)" "Final Note: A warning that no breakpoint command was generated when there \
160are no syntax errors may indicate that a function was declared but never called."
161 );
Caroline Tice405fe672010-10-04 22:28:36 +0000162
Jim Ingham5a988412012-06-08 21:56:10 +0000163 CommandArgumentEntry arg;
164 CommandArgumentData bp_id_arg;
Caroline Tice405fe672010-10-04 22:28:36 +0000165
Jim Ingham5a988412012-06-08 21:56:10 +0000166 // Define the first (and only) variant of this arg.
167 bp_id_arg.arg_type = eArgTypeBreakpointID;
Jim Ingham1bb07502014-08-28 00:50:17 +0000168 bp_id_arg.arg_repetition = eArgRepeatOptional;
Caroline Tice405fe672010-10-04 22:28:36 +0000169
Jim Ingham5a988412012-06-08 21:56:10 +0000170 // There is only one variant this argument could be; put it into the argument entry.
171 arg.push_back (bp_id_arg);
Caroline Tice405fe672010-10-04 22:28:36 +0000172
Jim Ingham5a988412012-06-08 21:56:10 +0000173 // Push the data for the first argument into the m_arguments vector.
174 m_arguments.push_back (arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000175 }
176
Eugene Zelenkoc8ecc2a2016-02-19 19:33:46 +0000177 ~CommandObjectBreakpointCommandAdd() override = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000178
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000179 Options *
180 GetOptions () override
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000181 {
Jim Ingham5a988412012-06-08 21:56:10 +0000182 return &m_options;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000183 }
184
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000185 void
186 IOHandlerActivated (IOHandler &io_handler) override
Greg Clayton44d93782014-01-27 23:43:24 +0000187 {
188 StreamFileSP output_sp(io_handler.GetOutputStreamFile());
189 if (output_sp)
190 {
191 output_sp->PutCString(g_reader_instructions);
192 output_sp->Flush();
193 }
194 }
Eugene Zelenkoc8ecc2a2016-02-19 19:33:46 +0000195
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000196 void
197 IOHandlerInputComplete (IOHandler &io_handler, std::string &line) override
Greg Clayton44d93782014-01-27 23:43:24 +0000198 {
199 io_handler.SetIsDone(true);
200
Jim Inghamb5796cb2014-08-29 17:34:17 +0000201 std::vector<BreakpointOptions *> *bp_options_vec = (std::vector<BreakpointOptions *> *)io_handler.GetUserData();
202 for (BreakpointOptions *bp_options : *bp_options_vec)
Greg Clayton44d93782014-01-27 23:43:24 +0000203 {
Jim Inghamb5796cb2014-08-29 17:34:17 +0000204 if (!bp_options)
205 continue;
206
Greg Clayton44d93782014-01-27 23:43:24 +0000207 std::unique_ptr<BreakpointOptions::CommandData> data_ap(new BreakpointOptions::CommandData());
Eugene Zelenkoc8ecc2a2016-02-19 19:33:46 +0000208 if (data_ap)
Greg Clayton44d93782014-01-27 23:43:24 +0000209 {
210 data_ap->user_source.SplitIntoLines (line.c_str(), line.size());
211 BatonSP baton_sp (new BreakpointOptions::CommandBaton (data_ap.release()));
212 bp_options->SetCallback (BreakpointOptionsCallbackFunction, baton_sp);
213 }
214 }
Greg Clayton44d93782014-01-27 23:43:24 +0000215 }
216
Jim Ingham5a988412012-06-08 21:56:10 +0000217 void
Jim Inghamb5796cb2014-08-29 17:34:17 +0000218 CollectDataForBreakpointCommandCallback (std::vector<BreakpointOptions *> &bp_options_vec,
Jim Ingham5a988412012-06-08 21:56:10 +0000219 CommandReturnObject &result)
Enrico Granata8d4a8012012-04-04 17:30:31 +0000220 {
Greg Clayton44d93782014-01-27 23:43:24 +0000221 m_interpreter.GetLLDBCommandsFromIOHandler ("> ", // Prompt
222 *this, // IOHandlerDelegate
223 true, // Run IOHandler in async mode
Jim Inghamb5796cb2014-08-29 17:34:17 +0000224 &bp_options_vec); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000225 }
Caroline Ticed61c10b2011-06-16 16:27:19 +0000226
Jim Ingham5a988412012-06-08 21:56:10 +0000227 /// Set a one-liner as the callback for the breakpoint.
228 void
Jim Inghamb5796cb2014-08-29 17:34:17 +0000229 SetBreakpointCommandCallback (std::vector<BreakpointOptions *> &bp_options_vec,
Jim Ingham5a988412012-06-08 21:56:10 +0000230 const char *oneliner)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000231 {
Jim Inghamb5796cb2014-08-29 17:34:17 +0000232 for (auto bp_options : bp_options_vec)
233 {
234 std::unique_ptr<BreakpointOptions::CommandData> data_ap(new BreakpointOptions::CommandData());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000235
Jim Inghamb5796cb2014-08-29 17:34:17 +0000236 // It's necessary to set both user_source and script_source to the oneliner.
237 // The former is used to generate callback description (as in breakpoint command list)
238 // while the latter is used for Python to interpret during the actual callback.
239 data_ap->user_source.AppendString (oneliner);
240 data_ap->script_source.assign (oneliner);
241 data_ap->stop_on_error = m_options.m_stop_on_error;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000242
Jim Inghamb5796cb2014-08-29 17:34:17 +0000243 BatonSP baton_sp (new BreakpointOptions::CommandBaton (data_ap.release()));
244 bp_options->SetCallback (BreakpointOptionsCallbackFunction, baton_sp);
245 }
Jim Ingham5a988412012-06-08 21:56:10 +0000246 }
Jim Ingham5a988412012-06-08 21:56:10 +0000247
248 static bool
249 BreakpointOptionsCallbackFunction (void *baton,
250 StoppointCallbackContext *context,
251 lldb::user_id_t break_id,
252 lldb::user_id_t break_loc_id)
253 {
254 bool ret_value = true;
Eugene Zelenkoc8ecc2a2016-02-19 19:33:46 +0000255 if (baton == nullptr)
Jim Ingham5a988412012-06-08 21:56:10 +0000256 return true;
Eugene Zelenkoc8ecc2a2016-02-19 19:33:46 +0000257
Jim Ingham5a988412012-06-08 21:56:10 +0000258 BreakpointOptions::CommandData *data = (BreakpointOptions::CommandData *) baton;
259 StringList &commands = data->user_source;
260
261 if (commands.GetSize() > 0)
262 {
263 ExecutionContext exe_ctx (context->exe_ctx_ref);
264 Target *target = exe_ctx.GetTargetPtr();
265 if (target)
266 {
267 CommandReturnObject result;
268 Debugger &debugger = target->GetDebugger();
269 // Rig up the results secondary output stream to the debugger's, so the output will come out synchronously
270 // if the debugger is set up that way.
271
272 StreamSP output_stream (debugger.GetAsyncOutputStream());
273 StreamSP error_stream (debugger.GetAsyncErrorStream());
274 result.SetImmediateOutputStream (output_stream);
275 result.SetImmediateErrorStream (error_stream);
276
Jim Ingham26c7bf92014-10-11 00:38:27 +0000277 CommandInterpreterRunOptions options;
278 options.SetStopOnContinue(true);
279 options.SetStopOnError (data->stop_on_error);
280 options.SetEchoCommands (true);
281 options.SetPrintResults (true);
282 options.SetAddToHistory (false);
Jim Ingham5a988412012-06-08 21:56:10 +0000283
Jim Ingham26c7bf92014-10-11 00:38:27 +0000284 debugger.GetCommandInterpreter().HandleCommands (commands,
Jim Ingham5a988412012-06-08 21:56:10 +0000285 &exe_ctx,
Jim Ingham26c7bf92014-10-11 00:38:27 +0000286 options,
Jim Ingham5a988412012-06-08 21:56:10 +0000287 result);
288 result.GetImmediateOutputStream()->Flush();
289 result.GetImmediateErrorStream()->Flush();
290 }
291 }
292 return ret_value;
293 }
294
295 class CommandOptions : public Options
296 {
297 public:
Todd Fialae1cfbc72016-08-11 23:51:28 +0000298 CommandOptions () :
299 Options (),
Jim Ingham5a988412012-06-08 21:56:10 +0000300 m_use_commands (false),
301 m_use_script_language (false),
302 m_script_language (eScriptLanguageNone),
303 m_use_one_liner (false),
304 m_one_liner(),
305 m_function_name()
306 {
307 }
308
Eugene Zelenkoc8ecc2a2016-02-19 19:33:46 +0000309 ~CommandOptions() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +0000310
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000311 Error
Todd Fialae1cfbc72016-08-11 23:51:28 +0000312 SetOptionValue (uint32_t option_idx, const char *option_arg,
313 ExecutionContext *execution_context) override
Jim Ingham5a988412012-06-08 21:56:10 +0000314 {
315 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000316 const int short_option = m_getopt_table[option_idx].val;
Jim Ingham5a988412012-06-08 21:56:10 +0000317
318 switch (short_option)
319 {
320 case 'o':
321 m_use_one_liner = true;
322 m_one_liner = option_arg;
323 break;
324
325 case 's':
326 m_script_language = (lldb::ScriptLanguage) Args::StringToOptionEnum (option_arg,
327 g_option_table[option_idx].enum_values,
328 eScriptLanguageNone,
329 error);
330
331 if (m_script_language == eScriptLanguagePython || m_script_language == eScriptLanguageDefault)
332 {
333 m_use_script_language = true;
334 }
335 else
336 {
337 m_use_script_language = false;
338 }
339 break;
340
341 case 'e':
342 {
343 bool success = false;
344 m_stop_on_error = Args::StringToBoolean(option_arg, false, &success);
345 if (!success)
346 error.SetErrorStringWithFormat("invalid value for stop-on-error: \"%s\"", option_arg);
347 }
348 break;
349
350 case 'F':
Eugene Zelenkoc8ecc2a2016-02-19 19:33:46 +0000351 m_use_one_liner = false;
352 m_use_script_language = true;
353 m_function_name.assign(option_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000354 break;
355
Jim Ingham33df7cd2014-12-06 01:28:03 +0000356 case 'D':
357 m_use_dummy = true;
358 break;
359
Jim Ingham5a988412012-06-08 21:56:10 +0000360 default:
361 break;
362 }
363 return error;
364 }
Eugene Zelenkoc8ecc2a2016-02-19 19:33:46 +0000365
Jim Ingham5a988412012-06-08 21:56:10 +0000366 void
Todd Fialae1cfbc72016-08-11 23:51:28 +0000367 OptionParsingStarting (ExecutionContext *execution_context) override
Jim Ingham5a988412012-06-08 21:56:10 +0000368 {
369 m_use_commands = true;
370 m_use_script_language = false;
371 m_script_language = eScriptLanguageNone;
372
373 m_use_one_liner = false;
374 m_stop_on_error = true;
375 m_one_liner.clear();
376 m_function_name.clear();
Jim Ingham33df7cd2014-12-06 01:28:03 +0000377 m_use_dummy = false;
Jim Ingham5a988412012-06-08 21:56:10 +0000378 }
379
380 const OptionDefinition*
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000381 GetDefinitions () override
Jim Ingham5a988412012-06-08 21:56:10 +0000382 {
383 return g_option_table;
384 }
385
386 // Options table: Required for subclasses of Options.
387
388 static OptionDefinition g_option_table[];
389
390 // Instance variables to hold the values for command options.
391
392 bool m_use_commands;
393 bool m_use_script_language;
394 lldb::ScriptLanguage m_script_language;
395
396 // Instance variables to hold the values for one_liner options.
397 bool m_use_one_liner;
398 std::string m_one_liner;
399 bool m_stop_on_error;
400 std::string m_function_name;
Jim Ingham33df7cd2014-12-06 01:28:03 +0000401 bool m_use_dummy;
Jim Ingham5a988412012-06-08 21:56:10 +0000402 };
403
404protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000405 bool
406 DoExecute (Args& command, CommandReturnObject &result) override
Jim Ingham5a988412012-06-08 21:56:10 +0000407 {
Jim Ingham33df7cd2014-12-06 01:28:03 +0000408 Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
Jim Ingham5a988412012-06-08 21:56:10 +0000409
Eugene Zelenkoc8ecc2a2016-02-19 19:33:46 +0000410 if (target == nullptr)
Jim Ingham5a988412012-06-08 21:56:10 +0000411 {
412 result.AppendError ("There is not a current executable; there are no breakpoints to which to add commands");
413 result.SetStatus (eReturnStatusFailed);
414 return false;
415 }
416
417 const BreakpointList &breakpoints = target->GetBreakpointList();
418 size_t num_breakpoints = breakpoints.GetSize();
419
420 if (num_breakpoints == 0)
421 {
422 result.AppendError ("No breakpoints exist to have commands added");
423 result.SetStatus (eReturnStatusFailed);
424 return false;
425 }
426
Eugene Zelenkoc8ecc2a2016-02-19 19:33:46 +0000427 if (!m_options.m_use_script_language && !m_options.m_function_name.empty())
Jim Ingham5a988412012-06-08 21:56:10 +0000428 {
429 result.AppendError ("need to enable scripting to have a function run as a breakpoint command");
430 result.SetStatus (eReturnStatusFailed);
431 return false;
432 }
433
434 BreakpointIDList valid_bp_ids;
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000435 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
Jim Ingham5a988412012-06-08 21:56:10 +0000436
Jim Inghamb5796cb2014-08-29 17:34:17 +0000437 m_bp_options_vec.clear();
438
Jim Ingham5a988412012-06-08 21:56:10 +0000439 if (result.Succeeded())
440 {
441 const size_t count = valid_bp_ids.GetSize();
Jim Inghamd9916ea2013-02-28 19:30:07 +0000442
Jim Ingham5a988412012-06-08 21:56:10 +0000443 for (size_t i = 0; i < count; ++i)
444 {
445 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
446 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
447 {
448 Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
Eugene Zelenkoc8ecc2a2016-02-19 19:33:46 +0000449 BreakpointOptions *bp_options = nullptr;
Jim Ingham5a988412012-06-08 21:56:10 +0000450 if (cur_bp_id.GetLocationID() == LLDB_INVALID_BREAK_ID)
451 {
452 // This breakpoint does not have an associated location.
453 bp_options = bp->GetOptions();
454 }
455 else
456 {
457 BreakpointLocationSP bp_loc_sp(bp->FindLocationByID (cur_bp_id.GetLocationID()));
458 // This breakpoint does have an associated location.
459 // Get its breakpoint options.
460 if (bp_loc_sp)
461 bp_options = bp_loc_sp->GetLocationOptions();
462 }
Jim Inghamb5796cb2014-08-29 17:34:17 +0000463 if (bp_options)
464 m_bp_options_vec.push_back (bp_options);
Jim Ingham5a988412012-06-08 21:56:10 +0000465 }
466 }
Jim Inghamb5796cb2014-08-29 17:34:17 +0000467
468 // If we are using script language, get the script interpreter
469 // in order to set or collect command callback. Otherwise, call
470 // the methods associated with this object.
471 if (m_options.m_use_script_language)
472 {
473 ScriptInterpreter *script_interp = m_interpreter.GetScriptInterpreter();
474 // Special handling for one-liner specified inline.
475 if (m_options.m_use_one_liner)
476 {
477 script_interp->SetBreakpointCommandCallback (m_bp_options_vec,
478 m_options.m_one_liner.c_str());
479 }
Eugene Zelenkoc8ecc2a2016-02-19 19:33:46 +0000480 else if (!m_options.m_function_name.empty())
Jim Inghamb5796cb2014-08-29 17:34:17 +0000481 {
482 script_interp->SetBreakpointCommandCallbackFunction (m_bp_options_vec,
483 m_options.m_function_name.c_str());
484 }
485 else
486 {
487 script_interp->CollectDataForBreakpointCommandCallback (m_bp_options_vec,
488 result);
489 }
490 }
491 else
492 {
493 // Special handling for one-liner specified inline.
494 if (m_options.m_use_one_liner)
495 SetBreakpointCommandCallback (m_bp_options_vec,
496 m_options.m_one_liner.c_str());
497 else
498 CollectDataForBreakpointCommandCallback (m_bp_options_vec,
499 result);
500 }
Jim Ingham5a988412012-06-08 21:56:10 +0000501 }
502
503 return result.Succeeded();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000504 }
505
Jim Ingham5a988412012-06-08 21:56:10 +0000506private:
507 CommandOptions m_options;
Jim Inghamb5796cb2014-08-29 17:34:17 +0000508 std::vector<BreakpointOptions *> m_bp_options_vec; // This stores the breakpoint options that we are currently
509 // collecting commands for. In the CollectData... calls we need
510 // to hand this off to the IOHandler, which may run asynchronously.
511 // So we have to have some way to keep it alive, and not leak it.
512 // Making it an ivar of the command object, which never goes away
513 // achieves this. Note that if we were able to run
514 // the same command concurrently in one interpreter we'd have to
515 // make this "per invocation". But there are many more reasons
516 // why it is not in general safe to do that in lldb at present,
517 // so it isn't worthwhile to come up with a more complex mechanism
518 // to address this particular weakness right now.
Jim Ingham5a988412012-06-08 21:56:10 +0000519 static const char *g_reader_instructions;
Jim Ingham5a988412012-06-08 21:56:10 +0000520};
521
522const char *
Greg Clayton44d93782014-01-27 23:43:24 +0000523CommandObjectBreakpointCommandAdd::g_reader_instructions = "Enter your debugger command(s). Type 'DONE' to end.\n";
Jim Ingham5a988412012-06-08 21:56:10 +0000524
525// FIXME: "script-type" needs to have its contents determined dynamically, so somebody can add a new scripting
526// language to lldb and have it pickable here without having to change this enumeration by hand and rebuild lldb proper.
527
528static OptionEnumValueElement
529g_script_option_enumeration[4] =
530{
531 { eScriptLanguageNone, "command", "Commands are in the lldb command interpreter language"},
532 { eScriptLanguagePython, "python", "Commands are in the Python language."},
533 { eSortOrderByName, "default-script", "Commands are in the default scripting language."},
Eugene Zelenkoc8ecc2a2016-02-19 19:33:46 +0000534 { 0, nullptr, nullptr }
Jim Ingham5a988412012-06-08 21:56:10 +0000535};
536
537OptionDefinition
538CommandObjectBreakpointCommandAdd::CommandOptions::g_option_table[] =
539{
Eugene Zelenkoc8ecc2a2016-02-19 19:33:46 +0000540 { LLDB_OPT_SET_1, false, "one-liner", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeOneLiner,
Jim Ingham5a988412012-06-08 21:56:10 +0000541 "Specify a one-line breakpoint command inline. Be sure to surround it with quotes." },
542
Eugene Zelenkoc8ecc2a2016-02-19 19:33:46 +0000543 { LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean,
Jim Ingham5a988412012-06-08 21:56:10 +0000544 "Specify whether breakpoint command execution should terminate on error." },
545
Eugene Zelenkoc8ecc2a2016-02-19 19:33:46 +0000546 { LLDB_OPT_SET_ALL, false, "script-type", 's', OptionParser::eRequiredArgument, nullptr, g_script_option_enumeration, 0, eArgTypeNone,
Jim Ingham5a988412012-06-08 21:56:10 +0000547 "Specify the language for the commands - if none is specified, the lldb command interpreter will be used."},
548
Eugene Zelenkoc8ecc2a2016-02-19 19:33:46 +0000549 { LLDB_OPT_SET_2, false, "python-function", 'F', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePythonFunction,
Jim Ingham5a988412012-06-08 21:56:10 +0000550 "Give the name of a Python function to run as command for this breakpoint. Be sure to give a module name if appropriate."},
551
Eugene Zelenkoc8ecc2a2016-02-19 19:33:46 +0000552 { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
Jim Ingham33df7cd2014-12-06 01:28:03 +0000553 "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
554
Eugene Zelenkoc8ecc2a2016-02-19 19:33:46 +0000555 { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
Jim Ingham5a988412012-06-08 21:56:10 +0000556};
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000557
558//-------------------------------------------------------------------------
Caroline Tice93e0f192011-05-22 07:14:46 +0000559// CommandObjectBreakpointCommandDelete
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000560//-------------------------------------------------------------------------
561
Jim Ingham5a988412012-06-08 21:56:10 +0000562class CommandObjectBreakpointCommandDelete : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000563{
Jim Ingham5a988412012-06-08 21:56:10 +0000564public:
565 CommandObjectBreakpointCommandDelete (CommandInterpreter &interpreter) :
Eugene Zelenkoc8ecc2a2016-02-19 19:33:46 +0000566 CommandObjectParsed(interpreter,
567 "delete",
568 "Delete the set of commands from a breakpoint.",
569 nullptr),
Todd Fialae1cfbc72016-08-11 23:51:28 +0000570 m_options()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000571 {
Jim Ingham5a988412012-06-08 21:56:10 +0000572 CommandArgumentEntry arg;
573 CommandArgumentData bp_id_arg;
574
575 // Define the first (and only) variant of this arg.
576 bp_id_arg.arg_type = eArgTypeBreakpointID;
577 bp_id_arg.arg_repetition = eArgRepeatPlain;
578
579 // There is only one variant this argument could be; put it into the argument entry.
580 arg.push_back (bp_id_arg);
581
582 // Push the data for the first argument into the m_arguments vector.
583 m_arguments.push_back (arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000584 }
585
Eugene Zelenkoc8ecc2a2016-02-19 19:33:46 +0000586 ~CommandObjectBreakpointCommandDelete() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +0000587
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000588 Options *
589 GetOptions () override
Jim Ingham33df7cd2014-12-06 01:28:03 +0000590 {
591 return &m_options;
592 }
593
594 class CommandOptions : public Options
595 {
596 public:
Todd Fialae1cfbc72016-08-11 23:51:28 +0000597 CommandOptions() :
598 Options(),
599 m_use_dummy(false)
Jim Ingham33df7cd2014-12-06 01:28:03 +0000600 {
601 }
602
Eugene Zelenkoc8ecc2a2016-02-19 19:33:46 +0000603 ~CommandOptions() override = default;
Jim Ingham33df7cd2014-12-06 01:28:03 +0000604
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000605 Error
Todd Fialae1cfbc72016-08-11 23:51:28 +0000606 SetOptionValue (uint32_t option_idx, const char *option_arg,
607 ExecutionContext *execution_context) override
Jim Ingham33df7cd2014-12-06 01:28:03 +0000608 {
609 Error error;
610 const int short_option = m_getopt_table[option_idx].val;
611
612 switch (short_option)
613 {
614 case 'D':
615 m_use_dummy = true;
616 break;
617
618 default:
619 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
620 break;
621 }
622
623 return error;
624 }
625
626 void
Todd Fialae1cfbc72016-08-11 23:51:28 +0000627 OptionParsingStarting (ExecutionContext *execution_context) override
Jim Ingham33df7cd2014-12-06 01:28:03 +0000628 {
629 m_use_dummy = false;
630 }
631
632 const OptionDefinition*
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000633 GetDefinitions () override
Jim Ingham33df7cd2014-12-06 01:28:03 +0000634 {
635 return g_option_table;
636 }
637
638 // Options table: Required for subclasses of Options.
639
640 static OptionDefinition g_option_table[];
641
642 // Instance variables to hold the values for command options.
643 bool m_use_dummy;
644 };
645
Jim Ingham5a988412012-06-08 21:56:10 +0000646protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000647 bool
648 DoExecute (Args& command, CommandReturnObject &result) override
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000649 {
Jim Ingham33df7cd2014-12-06 01:28:03 +0000650 Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000651
Eugene Zelenkoc8ecc2a2016-02-19 19:33:46 +0000652 if (target == nullptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000653 {
Jim Ingham5a988412012-06-08 21:56:10 +0000654 result.AppendError ("There is not a current executable; there are no breakpoints from which to delete commands");
655 result.SetStatus (eReturnStatusFailed);
656 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000657 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000658
Jim Ingham5a988412012-06-08 21:56:10 +0000659 const BreakpointList &breakpoints = target->GetBreakpointList();
660 size_t num_breakpoints = breakpoints.GetSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000661
Jim Ingham5a988412012-06-08 21:56:10 +0000662 if (num_breakpoints == 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000663 {
Jim Ingham5a988412012-06-08 21:56:10 +0000664 result.AppendError ("No breakpoints exist to have commands deleted");
665 result.SetStatus (eReturnStatusFailed);
666 return false;
667 }
668
669 if (command.GetArgumentCount() == 0)
670 {
671 result.AppendError ("No breakpoint specified from which to delete the commands");
672 result.SetStatus (eReturnStatusFailed);
673 return false;
674 }
675
676 BreakpointIDList valid_bp_ids;
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000677 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
Jim Ingham5a988412012-06-08 21:56:10 +0000678
679 if (result.Succeeded())
680 {
681 const size_t count = valid_bp_ids.GetSize();
682 for (size_t i = 0; i < count; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000683 {
Jim Ingham5a988412012-06-08 21:56:10 +0000684 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
685 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000686 {
Jim Ingham5a988412012-06-08 21:56:10 +0000687 Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000688 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
689 {
Jim Ingham5a988412012-06-08 21:56:10 +0000690 BreakpointLocationSP bp_loc_sp (bp->FindLocationByID (cur_bp_id.GetLocationID()));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000691 if (bp_loc_sp)
Jim Ingham5a988412012-06-08 21:56:10 +0000692 bp_loc_sp->ClearCallback();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000693 else
694 {
695 result.AppendErrorWithFormat("Invalid breakpoint ID: %u.%u.\n",
696 cur_bp_id.GetBreakpointID(),
697 cur_bp_id.GetLocationID());
698 result.SetStatus (eReturnStatusFailed);
699 return false;
700 }
701 }
702 else
703 {
Jim Ingham5a988412012-06-08 21:56:10 +0000704 bp->ClearCallback();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000705 }
Jim Ingham5a988412012-06-08 21:56:10 +0000706 }
707 }
708 }
709 return result.Succeeded();
710 }
Eugene Zelenkoc8ecc2a2016-02-19 19:33:46 +0000711
Jim Ingham33df7cd2014-12-06 01:28:03 +0000712private:
713 CommandOptions m_options;
Jim Ingham5a988412012-06-08 21:56:10 +0000714};
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000715
Jim Ingham33df7cd2014-12-06 01:28:03 +0000716OptionDefinition
717CommandObjectBreakpointCommandDelete::CommandOptions::g_option_table[] =
718{
Eugene Zelenkoc8ecc2a2016-02-19 19:33:46 +0000719 { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
Jim Ingham33df7cd2014-12-06 01:28:03 +0000720 "Delete commands from Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
721
Eugene Zelenkoc8ecc2a2016-02-19 19:33:46 +0000722 { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
Jim Ingham33df7cd2014-12-06 01:28:03 +0000723};
724
Jim Ingham5a988412012-06-08 21:56:10 +0000725//-------------------------------------------------------------------------
726// CommandObjectBreakpointCommandList
727//-------------------------------------------------------------------------
728
729class CommandObjectBreakpointCommandList : public CommandObjectParsed
730{
731public:
732 CommandObjectBreakpointCommandList (CommandInterpreter &interpreter) :
Eugene Zelenkoc8ecc2a2016-02-19 19:33:46 +0000733 CommandObjectParsed(interpreter,
734 "list",
735 "List the script or set of commands to be executed when the breakpoint is hit.",
736 nullptr)
Jim Ingham5a988412012-06-08 21:56:10 +0000737 {
738 CommandArgumentEntry arg;
739 CommandArgumentData bp_id_arg;
740
741 // Define the first (and only) variant of this arg.
742 bp_id_arg.arg_type = eArgTypeBreakpointID;
743 bp_id_arg.arg_repetition = eArgRepeatPlain;
744
745 // There is only one variant this argument could be; put it into the argument entry.
746 arg.push_back (bp_id_arg);
747
748 // Push the data for the first argument into the m_arguments vector.
749 m_arguments.push_back (arg);
750 }
751
Eugene Zelenkoc8ecc2a2016-02-19 19:33:46 +0000752 ~CommandObjectBreakpointCommandList() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +0000753
754protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000755 bool
Jim Ingham5a988412012-06-08 21:56:10 +0000756 DoExecute (Args& command,
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000757 CommandReturnObject &result) override
Jim Ingham5a988412012-06-08 21:56:10 +0000758 {
759 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
760
Eugene Zelenkoc8ecc2a2016-02-19 19:33:46 +0000761 if (target == nullptr)
Jim Ingham5a988412012-06-08 21:56:10 +0000762 {
763 result.AppendError ("There is not a current executable; there are no breakpoints for which to list commands");
764 result.SetStatus (eReturnStatusFailed);
765 return false;
766 }
767
768 const BreakpointList &breakpoints = target->GetBreakpointList();
769 size_t num_breakpoints = breakpoints.GetSize();
770
771 if (num_breakpoints == 0)
772 {
773 result.AppendError ("No breakpoints exist for which to list commands");
774 result.SetStatus (eReturnStatusFailed);
775 return false;
776 }
777
778 if (command.GetArgumentCount() == 0)
779 {
780 result.AppendError ("No breakpoint specified for which to list the commands");
781 result.SetStatus (eReturnStatusFailed);
782 return false;
783 }
784
785 BreakpointIDList valid_bp_ids;
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000786 CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
Jim Ingham5a988412012-06-08 21:56:10 +0000787
788 if (result.Succeeded())
789 {
790 const size_t count = valid_bp_ids.GetSize();
791 for (size_t i = 0; i < count; ++i)
792 {
793 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
794 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
795 {
796 Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
797
798 if (bp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000799 {
Eugene Zelenkoc8ecc2a2016-02-19 19:33:46 +0000800 const BreakpointOptions *bp_options = nullptr;
Jim Ingham5a988412012-06-08 21:56:10 +0000801 if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000802 {
Jim Ingham5a988412012-06-08 21:56:10 +0000803 BreakpointLocationSP bp_loc_sp(bp->FindLocationByID (cur_bp_id.GetLocationID()));
804 if (bp_loc_sp)
805 bp_options = bp_loc_sp->GetOptionsNoCreate();
806 else
807 {
808 result.AppendErrorWithFormat("Invalid breakpoint ID: %u.%u.\n",
809 cur_bp_id.GetBreakpointID(),
810 cur_bp_id.GetLocationID());
811 result.SetStatus (eReturnStatusFailed);
812 return false;
813 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000814 }
815 else
816 {
Jim Ingham5a988412012-06-08 21:56:10 +0000817 bp_options = bp->GetOptions();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000818 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000819
Jim Ingham5a988412012-06-08 21:56:10 +0000820 if (bp_options)
821 {
822 StreamString id_str;
823 BreakpointID::GetCanonicalReference (&id_str,
824 cur_bp_id.GetBreakpointID(),
825 cur_bp_id.GetLocationID());
826 const Baton *baton = bp_options->GetBaton();
827 if (baton)
828 {
829 result.GetOutputStream().Printf ("Breakpoint %s:\n", id_str.GetData());
830 result.GetOutputStream().IndentMore ();
831 baton->GetDescription(&result.GetOutputStream(), eDescriptionLevelFull);
832 result.GetOutputStream().IndentLess ();
833 }
834 else
835 {
836 result.AppendMessageWithFormat ("Breakpoint %s does not have an associated command.\n",
837 id_str.GetData());
838 }
839 }
840 result.SetStatus (eReturnStatusSuccessFinishResult);
841 }
842 else
843 {
844 result.AppendErrorWithFormat("Invalid breakpoint ID: %u.\n", cur_bp_id.GetBreakpointID());
845 result.SetStatus (eReturnStatusFailed);
846 }
Jim Ingham5a988412012-06-08 21:56:10 +0000847 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000848 }
849 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000850
Jim Ingham5a988412012-06-08 21:56:10 +0000851 return result.Succeeded();
852 }
853};
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000854
855//-------------------------------------------------------------------------
856// CommandObjectBreakpointCommand
857//-------------------------------------------------------------------------
858
Kate Stone7428a182016-07-14 22:03:10 +0000859CommandObjectBreakpointCommand::CommandObjectBreakpointCommand(CommandInterpreter &interpreter)
860 : CommandObjectMultiword(
861 interpreter, "command",
862 "Commands for adding, removing and listing LLDB commands executed when a breakpoint is hit.",
863 "command <sub-command> [<sub-command-options>] <breakpoint-id>")
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000864{
Greg Claytona7015092010-09-18 01:14:36 +0000865 CommandObjectSP add_command_object (new CommandObjectBreakpointCommandAdd (interpreter));
Caroline Tice93e0f192011-05-22 07:14:46 +0000866 CommandObjectSP delete_command_object (new CommandObjectBreakpointCommandDelete (interpreter));
Greg Claytona7015092010-09-18 01:14:36 +0000867 CommandObjectSP list_command_object (new CommandObjectBreakpointCommandList (interpreter));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000868
869 add_command_object->SetCommandName ("breakpoint command add");
Caroline Tice93e0f192011-05-22 07:14:46 +0000870 delete_command_object->SetCommandName ("breakpoint command delete");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000871 list_command_object->SetCommandName ("breakpoint command list");
872
Greg Clayton23f59502012-07-17 03:23:13 +0000873 LoadSubCommand ("add", add_command_object);
874 LoadSubCommand ("delete", delete_command_object);
875 LoadSubCommand ("list", list_command_object);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000876}
877
Eugene Zelenkoc8ecc2a2016-02-19 19:33:46 +0000878CommandObjectBreakpointCommand::~CommandObjectBreakpointCommand() = default;