[Lldb-commits] [lldb] df71f92 - [lldb/Command] Add --force option for `watchpoint delete` command
Med Ismail Bennani via lldb-commits
lldb-commits at lists.llvm.org
Fri Jan 3 18:11:33 PST 2020
Author: Med Ismail Bennani
Date: 2020-01-04T03:11:15+01:00
New Revision: df71f92fbb7c96cfd36d247ae6fb6929cb9bce35
URL: https://github.com/llvm/llvm-project/commit/df71f92fbb7c96cfd36d247ae6fb6929cb9bce35
DIFF: https://github.com/llvm/llvm-project/commit/df71f92fbb7c96cfd36d247ae6fb6929cb9bce35.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
Differential Revision: https://reviews.llvm.org/D72096
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..a428d18f12c7 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
@@ -105,24 +105,9 @@ def test_rw_watchpoint(self):
@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'])
+ self.build()
+ lldbutil.run_to_line_breakpoint(self, lldb.SBFileSpec(self.source),
+ self.line)
# Now let's set a read_write-type watchpoint for 'global'.
# There should be two watchpoint hits (see main.c).
@@ -145,8 +130,28 @@ def test_rw_watchpoint_delete(self):
# Restore the original setting of auto-confirm.
self.runCmd("settings clear auto-confirm")
- # Use the '-v' option to do verbose listing of the watchpoint.
- self.runCmd("watchpoint list -v")
+ target = self.dbg.GetSelectedTarget()
+ self.assertTrue(target and not target.GetNumWatchpoints())
+
+ # 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.'])
+
+ self.assertTrue(target and not target.GetNumWatchpoints())
self.runCmd("process continue")
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