Add `breakpoint delete --disabled`: deletes all disabled breakpoints.
Differential Revision: https://reviews.llvm.org/D88129
This commit is contained in:
parent
b92d084910
commit
3726ac41e9
|
@ -1423,7 +1423,8 @@ public:
|
||||||
|
|
||||||
class CommandOptions : public Options {
|
class CommandOptions : public Options {
|
||||||
public:
|
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;
|
~CommandOptions() override = default;
|
||||||
|
|
||||||
|
@ -1441,6 +1442,10 @@ public:
|
||||||
m_use_dummy = true;
|
m_use_dummy = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'd':
|
||||||
|
m_delete_disabled = true;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
llvm_unreachable("Unimplemented option");
|
llvm_unreachable("Unimplemented option");
|
||||||
}
|
}
|
||||||
|
@ -1451,6 +1456,7 @@ public:
|
||||||
void OptionParsingStarting(ExecutionContext *execution_context) override {
|
void OptionParsingStarting(ExecutionContext *execution_context) override {
|
||||||
m_use_dummy = false;
|
m_use_dummy = false;
|
||||||
m_force = false;
|
m_force = false;
|
||||||
|
m_delete_disabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
|
llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
|
||||||
|
@ -1460,16 +1466,18 @@ public:
|
||||||
// Instance variables to hold the values for command options.
|
// Instance variables to hold the values for command options.
|
||||||
bool m_use_dummy;
|
bool m_use_dummy;
|
||||||
bool m_force;
|
bool m_force;
|
||||||
|
bool m_delete_disabled;
|
||||||
};
|
};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool DoExecute(Args &command, CommandReturnObject &result) override {
|
bool DoExecute(Args &command, CommandReturnObject &result) override {
|
||||||
Target &target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
|
Target &target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
|
||||||
|
result.Clear();
|
||||||
|
|
||||||
std::unique_lock<std::recursive_mutex> lock;
|
std::unique_lock<std::recursive_mutex> lock;
|
||||||
target.GetBreakpointList().GetListMutex(lock);
|
target.GetBreakpointList().GetListMutex(lock);
|
||||||
|
|
||||||
const BreakpointList &breakpoints = target.GetBreakpointList();
|
BreakpointList &breakpoints = target.GetBreakpointList();
|
||||||
|
|
||||||
size_t num_breakpoints = breakpoints.GetSize();
|
size_t num_breakpoints = breakpoints.GetSize();
|
||||||
|
|
||||||
|
@ -1479,7 +1487,7 @@ protected:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (command.empty()) {
|
if (command.empty() && !m_options.m_delete_disabled) {
|
||||||
if (!m_options.m_force &&
|
if (!m_options.m_force &&
|
||||||
!m_interpreter.Confirm(
|
!m_interpreter.Confirm(
|
||||||
"About to delete all breakpoints, do you want to do that?",
|
"About to delete all breakpoints, do you want to do that?",
|
||||||
|
@ -1495,9 +1503,33 @@ protected:
|
||||||
} else {
|
} else {
|
||||||
// Particular breakpoint selected; disable that breakpoint.
|
// Particular breakpoint selected; disable that breakpoint.
|
||||||
BreakpointIDList valid_bp_ids;
|
BreakpointIDList valid_bp_ids;
|
||||||
|
|
||||||
|
if (m_options.m_delete_disabled) {
|
||||||
|
BreakpointIDList excluded_bp_ids;
|
||||||
|
|
||||||
|
if (!command.empty()) {
|
||||||
|
CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
|
||||||
|
command, &target, result, &excluded_bp_ids,
|
||||||
|
BreakpointName::Permissions::PermissionKinds::deletePerm);
|
||||||
|
}
|
||||||
|
for (auto breakpoint_sp : breakpoints.Breakpoints()) {
|
||||||
|
if (!breakpoint_sp->IsEnabled() && breakpoint_sp->AllowDelete()) {
|
||||||
|
BreakpointID bp_id(breakpoint_sp->GetID());
|
||||||
|
size_t pos = 0;
|
||||||
|
if (!excluded_bp_ids.FindBreakpointID(bp_id, &pos))
|
||||||
|
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(
|
CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
|
||||||
command, &target, result, &valid_bp_ids,
|
command, &target, result, &valid_bp_ids,
|
||||||
BreakpointName::Permissions::PermissionKinds::deletePerm);
|
BreakpointName::Permissions::PermissionKinds::deletePerm);
|
||||||
|
}
|
||||||
|
|
||||||
if (result.Succeeded()) {
|
if (result.Succeeded()) {
|
||||||
int delete_count = 0;
|
int delete_count = 0;
|
||||||
|
|
|
@ -227,6 +227,9 @@ let Command = "breakpoint delete" in {
|
||||||
def breakpoint_delete_dummy_breakpoints : Option<"dummy-breakpoints", "D">,
|
def breakpoint_delete_dummy_breakpoints : Option<"dummy-breakpoints", "D">,
|
||||||
Group<1>, Desc<"Delete Dummy breakpoints - i.e. breakpoints set before a "
|
Group<1>, Desc<"Delete Dummy breakpoints - i.e. breakpoints set before a "
|
||||||
"file is provided, which prime new targets.">;
|
"file is provided, which prime new targets.">;
|
||||||
|
def breakpoint_delete_disabled : Option<"disabled", "d">, Group<1>,
|
||||||
|
Desc<"Delete all breakpoints which are currently disabled. When using the disabled option "
|
||||||
|
"any breakpoints listed on the command line are EXCLUDED from deletion.">;
|
||||||
}
|
}
|
||||||
|
|
||||||
let Command = "breakpoint name" in {
|
let Command = "breakpoint name" in {
|
||||||
|
|
|
@ -287,3 +287,33 @@ class BreakpointCommandTestCase(TestBase):
|
||||||
self.assertEqual(com_list.GetStringAtIndex(0), "bt", "First bt")
|
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(1), "thread list", "Next thread list")
|
||||||
self.assertEqual(com_list.GetStringAtIndex(2), "continue", "Last continue")
|
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_3.AddName("DeleteMeNot")
|
||||||
|
|
||||||
|
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 DeleteMeNot")
|
||||||
|
|
||||||
|
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.assertTrue(bp_3.IsValid(), "DeleteMeNot didn't protect disabled breakpoint 3")
|
||||||
|
|
Loading…
Reference in New Issue