Skip to content

Commit 3726ac4

Browse files
committed
Add breakpoint delete --disabled: deletes all disabled breakpoints.
Differential Revision: https://reviews.llvm.org/D88129
1 parent b92d084 commit 3726ac4

File tree

3 files changed

+72
-7
lines changed

3 files changed

+72
-7
lines changed

lldb/source/Commands/CommandObjectBreakpoint.cpp

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1423,7 +1423,8 @@ class CommandObjectBreakpointDelete : public CommandObjectParsed {
14231423

14241424
class CommandOptions : public Options {
14251425
public:
1426-
CommandOptions() : Options(), m_use_dummy(false), m_force(false) {}
1426+
CommandOptions() : Options(), m_use_dummy(false), m_force(false),
1427+
m_delete_disabled(false) {}
14271428

14281429
~CommandOptions() override = default;
14291430

@@ -1440,6 +1441,10 @@ class CommandObjectBreakpointDelete : public CommandObjectParsed {
14401441
case 'D':
14411442
m_use_dummy = true;
14421443
break;
1444+
1445+
case 'd':
1446+
m_delete_disabled = true;
1447+
break;
14431448

14441449
default:
14451450
llvm_unreachable("Unimplemented option");
@@ -1451,6 +1456,7 @@ class CommandObjectBreakpointDelete : public CommandObjectParsed {
14511456
void OptionParsingStarting(ExecutionContext *execution_context) override {
14521457
m_use_dummy = false;
14531458
m_force = false;
1459+
m_delete_disabled = false;
14541460
}
14551461

14561462
llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
@@ -1460,16 +1466,18 @@ class CommandObjectBreakpointDelete : public CommandObjectParsed {
14601466
// Instance variables to hold the values for command options.
14611467
bool m_use_dummy;
14621468
bool m_force;
1469+
bool m_delete_disabled;
14631470
};
14641471

14651472
protected:
14661473
bool DoExecute(Args &command, CommandReturnObject &result) override {
14671474
Target &target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
1468-
1475+
result.Clear();
1476+
14691477
std::unique_lock<std::recursive_mutex> lock;
14701478
target.GetBreakpointList().GetListMutex(lock);
14711479

1472-
const BreakpointList &breakpoints = target.GetBreakpointList();
1480+
BreakpointList &breakpoints = target.GetBreakpointList();
14731481

14741482
size_t num_breakpoints = breakpoints.GetSize();
14751483

@@ -1479,7 +1487,7 @@ class CommandObjectBreakpointDelete : public CommandObjectParsed {
14791487
return false;
14801488
}
14811489

1482-
if (command.empty()) {
1490+
if (command.empty() && !m_options.m_delete_disabled) {
14831491
if (!m_options.m_force &&
14841492
!m_interpreter.Confirm(
14851493
"About to delete all breakpoints, do you want to do that?",
@@ -1495,10 +1503,34 @@ class CommandObjectBreakpointDelete : public CommandObjectParsed {
14951503
} else {
14961504
// Particular breakpoint selected; disable that breakpoint.
14971505
BreakpointIDList valid_bp_ids;
1498-
CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
1499-
command, &target, result, &valid_bp_ids,
1500-
BreakpointName::Permissions::PermissionKinds::deletePerm);
1506+
1507+
if (m_options.m_delete_disabled) {
1508+
BreakpointIDList excluded_bp_ids;
15011509

1510+
if (!command.empty()) {
1511+
CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
1512+
command, &target, result, &excluded_bp_ids,
1513+
BreakpointName::Permissions::PermissionKinds::deletePerm);
1514+
}
1515+
for (auto breakpoint_sp : breakpoints.Breakpoints()) {
1516+
if (!breakpoint_sp->IsEnabled() && breakpoint_sp->AllowDelete()) {
1517+
BreakpointID bp_id(breakpoint_sp->GetID());
1518+
size_t pos = 0;
1519+
if (!excluded_bp_ids.FindBreakpointID(bp_id, &pos))
1520+
valid_bp_ids.AddBreakpointID(breakpoint_sp->GetID());
1521+
}
1522+
}
1523+
if (valid_bp_ids.GetSize() == 0) {
1524+
result.AppendError("No disabled breakpoints.");
1525+
result.SetStatus(eReturnStatusFailed);
1526+
return false;
1527+
}
1528+
} else {
1529+
CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
1530+
command, &target, result, &valid_bp_ids,
1531+
BreakpointName::Permissions::PermissionKinds::deletePerm);
1532+
}
1533+
15021534
if (result.Succeeded()) {
15031535
int delete_count = 0;
15041536
int disable_count = 0;

lldb/source/Commands/Options.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,9 @@ let Command = "breakpoint delete" in {
227227
def breakpoint_delete_dummy_breakpoints : Option<"dummy-breakpoints", "D">,
228228
Group<1>, Desc<"Delete Dummy breakpoints - i.e. breakpoints set before a "
229229
"file is provided, which prime new targets.">;
230+
def breakpoint_delete_disabled : Option<"disabled", "d">, Group<1>,
231+
Desc<"Delete all breakpoints which are currently disabled. When using the disabled option "
232+
"any breakpoints listed on the command line are EXCLUDED from deletion.">;
230233
}
231234

232235
let Command = "breakpoint name" in {

lldb/test/API/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,3 +287,33 @@ def breakpoint_commands_on_creation(self):
287287
self.assertEqual(com_list.GetStringAtIndex(0), "bt", "First bt")
288288
self.assertEqual(com_list.GetStringAtIndex(1), "thread list", "Next thread list")
289289
self.assertEqual(com_list.GetStringAtIndex(2), "continue", "Last continue")
290+
291+
def test_breakpoint_delete_disabled(self):
292+
"""Test 'break delete --disabled' works"""
293+
self.build()
294+
exe = self.getBuildArtifact("a.out")
295+
target = self.dbg.CreateTarget(exe)
296+
self.assertTrue(target.IsValid(), "Created an invalid target.")
297+
298+
bp_1 = target.BreakpointCreateByName("main")
299+
bp_2 = target.BreakpointCreateByName("not_here")
300+
bp_3 = target.BreakpointCreateByName("main")
301+
bp_3.AddName("DeleteMeNot")
302+
303+
bp_1.SetEnabled(False)
304+
bp_3.SetEnabled(False)
305+
306+
bp_id_1 = bp_1.GetID()
307+
bp_id_2 = bp_2.GetID()
308+
bp_id_3 = bp_3.GetID()
309+
310+
self.runCmd("breakpoint delete --disabled DeleteMeNot")
311+
312+
bp_1 = target.FindBreakpointByID(bp_id_1)
313+
self.assertFalse(bp_1.IsValid(), "Didn't delete disabled breakpoint 1")
314+
315+
bp_2 = target.FindBreakpointByID(bp_id_2)
316+
self.assertTrue(bp_2.IsValid(), "Deleted enabled breakpoint 2")
317+
318+
bp_3 = target.FindBreakpointByID(bp_id_3)
319+
self.assertTrue(bp_3.IsValid(), "DeleteMeNot didn't protect disabled breakpoint 3")

0 commit comments

Comments
 (0)