[0.3.x] reworked : setBp returns now strong reference

git-svn-id: https://pykd.svn.codeplex.com/svn@90851 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
SND\kernelnet_cp 2015-10-21 11:03:41 +00:00 committed by Mikhail I. Izmestev
parent 9512318443
commit 63e824d50a
3 changed files with 142 additions and 180 deletions

View File

@ -511,42 +511,51 @@ void EventHandler::onStopInput()
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
Breakpoint::Breakpoint(kdlib::BreakpointPtr bp) Breakpoint::Breakpoint(kdlib::BreakpointPtr bp, bool weakbp)
{ {
m_pystate = PyThreadState_Get();
m_breakpoint = bp; m_breakpoint = bp;
m_weakBp = weakbp;
} }
Breakpoint::Breakpoint(kdlib::MEMOFFSET_64 offset) Breakpoint::Breakpoint(kdlib::MEMOFFSET_64 offset)
{ {
AutoRestorePyState pystate(&m_pystate); AutoRestorePyState pystate(&m_pystate);
m_breakpoint = kdlib::softwareBreakPointSet(offset, this); m_breakpoint = kdlib::softwareBreakPointSet(offset, this);
m_weakBp = false;
} }
Breakpoint::Breakpoint(kdlib::MEMOFFSET_64 offset, python::object &callback) Breakpoint::Breakpoint(kdlib::MEMOFFSET_64 offset, python::object &callback)
{ {
m_callback = callback; m_callback = callback;
AutoRestorePyState pystate(&m_pystate); AutoRestorePyState pystate(&m_pystate);
m_breakpoint = kdlib::softwareBreakPointSet(offset, this); m_breakpoint = kdlib::softwareBreakPointSet(offset, this);
m_weakBp = false;
} }
Breakpoint::Breakpoint(kdlib::MEMOFFSET_64 offset, size_t size, kdlib::ACCESS_TYPE accessType) Breakpoint::Breakpoint(kdlib::MEMOFFSET_64 offset, size_t size, kdlib::ACCESS_TYPE accessType)
{ {
AutoRestorePyState pystate(&m_pystate); AutoRestorePyState pystate(&m_pystate);
m_breakpoint = kdlib::hardwareBreakPointSet(offset, size, accessType, this); m_breakpoint = kdlib::hardwareBreakPointSet(offset, size, accessType, this);
m_weakBp = false;
} }
Breakpoint::Breakpoint(kdlib::MEMOFFSET_64 offset, size_t size, kdlib::ACCESS_TYPE accessType, python::object &callback) Breakpoint::Breakpoint(kdlib::MEMOFFSET_64 offset, size_t size, kdlib::ACCESS_TYPE accessType, python::object &callback)
{ {
m_callback = callback; m_callback = callback;
AutoRestorePyState pystate(&m_pystate); AutoRestorePyState pystate(&m_pystate);
m_breakpoint = kdlib::hardwareBreakPointSet(offset, size, accessType, this); m_breakpoint = kdlib::hardwareBreakPointSet(offset, size, accessType, this);
m_weakBp = false;
}
/////////////////////////////////////////////////////////////////////////////////
Breakpoint::~Breakpoint()
{
AutoRestorePyState pystate;
if (!m_weakBp && m_breakpoint )
{
m_breakpoint->remove();
}
} }
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
@ -615,18 +624,54 @@ kdlib::DebugCallbackResult Breakpoint::onHit()
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
void Breakpoint::remove()
{
AutoRestorePyState pystate;
if (m_breakpoint)
{
m_breakpoint->remove();
m_breakpoint = 0;
}
}
/////////////////////////////////////////////////////////////////////////////////
Breakpoint* Breakpoint::setSoftwareBreakpoint( kdlib::MEMOFFSET_64 offset, python::object &callback ) Breakpoint* Breakpoint::setSoftwareBreakpoint( kdlib::MEMOFFSET_64 offset, python::object &callback )
{ {
Breakpoint *internalBp = new Breakpoint(offset, callback); if (!callback)
return new Breakpoint(internalBp->m_breakpoint); {
AutoRestorePyState pystate;
kdlib::BreakpointPtr bp = kdlib::softwareBreakPointSet(offset, 0);
return new Breakpoint(bp, false);
}
else
{
return new Breakpoint(offset, callback);
}
} }
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
Breakpoint* Breakpoint::setHardwareBreakpoint( kdlib::MEMOFFSET_64 offset, size_t size, kdlib::ACCESS_TYPE accessType, python::object &callback ) Breakpoint* Breakpoint::setHardwareBreakpoint( kdlib::MEMOFFSET_64 offset, size_t size, kdlib::ACCESS_TYPE accessType, python::object &callback )
{ {
Breakpoint *internalBp = new Breakpoint(offset, size, accessType, callback); if (!callback)
return new Breakpoint(internalBp->m_breakpoint); {
AutoRestorePyState pystate;
kdlib::BreakpointPtr bp = kdlib::hardwareBreakPointSet(offset, size, accessType, 0);
return new Breakpoint(bp, false);
}
else
{
return new Breakpoint(offset, size, accessType, callback);
}
}
/////////////////////////////////////////////////////////////////////////////////
unsigned long Breakpoint::getNumberBreakpoints()
{
AutoRestorePyState pystate;
return kdlib::getNumberBreakpoints();
} }
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
@ -645,16 +690,6 @@ Breakpoint* Breakpoint::getBreakpointByIndex(unsigned long index)
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
void Breakpoint::remove()
{
AutoRestorePyState pystate;
if (m_breakpoint)
{
m_breakpoint->remove();
m_breakpoint = 0;
}
}
/////////////////////////////////////////////////////////////////////////////////
} // end namespace pykd } // end namespace pykd

