[0.1.x] added : eventHandler class

git-svn-id: https://pykd.svn.codeplex.com/svn@70386 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
SND\kernelnet_cp 2011-10-14 07:03:51 +00:00 committed by Mikhail I. Izmestev
parent e3551dcdd4
commit 8c14fd3208
10 changed files with 507 additions and 257 deletions

View File

@ -10,6 +10,38 @@ namespace pykd {
DebugClientPtr g_dbgClient( DebugClient::createDbgClient() ); DebugClientPtr g_dbgClient( DebugClient::createDbgClient() );
///////////////////////////////////////////////////////////////////////////////////
DebugClientPtr DebugClient::createDbgClient() {
HRESULT hres;
CComPtr<IDebugClient4> client = NULL;
hres = DebugCreate( __uuidof(IDebugClient4), (void **)&client );
if ( FAILED( hres ) )
throw DbgException("DebugCreate failed");
return createDbgClient( client );
}
///////////////////////////////////////////////////////////////////////////////////
DebugClientPtr DebugClient::createDbgClient( IDebugClient4 *client ) {
HRESULT hres;
CComPtr<IDebugClient> newClient = NULL;
hres = client->CreateClient( &newClient );
if ( FAILED( hres ) )
throw DbgException("DebugCreate failed");
CComQIPtr<IDebugClient4> client4= newClient;
return DebugClientPtr( new DebugClient(client4) );
}
///////////////////////////////////////////////////////////////////////////////////
DebugClientPtr DebugClient::setDbgClientCurrent( DebugClientPtr newDbgClient ) { DebugClientPtr DebugClient::setDbgClientCurrent( DebugClientPtr newDbgClient ) {
DebugClientPtr oldClient = g_dbgClient; DebugClientPtr oldClient = g_dbgClient;
g_dbgClient = newDbgClient; g_dbgClient = newDbgClient;

View File

@ -30,22 +30,10 @@ public:
virtual ~DebugClient() {} virtual ~DebugClient() {}
static static
DebugClientPtr createDbgClient() { DebugClientPtr createDbgClient() ;
HRESULT hres;
CComPtr<IDebugClient4> client = NULL;
hres = DebugCreate( __uuidof(IDebugClient4), (void **)&client );
if ( FAILED( hres ) )
throw DbgException("DebugCreate failed");
return createDbgClient( client );
}
static static
DebugClientPtr createDbgClient( IDebugClient4 *client ) { DebugClientPtr createDbgClient( IDebugClient4 *client );
return DebugClientPtr( new DebugClient(client) );
}
static static
DebugClientPtr setDbgClientCurrent( DebugClientPtr newDbgClient ); DebugClientPtr setDbgClientCurrent( DebugClientPtr newDbgClient );
@ -62,6 +50,8 @@ public:
void attachKernel( const std::wstring &param ); void attachKernel( const std::wstring &param );
//createEventHandler();
ULONG64 evaluate( const std::wstring &expression ); ULONG64 evaluate( const std::wstring &expression );
python::tuple getDebuggeeType(); python::tuple getDebuggeeType();

View File

@ -4,214 +4,267 @@
// //
#include "stdafx.h" #include "stdafx.h"
#include "dbgevent.h" #include "dbgevent.h"
#include "dbgio.h" #include "dbgclient.h"
#include "dbgexcept.h"
#include "pyaux.h"
namespace pykd {
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
debugEvent::debugEvent() EventHandler::EventHandler()
{ {
HRESULT hres; HRESULT hres;
hres = dbgExt->client->CreateClient( &m_debugClient ); hres = g_dbgClient->client()->CreateClient( &m_client );
if ( FAILED( hres ) ) if ( FAILED( hres ) )
throw DbgException( "IDebugClient::CreateClient" ); throw DbgException( "IDebugClient::CreateClient" );
hres = m_debugClient->SetEventCallbacks(this); hres = m_client->SetEventCallbacks(this);
if (FAILED(hres)) if (FAILED(hres))
throw DbgException( "IDebugClient::SetEventCallbacks" ); throw DbgException( "IDebugClient::SetEventCallbacks" );
} }
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
debugEvent::~debugEvent() EventHandler::EventHandler( DebugClient &client )
{ {
m_debugClient->SetEventCallbacks( NULL );
m_debugClient->Release();
}
///////////////////////////////////////////////////////////////////////////////////
HRESULT debugEvent::GetInterestMask(
__out PULONG Mask
)
{
*Mask = 0;
*Mask |= DEBUG_EVENT_LOAD_MODULE;
*Mask |= DEBUG_EVENT_UNLOAD_MODULE;
*Mask |= DEBUG_EVENT_SESSION_STATUS;
*Mask |= DEBUG_EVENT_EXCEPTION;
*Mask |= DEBUG_EVENT_BREAKPOINT;
return S_OK;
}
///////////////////////////////////////////////////////////////////////////////////
HRESULT debugEvent::Breakpoint(
__in PDEBUG_BREAKPOINT Bp
)
{
boost::python::dict bpParameters;
HRESULT hres; HRESULT hres;
ULONG Value = 0;
ULONG Value2 = 0;
ULONG64 Value64 = 0;
std::string str;
#define _ADD_BP_ULONG(x) \ hres = client.client()->CreateClient( &m_client );
hres = Bp->Get##x(&Value); \ if ( FAILED( hres ) )
BOOST_ASSERT( SUCCEEDED( hres ) || hres == E_NOINTERFACE ); \ throw DbgException( "IDebugClient::CreateClient" );
if (SUCCEEDED( hres )) \
bpParameters[#x] = Value;
#define _ADD_BP_ULONG2(x, n1, n2) \ hres = m_client->SetEventCallbacks(this);
hres = Bp->Get##x(&Value, &Value2); \ if (FAILED(hres))
BOOST_ASSERT( SUCCEEDED( hres ) || hres == E_NOINTERFACE ); \ throw DbgException( "IDebugClient::SetEventCallbacks" );
if (SUCCEEDED( hres )) \
{ \
bpParameters[n1] = Value; bpParameters[n2] = Value2; \
}
#define _ADD_BP_ULONG64(x) \
hres = Bp->Get##x(&Value64); \
BOOST_ASSERT( SUCCEEDED( hres ) || hres == E_NOINTERFACE ); \
if (SUCCEEDED( hres )) \
bpParameters[#x] = Value64;
#define _ADD_BP_STR(x) \
Value = 0; \
Bp->Get##x(NULL, 0, &Value); \
if (Value) \
{ \
str.resize(Value + 1); \
BOOST_VERIFY( SUCCEEDED( \
Bp->Get##x(&str[0], (ULONG)str.size(), NULL) \
) ); \
if (!str.empty()) bpParameters[#x] = str.c_str(); \
}
_ADD_BP_ULONG(Id);
_ADD_BP_ULONG2(Type, "BreakType", "ProcType");
_ADD_BP_ULONG(Flags);
_ADD_BP_ULONG64(Offset);
_ADD_BP_ULONG2(DataParameters, "Size", "AccessType");
_ADD_BP_ULONG(PassCount);
_ADD_BP_ULONG(CurrentPassCount);
_ADD_BP_ULONG(MatchThreadId);
_ADD_BP_STR(Command);
_ADD_BP_STR(OffsetExpression);
#undef _ADD_BP_ULONG
#undef _ADD_BP_ULONG2
#undef _ADD_BP_ULONG64
#undef _ADD_BP_STR
PyThread_StateSave pyThreadSave;
return onException(bpParameters);
} }
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
HRESULT debugEvent::Exception( EventHandler::~EventHandler()
__in PEXCEPTION_RECORD64 Exception,
__in ULONG FirstChance
)
{ {
boost::python::list exceptParams; m_client->SetEventCallbacks( NULL );
boost::python::dict exceptData;
// build list of parameters
for (ULONG i = 0; i < Exception->NumberParameters; ++i)
exceptParams.append(Exception->ExceptionInformation[i]);
// build dict of exception data
#define _ADD_EXCEPTION_ENTRY(x) exceptData[#x] = Exception->Exception##x
_ADD_EXCEPTION_ENTRY(Code);
_ADD_EXCEPTION_ENTRY(Flags);
_ADD_EXCEPTION_ENTRY(Record);
_ADD_EXCEPTION_ENTRY(Address);
#undef _ADD_EXCEPTION_ENTRY
exceptData["Parameters"] = exceptParams;
exceptData["FirstChance"] = (0 != FirstChance);
PyThread_StateSave pyThreadSave;
return onException(exceptData);
} }
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
HRESULT debugEvent::LoadModule( }; // end pykd namespace
__in ULONG64 ImageFileHandle,
__in ULONG64 BaseOffset,
__in ULONG ModuleSize,
__in PCSTR ModuleName,
__in PCSTR ImageName,
__in ULONG CheckSum,
__in ULONG TimeDateStamp
)
{
std::auto_ptr<OutputReader> silentMode( new OutputReader(dbgExt->client) );
ULONG64 moduleBase;
ULONG moduleSize;
std::string moduleName;
queryModuleParams(BaseOffset, moduleName, moduleBase, moduleSize);
dbgModuleClass module(moduleName, moduleBase, moduleSize);
silentMode.reset();
PyThread_StateSave pyThreadSave;
return onLoadModule( module );
}
///////////////////////////////////////////////////////////////////////////////////
HRESULT debugEvent::UnloadModule(
__in PCSTR ImageBaseName,
__in ULONG64 BaseOffset
)
{
std::auto_ptr<OutputReader> silentMode( new OutputReader(dbgExt->client) );
ULONG64 moduleBase;
ULONG moduleSize;
std::string moduleName;
queryModuleParams(BaseOffset, moduleName, moduleBase, moduleSize);
dbgModuleClass module(moduleName, moduleBase, moduleSize);
silentMode.reset();
PyThread_StateSave pyThreadSave;
return onUnloadModule( module );
}
///////////////////////////////////////////////////////////////////////////////////
HRESULT debugEvent::SessionStatus(
__in ULONG Status
)
{
PyThread_StateSave pyThreadSave;
return onChangeSessionStatus( Status );
}
///////////////////////////////////////////////////////////////////////////////////
HRESULT debugEvent::ChangeDebuggeeState(
__in ULONG Flags,
__in ULONG64 Argument
)
{
PyThread_StateSave pyThreadSave;
return onChangeDebugeeState();
}
///////////////////////////////////////////////////////////////////////////////////
//#include "dbgevent.h"
//#include "dbgio.h"
//#include "dbgexcept.h"
//#include "pyaux.h"
//
/////////////////////////////////////////////////////////////////////////////////////
//
//debugEvent::debugEvent()
//{
// HRESULT hres;
//
// hres = dbgExt->client->CreateClient( &m_debugClient );
// if ( FAILED( hres ) )
// throw DbgException( "IDebugClient::CreateClient" );
//
// hres = m_debugClient->SetEventCallbacks(this);
// if (FAILED(hres))
// throw DbgException( "IDebugClient::SetEventCallbacks" );
//}
//
/////////////////////////////////////////////////////////////////////////////////////
//
//debugEvent::~debugEvent()
//{
// m_debugClient->SetEventCallbacks( NULL );
//
// m_debugClient->Release();
//}
//
/////////////////////////////////////////////////////////////////////////////////////
//
//HRESULT debugEvent::GetInterestMask(
// __out PULONG Mask
//)
//{
// *Mask = 0;
//
// *Mask |= DEBUG_EVENT_LOAD_MODULE;
// *Mask |= DEBUG_EVENT_UNLOAD_MODULE;
// *Mask |= DEBUG_EVENT_SESSION_STATUS;
// *Mask |= DEBUG_EVENT_EXCEPTION;
// *Mask |= DEBUG_EVENT_BREAKPOINT;
//
// return S_OK;
//}
//
/////////////////////////////////////////////////////////////////////////////////////
//
//HRESULT debugEvent::Breakpoint(
// __in PDEBUG_BREAKPOINT Bp
//)
//{
// boost::python::dict bpParameters;
//
// HRESULT hres;
// ULONG Value = 0;
// ULONG Value2 = 0;
// ULONG64 Value64 = 0;
// std::string str;
//
//#define _ADD_BP_ULONG(x) \
// hres = Bp->Get##x(&Value); \
// BOOST_ASSERT( SUCCEEDED( hres ) || hres == E_NOINTERFACE ); \
// if (SUCCEEDED( hres )) \
// bpParameters[#x] = Value;
//
//#define _ADD_BP_ULONG2(x, n1, n2) \
// hres = Bp->Get##x(&Value, &Value2); \
// BOOST_ASSERT( SUCCEEDED( hres ) || hres == E_NOINTERFACE ); \
// if (SUCCEEDED( hres )) \
// { \
// bpParameters[n1] = Value; bpParameters[n2] = Value2; \
// }
//
//#define _ADD_BP_ULONG64(x) \
// hres = Bp->Get##x(&Value64); \
// BOOST_ASSERT( SUCCEEDED( hres ) || hres == E_NOINTERFACE ); \
// if (SUCCEEDED( hres )) \
// bpParameters[#x] = Value64;
//
//#define _ADD_BP_STR(x) \
// Value = 0; \
// Bp->Get##x(NULL, 0, &Value); \
// if (Value) \
// { \
// str.resize(Value + 1); \
// BOOST_VERIFY( SUCCEEDED( \
// Bp->Get##x(&str[0], (ULONG)str.size(), NULL) \
// ) ); \
// if (!str.empty()) bpParameters[#x] = str.c_str(); \
// }
//
// _ADD_BP_ULONG(Id);
// _ADD_BP_ULONG2(Type, "BreakType", "ProcType");
// _ADD_BP_ULONG(Flags);
// _ADD_BP_ULONG64(Offset);
// _ADD_BP_ULONG2(DataParameters, "Size", "AccessType");
// _ADD_BP_ULONG(PassCount);
// _ADD_BP_ULONG(CurrentPassCount);
// _ADD_BP_ULONG(MatchThreadId);
// _ADD_BP_STR(Command);
// _ADD_BP_STR(OffsetExpression);
//
//#undef _ADD_BP_ULONG
//#undef _ADD_BP_ULONG2
//#undef _ADD_BP_ULONG64
//#undef _ADD_BP_STR
//
// PyThread_StateSave pyThreadSave;
// return onException(bpParameters);
//}
//
/////////////////////////////////////////////////////////////////////////////////////
//
//HRESULT debugEvent::Exception(
// __in PEXCEPTION_RECORD64 Exception,
// __in ULONG FirstChance
//)
//{
// boost::python::list exceptParams;
// boost::python::dict exceptData;
//
// // build list of parameters
// for (ULONG i = 0; i < Exception->NumberParameters; ++i)
// exceptParams.append(Exception->ExceptionInformation[i]);
//
// // build dict of exception data
//#define _ADD_EXCEPTION_ENTRY(x) exceptData[#x] = Exception->Exception##x
// _ADD_EXCEPTION_ENTRY(Code);
// _ADD_EXCEPTION_ENTRY(Flags);
// _ADD_EXCEPTION_ENTRY(Record);
// _ADD_EXCEPTION_ENTRY(Address);
//#undef _ADD_EXCEPTION_ENTRY
//
// exceptData["Parameters"] = exceptParams;
//
// exceptData["FirstChance"] = (0 != FirstChance);
//
// PyThread_StateSave pyThreadSave;
// return onException(exceptData);
//}
//
/////////////////////////////////////////////////////////////////////////////////////
//
//HRESULT debugEvent::LoadModule(
// __in ULONG64 ImageFileHandle,
// __in ULONG64 BaseOffset,
// __in ULONG ModuleSize,
// __in PCSTR ModuleName,
// __in PCSTR ImageName,
// __in ULONG CheckSum,
// __in ULONG TimeDateStamp
//)
//{
// std::auto_ptr<OutputReader> silentMode( new OutputReader(dbgExt->client) );
//
// ULONG64 moduleBase;
// ULONG moduleSize;
// std::string moduleName;
//
// queryModuleParams(BaseOffset, moduleName, moduleBase, moduleSize);
// dbgModuleClass module(moduleName, moduleBase, moduleSize);
// silentMode.reset();
//
// PyThread_StateSave pyThreadSave;
// return onLoadModule( module );
//}
//
/////////////////////////////////////////////////////////////////////////////////////
//
//HRESULT debugEvent::UnloadModule(
// __in PCSTR ImageBaseName,
// __in ULONG64 BaseOffset
//)
//{
// std::auto_ptr<OutputReader> silentMode( new OutputReader(dbgExt->client) );
//
// ULONG64 moduleBase;
// ULONG moduleSize;
// std::string moduleName;
//
// queryModuleParams(BaseOffset, moduleName, moduleBase, moduleSize);
// dbgModuleClass module(moduleName, moduleBase, moduleSize);
// silentMode.reset();
//
// PyThread_StateSave pyThreadSave;
// return onUnloadModule( module );
//}
//
/////////////////////////////////////////////////////////////////////////////////////
//
//HRESULT debugEvent::SessionStatus(
// __in ULONG Status
//)
//{
// PyThread_StateSave pyThreadSave;
// return onChangeSessionStatus( Status );
//}
//
/////////////////////////////////////////////////////////////////////////////////////
//
//HRESULT debugEvent::ChangeDebuggeeState(
// __in ULONG Flags,
// __in ULONG64 Argument
//)
//{
// PyThread_StateSave pyThreadSave;
// return onChangeDebugeeState();
//}
//
/////////////////////////////////////////////////////////////////////////////////////
//

View File

@ -2,100 +2,92 @@
// user-customizing debug event handler // user-customizing debug event handler
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
#include "dbgeventcb.h" #pragma once
#include "dbgmodule.h"
#include "pyaux.h" #include "stdafx.h"
#include <dbgeng.h>
#include "dbgobj.h"
#include "module.h"
#include "dbgclient.h"
namespace pykd {
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
class debugEvent : public DebugBaseEventCallbacks class EventHandler : public DebugBaseEventCallbacks
{ {
public: public:
debugEvent(); EventHandler();
virtual ~debugEvent(); EventHandler( DebugClient &client );
virtual ULONG onBreakpoint(boost::python::dict &/*bpParameters*/) = 0; virtual ~EventHandler();
virtual ULONG onException(boost::python::dict &/*exceptData*/) = 0; protected:
virtual ULONG onLoadModule(const dbgModuleClass &/* module */) = 0;
virtual ULONG onUnloadModule(const dbgModuleClass &/* module */) = 0;
virtual ULONG onChangeSessionStatus( ULONG status ) = 0;
virtual ULONG onChangeDebugeeState() = 0;
private:
STDMETHOD_(ULONG, AddRef)() { return 1; } STDMETHOD_(ULONG, AddRef)() { return 1; }
STDMETHOD_(ULONG, Release)() { return 1; } STDMETHOD_(ULONG, Release)() { return 1; }
STDMETHOD(GetInterestMask)( STDMETHOD(GetInterestMask)(
__out PULONG Mask __out PULONG Mask
); ) {
*Mask = 0;
*Mask |= DEBUG_EVENT_LOAD_MODULE;
*Mask |= DEBUG_EVENT_UNLOAD_MODULE;
*Mask |= DEBUG_EVENT_SESSION_STATUS;
*Mask |= DEBUG_EVENT_EXCEPTION;
*Mask |= DEBUG_EVENT_BREAKPOINT;
return S_OK;
}
STDMETHOD(Breakpoint)( protected:
__in PDEBUG_BREAKPOINT Bp
);
virtual ULONG onBreakpoint(const python::dict &/*bpParameters*/) = 0;
STDMETHOD(Exception)( virtual ULONG onException(const python::dict &/*exceptData*/) = 0;
__in PEXCEPTION_RECORD64 Exception,
__in ULONG FirstChance
);
STDMETHOD(LoadModule)( virtual ULONG onLoadModule(const Module &/* module */) = 0;
__in ULONG64 ImageFileHandle,
__in ULONG64 BaseOffset,
__in ULONG ModuleSize,
__in PCSTR ModuleName,
__in PCSTR ImageName,
__in ULONG CheckSum,
__in ULONG TimeDateStamp
);
STDMETHOD(UnloadModule)( virtual ULONG onUnloadModule(const Module &/* module */) = 0;
__in PCSTR ImageBaseName,
__in ULONG64 BaseOffset
);
STDMETHOD(SessionStatus)( virtual ULONG onChangeSessionStatus( ULONG status ) = 0;
__in ULONG Status
);
STDMETHOD(ChangeDebuggeeState)( virtual ULONG onChangeDebugeeState() = 0;
__in ULONG Flags,
__in ULONG64 Argument );
private: protected:
IDebugClient *m_debugClient; CComPtr<IDebugClient> m_client;
}; };
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
class debugEventWrap : public boost::python::wrapper<debugEvent>, public debugEvent class EventHandlerWrap : public boost::python::wrapper<EventHandler>, public EventHandler
{ {
public: public:
ULONG onBreakpoint(boost::python::dict &bpParameters) { EventHandlerWrap()
return handler<boost::python::dict &>("onBreakpoint", bpParameters); {}
EventHandlerWrap( DebugClient &client ) : EventHandler( client )
{}
ULONG onBreakpoint(const python::dict &bpParameters) {
return handler<const python::dict&>("onBreakpoint", bpParameters);
} }
ULONG onException(boost::python::dict &exceptData) { ULONG onException(const python::dict &exceptData) {
return handler<boost::python::dict &>("onException", exceptData); return handler<const python::dict&>("onException", exceptData);
} }
ULONG onLoadModule(const dbgModuleClass &module) { ULONG onLoadModule(const Module &module) {
return handler<const dbgModuleClass &>("onLoadModule", module ); return handler<const Module&>("onLoadModule", module );
} }
ULONG onUnloadModule(const dbgModuleClass &module) { ULONG onUnloadModule(const Module &module) {
return handler<const dbgModuleClass &>("onUnloadModule", module ); return handler<const Module&>("onUnloadModule", module );
} }
ULONG onChangeSessionStatus( ULONG status ) { ULONG onChangeSessionStatus( ULONG status ) {
@ -111,7 +103,7 @@ private:
template<typename Arg1Type> template<typename Arg1Type>
ULONG handler( const char* handlerName, Arg1Type arg1 ) ULONG handler( const char* handlerName, Arg1Type arg1 )
{ {
if (boost::python::override pythonHandler = get_override( handlerName )) if (python::override pythonHandler = get_override( handlerName ))
return pythonHandler(arg1); return pythonHandler(arg1);
return DEBUG_STATUS_NO_CHANGE; return DEBUG_STATUS_NO_CHANGE;
@ -119,7 +111,7 @@ private:
ULONG handler( const char* handlerName ) ULONG handler( const char* handlerName )
{ {
if (boost::python::override pythonHandler = get_override( handlerName )) if (python::override pythonHandler = get_override( handlerName ))
return pythonHandler(); return pythonHandler();
return DEBUG_STATUS_NO_CHANGE; return DEBUG_STATUS_NO_CHANGE;
@ -127,3 +119,142 @@ private:
}; };
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
}; // end namespace pykd
//#include "dbgeventcb.h"
//#include "dbgmodule.h"
//#include "pyaux.h"
//
///////////////////////////////////////////////////////////////////////////////////
//
//class debugEvent : public DebugBaseEventCallbacks
//{
//public:
//
// debugEvent();
//
// virtual ~debugEvent();
//
// virtual ULONG onBreakpoint(boost::python::dict &/*bpParameters*/) = 0;
//
// virtual ULONG onException(boost::python::dict &/*exceptData*/) = 0;
//
// virtual ULONG onLoadModule(const dbgModuleClass &/* module */) = 0;
//
// virtual ULONG onUnloadModule(const dbgModuleClass &/* module */) = 0;
//
// virtual ULONG onChangeSessionStatus( ULONG status ) = 0;
//
// virtual ULONG onChangeDebugeeState() = 0;
//
//private:
//
// STDMETHOD_(ULONG, AddRef)() { return 1; }
// STDMETHOD_(ULONG, Release)() { return 1; }
//
// STDMETHOD(GetInterestMask)(
// __out PULONG Mask
// );
//
// STDMETHOD(Breakpoint)(
// __in PDEBUG_BREAKPOINT Bp
// );
//
//
// STDMETHOD(Exception)(
// __in PEXCEPTION_RECORD64 Exception,
// __in ULONG FirstChance
// );
//
// STDMETHOD(LoadModule)(
// __in ULONG64 ImageFileHandle,
// __in ULONG64 BaseOffset,
// __in ULONG ModuleSize,
// __in PCSTR ModuleName,
// __in PCSTR ImageName,
// __in ULONG CheckSum,
// __in ULONG TimeDateStamp
// );
//
// STDMETHOD(UnloadModule)(
// __in PCSTR ImageBaseName,
// __in ULONG64 BaseOffset
// );
//
// STDMETHOD(SessionStatus)(
// __in ULONG Status
// );
//
// STDMETHOD(ChangeDebuggeeState)(
// __in ULONG Flags,
// __in ULONG64 Argument );
//
//private:
//
// IDebugClient *m_debugClient;
//};
//
///////////////////////////////////////////////////////////////////////////////////
//
//class debugEventWrap : public boost::python::wrapper<debugEvent>, public debugEvent
//{
//
//public:
//
// ULONG onBreakpoint(boost::python::dict &bpParameters) {
// return handler<boost::python::dict &>("onBreakpoint", bpParameters);
// }
//
// ULONG onException(boost::python::dict &exceptData) {
// return handler<boost::python::dict &>("onException", exceptData);
// }
//
// ULONG onLoadModule(const dbgModuleClass &module) {
// return handler<const dbgModuleClass &>("onLoadModule", module );
// }
//
// ULONG onUnloadModule(const dbgModuleClass &module) {
// return handler<const dbgModuleClass &>("onUnloadModule", module );
// }
//
// ULONG onChangeSessionStatus( ULONG status ) {
// return handler( "onChangeSessionStatus", status );
// }
//
// ULONG onChangeDebugeeState() {
// return handler( "onChangeDebugeeState" );
// }
//
//private:
//
// template<typename Arg1Type>
// ULONG handler( const char* handlerName, Arg1Type arg1 )
// {
// if (boost::python::override pythonHandler = get_override( handlerName ))
// return pythonHandler(arg1);
//
// return DEBUG_STATUS_NO_CHANGE;
// }
//
// ULONG handler( const char* handlerName )
// {
// if (boost::python::override pythonHandler = get_override( handlerName ))
// return pythonHandler();
//
// return DEBUG_STATUS_NO_CHANGE;
// }
//};
//
///////////////////////////////////////////////////////////////////////////////////

View File

@ -12,6 +12,7 @@
#include "dbgio.h" #include "dbgio.h"
#include "dbgpath.h" #include "dbgpath.h"
#include "dbgcmd.h" #include "dbgcmd.h"
#include "dbgevent.h"
using namespace pykd; using namespace pykd;
@ -158,6 +159,31 @@ BOOST_PYTHON_MODULE( pykd )
.def( "call", &pykd::DbgExtension::call, .def( "call", &pykd::DbgExtension::call,
"Call debug extension command end return it's result as a string" ); "Call debug extension command end return it's result as a string" );
python::class_<EventHandlerWrap, boost::noncopyable>(
"eventHandler", "Base class for overriding and handling debug notifications" )
.def( python::init<>() )
.def( python::init<DebugClient&>() )
.def( "onBreakpoint", &pykd::EventHandlerWrap::onBreakpoint,
"Triggered breakpoint event. Parameter is dict:\n"
"{\"Id\":int, \"BreakType\":int, \"ProcType\":int, \"Flags\":int, \"Offset\":int,"
" \"Size\":int, \"AccessType\":int, \"PassCount\":int, \"CurrentPassCount\":int,"
" \"MatchThreadId\":int, \"Command\":str, \"OffsetExpression\":str}\n"
"Detailed information: http://msdn.microsoft.com/en-us/library/ff539284(VS.85).aspx \n"
"For ignore event method must return DEBUG_STATUS_NO_CHANGE value" )
.def( "onException", &pykd::EventHandlerWrap::onException,
"Exception event. Parameter is dict:\n"
"{\"Code\":int, \"Flags\":int, \"Record\":int, \"Address\":int,"
" \"Parameters\":[int], \"FirstChance\":bool}\n"
"Detailed information: http://msdn.microsoft.com/en-us/library/aa363082(VS.85).aspx \n"
"For ignore event method must return DEBUG_STATUS_NO_CHANGE value" )
.def( "onLoadModule", &pykd::EventHandlerWrap::onLoadModule,
"Load module event. Parameter is instance of dbgModuleClass.\n"
"For ignore event method must return DEBUG_STATUS_NO_CHANGE value" )
.def( "onUnloadModule", &pykd::EventHandlerWrap::onUnloadModule,
"Unload module event. Parameter is instance of dbgModuleClass.\n"
"For ignore event method must return DEBUG_STATUS_NO_CHANGE value" );
python::def( "diaLoadPdb", &pyDia::GlobalScope::loadPdb, python::def( "diaLoadPdb", &pyDia::GlobalScope::loadPdb,
"Open pdb file for quering debug symbols. Return DiaSymbol of global scope"); "Open pdb file for quering debug symbols. Return DiaSymbol of global scope");

View File

@ -357,6 +357,10 @@
RelativePath=".\dbgcmd.cpp" RelativePath=".\dbgcmd.cpp"
> >
</File> </File>
<File
RelativePath=".\dbgevent.cpp"
>
</File>
<File <File
RelativePath=".\dbgexcept.cpp" RelativePath=".\dbgexcept.cpp"
> >
@ -447,6 +451,10 @@
RelativePath=".\dbgcmd.h" RelativePath=".\dbgcmd.h"
> >
</File> </File>
<File
RelativePath=".\dbgevent.h"
>
</File>
<File <File
RelativePath=".\dbgexcept.h" RelativePath=".\dbgexcept.h"
> >

View File

@ -94,7 +94,6 @@ class BaseTest( unittest.TestCase ):
self.assertTrue( hasattr(pykd, 'bp') ) self.assertTrue( hasattr(pykd, 'bp') )
self.assertTrue( hasattr(pykd, 'cpuReg') ) self.assertTrue( hasattr(pykd, 'cpuReg') )
self.assertTrue( hasattr(pykd, 'dbgStackFrameClass') ) self.assertTrue( hasattr(pykd, 'dbgStackFrameClass') )
self.assertTrue( hasattr(pykd, 'debugEvent') )
self.assertTrue( hasattr(pykd, 'disasm') ) self.assertTrue( hasattr(pykd, 'disasm') )
self.assertTrue( hasattr(pykd, 'ext') ) self.assertTrue( hasattr(pykd, 'ext') )
self.assertTrue( hasattr(pykd, 'intBase') ) self.assertTrue( hasattr(pykd, 'intBase') )
@ -104,6 +103,7 @@ class BaseTest( unittest.TestCase ):
def testOldRemovedApi( self ): def testOldRemovedApi( self ):
""" Branch test: old API 0.0.x what should be removed """ """ Branch test: old API 0.0.x what should be removed """
self.assertFalse( hasattr(pykd, 'dbgModuleClass') ) self.assertFalse( hasattr(pykd, 'dbgModuleClass') )
self.assertFalse( hasattr(pykd, 'debugEvent') )
self.assertFalse( hasattr(pykd, 'windbgIn') ) self.assertFalse( hasattr(pykd, 'windbgIn') )
self.assertFalse( hasattr(pykd, 'windbgOut') ) self.assertFalse( hasattr(pykd, 'windbgOut') )
@ -121,3 +121,4 @@ class BaseTest( unittest.TestCase ):
self.assertTrue( hasattr(pykd, 'din') ) self.assertTrue( hasattr(pykd, 'din') )
self.assertTrue( hasattr(pykd, 'dout') ) self.assertTrue( hasattr(pykd, 'dout') )
self.assertTrue( hasattr(pykd, 'module') ) self.assertTrue( hasattr(pykd, 'module') )
self.assertTrue( hasattr(pykd, 'eventHandler' ) )

View File

@ -18,6 +18,7 @@ import moduletest
import diatest import diatest
import dbgcmd import dbgcmd
import clienttest import clienttest
import eventtest
def getTestSuite( singleName = "" ): def getTestSuite( singleName = "" ):
if singleName == "": if singleName == "":
@ -27,7 +28,8 @@ def getTestSuite( singleName = "" ):
unittest.TestLoader().loadTestsFromTestCase( diatest.DiaTest ), unittest.TestLoader().loadTestsFromTestCase( diatest.DiaTest ),
unittest.TestLoader().loadTestsFromTestCase( typeinfo.TypeInfoTest ), unittest.TestLoader().loadTestsFromTestCase( typeinfo.TypeInfoTest ),
unittest.TestLoader().loadTestsFromTestCase( dbgcmd.DbgcmdTest ), unittest.TestLoader().loadTestsFromTestCase( dbgcmd.DbgcmdTest ),
unittest.TestLoader().loadTestsFromTestCase( clienttest.DbgClientTest ) unittest.TestLoader().loadTestsFromTestCase( clienttest.DbgClientTest ),
unittest.TestLoader().loadTestsFromTestCase( eventtest.EventTest )
] ) ] )
else: else:
return unittest.TestSuite( unittest.TestLoader().loadTestsFromName( singleName ) ) return unittest.TestSuite( unittest.TestLoader().loadTestsFromName( singleName ) )

View File

@ -104,6 +104,9 @@ int _tmain(int argc, _TCHAR* argv[])
{ {
// Let test scripts to execute // Let test scripts to execute
__debugbreak(); __debugbreak();
__debugbreak();
__debugbreak();
__debugbreak();
FuncWithName0(); FuncWithName0();
FuncWithName1(2); FuncWithName1(2);
} }

View File

@ -416,6 +416,10 @@
RelativePath="..\scripts\diatest.py" RelativePath="..\scripts\diatest.py"
> >
</File> </File>
<File
RelativePath="..\scripts\eventtest.py"
>
</File>
<File <File
RelativePath="..\scripts\moduletest.py" RelativePath="..\scripts\moduletest.py"
> >