jingham created this revision.
Herald added subscribers: lldb-commits, dang.
Herald added a reviewer: JDevlieghere.
Herald added a project: LLDB.
jingham requested review of this revision.

Sometimes in a debug session you set a whole bunch of breakpoints and gradually 
disable the ones that aren't helpful.  At some point you want to clean up the 
breakpoint state before continuing, and getting rid of all those disabled 
breakpoints at one blow is a handy tool to have.

This patch adds "break delete --disabled" that deletes all the currently 
disabled breakpoints.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D88129

Files:
  lldb/source/Commands/CommandObjectBreakpoint.cpp
  lldb/source/Commands/Options.td
  
lldb/test/API/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py

Index: lldb/test/API/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py
===================================================================
--- lldb/test/API/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py
+++ lldb/test/API/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py
@@ -287,3 +287,32 @@
         self.assertEqual(com_list.GetStringAtIndex(0), "bt", "First bt")
         self.assertEqual(com_list.GetStringAtIndex(1), "thread list", "Next thread list")
         self.assertEqual(com_list.GetStringAtIndex(2), "continue", "Last continue")
+
+    def test_breakpoint_delete_disabled(self):
+        """Test 'break delete --disabled' works"""
+        self.build()
+        exe = self.getBuildArtifact("a.out")
+        target = self.dbg.CreateTarget(exe)
+        self.assertTrue(target.IsValid(), "Created an invalid target.")
+
+        bp_1 = target.BreakpointCreateByName("main")
+        bp_2 = target.BreakpointCreateByName("not_here")
+        bp_3 = target.BreakpointCreateByName("main")
+
+        bp_1.SetEnabled(False)
+        bp_3.SetEnabled(False)
+
+        bp_id_1 = bp_1.GetID()
+        bp_id_2 = bp_2.GetID()
+        bp_id_3 = bp_3.GetID()
+        
+        self.runCmd("breakpoint delete --disabled")
+
+        bp_1 = target.FindBreakpointByID(bp_id_1)
+        self.assertFalse(bp_1.IsValid(), "Didn't delete disabled breakpoint 1")
+
+        bp_2 = target.FindBreakpointByID(bp_id_2)
+        self.assertTrue(bp_2.IsValid(), "Deleted enabled breakpoint 2")
+
+        bp_3 = target.FindBreakpointByID(bp_id_3)
+        self.assertFalse(bp_3.IsValid(), "Didn't delete disabled breakpoint 3")
Index: lldb/source/Commands/Options.td
===================================================================
--- lldb/source/Commands/Options.td
+++ lldb/source/Commands/Options.td
@@ -227,6 +227,8 @@
   def breakpoint_delete_dummy_breakpoints : Option<"dummy-breakpoints", "D">,
     Group<1>, Desc<"Delete Dummy breakpoints - i.e. breakpoints set before a "
     "file is provided, which prime new targets.">;
+  def breakpoint_delete_disabled : Option<"disabled", "d">, Group<1>,
+    Desc<"Delete all breakpoints which are currently disabled.">;
 }
 
 let Command = "breakpoint name" in {
Index: lldb/source/Commands/CommandObjectBreakpoint.cpp
===================================================================
--- lldb/source/Commands/CommandObjectBreakpoint.cpp
+++ lldb/source/Commands/CommandObjectBreakpoint.cpp
@@ -1423,7 +1423,8 @@
 
   class CommandOptions : public Options {
   public:
-    CommandOptions() : Options(), m_use_dummy(false), m_force(false) {}
+    CommandOptions() : Options(), m_use_dummy(false), m_force(false),
+      m_delete_disabled(false) {}
 
     ~CommandOptions() override = default;
 
@@ -1440,6 +1441,10 @@
       case 'D':
         m_use_dummy = true;
         break;
+        
+      case 'd':
+        m_delete_disabled = true;
+        break;
 
       default:
         llvm_unreachable("Unimplemented option");
@@ -1451,6 +1456,7 @@
     void OptionParsingStarting(ExecutionContext *execution_context) override {
       m_use_dummy = false;
       m_force = false;
+      m_delete_disabled = false;
     }
 
     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
@@ -1460,16 +1466,18 @@
     // Instance variables to hold the values for command options.
     bool m_use_dummy;
     bool m_force;
+    bool m_delete_disabled;
   };
 
 protected:
   bool DoExecute(Args &command, CommandReturnObject &result) override {
     Target &target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
-
+    result.Clear();
+    
     std::unique_lock<std::recursive_mutex> lock;
     target.GetBreakpointList().GetListMutex(lock);
 
-    const BreakpointList &breakpoints = target.GetBreakpointList();
+    BreakpointList &breakpoints = target.GetBreakpointList();
 
     size_t num_breakpoints = breakpoints.GetSize();
 
@@ -1479,7 +1487,7 @@
       return false;
     }
 
-    if (command.empty()) {
+    if (command.empty() && !m_options.m_delete_disabled) {
       if (!m_options.m_force &&
           !m_interpreter.Confirm(
               "About to delete all breakpoints, do you want to do that?",
@@ -1495,10 +1503,30 @@
     } else {
       // Particular breakpoint selected; disable that breakpoint.
       BreakpointIDList valid_bp_ids;
-      CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
-          command, &target, result, &valid_bp_ids,
-          BreakpointName::Permissions::PermissionKinds::deletePerm);
-
+      
+      if (m_options.m_delete_disabled) {
+        if (!command.empty()) {
+          result.AppendError("Can't specify --disabled with breakpoint "
+                             "arguments.");
+          result.SetStatus(eReturnStatusFailed);
+          return false;
+        }
+        for (auto breakpoint_sp : breakpoints.Breakpoints()) {
+          if (!breakpoint_sp->IsEnabled() && breakpoint_sp->AllowDelete()) {
+            valid_bp_ids.AddBreakpointID(breakpoint_sp->GetID());
+          }
+        }
+        if (valid_bp_ids.GetSize() == 0) {
+          result.AppendError("No disabled breakpoints.");
+          result.SetStatus(eReturnStatusFailed);
+          return false;
+        }
+      } else {
+        CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
+            command, &target, result, &valid_bp_ids,
+            BreakpointName::Permissions::PermissionKinds::deletePerm);
+      }
+      
       if (result.Succeeded()) {
         int delete_count = 0;
         int disable_count = 0;
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to