View File

@ -60,16 +60,13 @@ public:
static Breakpoint* setHardwareBreakpoint( kdlib::MEMOFFSET_64 offset, size_t size, kdlib::ACCESS_TYPE accessType, python::object &callback= python::object() ); static Breakpoint* setHardwareBreakpoint( kdlib::MEMOFFSET_64 offset, size_t size, kdlib::ACCESS_TYPE accessType, python::object &callback= python::object() );
static unsigned long getNumberBreakpoints() { static unsigned long getNumberBreakpoints();
AutoRestorePyState pystate;
return kdlib::getNumberBreakpoints();
}
static Breakpoint* getBreakpointByIndex(unsigned long index); static Breakpoint* getBreakpointByIndex(unsigned long index);
public: public:
explicit Breakpoint(kdlib::BreakpointPtr bp); explicit Breakpoint(kdlib::BreakpointPtr bp, bool weakbp = true);
explicit Breakpoint(kdlib::MEMOFFSET_64 offset); explicit Breakpoint(kdlib::MEMOFFSET_64 offset);
@ -79,8 +76,7 @@ public:
Breakpoint(kdlib::MEMOFFSET_64 offset, size_t size, kdlib::ACCESS_TYPE accessType, python::object &callback); Breakpoint(kdlib::MEMOFFSET_64 offset, size_t size, kdlib::ACCESS_TYPE accessType, python::object &callback);
~Breakpoint() ~Breakpoint();
{}
virtual kdlib::DebugCallbackResult onHit(); virtual kdlib::DebugCallbackResult onHit();
@ -111,6 +107,8 @@ private:
kdlib::BreakpointPtr m_breakpoint; kdlib::BreakpointPtr m_breakpoint;
python::object m_callback; python::object m_callback;
bool m_weakBp;
}; };

View File

