From 82c543c5ba4d496fec0dbafc735fdf120d625966 Mon Sep 17 00:00:00 2001 From: Xusheng Date: Fri, 14 Aug 2026 16:11:30 -0400 Subject: [PATCH] Fix breakpoint removal after debugger exit --- core/debuggerstate.cpp | 8 ++++---- test/debugger_test.py | 17 +++++++++++++++++ 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/core/debuggerstate.cpp b/core/debuggerstate.cpp index 71ef401a..51321204 100644 --- a/core/debuggerstate.cpp +++ b/core/debuggerstate.cpp @@ -683,9 +683,6 @@ bool DebuggerBreakpoints::AddOffset(const ModuleNameAndOffset& address) bool DebuggerBreakpoints::RemoveAbsolute(uint64_t remoteAddress) { - if (!m_state->GetAdapter()) - return false; - ModuleNameAndOffset info = m_state->GetModules()->AbsoluteAddressToRelative(remoteAddress); auto it = FindBreakpoint(info); if (it == m_breakpoints.end()) @@ -693,7 +690,10 @@ bool DebuggerBreakpoints::RemoveAbsolute(uint64_t remoteAddress) m_breakpoints.erase(it); SerializeMetadata(); - m_state->GetAdapter()->RemoveBreakpoint(remoteAddress); + + if (m_state->GetAdapter() && m_state->IsConnected()) + m_state->GetAdapter()->RemoveBreakpoint(remoteAddress); + return true; } diff --git a/test/debugger_test.py b/test/debugger_test.py index 823d66e6..685dcee5 100644 --- a/test/debugger_test.py +++ b/test/debugger_test.py @@ -367,6 +367,23 @@ def test_breakpoint(self): self.assertEqual(dbg.ip, entry) dbg.quit_and_wait() + def test_remove_breakpoint_after_exit(self): + """Removing a logical breakpoint after DbgEng teardown must not call the backend.""" + if self.adapter_type != 'DBGENG': + self.skipTest('Regression is specific to DbgEng teardown') + + fpath = name_to_fpath('helloworld', self.arch) + bv = load(fpath) + dbg = self.create_debugger(bv) + self.assertNotIn(dbg.launch_and_wait(), [DebugStopReason.ProcessExited, DebugStopReason.InternalError]) + self.assertEqual(sleep_and_go(dbg), DebugStopReason.ProcessExited) + + entry = dbg.data.entry_point + dbg.add_breakpoint(entry) + self.assertTrue(any(bp.address == entry for bp in dbg.breakpoints)) + dbg.delete_breakpoint(entry) + self.assertFalse(any(bp.address == entry for bp in dbg.breakpoints)) + def test_breakpoint_condition(self): fpath = name_to_fpath('helloworld', self.arch) bv = load(fpath)