LLDB  mainline
CommandObjectWatchpointCommand.cpp
Go to the documentation of this file.
1 //===-- CommandObjectWatchpointCommand.cpp ----------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include <vector>
10 
15 #include "lldb/Core/IOHandler.h"
16 #include "lldb/Host/OptionParser.h"
20 #include "lldb/Target/Target.h"
21 #include "lldb/Target/Thread.h"
22 #include "lldb/Utility/State.h"
23 
24 using namespace lldb;
25 using namespace lldb_private;
26 
27 // CommandObjectWatchpointCommandAdd
28 
29 // FIXME: "script-type" needs to have its contents determined dynamically, so
30 // somebody can add a new scripting
31 // language to lldb and have it pickable here without having to change this
32 // enumeration by hand and rebuild lldb proper.
33 
34 static constexpr OptionEnumValueElement g_script_option_enumeration[] = {
35  {eScriptLanguageNone, "command",
36  "Commands are in the lldb command interpreter language"},
37  {eScriptLanguagePython, "python", "Commands are in the Python language."},
38  {eSortOrderByName, "default-script",
39  "Commands are in the default scripting language."} };
40 
41 static constexpr OptionEnumValues ScriptOptionEnum() {
42  return OptionEnumValues(g_script_option_enumeration);
43 }
44 
45 static constexpr OptionDefinition g_watchpoint_command_add_options[] = {
46  // clang-format off
47  { LLDB_OPT_SET_1, false, "one-liner", 'o', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeOneLiner, "Specify a one-line watchpoint command inline. Be sure to surround it with quotes." },
48  { LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Specify whether watchpoint command execution should terminate on error." },
49  { LLDB_OPT_SET_ALL, false, "script-type", 's', OptionParser::eRequiredArgument, nullptr, ScriptOptionEnum(), 0, eArgTypeNone, "Specify the language for the commands - if none is specified, the lldb command interpreter will be used." },
50  { LLDB_OPT_SET_2, false, "python-function", 'F', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePythonFunction, "Give the name of a Python function to run as command for this watchpoint. Be sure to give a module name if appropriate." }
51  // clang-format on
52 };
53 
56 public:
58  : CommandObjectParsed(interpreter, "add",
59  "Add a set of LLDB commands to a watchpoint, to be "
60  "executed whenever the watchpoint is hit.",
61  nullptr),
63  IOHandlerDelegate::Completion::LLDBCommand),
64  m_options() {
65  SetHelpLong(
66  R"(
67 General information about entering watchpoint commands
68 ------------------------------------------------------
69 
70 )"
71  "This command will prompt for commands to be executed when the specified \
72 watchpoint is hit. Each command is typed on its own line following the '> ' \
73 prompt until 'DONE' is entered."
74  R"(
75 
76 )"
77  "Syntactic errors may not be detected when initially entered, and many \
78 malformed commands can silently fail when executed. If your watchpoint commands \
79 do not appear to be executing, double-check the command syntax."
80  R"(
81 
82 )"
83  "Note: You may enter any debugger command exactly as you would at the debugger \
84 prompt. There is no limit to the number of commands supplied, but do NOT enter \
85 more than one command per line."
86  R"(
87 
88 Special information about PYTHON watchpoint commands
89 ----------------------------------------------------
90 
91 )"
92  "You may enter either one or more lines of Python, including function \
93 definitions or calls to functions that will have been imported by the time \
94 the code executes. Single line watchpoint commands will be interpreted 'as is' \
95 when the watchpoint is hit. Multiple lines of Python will be wrapped in a \
96 generated function, and a call to the function will be attached to the watchpoint."
97  R"(
98 
99 This auto-generated function is passed in three arguments:
100 
101  frame: an lldb.SBFrame object for the frame which hit the watchpoint.
102 
103  wp: the watchpoint that was hit.
104 
105 )"
106  "When specifying a python function with the --python-function option, you need \
107 to supply the function name prepended by the module name:"
108  R"(
109 
110  --python-function myutils.watchpoint_callback
111 
112 The function itself must have the following prototype:
113 
114 def watchpoint_callback(frame, wp):
115  # Your code goes here
116 
117 )"
118  "The arguments are the same as the arguments passed to generated functions as \
119 described above. Note that the global variable 'lldb.frame' will NOT be updated when \
120 this function is called, so be sure to use the 'frame' argument. The 'frame' argument \
121 can get you to the thread via frame.GetThread(), the thread can get you to the \
122 process via thread.GetProcess(), and the process can get you back to the target \
123 via process.GetTarget()."
124  R"(
125 
126 )"
127  "Important Note: As Python code gets collected into functions, access to global \
128 variables requires explicit scoping using the 'global' keyword. Be sure to use correct \
129 Python syntax, including indentation, when entering Python watchpoint commands."
130  R"(
131 
132 Example Python one-line watchpoint command:
133 
134 (lldb) watchpoint command add -s python 1
135 Enter your Python command(s). Type 'DONE' to end.
136 > print "Hit this watchpoint!"
137 > DONE
138 
139 As a convenience, this also works for a short Python one-liner:
140 
141 (lldb) watchpoint command add -s python 1 -o 'import time; print time.asctime()'
142 (lldb) run
143 Launching '.../a.out' (x86_64)
144 (lldb) Fri Sep 10 12:17:45 2010
145 Process 21778 Stopped
146 * thread #1: tid = 0x2e03, 0x0000000100000de8 a.out`c + 7 at main.c:39, stop reason = watchpoint 1.1, queue = com.apple.main-thread
147  36
148  37 int c(int val)
149  38 {
150  39 -> return val + 3;
151  40 }
152  41
153  42 int main (int argc, char const *argv[])
154 
155 Example multiple line Python watchpoint command, using function definition:
156 
157 (lldb) watchpoint command add -s python 1
158 Enter your Python command(s). Type 'DONE' to end.
159 > def watchpoint_output (wp_no):
160 > out_string = "Hit watchpoint number " + repr (wp_no)
161 > print out_string
162 > return True
163 > watchpoint_output (1)
164 > DONE
165 
166 Example multiple line Python watchpoint command, using 'loose' Python:
167 
168 (lldb) watchpoint command add -s p 1
169 Enter your Python command(s). Type 'DONE' to end.
170 > global wp_count
171 > wp_count = wp_count + 1
172 > print "Hit this watchpoint " + repr(wp_count) + " times!"
173 > DONE
174 
175 )"
176  "In this case, since there is a reference to a global variable, \
177 'wp_count', you will also need to make sure 'wp_count' exists and is \
178 initialized:"
179  R"(
180 
181 (lldb) script
182 >>> wp_count = 0
183 >>> quit()
184 
185 )"
186  "Final Note: A warning that no watchpoint command was generated when there \
187 are no syntax errors may indicate that a function was declared but never called.");
188 
190  CommandArgumentData wp_id_arg;
191 
192  // Define the first (and only) variant of this arg.
193  wp_id_arg.arg_type = eArgTypeWatchpointID;
194  wp_id_arg.arg_repetition = eArgRepeatPlain;
195 
196  // There is only one variant this argument could be; put it into the
197  // argument entry.
198  arg.push_back(wp_id_arg);
199 
200  // Push the data for the first argument into the m_arguments vector.
201  m_arguments.push_back(arg);
202  }
203 
204  ~CommandObjectWatchpointCommandAdd() override = default;
205 
206  Options *GetOptions() override { return &m_options; }
207 
208  void IOHandlerActivated(IOHandler &io_handler, bool interactive) override {
209  StreamFileSP output_sp(io_handler.GetOutputStreamFile());
210  if (output_sp && interactive) {
211  output_sp->PutCString(
212  "Enter your debugger command(s). Type 'DONE' to end.\n");
213  output_sp->Flush();
214  }
215  }
216 
218  std::string &line) override {
219  io_handler.SetIsDone(true);
220 
221  // The WatchpointOptions object is owned by the watchpoint or watchpoint
222  // location
223  WatchpointOptions *wp_options =
224  (WatchpointOptions *)io_handler.GetUserData();
225  if (wp_options) {
226  std::unique_ptr<WatchpointOptions::CommandData> data_up(
228  if (data_up) {
229  data_up->user_source.SplitIntoLines(line);
230  auto baton_sp = std::make_shared<WatchpointOptions::CommandBaton>(
231  std::move(data_up));
232  wp_options->SetCallback(WatchpointOptionsCallbackFunction, baton_sp);
233  }
234  }
235  }
236 
238  CommandReturnObject &result) {
239  m_interpreter.GetLLDBCommandsFromIOHandler(
240  "> ", // Prompt
241  *this, // IOHandlerDelegate
242  true, // Run IOHandler in async mode
243  wp_options); // Baton for the "io_handler" that will be passed back into
244  // our IOHandlerDelegate functions
245  }
246 
247  /// Set a one-liner as the callback for the watchpoint.
249  const char *oneliner) {
250  std::unique_ptr<WatchpointOptions::CommandData> data_up(
252 
253  // It's necessary to set both user_source and script_source to the
254  // oneliner. The former is used to generate callback description (as in
255  // watchpoint command list) while the latter is used for Python to
256  // interpret during the actual callback.
257  data_up->user_source.AppendString(oneliner);
258  data_up->script_source.assign(oneliner);
259  data_up->stop_on_error = m_options.m_stop_on_error;
260 
261  auto baton_sp =
262  std::make_shared<WatchpointOptions::CommandBaton>(std::move(data_up));
263  wp_options->SetCallback(WatchpointOptionsCallbackFunction, baton_sp);
264  }
265 
266  static bool
268  StoppointCallbackContext *context,
269  lldb::user_id_t watch_id) {
270  bool ret_value = true;
271  if (baton == nullptr)
272  return true;
273 
276  StringList &commands = data->user_source;
277 
278  if (commands.GetSize() > 0) {
279  ExecutionContext exe_ctx(context->exe_ctx_ref);
280  Target *target = exe_ctx.GetTargetPtr();
281  if (target) {
282  CommandReturnObject result;
283  Debugger &debugger = target->GetDebugger();
284  // Rig up the results secondary output stream to the debugger's, so the
285  // output will come out synchronously if the debugger is set up that
286  // way.
287 
288  StreamSP output_stream(debugger.GetAsyncOutputStream());
289  StreamSP error_stream(debugger.GetAsyncErrorStream());
290  result.SetImmediateOutputStream(output_stream);
291  result.SetImmediateErrorStream(error_stream);
292 
294  options.SetStopOnContinue(true);
295  options.SetStopOnError(data->stop_on_error);
296  options.SetEchoCommands(false);
297  options.SetPrintResults(true);
298  options.SetAddToHistory(false);
299 
300  debugger.GetCommandInterpreter().HandleCommands(commands, &exe_ctx,
301  options, result);
302  result.GetImmediateOutputStream()->Flush();
303  result.GetImmediateErrorStream()->Flush();
304  }
305  }
306  return ret_value;
307  }
308 
309  class CommandOptions : public Options {
310  public:
312  : Options(), m_use_commands(false), m_use_script_language(false),
313  m_script_language(eScriptLanguageNone), m_use_one_liner(false),
314  m_one_liner(), m_function_name() {}
315 
316  ~CommandOptions() override = default;
317 
318  Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
319  ExecutionContext *execution_context) override {
320  Status error;
321  const int short_option = m_getopt_table[option_idx].val;
322 
323  switch (short_option) {
324  case 'o':
325  m_use_one_liner = true;
326  m_one_liner = option_arg;
327  break;
328 
329  case 's':
330  m_script_language = (lldb::ScriptLanguage)OptionArgParser::ToOptionEnum(
331  option_arg, GetDefinitions()[option_idx].enum_values,
332  eScriptLanguageNone, error);
333 
334  m_use_script_language = (m_script_language == eScriptLanguagePython ||
335  m_script_language == eScriptLanguageDefault);
336  break;
337 
338  case 'e': {
339  bool success = false;
340  m_stop_on_error =
341  OptionArgParser::ToBoolean(option_arg, false, &success);
342  if (!success)
344  "invalid value for stop-on-error: \"%s\"",
345  option_arg.str().c_str());
346  } break;
347 
348  case 'F':
349  m_use_one_liner = false;
350  m_use_script_language = true;
351  m_function_name.assign(option_arg);
352  break;
353 
354  default:
355  break;
356  }
357  return error;
358  }
359 
360  void OptionParsingStarting(ExecutionContext *execution_context) override {
361  m_use_commands = true;
362  m_use_script_language = false;
363  m_script_language = eScriptLanguageNone;
364 
365  m_use_one_liner = false;
366  m_stop_on_error = true;
367  m_one_liner.clear();
368  m_function_name.clear();
369  }
370 
371  llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
372  return llvm::makeArrayRef(g_watchpoint_command_add_options);
373  }
374 
375  // Instance variables to hold the values for command options.
376 
380 
381  // Instance variables to hold the values for one_liner options.
383  std::string m_one_liner;
385  std::string m_function_name;
386  };
387 
388 protected:
389  bool DoExecute(Args &command, CommandReturnObject &result) override {
390  Target *target = GetDebugger().GetSelectedTarget().get();
391 
392  if (target == nullptr) {
393  result.AppendError("There is not a current executable; there are no "
394  "watchpoints to which to add commands");
396  return false;
397  }
398 
399  const WatchpointList &watchpoints = target->GetWatchpointList();
400  size_t num_watchpoints = watchpoints.GetSize();
401 
402  if (num_watchpoints == 0) {
403  result.AppendError("No watchpoints exist to have commands added");
405  return false;
406  }
407 
408  if (!m_options.m_use_script_language &&
409  !m_options.m_function_name.empty()) {
410  result.AppendError("need to enable scripting to have a function run as a "
411  "watchpoint command");
413  return false;
414  }
415 
416  std::vector<uint32_t> valid_wp_ids;
417  if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(target, command,
418  valid_wp_ids)) {
419  result.AppendError("Invalid watchpoints specification.");
421  return false;
422  }
423 
425  const size_t count = valid_wp_ids.size();
426  for (size_t i = 0; i < count; ++i) {
427  uint32_t cur_wp_id = valid_wp_ids.at(i);
428  if (cur_wp_id != LLDB_INVALID_WATCH_ID) {
429  Watchpoint *wp = target->GetWatchpointList().FindByID(cur_wp_id).get();
430  // Sanity check wp first.
431  if (wp == nullptr)
432  continue;
433 
434  WatchpointOptions *wp_options = wp->GetOptions();
435  // Skip this watchpoint if wp_options is not good.
436  if (wp_options == nullptr)
437  continue;
438 
439  // If we are using script language, get the script interpreter in order
440  // to set or collect command callback. Otherwise, call the methods
441  // associated with this object.
442  if (m_options.m_use_script_language) {
443  // Special handling for one-liner specified inline.
444  if (m_options.m_use_one_liner) {
445  GetDebugger().GetScriptInterpreter()->SetWatchpointCommandCallback(
446  wp_options, m_options.m_one_liner.c_str());
447  }
448  // Special handling for using a Python function by name instead of
449  // extending the watchpoint callback data structures, we just
450  // automatize what the user would do manually: make their watchpoint
451  // command be a function call
452  else if (!m_options.m_function_name.empty()) {
453  std::string oneliner(m_options.m_function_name);
454  oneliner += "(frame, wp, internal_dict)";
455  GetDebugger().GetScriptInterpreter()->SetWatchpointCommandCallback(
456  wp_options, oneliner.c_str());
457  } else {
458  GetDebugger()
459  .GetScriptInterpreter()
460  ->CollectDataForWatchpointCommandCallback(wp_options, result);
461  }
462  } else {
463  // Special handling for one-liner specified inline.
464  if (m_options.m_use_one_liner)
465  SetWatchpointCommandCallback(wp_options,
466  m_options.m_one_liner.c_str());
467  else
468  CollectDataForWatchpointCommandCallback(wp_options, result);
469  }
470  }
471  }
472 
473  return result.Succeeded();
474  }
475 
476 private:
477  CommandOptions m_options;
478 };
479 
480 // CommandObjectWatchpointCommandDelete
481 
483 public:
485  : CommandObjectParsed(interpreter, "delete",
486  "Delete the set of commands from a watchpoint.",
487  nullptr) {
489  CommandArgumentData wp_id_arg;
490 
491  // Define the first (and only) variant of this arg.
492  wp_id_arg.arg_type = eArgTypeWatchpointID;
493  wp_id_arg.arg_repetition = eArgRepeatPlain;
494 
495  // There is only one variant this argument could be; put it into the
496  // argument entry.
497  arg.push_back(wp_id_arg);
498 
499  // Push the data for the first argument into the m_arguments vector.
500  m_arguments.push_back(arg);
501  }
502 
503  ~CommandObjectWatchpointCommandDelete() override = default;
504 
505 protected:
506  bool DoExecute(Args &command, CommandReturnObject &result) override {
507  Target *target = GetDebugger().GetSelectedTarget().get();
508 
509  if (target == nullptr) {
510  result.AppendError("There is not a current executable; there are no "
511  "watchpoints from which to delete commands");
513  return false;
514  }
515 
516  const WatchpointList &watchpoints = target->GetWatchpointList();
517  size_t num_watchpoints = watchpoints.GetSize();
518 
519  if (num_watchpoints == 0) {
520  result.AppendError("No watchpoints exist to have commands deleted");
522  return false;
523  }
524 
525  if (command.GetArgumentCount() == 0) {
526  result.AppendError(
527  "No watchpoint specified from which to delete the commands");
529  return false;
530  }
531 
532  std::vector<uint32_t> valid_wp_ids;
533  if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(target, command,
534  valid_wp_ids)) {
535  result.AppendError("Invalid watchpoints specification.");
537  return false;
538  }
539 
541  const size_t count = valid_wp_ids.size();
542  for (size_t i = 0; i < count; ++i) {
543  uint32_t cur_wp_id = valid_wp_ids.at(i);
544  if (cur_wp_id != LLDB_INVALID_WATCH_ID) {
545  Watchpoint *wp = target->GetWatchpointList().FindByID(cur_wp_id).get();
546  if (wp)
547  wp->ClearCallback();
548  } else {
549  result.AppendErrorWithFormat("Invalid watchpoint ID: %u.\n", cur_wp_id);
551  return false;
552  }
553  }
554  return result.Succeeded();
555  }
556 };
557 
558 // CommandObjectWatchpointCommandList
559 
561 public:
563  : CommandObjectParsed(interpreter, "list", "List the script or set of "
564  "commands to be executed when "
565  "the watchpoint is hit.",
566  nullptr) {
568  CommandArgumentData wp_id_arg;
569 
570  // Define the first (and only) variant of this arg.
571  wp_id_arg.arg_type = eArgTypeWatchpointID;
572  wp_id_arg.arg_repetition = eArgRepeatPlain;
573 
574  // There is only one variant this argument could be; put it into the
575  // argument entry.
576  arg.push_back(wp_id_arg);
577 
578  // Push the data for the first argument into the m_arguments vector.
579  m_arguments.push_back(arg);
580  }
581 
582  ~CommandObjectWatchpointCommandList() override = default;
583 
584 protected:
585  bool DoExecute(Args &command, CommandReturnObject &result) override {
586  Target *target = GetDebugger().GetSelectedTarget().get();
587 
588  if (target == nullptr) {
589  result.AppendError("There is not a current executable; there are no "
590  "watchpoints for which to list commands");
592  return false;
593  }
594 
595  const WatchpointList &watchpoints = target->GetWatchpointList();
596  size_t num_watchpoints = watchpoints.GetSize();
597 
598  if (num_watchpoints == 0) {
599  result.AppendError("No watchpoints exist for which to list commands");
601  return false;
602  }
603 
604  if (command.GetArgumentCount() == 0) {
605  result.AppendError(
606  "No watchpoint specified for which to list the commands");
608  return false;
609  }
610 
611  std::vector<uint32_t> valid_wp_ids;
612  if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(target, command,
613  valid_wp_ids)) {
614  result.AppendError("Invalid watchpoints specification.");
616  return false;
617  }
618 
620  const size_t count = valid_wp_ids.size();
621  for (size_t i = 0; i < count; ++i) {
622  uint32_t cur_wp_id = valid_wp_ids.at(i);
623  if (cur_wp_id != LLDB_INVALID_WATCH_ID) {
624  Watchpoint *wp = target->GetWatchpointList().FindByID(cur_wp_id).get();
625 
626  if (wp) {
627  const WatchpointOptions *wp_options = wp->GetOptions();
628  if (wp_options) {
629  // Get the callback baton associated with the current watchpoint.
630  const Baton *baton = wp_options->GetBaton();
631  if (baton) {
632  result.GetOutputStream().Printf("Watchpoint %u:\n", cur_wp_id);
633  result.GetOutputStream().IndentMore();
634  baton->GetDescription(&result.GetOutputStream(),
636  result.GetOutputStream().IndentLess();
637  } else {
639  "Watchpoint %u does not have an associated command.\n",
640  cur_wp_id);
641  }
642  }
644  } else {
645  result.AppendErrorWithFormat("Invalid watchpoint ID: %u.\n",
646  cur_wp_id);
648  }
649  }
650  }
651 
652  return result.Succeeded();
653  }
654 };
655 
656 // CommandObjectWatchpointCommand
657 
658 CommandObjectWatchpointCommand::CommandObjectWatchpointCommand(
659  CommandInterpreter &interpreter)
661  interpreter, "command",
662  "Commands for adding, removing and examining LLDB commands "
663  "executed when the watchpoint is hit (watchpoint 'commands').",
664  "command <sub-command> [<sub-command-options>] <watchpoint-id>") {
665  CommandObjectSP add_command_object(
666  new CommandObjectWatchpointCommandAdd(interpreter));
667  CommandObjectSP delete_command_object(
668  new CommandObjectWatchpointCommandDelete(interpreter));
669  CommandObjectSP list_command_object(
670  new CommandObjectWatchpointCommandList(interpreter));
671 
672  add_command_object->SetCommandName("watchpoint command add");
673  delete_command_object->SetCommandName("watchpoint command delete");
674  list_command_object->SetCommandName("watchpoint command list");
675 
676  LoadSubCommand("add", add_command_object);
677  LoadSubCommand("delete", delete_command_object);
678  LoadSubCommand("list", list_command_object);
679 }
680 
A class to manage flag bits.
Definition: Debugger.h:82
CommandObjectWatchpointCommandDelete(CommandInterpreter &interpreter)
std::vector< CommandArgumentData > CommandArgumentEntry
A command line argument class.
Definition: Args.h:32
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
WatchpointList & GetWatchpointList()
Definition: Target.h:694
CommandInterpreter & GetCommandInterpreter()
Definition: Debugger.h:152
This class is used by Watchpoint to manage a list of watchpoints,.
void CollectDataForWatchpointCommandCallback(WatchpointOptions *wp_options, CommandReturnObject &result)
static constexpr OptionEnumValueElement g_script_option_enumeration[]
bool LoadSubCommand(llvm::StringRef cmd_name, const lldb::CommandObjectSP &command_obj) override
void AppendErrorWithFormat(const char *format,...) __attribute__((format(printf
void SetImmediateErrorStream(const lldb::StreamSP &stream_sp)
size_t GetArgumentCount() const
Gets the number of arguments left in this command object.
Definition: Args.cpp:254
lldb::WatchpointSP FindByID(lldb::watch_id_t watchID) const
Returns a shared pointer to the watchpoint with id watchID, const version.
void IOHandlerActivated(IOHandler &io_handler, bool interactive) override
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
lldb::StreamSP GetAsyncErrorStream()
Definition: Debugger.cpp:1153
A delegate class for use with IOHandler subclasses.
Definition: IOHandler.h:188
static constexpr OptionEnumValues ScriptOptionEnum()
size_t GetSize() const
Returns the number of elements in this watchpoint list.
WatchpointOptions * GetOptions()
Returns the WatchpointOptions structure set for this watchpoint.
Definition: Watchpoint.h:104
bool DoExecute(Args &command, CommandReturnObject &result) override
virtual void GetDescription(Stream *s, lldb::DescriptionLevel level) const =0
Target * GetTargetPtr() const
Returns a pointer to the target object.
lldb::StreamSP GetAsyncOutputStream()
Definition: Debugger.cpp:1149
uint64_t user_id_t
Definition: lldb-types.h:84
bool DoExecute(Args &command, CommandReturnObject &result) override
void AppendMessageWithFormat(const char *format,...) __attribute__((format(printf
void SetImmediateOutputStream(const lldb::StreamSP &stream_sp)
void SetCallback(WatchpointHitCallback callback, const lldb::BatonSP &baton_sp, bool synchronous=false)
Adds a callback to the watchpoint option set.
void IndentLess(int amount=2)
Decrement the current indentation level.
Definition: Stream.cpp:221
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:106
CommandObjectWatchpointCommandAdd(CommandInterpreter &interpreter)
CommandObjectWatchpointCommandList(CommandInterpreter &interpreter)
Baton * GetBaton()
Fetch the baton from the callback.
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
size_t GetSize() const
Definition: StringList.cpp:70
#define LLDB_OPT_SET_2
Definition: lldb-defines.h:112
bool DoExecute(Args &command, CommandReturnObject &result) override
void HandleCommands(const StringList &commands, ExecutionContext *context, CommandInterpreterRunOptions &options, CommandReturnObject &result)
Execute a list of commands in sequence.
A command line option parsing protocol class.
Definition: Options.h:62
"lldb/Breakpoint/WatchpointOptions.h" Class that manages the options on a watchpoint.
static constexpr OptionDefinition g_watchpoint_command_add_options[]
void void AppendError(llvm::StringRef in_string)
void SetStopOnContinue(bool stop_on_continue)
void SetWatchpointCommandCallback(WatchpointOptions *wp_options, const char *oneliner)
Set a one-liner as the callback for the watchpoint.
#define LLDB_INVALID_WATCH_ID
Definition: lldb-defines.h:55
Definition: SBAddress.h:15
virtual void SetIsDone(bool b)
Definition: IOHandler.h:86
#define LLDB_OPT_SET_ALL
Definition: lldb-defines.h:110
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
A class designed to wrap callback batons so they can cleanup any acquired resources.
Definition: Baton.h:33
lldb::StreamFileSP & GetOutputStreamFile()
Definition: IOHandler.cpp:126
int SetErrorStringWithFormat(const char *format,...) __attribute__((format(printf
Set the current error string to a formatted error string.
Definition: Status.cpp:255
General Outline: When we hit a breakpoint we need to package up whatever information is needed to eva...
void IOHandlerInputComplete(IOHandler &io_handler, std::string &line) override
Called when a line or lines have been retrieved.
void IndentMore(int amount=2)
Increment the current indentation level.
Definition: Stream.cpp:218
#define LLDB_OPT_SET_1
Definition: lldb-defines.h:111
static bool WatchpointOptionsCallbackFunction(void *baton, StoppointCallbackContext *context, lldb::user_id_t watch_id)
void OptionParsingStarting(ExecutionContext *execution_context) override
void SetStatus(lldb::ReturnStatus status)
Debugger & GetDebugger()
Definition: Target.h:974
An error handling class.
Definition: Status.h:44