LLDB  mainline
CommandObjectWatchpoint.cpp
Go to the documentation of this file.
1 //===-- CommandObjectWatchpoint.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 
11 
12 #include <vector>
13 
14 #include "llvm/ADT/StringRef.h"
15 
18 #include "lldb/Core/ValueObject.h"
20 #include "lldb/Host/OptionParser.h"
24 #include "lldb/Symbol/Variable.h"
26 #include "lldb/Target/StackFrame.h"
27 #include "lldb/Target/Target.h"
29 
30 using namespace lldb;
31 using namespace lldb_private;
32 
34  lldb::DescriptionLevel level) {
35  s->IndentMore();
36  wp->GetDescription(s, level);
37  s->IndentLess();
38  s->EOL();
39 }
40 
42  CommandReturnObject &result) {
43  if (target == nullptr) {
44  result.AppendError("Invalid target. No existing target or watchpoints.");
46  return false;
47  }
48  bool process_is_valid =
49  target->GetProcessSP() && target->GetProcessSP()->IsAlive();
50  if (!process_is_valid) {
51  result.AppendError("Thre's no process or it is not alive.");
53  return false;
54  }
55  // Target passes our checks, return true.
56  return true;
57 }
58 
59 // Equivalent class: {"-", "to", "To", "TO"} of range specifier array.
60 static const char *RSA[4] = {"-", "to", "To", "TO"};
61 
62 // Return the index to RSA if found; otherwise -1 is returned.
63 static int32_t WithRSAIndex(llvm::StringRef Arg) {
64 
65  uint32_t i;
66  for (i = 0; i < 4; ++i)
67  if (Arg.find(RSA[i]) != llvm::StringRef::npos)
68  return i;
69  return -1;
70 }
71 
72 // Return true if wp_ids is successfully populated with the watch ids. False
73 // otherwise.
74 bool CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(
75  Target *target, Args &args, std::vector<uint32_t> &wp_ids) {
76  // Pre-condition: args.GetArgumentCount() > 0.
77  if (args.GetArgumentCount() == 0) {
78  if (target == nullptr)
79  return false;
80  WatchpointSP watch_sp = target->GetLastCreatedWatchpoint();
81  if (watch_sp) {
82  wp_ids.push_back(watch_sp->GetID());
83  return true;
84  } else
85  return false;
86  }
87 
88  llvm::StringRef Minus("-");
89  std::vector<llvm::StringRef> StrRefArgs;
90  llvm::StringRef first;
91  llvm::StringRef second;
92  size_t i;
93  int32_t idx;
94  // Go through the arguments and make a canonical form of arg list containing
95  // only numbers with possible "-" in between.
96  for (auto &entry : args.entries()) {
97  if ((idx = WithRSAIndex(entry.ref)) == -1) {
98  StrRefArgs.push_back(entry.ref);
99  continue;
100  }
101  // The Arg contains the range specifier, split it, then.
102  std::tie(first, second) = entry.ref.split(RSA[idx]);
103  if (!first.empty())
104  StrRefArgs.push_back(first);
105  StrRefArgs.push_back(Minus);
106  if (!second.empty())
107  StrRefArgs.push_back(second);
108  }
109  // Now process the canonical list and fill in the vector of uint32_t's. If
110  // there is any error, return false and the client should ignore wp_ids.
111  uint32_t beg, end, id;
112  size_t size = StrRefArgs.size();
113  bool in_range = false;
114  for (i = 0; i < size; ++i) {
115  llvm::StringRef Arg = StrRefArgs[i];
116  if (in_range) {
117  // Look for the 'end' of the range. Note StringRef::getAsInteger()
118  // returns true to signify error while parsing.
119  if (Arg.getAsInteger(0, end))
120  return false;
121  // Found a range! Now append the elements.
122  for (id = beg; id <= end; ++id)
123  wp_ids.push_back(id);
124  in_range = false;
125  continue;
126  }
127  if (i < (size - 1) && StrRefArgs[i + 1] == Minus) {
128  if (Arg.getAsInteger(0, beg))
129  return false;
130  // Turn on the in_range flag, we are looking for end of range next.
131  ++i;
132  in_range = true;
133  continue;
134  }
135  // Otherwise, we have a simple ID. Just append it.
136  if (Arg.getAsInteger(0, beg))
137  return false;
138  wp_ids.push_back(beg);
139  }
140 
141  // It is an error if after the loop, we're still in_range.
142  return !in_range;
143 }
144 
145 // CommandObjectWatchpointList
146 
147 // CommandObjectWatchpointList::Options
148 #pragma mark List::CommandOptions
149 
150 static constexpr OptionDefinition g_watchpoint_list_options[] = {
151  // clang-format off
152  { LLDB_OPT_SET_1, false, "brief", 'b', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Give a brief description of the watchpoint (no location info)." },
153  { LLDB_OPT_SET_2, false, "full", 'f', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Give a full description of the watchpoint and its locations." },
154  { LLDB_OPT_SET_3, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Explain everything we know about the watchpoint (for debugging debugger bugs)." }
155  // clang-format on
156 };
157 
158 #pragma mark List
159 
161 public:
164  interpreter, "watchpoint list",
165  "List all watchpoints at configurable levels of detail.", nullptr),
166  m_options() {
168  CommandObject::AddIDsArgumentData(arg, eArgTypeWatchpointID,
170  // Add the entry for the first argument for this command to the object's
171  // arguments vector.
172  m_arguments.push_back(arg);
173  }
174 
175  ~CommandObjectWatchpointList() override = default;
176 
177  Options *GetOptions() override { return &m_options; }
178 
179  class CommandOptions : public Options {
180  public:
182  : Options(),
183  m_level(lldb::eDescriptionLevelBrief) // Watchpoint List defaults to
184  // brief descriptions
185  {}
186 
187  ~CommandOptions() override = default;
188 
189  Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
190  ExecutionContext *execution_context) override {
191  Status error;
192  const int short_option = m_getopt_table[option_idx].val;
193 
194  switch (short_option) {
195  case 'b':
197  break;
198  case 'f':
199  m_level = lldb::eDescriptionLevelFull;
200  break;
201  case 'v':
203  break;
204  default:
205  error.SetErrorStringWithFormat("unrecognized option '%c'",
206  short_option);
207  break;
208  }
209 
210  return error;
211  }
212 
213  void OptionParsingStarting(ExecutionContext *execution_context) override {
214  m_level = lldb::eDescriptionLevelFull;
215  }
216 
217  llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
218  return llvm::makeArrayRef(g_watchpoint_list_options);
219  }
220 
221  // Instance variables to hold the values for command options.
222 
224  };
225 
226 protected:
227  bool DoExecute(Args &command, CommandReturnObject &result) override {
228  Target *target = GetDebugger().GetSelectedTarget().get();
229  if (target == nullptr) {
230  result.AppendError("Invalid target. No current target or watchpoints.");
232  return true;
233  }
234 
235  if (target->GetProcessSP() && target->GetProcessSP()->IsAlive()) {
236  uint32_t num_supported_hardware_watchpoints;
237  Status error = target->GetProcessSP()->GetWatchpointSupportInfo(
238  num_supported_hardware_watchpoints);
239  if (error.Success())
241  "Number of supported hardware watchpoints: %u\n",
242  num_supported_hardware_watchpoints);
243  }
244 
245  const WatchpointList &watchpoints = target->GetWatchpointList();
246 
247  std::unique_lock<std::recursive_mutex> lock;
248  target->GetWatchpointList().GetListMutex(lock);
249 
250  size_t num_watchpoints = watchpoints.GetSize();
251 
252  if (num_watchpoints == 0) {
253  result.AppendMessage("No watchpoints currently set.");
255  return true;
256  }
257 
258  Stream &output_stream = result.GetOutputStream();
259 
260  if (command.GetArgumentCount() == 0) {
261  // No watchpoint selected; show info about all currently set watchpoints.
262  result.AppendMessage("Current watchpoints:");
263  for (size_t i = 0; i < num_watchpoints; ++i) {
264  Watchpoint *wp = watchpoints.GetByIndex(i).get();
265  AddWatchpointDescription(&output_stream, wp, m_options.m_level);
266  }
268  } else {
269  // Particular watchpoints selected; enable them.
270  std::vector<uint32_t> wp_ids;
271  if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(
272  target, command, wp_ids)) {
273  result.AppendError("Invalid watchpoints specification.");
275  return false;
276  }
277 
278  const size_t size = wp_ids.size();
279  for (size_t i = 0; i < size; ++i) {
280  Watchpoint *wp = watchpoints.FindByID(wp_ids[i]).get();
281  if (wp)
282  AddWatchpointDescription(&output_stream, wp, m_options.m_level);
284  }
285  }
286 
287  return result.Succeeded();
288  }
289 
290 private:
291  CommandOptions m_options;
292 };
293 
294 // CommandObjectWatchpointEnable
295 #pragma mark Enable
296 
298 public:
300  : CommandObjectParsed(interpreter, "enable",
301  "Enable the specified disabled watchpoint(s). If "
302  "no watchpoints are specified, enable all of them.",
303  nullptr) {
305  CommandObject::AddIDsArgumentData(arg, eArgTypeWatchpointID,
307  // Add the entry for the first argument for this command to the object's
308  // arguments vector.
309  m_arguments.push_back(arg);
310  }
311 
312  ~CommandObjectWatchpointEnable() override = default;
313 
314 protected:
315  bool DoExecute(Args &command, CommandReturnObject &result) override {
316  Target *target = GetDebugger().GetSelectedTarget().get();
317  if (!CheckTargetForWatchpointOperations(target, result))
318  return false;
319 
320  std::unique_lock<std::recursive_mutex> lock;
321  target->GetWatchpointList().GetListMutex(lock);
322 
323  const WatchpointList &watchpoints = target->GetWatchpointList();
324 
325  size_t num_watchpoints = watchpoints.GetSize();
326 
327  if (num_watchpoints == 0) {
328  result.AppendError("No watchpoints exist to be enabled.");
330  return false;
331  }
332 
333  if (command.GetArgumentCount() == 0) {
334  // No watchpoint selected; enable all currently set watchpoints.
335  target->EnableAllWatchpoints();
336  result.AppendMessageWithFormat("All watchpoints enabled. (%" PRIu64
337  " watchpoints)\n",
338  (uint64_t)num_watchpoints);
340  } else {
341  // Particular watchpoints selected; enable them.
342  std::vector<uint32_t> wp_ids;
343  if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(
344  target, command, wp_ids)) {
345  result.AppendError("Invalid watchpoints specification.");
347  return false;
348  }
349 
350  int count = 0;
351  const size_t size = wp_ids.size();
352  for (size_t i = 0; i < size; ++i)
353  if (target->EnableWatchpointByID(wp_ids[i]))
354  ++count;
355  result.AppendMessageWithFormat("%d watchpoints enabled.\n", count);
357  }
358 
359  return result.Succeeded();
360  }
361 };
362 
363 // CommandObjectWatchpointDisable
364 #pragma mark Disable
365 
367 public:
369  : CommandObjectParsed(interpreter, "watchpoint disable",
370  "Disable the specified watchpoint(s) without "
371  "removing it/them. If no watchpoints are "
372  "specified, disable them all.",
373  nullptr) {
375  CommandObject::AddIDsArgumentData(arg, eArgTypeWatchpointID,
377  // Add the entry for the first argument for this command to the object's
378  // arguments vector.
379  m_arguments.push_back(arg);
380  }
381 
382  ~CommandObjectWatchpointDisable() override = default;
383 
384 protected:
385  bool DoExecute(Args &command, CommandReturnObject &result) override {
386  Target *target = GetDebugger().GetSelectedTarget().get();
387  if (!CheckTargetForWatchpointOperations(target, result))
388  return false;
389 
390  std::unique_lock<std::recursive_mutex> lock;
391  target->GetWatchpointList().GetListMutex(lock);
392 
393  const WatchpointList &watchpoints = target->GetWatchpointList();
394  size_t num_watchpoints = watchpoints.GetSize();
395 
396  if (num_watchpoints == 0) {
397  result.AppendError("No watchpoints exist to be disabled.");
399  return false;
400  }
401 
402  if (command.GetArgumentCount() == 0) {
403  // No watchpoint selected; disable all currently set watchpoints.
404  if (target->DisableAllWatchpoints()) {
405  result.AppendMessageWithFormat("All watchpoints disabled. (%" PRIu64
406  " watchpoints)\n",
407  (uint64_t)num_watchpoints);
409  } else {
410  result.AppendError("Disable all watchpoints failed\n");
412  }
413  } else {
414  // Particular watchpoints selected; disable them.
415  std::vector<uint32_t> wp_ids;
416  if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(
417  target, command, wp_ids)) {
418  result.AppendError("Invalid watchpoints specification.");
420  return false;
421  }
422 
423  int count = 0;
424  const size_t size = wp_ids.size();
425  for (size_t i = 0; i < size; ++i)
426  if (target->DisableWatchpointByID(wp_ids[i]))
427  ++count;
428  result.AppendMessageWithFormat("%d watchpoints disabled.\n", count);
430  }
431 
432  return result.Succeeded();
433  }
434 };
435 
436 // CommandObjectWatchpointDelete
437 #pragma mark Delete
438 
440 public:
442  : CommandObjectParsed(interpreter, "watchpoint delete",
443  "Delete the specified watchpoint(s). If no "
444  "watchpoints are specified, delete them all.",
445  nullptr) {
447  CommandObject::AddIDsArgumentData(arg, eArgTypeWatchpointID,
449  // Add the entry for the first argument for this command to the object's
450  // arguments vector.
451  m_arguments.push_back(arg);
452  }
453 
454  ~CommandObjectWatchpointDelete() override = default;
455 
456 protected:
457  bool DoExecute(Args &command, CommandReturnObject &result) override {
458  Target *target = GetDebugger().GetSelectedTarget().get();
459  if (!CheckTargetForWatchpointOperations(target, result))
460  return false;
461 
462  std::unique_lock<std::recursive_mutex> lock;
463  target->GetWatchpointList().GetListMutex(lock);
464 
465  const WatchpointList &watchpoints = target->GetWatchpointList();
466 
467  size_t num_watchpoints = watchpoints.GetSize();
468 
469  if (num_watchpoints == 0) {
470  result.AppendError("No watchpoints exist to be deleted.");
472  return false;
473  }
474 
475  if (command.GetArgumentCount() == 0) {
476  if (!m_interpreter.Confirm(
477  "About to delete all watchpoints, do you want to do that?",
478  true)) {
479  result.AppendMessage("Operation cancelled...");
480  } else {
481  target->RemoveAllWatchpoints();
482  result.AppendMessageWithFormat("All watchpoints removed. (%" PRIu64
483  " watchpoints)\n",
484  (uint64_t)num_watchpoints);
485  }
487  } else {
488  // Particular watchpoints selected; delete them.
489  std::vector<uint32_t> wp_ids;
490  if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(
491  target, command, wp_ids)) {
492  result.AppendError("Invalid watchpoints specification.");
494  return false;
495  }
496 
497  int count = 0;
498  const size_t size = wp_ids.size();
499  for (size_t i = 0; i < size; ++i)
500  if (target->RemoveWatchpointByID(wp_ids[i]))
501  ++count;
502  result.AppendMessageWithFormat("%d watchpoints deleted.\n", count);
504  }
505 
506  return result.Succeeded();
507  }
508 };
509 
510 // CommandObjectWatchpointIgnore
511 
512 #pragma mark Ignore::CommandOptions
513 static constexpr OptionDefinition g_watchpoint_ignore_options[] = {
514  // clang-format off
515  { LLDB_OPT_SET_ALL, true, "ignore-count", 'i', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeCount, "Set the number of times this watchpoint is skipped before stopping." }
516  // clang-format on
517 };
518 
520 public:
522  : CommandObjectParsed(interpreter, "watchpoint ignore",
523  "Set ignore count on the specified watchpoint(s). "
524  "If no watchpoints are specified, set them all.",
525  nullptr),
526  m_options() {
528  CommandObject::AddIDsArgumentData(arg, eArgTypeWatchpointID,
530  // Add the entry for the first argument for this command to the object's
531  // arguments vector.
532  m_arguments.push_back(arg);
533  }
534 
535  ~CommandObjectWatchpointIgnore() override = default;
536 
537  Options *GetOptions() override { return &m_options; }
538 
539  class CommandOptions : public Options {
540  public:
541  CommandOptions() : Options(), m_ignore_count(0) {}
542 
543  ~CommandOptions() override = default;
544 
545  Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
546  ExecutionContext *execution_context) override {
547  Status error;
548  const int short_option = m_getopt_table[option_idx].val;
549 
550  switch (short_option) {
551  case 'i':
552  if (option_arg.getAsInteger(0, m_ignore_count))
553  error.SetErrorStringWithFormat("invalid ignore count '%s'",
554  option_arg.str().c_str());
555  break;
556  default:
557  error.SetErrorStringWithFormat("unrecognized option '%c'",
558  short_option);
559  break;
560  }
561 
562  return error;
563  }
564 
565  void OptionParsingStarting(ExecutionContext *execution_context) override {
566  m_ignore_count = 0;
567  }
568 
569  llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
570  return llvm::makeArrayRef(g_watchpoint_ignore_options);
571  }
572 
573  // Instance variables to hold the values for command options.
574 
576  };
577 
578 protected:
579  bool DoExecute(Args &command, CommandReturnObject &result) override {
580  Target *target = GetDebugger().GetSelectedTarget().get();
581  if (!CheckTargetForWatchpointOperations(target, result))
582  return false;
583 
584  std::unique_lock<std::recursive_mutex> lock;
585  target->GetWatchpointList().GetListMutex(lock);
586 
587  const WatchpointList &watchpoints = target->GetWatchpointList();
588 
589  size_t num_watchpoints = watchpoints.GetSize();
590 
591  if (num_watchpoints == 0) {
592  result.AppendError("No watchpoints exist to be ignored.");
594  return false;
595  }
596 
597  if (command.GetArgumentCount() == 0) {
598  target->IgnoreAllWatchpoints(m_options.m_ignore_count);
599  result.AppendMessageWithFormat("All watchpoints ignored. (%" PRIu64
600  " watchpoints)\n",
601  (uint64_t)num_watchpoints);
603  } else {
604  // Particular watchpoints selected; ignore them.
605  std::vector<uint32_t> wp_ids;
606  if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(
607  target, command, wp_ids)) {
608  result.AppendError("Invalid watchpoints specification.");
610  return false;
611  }
612 
613  int count = 0;
614  const size_t size = wp_ids.size();
615  for (size_t i = 0; i < size; ++i)
616  if (target->IgnoreWatchpointByID(wp_ids[i], m_options.m_ignore_count))
617  ++count;
618  result.AppendMessageWithFormat("%d watchpoints ignored.\n", count);
620  }
621 
622  return result.Succeeded();
623  }
624 
625 private:
626  CommandOptions m_options;
627 };
628 
629 // CommandObjectWatchpointModify
630 
631 #pragma mark Modify::CommandOptions
632 
633 static constexpr OptionDefinition g_watchpoint_modify_options[] = {
634  // clang-format off
635  { LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeExpression, "The watchpoint stops only if this condition expression evaluates to true." }
636  // clang-format on
637 };
638 
639 #pragma mark Modify
640 
642 public:
645  interpreter, "watchpoint modify",
646  "Modify the options on a watchpoint or set of watchpoints in the "
647  "executable. "
648  "If no watchpoint is specified, act on the last created "
649  "watchpoint. "
650  "Passing an empty argument clears the modification.",
651  nullptr),
652  m_options() {
654  CommandObject::AddIDsArgumentData(arg, eArgTypeWatchpointID,
656  // Add the entry for the first argument for this command to the object's
657  // arguments vector.
658  m_arguments.push_back(arg);
659  }
660 
661  ~CommandObjectWatchpointModify() override = default;
662 
663  Options *GetOptions() override { return &m_options; }
664 
665  class CommandOptions : public Options {
666  public:
667  CommandOptions() : Options(), m_condition(), m_condition_passed(false) {}
668 
669  ~CommandOptions() override = default;
670 
671  Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
672  ExecutionContext *execution_context) override {
673  Status error;
674  const int short_option = m_getopt_table[option_idx].val;
675 
676  switch (short_option) {
677  case 'c':
678  m_condition = option_arg;
679  m_condition_passed = true;
680  break;
681  default:
682  error.SetErrorStringWithFormat("unrecognized option '%c'",
683  short_option);
684  break;
685  }
686 
687  return error;
688  }
689 
690  void OptionParsingStarting(ExecutionContext *execution_context) override {
691  m_condition.clear();
692  m_condition_passed = false;
693  }
694 
695  llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
696  return llvm::makeArrayRef(g_watchpoint_modify_options);
697  }
698 
699  // Instance variables to hold the values for command options.
700 
701  std::string m_condition;
703  };
704 
705 protected:
706  bool DoExecute(Args &command, CommandReturnObject &result) override {
707  Target *target = GetDebugger().GetSelectedTarget().get();
708  if (!CheckTargetForWatchpointOperations(target, result))
709  return false;
710 
711  std::unique_lock<std::recursive_mutex> lock;
712  target->GetWatchpointList().GetListMutex(lock);
713 
714  const WatchpointList &watchpoints = target->GetWatchpointList();
715 
716  size_t num_watchpoints = watchpoints.GetSize();
717 
718  if (num_watchpoints == 0) {
719  result.AppendError("No watchpoints exist to be modified.");
721  return false;
722  }
723 
724  if (command.GetArgumentCount() == 0) {
725  WatchpointSP wp_sp = target->GetLastCreatedWatchpoint();
726  wp_sp->SetCondition(m_options.m_condition.c_str());
728  } else {
729  // Particular watchpoints selected; set condition on them.
730  std::vector<uint32_t> wp_ids;
731  if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(
732  target, command, wp_ids)) {
733  result.AppendError("Invalid watchpoints specification.");
735  return false;
736  }
737 
738  int count = 0;
739  const size_t size = wp_ids.size();
740  for (size_t i = 0; i < size; ++i) {
741  WatchpointSP wp_sp = watchpoints.FindByID(wp_ids[i]);
742  if (wp_sp) {
743  wp_sp->SetCondition(m_options.m_condition.c_str());
744  ++count;
745  }
746  }
747  result.AppendMessageWithFormat("%d watchpoints modified.\n", count);
749  }
750 
751  return result.Succeeded();
752  }
753 
754 private:
755  CommandOptions m_options;
756 };
757 
758 // CommandObjectWatchpointSetVariable
759 #pragma mark SetVariable
760 
762 public:
765  interpreter, "watchpoint set variable",
766  "Set a watchpoint on a variable. "
767  "Use the '-w' option to specify the type of watchpoint and "
768  "the '-s' option to specify the byte size to watch for. "
769  "If no '-w' option is specified, it defaults to write. "
770  "If no '-s' option is specified, it defaults to the variable's "
771  "byte size. "
772  "Note that there are limited hardware resources for watchpoints. "
773  "If watchpoint setting fails, consider disable/delete existing "
774  "ones "
775  "to free up resources.",
776  nullptr,
777  eCommandRequiresFrame | eCommandTryTargetAPILock |
778  eCommandProcessMustBeLaunched | eCommandProcessMustBePaused),
779  m_option_group(), m_option_watchpoint() {
780  SetHelpLong(
781  R"(
782 Examples:
783 
784 (lldb) watchpoint set variable -w read_write my_global_var
785 
786 )"
787  " Watches my_global_var for read/write access, with the region to watch \
788 corresponding to the byte size of the data type.");
789 
791  CommandArgumentData var_name_arg;
792 
793  // Define the only variant of this arg.
794  var_name_arg.arg_type = eArgTypeVarName;
795  var_name_arg.arg_repetition = eArgRepeatPlain;
796 
797  // Push the variant into the argument entry.
798  arg.push_back(var_name_arg);
799 
800  // Push the data for the only argument into the m_arguments vector.
801  m_arguments.push_back(arg);
802 
803  // Absorb the '-w' and '-s' options into our option group.
804  m_option_group.Append(&m_option_watchpoint, LLDB_OPT_SET_ALL,
806  m_option_group.Finalize();
807  }
808 
809  ~CommandObjectWatchpointSetVariable() override = default;
810 
811  Options *GetOptions() override { return &m_option_group; }
812 
813 protected:
814  static size_t GetVariableCallback(void *baton, const char *name,
815  VariableList &variable_list) {
816  Target *target = static_cast<Target *>(baton);
817  if (target) {
818  return target->GetImages().FindGlobalVariables(ConstString(name),
819  UINT32_MAX, variable_list);
820  }
821  return 0;
822  }
823 
824  bool DoExecute(Args &command, CommandReturnObject &result) override {
825  Target *target = GetDebugger().GetSelectedTarget().get();
826  StackFrame *frame = m_exe_ctx.GetFramePtr();
827 
828  // If no argument is present, issue an error message. There's no way to
829  // set a watchpoint.
830  if (command.GetArgumentCount() <= 0) {
831  result.GetErrorStream().Printf("error: required argument missing; "
832  "specify your program variable to watch "
833  "for\n");
835  return false;
836  }
837 
838  // If no '-w' is specified, default to '-w write'.
839  if (!m_option_watchpoint.watch_type_specified) {
840  m_option_watchpoint.watch_type = OptionGroupWatchpoint::eWatchWrite;
841  }
842 
843  // We passed the sanity check for the command. Proceed to set the
844  // watchpoint now.
845  lldb::addr_t addr = 0;
846  size_t size = 0;
847 
848  VariableSP var_sp;
849  ValueObjectSP valobj_sp;
850  Stream &output_stream = result.GetOutputStream();
851 
852  // A simple watch variable gesture allows only one argument.
853  if (command.GetArgumentCount() != 1) {
854  result.GetErrorStream().Printf(
855  "error: specify exactly one variable to watch for\n");
857  return false;
858  }
859 
860  // Things have checked out ok...
861  Status error;
862  uint32_t expr_path_options =
863  StackFrame::eExpressionPathOptionCheckPtrVsMember |
864  StackFrame::eExpressionPathOptionsAllowDirectIVarAccess;
865  valobj_sp = frame->GetValueForVariableExpressionPath(
866  command.GetArgumentAtIndex(0), eNoDynamicValues, expr_path_options,
867  var_sp, error);
868 
869  if (!valobj_sp) {
870  // Not in the frame; let's check the globals.
871 
872  VariableList variable_list;
873  ValueObjectList valobj_list;
874 
875  Status error(Variable::GetValuesForVariableExpressionPath(
876  command.GetArgumentAtIndex(0),
877  m_exe_ctx.GetBestExecutionContextScope(), GetVariableCallback, target,
878  variable_list, valobj_list));
879 
880  if (valobj_list.GetSize())
881  valobj_sp = valobj_list.GetValueObjectAtIndex(0);
882  }
883 
884  CompilerType compiler_type;
885 
886  if (valobj_sp) {
887  AddressType addr_type;
888  addr = valobj_sp->GetAddressOf(false, &addr_type);
889  if (addr_type == eAddressTypeLoad) {
890  // We're in business.
891  // Find out the size of this variable.
892  size = m_option_watchpoint.watch_size == 0
893  ? valobj_sp->GetByteSize()
894  : m_option_watchpoint.watch_size;
895  }
896  compiler_type = valobj_sp->GetCompilerType();
897  } else {
898  const char *error_cstr = error.AsCString(nullptr);
899  if (error_cstr)
900  result.GetErrorStream().Printf("error: %s\n", error_cstr);
901  else
902  result.GetErrorStream().Printf("error: unable to find any variable "
903  "expression path that matches '%s'\n",
904  command.GetArgumentAtIndex(0));
905  return false;
906  }
907 
908  // Now it's time to create the watchpoint.
909  uint32_t watch_type = m_option_watchpoint.watch_type;
910 
911  error.Clear();
912  Watchpoint *wp =
913  target->CreateWatchpoint(addr, size, &compiler_type, watch_type, error)
914  .get();
915  if (wp) {
916  wp->SetWatchSpec(command.GetArgumentAtIndex(0));
917  wp->SetWatchVariable(true);
918  if (var_sp && var_sp->GetDeclaration().GetFile()) {
919  StreamString ss;
920  // True to show fullpath for declaration file.
921  var_sp->GetDeclaration().DumpStopContext(&ss, true);
922  wp->SetDeclInfo(ss.GetString());
923  }
924  output_stream.Printf("Watchpoint created: ");
925  wp->GetDescription(&output_stream, lldb::eDescriptionLevelFull);
926  output_stream.EOL();
928  } else {
929  result.AppendErrorWithFormat(
930  "Watchpoint creation failed (addr=0x%" PRIx64 ", size=%" PRIu64
931  ", variable expression='%s').\n",
932  addr, (uint64_t)size, command.GetArgumentAtIndex(0));
933  if (error.AsCString(nullptr))
934  result.AppendError(error.AsCString());
936  }
937 
938  return result.Succeeded();
939  }
940 
941 private:
942  OptionGroupOptions m_option_group;
943  OptionGroupWatchpoint m_option_watchpoint;
944 };
945 
946 // CommandObjectWatchpointSetExpression
947 #pragma mark Set
948 
950 public:
953  interpreter, "watchpoint set expression",
954  "Set a watchpoint on an address by supplying an expression. "
955  "Use the '-w' option to specify the type of watchpoint and "
956  "the '-s' option to specify the byte size to watch for. "
957  "If no '-w' option is specified, it defaults to write. "
958  "If no '-s' option is specified, it defaults to the target's "
959  "pointer byte size. "
960  "Note that there are limited hardware resources for watchpoints. "
961  "If watchpoint setting fails, consider disable/delete existing "
962  "ones "
963  "to free up resources.",
964  "",
965  eCommandRequiresFrame | eCommandTryTargetAPILock |
966  eCommandProcessMustBeLaunched | eCommandProcessMustBePaused),
967  m_option_group(), m_option_watchpoint() {
968  SetHelpLong(
969  R"(
970 Examples:
971 
972 (lldb) watchpoint set expression -w write -s 1 -- foo + 32
973 
974  Watches write access for the 1-byte region pointed to by the address 'foo + 32')");
975 
977  CommandArgumentData expression_arg;
978 
979  // Define the only variant of this arg.
980  expression_arg.arg_type = eArgTypeExpression;
981  expression_arg.arg_repetition = eArgRepeatPlain;
982 
983  // Push the only variant into the argument entry.
984  arg.push_back(expression_arg);
985 
986  // Push the data for the only argument into the m_arguments vector.
987  m_arguments.push_back(arg);
988 
989  // Absorb the '-w' and '-s' options into our option group.
990  m_option_group.Append(&m_option_watchpoint, LLDB_OPT_SET_ALL,
992  m_option_group.Finalize();
993  }
994 
995  ~CommandObjectWatchpointSetExpression() override = default;
996 
997  // Overrides base class's behavior where WantsCompletion =
998  // !WantsRawCommandString.
999  bool WantsCompletion() override { return true; }
1000 
1001  Options *GetOptions() override { return &m_option_group; }
1002 
1003 protected:
1004  bool DoExecute(llvm::StringRef raw_command,
1005  CommandReturnObject &result) override {
1006  auto exe_ctx = GetCommandInterpreter().GetExecutionContext();
1007  m_option_group.NotifyOptionParsingStarting(
1008  &exe_ctx); // This is a raw command, so notify the option group
1009 
1010  Target *target = GetDebugger().GetSelectedTarget().get();
1011  StackFrame *frame = m_exe_ctx.GetFramePtr();
1012 
1013  OptionsWithRaw args(raw_command);
1014 
1015  llvm::StringRef expr = args.GetRawPart();
1016 
1017  if (args.HasArgs())
1018  if (!ParseOptionsAndNotify(args.GetArgs(), result, m_option_group,
1019  exe_ctx))
1020  return false;
1021 
1022  // If no argument is present, issue an error message. There's no way to
1023  // set a watchpoint.
1024  if (raw_command.trim().empty()) {
1025  result.GetErrorStream().Printf("error: required argument missing; "
1026  "specify an expression to evaulate into "
1027  "the address to watch for\n");
1029  return false;
1030  }
1031 
1032  // If no '-w' is specified, default to '-w write'.
1033  if (!m_option_watchpoint.watch_type_specified) {
1034  m_option_watchpoint.watch_type = OptionGroupWatchpoint::eWatchWrite;
1035  }
1036 
1037  // We passed the sanity check for the command. Proceed to set the
1038  // watchpoint now.
1039  lldb::addr_t addr = 0;
1040  size_t size = 0;
1041 
1042  ValueObjectSP valobj_sp;
1043 
1044  // Use expression evaluation to arrive at the address to watch.
1045  EvaluateExpressionOptions options;
1046  options.SetCoerceToId(false);
1047  options.SetUnwindOnError(true);
1048  options.SetKeepInMemory(false);
1049  options.SetTryAllThreads(true);
1050  options.SetTimeout(llvm::None);
1051 
1052  ExpressionResults expr_result =
1053  target->EvaluateExpression(expr, frame, valobj_sp, options);
1054  if (expr_result != eExpressionCompleted) {
1055  result.GetErrorStream().Printf(
1056  "error: expression evaluation of address to watch failed\n");
1057  result.GetErrorStream() << "expression evaluated: \n" << expr << "\n";
1059  return false;
1060  }
1061 
1062  // Get the address to watch.
1063  bool success = false;
1064  addr = valobj_sp->GetValueAsUnsigned(0, &success);
1065  if (!success) {
1066  result.GetErrorStream().Printf(
1067  "error: expression did not evaluate to an address\n");
1069  return false;
1070  }
1071 
1072  if (m_option_watchpoint.watch_size != 0)
1073  size = m_option_watchpoint.watch_size;
1074  else
1075  size = target->GetArchitecture().GetAddressByteSize();
1076 
1077  // Now it's time to create the watchpoint.
1078  uint32_t watch_type = m_option_watchpoint.watch_type;
1079 
1080  // Fetch the type from the value object, the type of the watched object is
1081  // the pointee type
1082  /// of the expression, so convert to that if we found a valid type.
1083  CompilerType compiler_type(valobj_sp->GetCompilerType());
1084 
1085  Status error;
1086  Watchpoint *wp =
1087  target->CreateWatchpoint(addr, size, &compiler_type, watch_type, error)
1088  .get();
1089  if (wp) {
1090  Stream &output_stream = result.GetOutputStream();
1091  output_stream.Printf("Watchpoint created: ");
1092  wp->GetDescription(&output_stream, lldb::eDescriptionLevelFull);
1093  output_stream.EOL();
1095  } else {
1096  result.AppendErrorWithFormat("Watchpoint creation failed (addr=0x%" PRIx64
1097  ", size=%" PRIu64 ").\n",
1098  addr, (uint64_t)size);
1099  if (error.AsCString(nullptr))
1100  result.AppendError(error.AsCString());
1102  }
1103 
1104  return result.Succeeded();
1105  }
1106 
1107 private:
1108  OptionGroupOptions m_option_group;
1109  OptionGroupWatchpoint m_option_watchpoint;
1110 };
1111 
1112 // CommandObjectWatchpointSet
1113 #pragma mark Set
1114 
1116 public:
1119  interpreter, "watchpoint set", "Commands for setting a watchpoint.",
1120  "watchpoint set <subcommand> [<subcommand-options>]") {
1121 
1122  LoadSubCommand(
1123  "variable",
1124  CommandObjectSP(new CommandObjectWatchpointSetVariable(interpreter)));
1125  LoadSubCommand(
1126  "expression",
1127  CommandObjectSP(new CommandObjectWatchpointSetExpression(interpreter)));
1128  }
1129 
1130  ~CommandObjectWatchpointSet() override = default;
1131 };
1132 
1133 // CommandObjectMultiwordWatchpoint
1134 #pragma mark MultiwordWatchpoint
1135 
1136 CommandObjectMultiwordWatchpoint::CommandObjectMultiwordWatchpoint(
1137  CommandInterpreter &interpreter)
1138  : CommandObjectMultiword(interpreter, "watchpoint",
1139  "Commands for operating on watchpoints.",
1140  "watchpoint <subcommand> [<command-options>]") {
1141  CommandObjectSP list_command_object(
1142  new CommandObjectWatchpointList(interpreter));
1143  CommandObjectSP enable_command_object(
1144  new CommandObjectWatchpointEnable(interpreter));
1145  CommandObjectSP disable_command_object(
1146  new CommandObjectWatchpointDisable(interpreter));
1147  CommandObjectSP delete_command_object(
1148  new CommandObjectWatchpointDelete(interpreter));
1149  CommandObjectSP ignore_command_object(
1150  new CommandObjectWatchpointIgnore(interpreter));
1151  CommandObjectSP command_command_object(
1152  new CommandObjectWatchpointCommand(interpreter));
1153  CommandObjectSP modify_command_object(
1154  new CommandObjectWatchpointModify(interpreter));
1155  CommandObjectSP set_command_object(
1156  new CommandObjectWatchpointSet(interpreter));
1157 
1158  list_command_object->SetCommandName("watchpoint list");
1159  enable_command_object->SetCommandName("watchpoint enable");
1160  disable_command_object->SetCommandName("watchpoint disable");
1161  delete_command_object->SetCommandName("watchpoint delete");
1162  ignore_command_object->SetCommandName("watchpoint ignore");
1163  command_command_object->SetCommandName("watchpoint command");
1164  modify_command_object->SetCommandName("watchpoint modify");
1165  set_command_object->SetCommandName("watchpoint set");
1166 
1167  LoadSubCommand("list", list_command_object);
1168  LoadSubCommand("enable", enable_command_object);
1169  LoadSubCommand("disable", disable_command_object);
1170  LoadSubCommand("delete", delete_command_object);
1171  LoadSubCommand("ignore", ignore_command_object);
1172  LoadSubCommand("command", command_command_object);
1173  LoadSubCommand("modify", modify_command_object);
1174  LoadSubCommand("set", set_command_object);
1175 }
1176 
lldb::ValueObjectSP GetValueObjectAtIndex(size_t idx)
static constexpr OptionDefinition g_watchpoint_list_options[]
std::vector< CommandArgumentData > CommandArgumentEntry
A command line argument class.
Definition: Args.h:32
void OptionParsingStarting(ExecutionContext *execution_context) override
bool EnableWatchpointByID(lldb::watch_id_t watch_id)
Definition: Target.cpp:1326
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
const ArchSpec & GetArchitecture() const
Definition: Target.h:941
WatchpointList & GetWatchpointList()
Definition: Target.h:694
A stream class that can stream formatted output to a file.
Definition: Stream.h:28
static const char * RSA[4]
llvm::ArrayRef< ArgEntry > entries() const
Definition: Args.h:123
This class is used by Watchpoint to manage a list of watchpoints,.
uint32_t GetAddressByteSize() const
Returns the size in bytes of an address of the current architecture.
Definition: ArchSpec.cpp:742
bool LoadSubCommand(llvm::StringRef cmd_name, const lldb::CommandObjectSP &command_obj) override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
void AppendErrorWithFormat(const char *format,...) __attribute__((format(printf
bool IgnoreWatchpointByID(lldb::watch_id_t watch_id, uint32_t ignore_count)
Definition: Target.cpp:1363
void SetDeclInfo(const std::string &str)
Definition: Watchpoint.cpp:79
size_t GetArgumentCount() const
Gets the number of arguments left in this command object.
Definition: Args.cpp:254
void SetUnwindOnError(bool unwind=false)
Definition: Target.h:285
lldb::WatchpointSP FindByID(lldb::watch_id_t watchID) const
Returns a shared pointer to the watchpoint with id watchID, const version.
bool RemoveWatchpointByID(lldb::watch_id_t watch_id)
Definition: Target.cpp:1346
lldb::ExpressionResults EvaluateExpression(llvm::StringRef expression, ExecutionContextScope *exe_scope, lldb::ValueObjectSP &result_valobj_sp, const EvaluateExpressionOptions &options=EvaluateExpressionOptions(), std::string *fixed_expression=nullptr, ValueObject *ctx_obj=nullptr)
Definition: Target.cpp:2375
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
bool DoExecute(Args &command, CommandReturnObject &result) override
bool HasArgs() const
Returns true if there are any arguments before the raw suffix.
Definition: Args.h:352
bool DoExecute(Args &command, CommandReturnObject &result) override
static int32_t WithRSAIndex(llvm::StringRef Arg)
llvm::Optional< uint64_t > GetByteSize(ExecutionContextScope *exe_scope) const
Return the size of the type in bytes.
const char * GetArgumentAtIndex(size_t idx) const
Gets the NULL terminated C string argument pointer for the argument at index idx. ...
Definition: Args.cpp:256
static size_t GetVariableCallback(void *baton, const char *name, VariableList &variable_list)
size_t GetSize() const
Returns the number of elements in this watchpoint list.
CommandObjectWatchpointModify(CommandInterpreter &interpreter)
lldb::ValueObjectSP GetValueForVariableExpressionPath(llvm::StringRef var_expr, lldb::DynamicValueType use_dynamic, uint32_t options, lldb::VariableSP &var_sp, Status &error)
Create a ValueObject for a variable name / pathname, possibly including simple dereference/child sele...
Definition: StackFrame.cpp:486
#define LLDB_OPT_SET_3
Definition: lldb-defines.h:113
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
void SetKeepInMemory(bool keep=true)
Definition: Target.h:295
#define UINT32_MAX
Definition: lldb-defines.h:31
void SetTimeout(const Timeout< std::micro > &timeout)
Definition: Target.h:306
const lldb::ProcessSP & GetProcessSP() const
Definition: Target.cpp:206
size_t EOL()
Output and End of Line character to the stream.
Definition: Stream.cpp:127
void Clear()
Clear the object state.
Definition: Status.cpp:167
void AppendMessageWithFormat(const char *format,...) __attribute__((format(printf
bool EnableAllWatchpoints(bool end_to_end=true)
Definition: Target.cpp:1222
bool DoExecute(Args &command, CommandReturnObject &result) override
void AppendMessage(llvm::StringRef in_string)
llvm::StringRef GetString() const
const std::string & GetRawPart() const
Returns the raw suffix part of the parsed string.
Definition: Args.h:390
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
void GetListMutex(std::unique_lock< std::recursive_mutex > &lock)
Sets the passed in Locker to hold the Watchpoint List mutex.
bool Success() const
Test for success condition.
Definition: Status.cpp:287
lldb::WatchpointSP GetLastCreatedWatchpoint()
Definition: Target.h:690
void SetWatchVariable(bool val)
Definition: Watchpoint.cpp:93
CommandObjectWatchpointDisable(CommandInterpreter &interpreter)
void SetWatchSpec(const std::string &str)
Definition: Watchpoint.cpp:83
void OptionParsingStarting(ExecutionContext *execution_context) override
CommandObjectWatchpointList(CommandInterpreter &interpreter)
#define LLDB_OPT_SET_2
Definition: lldb-defines.h:112
CommandObjectWatchpointDelete(CommandInterpreter &interpreter)
const ModuleList & GetImages() const
Get accessor for the images for this process.
Definition: Target.h:899
void OptionParsingStarting(ExecutionContext *execution_context) override
bool RemoveAllWatchpoints(bool end_to_end=true)
Definition: Target.cpp:1160
bool DisableAllWatchpoints(bool end_to_end=true)
Definition: Target.cpp:1192
A command line option parsing protocol class.
Definition: Options.h:62
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
size_t FindGlobalVariables(ConstString name, size_t max_matches, VariableList &variable_list) const
Find global and static variables by name.
Definition: ModuleList.cpp:433
bool DoExecute(Args &command, CommandReturnObject &result) override
void SetCoerceToId(bool coerce=true)
Definition: Target.h:281
bool DoExecute(llvm::StringRef raw_command, CommandReturnObject &result) override
void void AppendError(llvm::StringRef in_string)
uint64_t addr_t
Definition: lldb-types.h:83
bool DisableWatchpointByID(lldb::watch_id_t watch_id)
Definition: Target.cpp:1306
CommandObjectWatchpointSetVariable(CommandInterpreter &interpreter)
A uniqued constant string class.
Definition: ConstString.h:38
Definition: SBAddress.h:15
void SetTryAllThreads(bool try_others=true)
Definition: Target.h:318
static void AddWatchpointDescription(Stream *s, Watchpoint *wp, lldb::DescriptionLevel level)
void GetDescription(Stream *s, lldb::DescriptionLevel level)
Definition: Watchpoint.cpp:136
lldb::WatchpointSP GetByIndex(uint32_t i)
Returns a shared pointer to the watchpoint with index i.
#define LLDB_OPT_SET_ALL
Definition: lldb-defines.h:110
bool DoExecute(Args &command, CommandReturnObject &result) override
Args & GetArgs()
Returns the list of arguments.
Definition: Args.h:357
int SetErrorStringWithFormat(const char *format,...) __attribute__((format(printf
Set the current error string to a formatted error string.
Definition: Status.cpp:255
CommandObjectWatchpointSet(CommandInterpreter &interpreter)
bool DoExecute(Args &command, CommandReturnObject &result) override
void IndentMore(int amount=2)
Increment the current indentation level.
Definition: Stream.cpp:218
#define LLDB_OPT_SET_1
Definition: lldb-defines.h:111
const char * AsCString(const char *default_error_str="unknown error") const
Get the error string associated with the current error.
Definition: Status.cpp:130
Address is an address as in the current target inferior process.
CommandObjectWatchpointIgnore(CommandInterpreter &interpreter)
static constexpr OptionDefinition g_watchpoint_ignore_options[]
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
CommandObjectWatchpointEnable(CommandInterpreter &interpreter)
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
A pair of an option list with a &#39;raw&#39; string as a suffix.
Definition: Args.h:341
CommandObjectWatchpointSetExpression(CommandInterpreter &interpreter)
static constexpr OptionDefinition g_watchpoint_modify_options[]
lldb::WatchpointSP CreateWatchpoint(lldb::addr_t addr, size_t size, const CompilerType *type, uint32_t kind, Status &error)
Definition: Target.cpp:796
static bool CheckTargetForWatchpointOperations(Target *target, CommandReturnObject &result)
void SetStatus(lldb::ReturnStatus status)
This base class provides an interface to stack frames.
Definition: StackFrame.h:40
bool IgnoreAllWatchpoints(uint32_t ignore_count)
Definition: Target.cpp:1286
bool DoExecute(Args &command, CommandReturnObject &result) override
An error handling class.
Definition: Status.h:44