From 8c14fd32085488e8432f0b88c5083090943d4d1c Mon Sep 17 00:00:00 2001 From: "SND\\kernelnet_cp" Date: Fri, 14 Oct 2011 07:03:51 +0000 Subject: [PATCH] [0.1.x] added : eventHandler class git-svn-id: https://pykd.svn.codeplex.com/svn@70386 9b283d60-5439-405e-af05-b73fd8c4d996 --- pykd/dbgclient.cpp | 32 +++ pykd/dbgclient.h | 18 +- pykd/dbgevent.cpp | 411 ++++++++++++++++++-------------- pykd/dbgevent.h | 255 +++++++++++++++----- pykd/dbgext.cpp | 26 ++ pykd/pykd_2008.vcproj | 8 + test/scripts/basetest.py | 3 +- test/scripts/pykdtest.py | 4 +- test/targetapp/targetapp.cpp | 3 + test/targetapp/targetapp.vcproj | 4 + 10 files changed, 507 insertions(+), 257 deletions(-) diff --git a/pykd/dbgclient.cpp b/pykd/dbgclient.cpp index 7191b8b..3675cb3 100644 --- a/pykd/dbgclient.cpp +++ b/pykd/dbgclient.cpp @@ -10,6 +10,38 @@ namespace pykd { DebugClientPtr g_dbgClient( DebugClient::createDbgClient() ); +/////////////////////////////////////////////////////////////////////////////////// + +DebugClientPtr DebugClient::createDbgClient() { + + HRESULT hres; + CComPtr 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 newClient = NULL; + + hres = client->CreateClient( &newClient ); + if ( FAILED( hres ) ) + throw DbgException("DebugCreate failed"); + + CComQIPtr client4= newClient; + + return DebugClientPtr( new DebugClient(client4) ); +} + +/////////////////////////////////////////////////////////////////////////////////// + DebugClientPtr DebugClient::setDbgClientCurrent( DebugClientPtr newDbgClient ) { DebugClientPtr oldClient = g_dbgClient; g_dbgClient = newDbgClient; diff --git a/pykd/dbgclient.h b/pykd/dbgclient.h index 40f0d8e..dfc43b5 100644 --- a/pykd/dbgclient.h +++ b/pykd/dbgclient.h @@ -30,22 +30,10 @@ public: virtual ~DebugClient() {} static - DebugClientPtr createDbgClient() { - - HRESULT hres; - CComPtr client = NULL; - - hres = DebugCreate( __uuidof(IDebugClient4), (void **)&client ); - if ( FAILED( hres ) ) - throw DbgException("DebugCreate failed"); - - return createDbgClient( client ); - } + DebugClientPtr createDbgClient() ; static - DebugClientPtr createDbgClient( IDebugClient4 *client ) { - return DebugClientPtr( new DebugClient(client) ); - } + DebugClientPtr createDbgClient( IDebugClient4 *client ); static DebugClientPtr setDbgClientCurrent( DebugClientPtr newDbgClient ); @@ -62,6 +50,8 @@ public: void attachKernel( const std::wstring ¶m ); + //createEventHandler(); + ULONG64 evaluate( const std::wstring &expression ); python::tuple getDebuggeeType(); diff --git a/pykd/dbgevent.cpp b/pykd/dbgevent.cpp index 3d47ab9..3f2d19a 100644 --- a/pykd/dbgevent.cpp +++ b/pykd/dbgevent.cpp @@ -4,214 +4,267 @@ // #include "stdafx.h" #include "dbgevent.h" -#include "dbgio.h" -#include "dbgexcept.h" -#include "pyaux.h" +#include "dbgclient.h" + + +namespace pykd { /////////////////////////////////////////////////////////////////////////////////// -debugEvent::debugEvent() +EventHandler::EventHandler() { HRESULT hres; - hres = dbgExt->client->CreateClient( &m_debugClient ); + hres = g_dbgClient->client()->CreateClient( &m_client ); if ( FAILED( hres ) ) throw DbgException( "IDebugClient::CreateClient" ); - hres = m_debugClient->SetEventCallbacks(this); + hres = m_client->SetEventCallbacks(this); if (FAILED(hres)) - throw DbgException( "IDebugClient::SetEventCallbacks" ); + throw DbgException( "IDebugClient::SetEventCallbacks" ); } /////////////////////////////////////////////////////////////////////////////////// -debugEvent::~debugEvent() +EventHandler::EventHandler( DebugClient &client ) { - m_debugClient->SetEventCallbacks( NULL ); + HRESULT hres; - m_debugClient->Release(); + hres = client.client()->CreateClient( &m_client ); + if ( FAILED( hres ) ) + throw DbgException( "IDebugClient::CreateClient" ); + + hres = m_client->SetEventCallbacks(this); + if (FAILED(hres)) + throw DbgException( "IDebugClient::SetEventCallbacks" ); } /////////////////////////////////////////////////////////////////////////////////// -HRESULT debugEvent::GetInterestMask( - __out PULONG Mask -) +EventHandler::~EventHandler() { - *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; + m_client->SetEventCallbacks( NULL ); } /////////////////////////////////////////////////////////////////////////////////// -HRESULT debugEvent::Breakpoint( - __in PDEBUG_BREAKPOINT Bp -) -{ - boost::python::dict bpParameters; +}; // end pykd namespace - 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 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 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 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 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(); +//} +// +///////////////////////////////////////////////////////////////////////////////////// +// diff --git a/pykd/dbgevent.h b/pykd/dbgevent.h index 5a577b9..b06bc85 100644 --- a/pykd/dbgevent.h +++ b/pykd/dbgevent.h @@ -2,100 +2,92 @@ // user-customizing debug event handler ///////////////////////////////////////////////////////////////////////////////// -#include "dbgeventcb.h" -#include "dbgmodule.h" -#include "pyaux.h" +#pragma once + +#include "stdafx.h" + +#include +#include "dbgobj.h" +#include "module.h" +#include "dbgclient.h" + +namespace pykd { ///////////////////////////////////////////////////////////////////////////////// -class debugEvent : public DebugBaseEventCallbacks +class EventHandler : public DebugBaseEventCallbacks { 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; - - 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: +protected: STDMETHOD_(ULONG, AddRef)() { return 1; } STDMETHOD_(ULONG, Release)() { return 1; } STDMETHOD(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; + } + +protected: - STDMETHOD(Breakpoint)( - __in PDEBUG_BREAKPOINT Bp - ); + virtual ULONG onBreakpoint(const python::dict &/*bpParameters*/) = 0; + virtual ULONG onException(const python::dict &/*exceptData*/) = 0; - STDMETHOD(Exception)( - __in PEXCEPTION_RECORD64 Exception, - __in ULONG FirstChance - ); + virtual ULONG onLoadModule(const Module &/* module */) = 0; - STDMETHOD(LoadModule)( - __in ULONG64 ImageFileHandle, - __in ULONG64 BaseOffset, - __in ULONG ModuleSize, - __in PCSTR ModuleName, - __in PCSTR ImageName, - __in ULONG CheckSum, - __in ULONG TimeDateStamp - ); + virtual ULONG onUnloadModule(const Module &/* module */) = 0; + + virtual ULONG onChangeSessionStatus( ULONG status ) = 0; + + virtual ULONG onChangeDebugeeState() = 0; - STDMETHOD(UnloadModule)( - __in PCSTR ImageBaseName, - __in ULONG64 BaseOffset - ); +protected: - STDMETHOD(SessionStatus)( - __in ULONG Status - ); - - STDMETHOD(ChangeDebuggeeState)( - __in ULONG Flags, - __in ULONG64 Argument ); - -private: - - IDebugClient *m_debugClient; + CComPtr m_client; }; ///////////////////////////////////////////////////////////////////////////////// -class debugEventWrap : public boost::python::wrapper, public debugEvent +class EventHandlerWrap : public boost::python::wrapper, public EventHandler { public: - ULONG onBreakpoint(boost::python::dict &bpParameters) { - return handler("onBreakpoint", bpParameters); + EventHandlerWrap() + {} + + EventHandlerWrap( DebugClient &client ) : EventHandler( client ) + {} + + ULONG onBreakpoint(const python::dict &bpParameters) { + return handler("onBreakpoint", bpParameters); } - ULONG onException(boost::python::dict &exceptData) { - return handler("onException", exceptData); + ULONG onException(const python::dict &exceptData) { + return handler("onException", exceptData); } - ULONG onLoadModule(const dbgModuleClass &module) { - return handler("onLoadModule", module ); + ULONG onLoadModule(const Module &module) { + return handler("onLoadModule", module ); } - ULONG onUnloadModule(const dbgModuleClass &module) { - return handler("onUnloadModule", module ); + ULONG onUnloadModule(const Module &module) { + return handler("onUnloadModule", module ); } ULONG onChangeSessionStatus( ULONG status ) { @@ -111,7 +103,7 @@ private: template 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 DEBUG_STATUS_NO_CHANGE; @@ -119,11 +111,150 @@ private: ULONG handler( const char* handlerName ) { - if (boost::python::override pythonHandler = get_override( handlerName )) + if (python::override pythonHandler = get_override( handlerName )) return pythonHandler(); return DEBUG_STATUS_NO_CHANGE; } -}; +}; ///////////////////////////////////////////////////////////////////////////////// + +}; // 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, public debugEvent +//{ +// +//public: +// +// ULONG onBreakpoint(boost::python::dict &bpParameters) { +// return handler("onBreakpoint", bpParameters); +// } +// +// ULONG onException(boost::python::dict &exceptData) { +// return handler("onException", exceptData); +// } +// +// ULONG onLoadModule(const dbgModuleClass &module) { +// return handler("onLoadModule", module ); +// } +// +// ULONG onUnloadModule(const dbgModuleClass &module) { +// return handler("onUnloadModule", module ); +// } +// +// ULONG onChangeSessionStatus( ULONG status ) { +// return handler( "onChangeSessionStatus", status ); +// } +// +// ULONG onChangeDebugeeState() { +// return handler( "onChangeDebugeeState" ); +// } +// +//private: +// +// template +// 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; +// } +//}; +// +/////////////////////////////////////////////////////////////////////////////////// diff --git a/pykd/dbgext.cpp b/pykd/dbgext.cpp index 1472f27..5871675 100644 --- a/pykd/dbgext.cpp +++ b/pykd/dbgext.cpp @@ -12,6 +12,7 @@ #include "dbgio.h" #include "dbgpath.h" #include "dbgcmd.h" +#include "dbgevent.h" using namespace pykd; @@ -157,6 +158,31 @@ BOOST_PYTHON_MODULE( pykd ) python::class_("ext", python::no_init ) .def( "call", &pykd::DbgExtension::call, "Call debug extension command end return it's result as a string" ); + + python::class_( + "eventHandler", "Base class for overriding and handling debug notifications" ) + .def( python::init<>() ) + .def( python::init() ) + .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, "Open pdb file for quering debug symbols. Return DiaSymbol of global scope"); diff --git a/pykd/pykd_2008.vcproj b/pykd/pykd_2008.vcproj index 420a45f..d1538d5 100644 --- a/pykd/pykd_2008.vcproj +++ b/pykd/pykd_2008.vcproj @@ -357,6 +357,10 @@ RelativePath=".\dbgcmd.cpp" > + + @@ -447,6 +451,10 @@ RelativePath=".\dbgcmd.h" > + + diff --git a/test/scripts/basetest.py b/test/scripts/basetest.py index a37e657..7d12959 100644 --- a/test/scripts/basetest.py +++ b/test/scripts/basetest.py @@ -94,7 +94,6 @@ class BaseTest( unittest.TestCase ): self.assertTrue( hasattr(pykd, 'bp') ) self.assertTrue( hasattr(pykd, 'cpuReg') ) self.assertTrue( hasattr(pykd, 'dbgStackFrameClass') ) - self.assertTrue( hasattr(pykd, 'debugEvent') ) self.assertTrue( hasattr(pykd, 'disasm') ) self.assertTrue( hasattr(pykd, 'ext') ) self.assertTrue( hasattr(pykd, 'intBase') ) @@ -104,6 +103,7 @@ class BaseTest( unittest.TestCase ): def testOldRemovedApi( self ): """ Branch test: old API 0.0.x what should be removed """ self.assertFalse( hasattr(pykd, 'dbgModuleClass') ) + self.assertFalse( hasattr(pykd, 'debugEvent') ) self.assertFalse( hasattr(pykd, 'windbgIn') ) self.assertFalse( hasattr(pykd, 'windbgOut') ) @@ -121,3 +121,4 @@ class BaseTest( unittest.TestCase ): self.assertTrue( hasattr(pykd, 'din') ) self.assertTrue( hasattr(pykd, 'dout') ) self.assertTrue( hasattr(pykd, 'module') ) + self.assertTrue( hasattr(pykd, 'eventHandler' ) ) diff --git a/test/scripts/pykdtest.py b/test/scripts/pykdtest.py index a6abff6..ff3a026 100644 --- a/test/scripts/pykdtest.py +++ b/test/scripts/pykdtest.py @@ -18,6 +18,7 @@ import moduletest import diatest import dbgcmd import clienttest +import eventtest def getTestSuite( singleName = "" ): if singleName == "": @@ -27,7 +28,8 @@ def getTestSuite( singleName = "" ): unittest.TestLoader().loadTestsFromTestCase( diatest.DiaTest ), unittest.TestLoader().loadTestsFromTestCase( typeinfo.TypeInfoTest ), unittest.TestLoader().loadTestsFromTestCase( dbgcmd.DbgcmdTest ), - unittest.TestLoader().loadTestsFromTestCase( clienttest.DbgClientTest ) + unittest.TestLoader().loadTestsFromTestCase( clienttest.DbgClientTest ), + unittest.TestLoader().loadTestsFromTestCase( eventtest.EventTest ) ] ) else: return unittest.TestSuite( unittest.TestLoader().loadTestsFromName( singleName ) ) diff --git a/test/targetapp/targetapp.cpp b/test/targetapp/targetapp.cpp index befd05c..57bea03 100644 --- a/test/targetapp/targetapp.cpp +++ b/test/targetapp/targetapp.cpp @@ -104,6 +104,9 @@ int _tmain(int argc, _TCHAR* argv[]) { // Let test scripts to execute __debugbreak(); + __debugbreak(); + __debugbreak(); + __debugbreak(); FuncWithName0(); FuncWithName1(2); } diff --git a/test/targetapp/targetapp.vcproj b/test/targetapp/targetapp.vcproj index f5ded62..6784c0e 100644 --- a/test/targetapp/targetapp.vcproj +++ b/test/targetapp/targetapp.vcproj @@ -416,6 +416,10 @@ RelativePath="..\scripts\diatest.py" > + +