[Lldb-commits] [lldb] 3620e5f - [lldb/Command] Add --force option for `watchpoint delete` command

Med Ismail Bennani via lldb-commits lldb-commits at lists.llvm.org
Thu Jan 2 16:53:45 PST 2020


Author: Med Ismail Bennani
Date: 2020-01-03T01:51:22+01:00
New Revision: 3620e5f28a4d2800fb6c325ec24b3d660e48b9ba

URL: https://github.com/llvm/llvm-project/commit/3620e5f28a4d2800fb6c325ec24b3d660e48b9ba
DIFF: https://github.com/llvm/llvm-project/commit/3620e5f28a4d2800fb6c325ec24b3d660e48b9ba.diff

LOG: [lldb/Command] Add --force option for `watchpoint delete` command

Currently, there is no option to delete all the watchpoint without LLDB
asking for a confirmation. Besides making the watchpoint delete command
homogeneous with the breakpoint delete command, this option could also
become handy to trigger automated watchpoint deletion i.e. using
breakpoint actions.

rdar://42560586

Signed-off-by: Med Ismail Bennani <medismail.bennani at gmail.com>

Added: 
    

Modified: 
    lldb/packages/Python/lldbsuite/test/commands/watchpoints/watchpoint_commands/TestWatchpointCommands.py
    lldb/source/Commands/CommandObjectWatchpoint.cpp
    lldb/source/Commands/Options.td

Removed: 
    


################################################################################
diff  --git a/lldb/packages/Python/lldbsuite/test/commands/watchpoints/watchpoint_commands/TestWatchpointCommands.py b/lldb/packages/Python/lldbsuite/test/commands/watchpoints/watchpoint_commands/TestWatchpointCommands.py
index 27c332b68bb4..e92af6dc9c6e 100644
--- a/lldb/packages/Python/lldbsuite/test/commands/watchpoints/watchpoint_commands/TestWatchpointCommands.py
+++ b/lldb/packages/Python/lldbsuite/test/commands/watchpoints/watchpoint_commands/TestWatchpointCommands.py
@@ -155,6 +155,56 @@ def test_rw_watchpoint_delete(self):
         self.expect("process status",
                     substrs=['exited'])
 
+    # Read-write watchpoints not supported on SystemZ
+    @expectedFailureAll(archs=['s390x'])
+    def test_rw_watchpoint_delete(self):
+        """Test delete watchpoint and expect not to stop for watchpoint."""
+        self.build(dictionary=self.d)
+        self.setTearDownCleanup(dictionary=self.d)
+
+        exe = self.getBuildArtifact(self.exe_name)
+        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+        # Add a breakpoint to set a watchpoint when stopped on the breakpoint.
+        lldbutil.run_break_set_by_file_and_line(
+            self, None, self.line, num_expected_locations=1)
+
+        # Run the program.
+        self.runCmd("run", RUN_SUCCEEDED)
+
+        # We should be stopped again due to the breakpoint.
+        # The stop reason of the thread should be breakpoint.
+        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+                    substrs=['stopped',
+                             'stop reason = breakpoint'])
+
+        # Now let's set a read_write-type watchpoint for 'global'.
+        # There should be two watchpoint hits (see main.c).
+        self.expect(
+            "watchpoint set variable -w read_write global",
+            WATCHPOINT_CREATED,
+            substrs=[
+                'Watchpoint created',
+                'size = 4',
+                'type = rw',
+                '%s:%d' %
+                (self.source,
+                 self.decl)])
+
+        # Delete the watchpoint immediately using the force option.
+        self.expect("watchpoint delete --force",
+                    substrs=['All watchpoints removed.'])
+
+        # Use the '-v' option to do verbose listing of the watchpoint.
+        self.runCmd("watchpoint list -v")
+
+        self.runCmd("process continue")
+
+        # There should be no more watchpoint hit and the process status should
+        # be 'exited'.
+        self.expect("process status",
+                    substrs=['exited'])
+
     # Read-write watchpoints not supported on SystemZ
     @expectedFailureAll(archs=['s390x'])
     def test_rw_watchpoint_set_ignore_count(self):

diff  --git a/lldb/source/Commands/CommandObjectWatchpoint.cpp b/lldb/source/Commands/CommandObjectWatchpoint.cpp
index 1b1d59740c86..c965d354f734 100644
--- a/lldb/source/Commands/CommandObjectWatchpoint.cpp
+++ b/lldb/source/Commands/CommandObjectWatchpoint.cpp
@@ -414,6 +414,10 @@ class CommandObjectWatchpointDisable : public CommandObjectParsed {
   }
 };
 
