Skip to content

Commit e6f2378

Browse files
committed
Add breakpoint delete --disabled: deletes all disabled breakpoints.
Differential Revision: https://reviews.llvm.org/D88129 (cherry picked from commit 3726ac4)
1 parent cbabbcc commit e6f2378

File tree

3 files changed

+73
-8
lines changed

3 files changed

+73
-8
lines changed

lldb/source/Commands/CommandObjectBreakpoint.cpp

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1407,7 +1407,8 @@ class CommandObjectBreakpointDelete : public CommandObjectParsed {
14071407

14081408
class CommandOptions : public Options {
14091409
public:
1410-
CommandOptions() : Options(), m_use_dummy(false), m_force(false) {}
1410+
CommandOptions() : Options(), m_use_dummy(false), m_force(false),
1411+
m_delete_disabled(false) {}
14111412

14121413
~CommandOptions() override = default;
14131414

@@ -1424,6 +1425,10 @@ class CommandObjectBreakpointDelete : public CommandObjectParsed {
14241425
case 'D':
14251426
m_use_dummy = true;
14261427
break;
1428+
1429+
case 'd':
1430+
m_delete_disabled = true;
1431+
break;
14271432

14281433
default:
14291434
llvm_unreachable("Unimplemented option");
@@ -1435,6 +1440,7 @@ class CommandObjectBreakpointDelete : public CommandObjectParsed {
14351440
void OptionParsingStarting(ExecutionContext *execution_context) override {
14361441
m_use_dummy = false;
14371442
m_force = false;
1443+
m_delete_disabled = false;
14381444
}
14391445

14401446
llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
@@ -1444,16 +1450,18 @@ class CommandObjectBreakpointDelete : public CommandObjectParsed {
14441450
// Instance variables to hold the values for command options.
14451451
bool m_use_dummy;
14461452
bool m_force;
1453+
bool m_delete_disabled;
14471454
};
14481455

14491456
protected:
14501457
bool DoExecute(Args &command, CommandReturnObject &result) override {
14511458
Target &target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
1452-
1459+
result.Clear();
1460+
14531461
std::unique_lock<std::recursive_mutex> lock;
14541462
target.GetBreakpointList().GetListMutex(lock);
14551463

1456-
const BreakpointList &breakpoints = target.GetBreakpointList();
1464+
BreakpointList &breakpoints = target.GetBreakpointList();
14571465

14581466
size_t num_breakpoints = breakpoints.GetSize();
14591467

@@ -1463,7 +1471,7 @@ class CommandObjectBreakpointDelete : public CommandObjectParsed {
14631471
return false;
14641472
}
14651473

1466-
if (command.empty()) {
1474+
if (command.empty() && !m_options.m_delete_disabled) {
14671475
if (!m_options.m_force &&
14681476
!m_interpreter.Confirm(
14691477
"About to delete all breakpoints, do you want to do that?",
@@ -1479,10 +1487,34 @@ class CommandObjectBreakpointDelete : public CommandObjectParsed {
14791487
} else {
14801488
// Particular breakpoint selected; disable that breakpoint.
14811489
BreakpointIDList valid_bp_ids;
1482-
CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
1483-
command, &target, result, &valid_bp_ids,
1484-
BreakpointName::Permissions::PermissionKinds::deletePerm);
1485-
1490+
1491+
if (m_options.m_delete_disabled) {
1492+
BreakpointIDList excluded_bp_ids;
1493+
1494+
if (!command.empty()) {
1495+
CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
1496+
command, &target, result, &excluded_bp_ids,
1497+
BreakpointName::Permissions::PermissionKinds::deletePerm);
1498+
}
1499+
for (auto breakpoint_sp : breakpoints.Breakpoints()) {
1500+
if (!breakpoint_sp->IsEnabled() && breakpoint_sp->AllowDelete()) {
1501+
BreakpointID bp_id(breakpoint_sp->GetID());
1502+
size_t pos = 0;
1503+
if (!excluded_bp_ids.FindBreakpointID(bp_id, &pos))
1504+
valid_bp_ids.AddBreakpointID(breakpoint_sp->GetID());
1505+
}
1506+
}
1507+
if (valid_bp_ids.GetSize() == 0) {
1508+
result.AppendError("No disabled breakpoints.");
1509+
result.SetStatus(eReturnStatusFailed);
1510+
return false;
1511+
}
1512+
} else {
1513+
CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
1514+
command, &target, result, &valid_bp_ids,
1515+
BreakpointName::Permissions::PermissionKinds::deletePerm);
1516+
}
1517+
14861518
if (result.Succeeded()) {
14871519
int delete_count = 0;
14881520
int disable_count = 0;

lldb/source/Commands/Options.td

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

229232
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)