mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-29 11:53:23 +08:00
[0.3.x] added : event handler
git-svn-id: https://pykd.svn.codeplex.com/svn@84101 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
parent
7373b0226b
commit
0b3beb39a2
@ -118,5 +118,46 @@ BreakpointPtr Breakpoint::setSoftwareBreakpoint( kdlib::MEMOFFSET_64 offset, pyt
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
EventHandler::EventHandler()
|
||||||
|
{
|
||||||
|
m_pystate = PyThreadState_Get();
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
kdlib::DebugCallbackResult EventHandler::onBreakpoint( kdlib::BREAKPOINT_ID bpId )
|
||||||
|
{
|
||||||
|
kdlib::DebugCallbackResult result = kdlib::DebugCallbackNoChange;
|
||||||
|
|
||||||
|
PyEval_RestoreThread( m_pystate );
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
do {
|
||||||
|
|
||||||
|
python::override pythonHandler = get_override( "onBreakpoint" );
|
||||||
|
if ( !pythonHandler )
|
||||||
|
{
|
||||||
|
result = kdlib::EventHandler::onBreakpoint( bpId );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pythonHandler(bpId );
|
||||||
|
|
||||||
|
} while( FALSE );
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (const python::error_already_set &)
|
||||||
|
{
|
||||||
|
printException();
|
||||||
|
result = kdlib::DebugCallbackBreak;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_pystate = PyEval_SaveThread();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
} // end namespace pykd
|
} // end namespace pykd
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "kdlib/dbgengine.h"
|
#include "kdlib/dbgengine.h"
|
||||||
|
#include "kdlib/eventhandler.h"
|
||||||
|
|
||||||
#include "boost/shared_ptr.hpp"
|
#include "boost/shared_ptr.hpp"
|
||||||
#include "boost/noncopyable.hpp"
|
#include "boost/noncopyable.hpp"
|
||||||
#include "boost/python/object.hpp"
|
#include "boost/python/object.hpp"
|
||||||
|
#include "boost/python/wrapper.hpp"
|
||||||
|
|
||||||
namespace python = boost::python;
|
namespace python = boost::python;
|
||||||
|
|
||||||
namespace pykd {
|
namespace pykd {
|
||||||
@ -30,4 +33,22 @@ protected:
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class EventHandler;
|
||||||
|
typedef boost::shared_ptr<EventHandler> EventHandlerPtr;
|
||||||
|
|
||||||
|
class EventHandler : public python::wrapper<kdlib::EventHandler>, public kdlib::EventHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
EventHandler();
|
||||||
|
|
||||||
|
virtual kdlib::DebugCallbackResult onBreakpoint( kdlib::BREAKPOINT_ID bpId );
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
PyThreadState* m_pystate;
|
||||||
|
};
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
} // end namespace pykd
|
} // end namespace pykd
|
||||||
|
@ -634,11 +634,11 @@ BOOST_PYTHON_MODULE( pykd )
|
|||||||
.value("NoDebuggee", kdlib::DebugStatusNoDebuggee )
|
.value("NoDebuggee", kdlib::DebugStatusNoDebuggee )
|
||||||
.export_values();
|
.export_values();
|
||||||
|
|
||||||
//python::class_<EventHandler, EventHandlerPtr, boost::noncopyable>(
|
python::class_<EventHandler, EventHandlerPtr, boost::noncopyable>(
|
||||||
// "eventHandler", "Base class for overriding and handling debug notifications" )
|
"eventHandler", "Base class for overriding and handling debug notifications" )
|
||||||
// .def( "onBreakpoint", &EventHandler::OnBreakpoint,
|
.def( "onBreakpoint", &EventHandler::onBreakpoint,
|
||||||
// "Triggered breakpoint event. Parameter is int: ID of breakpoint\n"
|
"Triggered breakpoint event. Parameter is int: ID of breakpoint\n"
|
||||||
// "For ignore event method must return eventResult.noChange" )
|
"For ignore event method must return eventResult.noChange" )
|
||||||
// .def( "onModuleLoad", &EventHandlerWrap::OnModuleLoad,
|
// .def( "onModuleLoad", &EventHandlerWrap::OnModuleLoad,
|
||||||
// "Triggered module load event. Parameter are long: module base, string: module name\n"
|
// "Triggered module load event. Parameter are long: module base, string: module name\n"
|
||||||
// "For ignore event method must return eventResult.noChange" )
|
// "For ignore event method must return eventResult.noChange" )
|
||||||
@ -657,7 +657,7 @@ BOOST_PYTHON_MODULE( pykd )
|
|||||||
// .def( "onSymbolsUnloaded", &EventHandlerWrap::onSymbolsUnloaded,
|
// .def( "onSymbolsUnloaded", &EventHandlerWrap::onSymbolsUnloaded,
|
||||||
// "Triggered debug symbols unloaded. Parameter - module base or 0 (all modules)\n"
|
// "Triggered debug symbols unloaded. Parameter - module base or 0 (all modules)\n"
|
||||||
// "There is no return value");
|
// "There is no return value");
|
||||||
|
;
|
||||||
|
|
||||||
python::register_exception_translator<kdlib::IndexException>( &ExceptionTranslator::indexTranslate );
|
python::register_exception_translator<kdlib::IndexException>( &ExceptionTranslator::indexTranslate );
|
||||||
|
|
||||||
|
112
test/scripts/breakpoint.py
Normal file
112
test/scripts/breakpoint.py
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
""" breakpoints """
|
||||||
|
|
||||||
|
import unittest
|
||||||
|
import pykd
|
||||||
|
import target
|
||||||
|
import testutils
|
||||||
|
|
||||||
|
class callCounter:
|
||||||
|
def __init__(self,func):
|
||||||
|
self.count = 0
|
||||||
|
self.func = func
|
||||||
|
def __call__(self,val):
|
||||||
|
self.count = self.count+1
|
||||||
|
return self.func(val)
|
||||||
|
|
||||||
|
def stopOnBreak(id):
|
||||||
|
return pykd.Break
|
||||||
|
|
||||||
|
def continueOnBreak(id):
|
||||||
|
return pykd.NoChange
|
||||||
|
|
||||||
|
|
||||||
|
class BreakpointTest( unittest.TestCase ):
|
||||||
|
|
||||||
|
def testNoBreakpoint(self):
|
||||||
|
processId = pykd.startProcess( target.appPath + " breakhandlertest" )
|
||||||
|
with testutils.ContextCallIt( testutils.KillProcess(processId) ) as killStartedProcess :
|
||||||
|
pykd.go()
|
||||||
|
self.assertEqual( pykd.NoDebuggee, pykd.go() )
|
||||||
|
|
||||||
|
def testSetBp(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 )
|
||||||
|
self.assertEqual( pykd.Break, pykd.go() )
|
||||||
|
|
||||||
|
|
||||||
|
def testRemoveBp(self):
|
||||||
|
processId = pykd.startProcess( target.appPath + " breakhandlertest" )
|
||||||
|
targetModule = pykd.module( target.moduleName )
|
||||||
|
targetModule.reload()
|
||||||
|
with testutils.ContextCallIt( testutils.KillProcess(processId) ) as killStartedProcess :
|
||||||
|
pykd.go()
|
||||||
|
bpid = pykd.setBp( targetModule.CdeclFunc )
|
||||||
|
pykd.removeBp( bpid )
|
||||||
|
self.assertEqual( pykd.NoDebuggee, pykd.go() )
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
bp = pykd.breakpoint( targetModule.CdeclFunc, breakCount )
|
||||||
|
|
||||||
|
self.assertEqual( pykd.Break, pykd.go() )
|
||||||
|
|
||||||
|
self.assertEqual( 1, breakCount.count )
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
bp = pykd.breakpoint( targetModule.CdeclFunc, breakCount )
|
||||||
|
|
||||||
|
self.assertEqual( pykd.NoDebuggee, pykd.go() )
|
||||||
|
|
||||||
|
self.assertEqual( 1, breakCount.count )
|
||||||
|
|
||||||
|
def testBreakpointHandler(self):
|
||||||
|
|
||||||
|
class BreakpointHandler( pykd.eventHandler ):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super(BreakpointHandler, self).__init__()
|
||||||
|
self.count = 0
|
||||||
|
|
||||||
|
def onBreakpoint( self, bpid_):
|
||||||
|
self.count = 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 = BreakpointHandler()
|
||||||
|
|
||||||
|
pykd.setBp( targetModule.CdeclFunc )
|
||||||
|
|
||||||
|
self.assertEqual( pykd.Break, pykd.go() )
|
||||||
|
|
||||||
|
self.assertEqual( 1, handler.count )
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user