+// CommandObjectWatchpointDelete
+#define LLDB_OPTIONS_watchpoint_delete
+#include "CommandOptions.inc"
+
 // CommandObjectWatchpointDelete
 #pragma mark Delete
 
@@ -423,7 +427,8 @@ class CommandObjectWatchpointDelete : public CommandObjectParsed {
       : CommandObjectParsed(interpreter, "watchpoint delete",
                             "Delete the specified watchpoint(s).  If no "
                             "watchpoints are specified, delete them all.",
-                            nullptr, eCommandRequiresTarget) {
+                            nullptr, eCommandRequiresTarget),
+        m_options() {
     CommandArgumentEntry arg;
     CommandObject::AddIDsArgumentData(arg, eArgTypeWatchpointID,
                                       eArgTypeWatchpointIDRange);
@@ -434,6 +439,41 @@ class CommandObjectWatchpointDelete : public CommandObjectParsed {
 
   ~CommandObjectWatchpointDelete() override = default;
 
+  Options *GetOptions() override { return &m_options; }
+
+  class CommandOptions : public Options {
+  public:
+    CommandOptions() : Options(), m_force(false) {}
+
+    ~CommandOptions() override = default;
+
+    Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+                          ExecutionContext *execution_context) override {
+      const int short_option = m_getopt_table[option_idx].val;
+
+      switch (short_option) {
+      case 'f':
+        m_force = true;
+        break;
+      default:
+        llvm_unreachable("Unimplemented option");
+      }
+
+      return {};
+    }
+
+    void OptionParsingStarting(ExecutionContext *execution_context) override {
+      m_force = false;
+    }
+
+    llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+      return llvm::makeArrayRef(g_watchpoint_delete_options);
+    }
+
+    // Instance variables to hold the values for command options.
+    bool m_force;
+  };
+
 protected:
   bool DoExecute(Args &command, CommandReturnObject &result) override {
     Target *target = &GetSelectedTarget();
@@ -453,8 +493,9 @@ class CommandObjectWatchpointDelete : public CommandObjectParsed {
       return false;
     }
 
-    if (command.GetArgumentCount() == 0) {
-      if (!m_interpreter.Confirm(
+    if (command.empty()) {
+      if (!m_options.m_force &&
+          !m_interpreter.Confirm(
               "About to delete all watchpoints, do you want to do that?",
               true)) {
         result.AppendMessage("Operation cancelled...");
@@ -465,27 +506,31 @@ class CommandObjectWatchpointDelete : public CommandObjectParsed {
                                        (uint64_t)num_watchpoints);
       }
       result.SetStatus(eReturnStatusSuccessFinishNoResult);
-    } else {
-      // Particular watchpoints selected; delete them.
-      std::vector<uint32_t> wp_ids;
-      if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(
-              target, command, wp_ids)) {
-        result.AppendError("Invalid watchpoints specification.");
-        result.SetStatus(eReturnStatusFailed);
-        return false;
-      }
+      return result.Succeeded();
+    }
 
-      int count = 0;
-      const size_t size = wp_ids.size();
-      for (size_t i = 0; i < size; ++i)
-        if (target->RemoveWatchpointByID(wp_ids[i]))
-          ++count;
-      result.AppendMessageWithFormat("%d watchpoints deleted.\n", count);
-      result.SetStatus(eReturnStatusSuccessFinishNoResult);
+    // Particular watchpoints selected; delete them.
+    std::vector<uint32_t> wp_ids;
+    if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(target, command,
+                                                               wp_ids)) {
+      result.AppendError("Invalid watchpoints specification.");
+      result.SetStatus(eReturnStatusFailed);
+      return false;
     }
 
+    int count = 0;
+    const size_t size = wp_ids.size();
+    for (size_t i = 0; i < size; ++i)
+      if (target->RemoveWatchpointByID(wp_ids[i]))
+        ++count;
+    result.AppendMessageWithFormat("%d watchpoints deleted.\n", count);
+    result.SetStatus(eReturnStatusSuccessFinishNoResult);
+
     return result.Succeeded();
   }
+
+private:
+  CommandOptions m_options;
 };
 
 // CommandObjectWatchpointIgnore

diff  --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td
index f53d1481f4e8..850df133a429 100644
--- a/lldb/source/Commands/Options.td
+++ b/lldb/source/Commands/Options.td
@@ -1126,3 +1126,8 @@ let Command = "watchpoint command add" in {
     "to run as command for this watchpoint. Be sure to give a module name if "
     "appropriate.">;
 }
+
+let Command = "watchpoint delete" in {
+  def watchpoint_delete_force : Option<"force", "f">, Group<1>,
+    Desc<"Delete all watchpoints without querying for confirmation.">;
+}


        


More information about the lldb-commits mailing list