diff --git a/pykd/pyeventhandler.cpp b/pykd/pyeventhandler.cpp index 69e1bc1..d4ac289 100644 --- a/pykd/pyeventhandler.cpp +++ b/pykd/pyeventhandler.cpp @@ -654,7 +654,36 @@ void Breakpoint::remove() { m_breakpoint->remove(); m_breakpoint = 0; + return; } + + throw kdlib::DbgException("Cannot remove breakpoint, it is detached"); +} + +///////////////////////////////////////////////////////////////////////////////// + +Breakpoint* Breakpoint::detach() +{ + AutoRestorePyState pystate; + + if (m_weakBp) + { + throw kdlib::DbgException("Cannot detach 'weak' breakpoint"); + } + + if (m_breakpoint) + { + if (m_callback) + { + throw kdlib::DbgException("Cannot detach breakpoint with callback"); + } + + auto bp = m_breakpoint; + m_breakpoint = 0; + return new Breakpoint(bp); + } + + throw kdlib::DbgException("Cannot remove breakpoint, it is detached"); } ///////////////////////////////////////////////////////////////////////////////// diff --git a/pykd/pyeventhandler.h b/pykd/pyeventhandler.h index c16f452..486571e 100644 --- a/pykd/pyeventhandler.h +++ b/pykd/pyeventhandler.h @@ -105,6 +105,8 @@ public: void remove(); + Breakpoint* detach(); + private: PyThreadState* m_pystate; diff --git a/pykd/pymod.cpp b/pykd/pymod.cpp index 3e830dc..b11dc91 100644 --- a/pykd/pymod.cpp +++ b/pykd/pymod.cpp @@ -1391,6 +1391,8 @@ void pykd_init() "Remove breakpoint" ) .def("onHit", &Breakpoint::onHit, "Breakpoint hit callback") + .def("detach", &Breakpoint::detach, python::return_value_policy(), + "detach breakpoint") ; python::class_( diff --git a/test/scripts/breakpoint.py b/test/scripts/breakpoint.py index 058bd81..795379e 100644 --- a/test/scripts/breakpoint.py +++ b/test/scripts/breakpoint.py @@ -184,3 +184,14 @@ class BreakpointTest( unittest.TestCase ): bp = pykd.getBp(0) self.assertEqual(0x100, bp.getOffset()) + def testDoubleRemove(self): + bp = pykd.setBp( self.targetModule.CdeclFunc ) + bp.remove() + self.assertRaises( pykd.DbgException, bp.remove ) + + def testDetach(self): + bp = pykd.setBp( self.targetModule.CdeclFunc ).detach() + self.assertEqual(1, pykd.getNumberBreakpoints()) + self.assertRaises(pykd.DbgException, bp.detach ) + del bp + self.assertEqual(1, pykd.getNumberBreakpoints()) \ No newline at end of file