@ -22,80 +22,44 @@ def continueOnBreak():
class BreakpointTest( unittest.TestCase ): class BreakpointTest( unittest.TestCase ):
def testNoBreakpoint(self): def setUp(self):
processId = pykd.startProcess( target.appPath + " breakhandlertest" ) pykd.startProcess( target.appPath + " breakhandlertest" )
with testutils.ContextCallIt( testutils.KillProcess(processId) ) as killStartedProcess : self.targetModule = pykd.module( target.moduleName )
self.targetModule.reload()
pykd.go() pykd.go()
def tearDown(self):
self.taregtModule = None
pykd.killAllProcesses()
def testNoBreakpoint(self):
self.assertEqual( pykd.executionStatus.NoDebuggee, pykd.go() ) self.assertEqual( pykd.executionStatus.NoDebuggee, pykd.go() )
def testSetBp(self): def testSetBp(self):
processId = pykd.startProcess( target.appPath + " breakhandlertest" ) bp = pykd.setBp( self.targetModule.CdeclFunc )
targetModule = pykd.module( target.moduleName )
targetModule.reload()
with testutils.ContextCallIt( testutils.KillProcess(processId) ) as killStartedProcess :
pykd.go()
pykd.setBp( targetModule.CdeclFunc )
self.assertEqual( pykd.executionStatus.Break, pykd.go() ) self.assertEqual( pykd.executionStatus.Break, pykd.go() )
def testRemoveBp(self): def testRemoveBp(self):
processId = pykd.startProcess( target.appPath + " breakhandlertest" ) bp = pykd.setBp( self.targetModule.CdeclFunc )
targetModule = pykd.module( target.moduleName )
targetModule.reload()
with testutils.ContextCallIt( testutils.KillProcess(processId) ) as killStartedProcess :
pykd.go()
bp = pykd.setBp( targetModule.CdeclFunc )
bp.remove() bp.remove()
self.assertEqual( pykd.executionStatus.NoDebuggee, pykd.go() ) self.assertEqual( pykd.executionStatus.NoDebuggee, pykd.go() )
def disable_testDeleteBp(self): def disable_testDeleteBp(self):
processId = pykd.startProcess( target.appPath + " breakhandlertest" ) bp = pykd.setBp( self.targetModule.CdeclFunc )
targetModule = pykd.module( target.moduleName )
targetModule.reload()
with testutils.ContextCallIt( testutils.KillProcess(processId) ) as killStartedProcess :
pykd.go()
bp = pykd.setBp( targetModule.CdeclFunc )
del bp del bp
self.assertEqual( pykd.executionStatus.NoDebuggee, pykd.go() ) self.assertEqual( pykd.executionStatus.NoDebuggee, pykd.go() )
def testBreakCallback(self): def testBreakCallback(self):
processId = pykd.startProcess( target.appPath + " breakhandlertest" )
targetModule = pykd.module( target.moduleName )
targetModule.reload()
with testutils.ContextCallIt( testutils.KillProcess(processId) ) as killStartedProcess :
pykd.go()
breakCount = callCounter(stopOnBreak) breakCount = callCounter(stopOnBreak)
pykd.setBp( targetModule.CdeclFunc, breakCount ) bp = pykd.setBp( self.targetModule.CdeclFunc, breakCount )
self.assertEqual( pykd.executionStatus.Break, pykd.go() ) self.assertEqual( pykd.executionStatus.Break, pykd.go() )
self.assertEqual( 1, breakCount.count ) self.assertEqual( 1, breakCount.count )
def testBpScope(self):
def setBpFunc():
#breakpoint must be set until remove method will be called explicitly
pykd.setBp(targetModule.CdeclFunc)
processId = pykd.startProcess( target.appPath + " breakhandlertest" )
targetModule = pykd.module( target.moduleName )
targetModule.reload()
with testutils.ContextCallIt( testutils.KillProcess(processId) ) as killStartedProcess :
pykd.go()
setBpFunc()
self.assertEqual( pykd.executionStatus.Break, pykd.go() )
def testNoBreakCallback(self): def testNoBreakCallback(self):
processId = pykd.startProcess( target.appPath + " breakhandlertest" )
targetModule = pykd.module( target.moduleName )
targetModule.reload()
with testutils.ContextCallIt( testutils.KillProcess(processId) ) as killStartedProcess :
pykd.go()
breakCount = callCounter(continueOnBreak) breakCount = callCounter(continueOnBreak)
bp = pykd.setBp( self.targetModule.CdeclFunc, breakCount )
pykd.setBp( targetModule.CdeclFunc, breakCount )
self.assertEqual( pykd.executionStatus.NoDebuggee, pykd.go() ) self.assertEqual( pykd.executionStatus.NoDebuggee, pykd.go() )
self.assertEqual( 1, breakCount.count ) self.assertEqual( 1, breakCount.count )
def testBreakpointHandler(self): def testBreakpointHandler(self):
@ -110,22 +74,11 @@ class BreakpointTest( unittest.TestCase ):
self.count = self.count + 1 self.count = self.count + 1
return True return True
processId = pykd.startProcess( target.appPath + " breakhandlertest" )
targetModule = pykd.module( target.moduleName )
targetModule.reload()
with testutils.ContextCallIt( testutils.KillProcess(processId) ) as killStartedProcess :
pykd.go()
handler = BreakpointHandler() handler = BreakpointHandler()
bp = pykd.setBp( self.targetModule.CdeclFunc )
pykd.setBp( targetModule.CdeclFunc )
self.assertEqual( pykd.executionStatus.Break, pykd.go() ) self.assertEqual( pykd.executionStatus.Break, pykd.go() )
self.assertEqual( 1, handler.count ) self.assertEqual( 1, handler.count )
def testBreakpointClass(self): def testBreakpointClass(self):
class MyBreakpoint(pykd.breakpoint): class MyBreakpoint(pykd.breakpoint):
@ -137,21 +90,12 @@ class BreakpointTest( unittest.TestCase ):
self.count = self.count + 1 self.count = self.count + 1
return True return True
processId = pykd.startProcess( target.appPath + " breakhandlertest" ) bp = MyBreakpoint( self.targetModule.typedVar("CdeclFunc").getDebugStart() )
targetModule = pykd.module( target.moduleName )
targetModule.reload()
with testutils.ContextCallIt( testutils.KillProcess(processId) ) as killStartedProcess :
pykd.go()
bp = MyBreakpoint( targetModule.typedVar("CdeclFunc").getDebugStart() )
self.assertEqual( pykd.executionStatus.Break, pykd.go() ) self.assertEqual( pykd.executionStatus.Break, pykd.go() )
self.assertEqual( 1, bp.count ) self.assertEqual( 1, bp.count )
def testBreakpointCondition(self): def testBreakpointCondition1(self):
def makebpcallback(n): def makebpcallback(n):
@ -161,33 +105,29 @@ class BreakpointTest( unittest.TestCase ):
return pykd.eventResult.Proceed return pykd.eventResult.Proceed
return bpcallback return bpcallback
processId = pykd.startProcess( target.appPath + " breakhandlertest" ) bp = pykd.setBp( self.targetModule.typedVar("CdeclFunc").getDebugStart(), makebpcallback(1) )
targetModule = pykd.module( target.moduleName )
targetModule.reload()
with testutils.ContextCallIt( testutils.KillProcess(processId) ) as killStartedProcess :
pykd.go()
bp = pykd.setBp( targetModule.typedVar("CdeclFunc").getDebugStart(), makebpcallback(1) )
self.assertEqual( pykd.executionStatus.Break, pykd.go() ) self.assertEqual( pykd.executionStatus.Break, pykd.go() )
processId = pykd.startProcess( target.appPath + " breakhandlertest" ) def testBreakpointCondition2(self):
targetModule = pykd.module( target.moduleName )
targetModule.reload() def makebpcallback(n):
with testutils.ContextCallIt( testutils.KillProcess(processId) ) as killStartedProcess :
pykd.go() def bpcallback():
bp = pykd.setBp(targetModule.typedVar("CdeclFunc").getDebugStart(), makebpcallback(100) ) if pykd.getParam("b") > n:
return pykd.eventResult.Break
return pykd.eventResult.Proceed
return bpcallback
bp = pykd.setBp(self.targetModule.typedVar("CdeclFunc").getDebugStart(), makebpcallback(100) )
self.assertEqual( pykd.executionStatus.NoDebuggee, pykd.go() ) self.assertEqual( pykd.executionStatus.NoDebuggee, pykd.go() )
def testBreakpointEnum(self):
processId = pykd.startProcess( target.appPath + " breakhandlertest" )
targetModule = pykd.module( target.moduleName )
targetModule.reload()
with testutils.ContextCallIt( testutils.KillProcess(processId) ) as killStartedProcess :
pykd.go()
pykd.setBp( targetModule.CdeclFunc) def testBreakpointEnum(self):
pykd.setBp( targetModule.CdeclFunc + 1)
pykd.setBp( targetModule.CdeclFunc + 2) b1 = pykd.setBp( self.targetModule.CdeclFunc)
b2 = pykd.setBp( self.targetModule.CdeclFunc + 1)
b3 = pykd.setBp( self.targetModule.CdeclFunc + 2)
self.assertEqual(3, pykd.getNumberBreakpoints()); self.assertEqual(3, pykd.getNumberBreakpoints());
bpLst = [pykd.getBp(i) for i in xrange(3)] bpLst = [pykd.getBp(i) for i in xrange(3)]
@ -199,43 +139,32 @@ class BreakpointTest( unittest.TestCase ):
class BreakpointChangeHandler( pykd.eventHandler ): class BreakpointChangeHandler( pykd.eventHandler ):
def onChangeBreakpoints(self): def __init__(self):
pass pykd.eventHandler.__init__(self)
self.count = 0
def onChangeBreakpoints(self):
self.count += 1
processId = pykd.startProcess( target.appPath + " breakhandlertest" )
targetModule = pykd.module( target.moduleName )
targetModule.reload()
with testutils.ContextCallIt( testutils.KillProcess(processId) ) as killStartedProcess :
pykd.go()
handler = BreakpointChangeHandler() handler = BreakpointChangeHandler()
bp = pykd.setBp( targetModule.CdeclFunc) bp = pykd.setBp(self.targetModule.CdeclFunc)
bp.remove() bp.remove()
self.assertEqual(0, pykd.getNumberBreakpoints()) self.assertEqual(0, pykd.getNumberBreakpoints())
self.assertEqual(4, handler.count)
def testLambdaBpContinue(self): def testLambdaBpContinue(self):
bp1 = pykd.setBp(self.targetModule.CdeclFunc, lambda : None )
processId = pykd.startProcess( target.appPath + " breakhandlertest" ) bp2 = pykd.setBp(self.targetModule.CdeclFunc, lambda : False )
targetModule = pykd.module( target.moduleName ) bp3 = pykd.setBp(self.targetModule.CdeclFunc, lambda : 0 )
targetModule.reload()
with testutils.ContextCallIt( testutils.KillProcess(processId) ) as killStartedProcess :
pykd.go()
bp1 = pykd.setBp(targetModule.CdeclFunc, lambda : None )
bp2 = pykd.setBp(targetModule.CdeclFunc, lambda : False )
bp3 = pykd.setBp(targetModule.CdeclFunc, lambda : 0 )
self.assertEqual( pykd.executionStatus.NoDebuggee, pykd.go() ) self.assertEqual( pykd.executionStatus.NoDebuggee, pykd.go() )
def testLambdaBpBreak(self): def testLambdaBpBreak(self):
bp2 = pykd.setBp(self.targetModule.CdeclFunc, lambda : True )
processId = pykd.startProcess( target.appPath + " breakhandlertest" )
targetModule = pykd.module( target.moduleName )
targetModule.reload()
with testutils.ContextCallIt( testutils.KillProcess(processId) ) as killStartedProcess :
pykd.go()
bp2 = pykd.setBp(targetModule.CdeclFunc, lambda : True )
self.assertEqual( pykd.executionStatus.Break, pykd.go() ) self.assertEqual( pykd.executionStatus.Break, pykd.go() )
def testBpCommand(self):
pykd.dbgCommand("bp 0x100")
self.assertEqual(1, pykd.getNumberBreakpoints())
bp = pykd.getBp(0)
self.assertEqual(0x100, bp.getOffset())