From 9e5fe5cab558e2901b6934ab68d90f4183db2d52 Mon Sep 17 00:00:00 2001 From: "SND\\kernelnet_cp" Date: Mon, 15 Aug 2011 14:23:25 +0000 Subject: [PATCH] [pykd] updated : support for GIL in callback git-svn-id: https://pykd.svn.codeplex.com/svn@69009 9b283d60-5439-405e-af05-b73fd8c4d996 --- pykd/dbgbreak.cpp | 3 + pykd/dbgcmd.h | 10 +-- pykd/dbgevent.cpp | 164 +++--------------------------------------- pykd/dbgext.cpp | 2 + pykd/dbgext.h | 7 ++ pykd/pyaux.h | 68 ++++++++++++++++++ pykd/pykd_2008.vcproj | 6 +- 7 files changed, 102 insertions(+), 158 deletions(-) create mode 100644 pykd/pyaux.h diff --git a/pykd/dbgbreak.cpp b/pykd/dbgbreak.cpp index 2623d28..db28a82 100644 --- a/pykd/dbgbreak.cpp +++ b/pykd/dbgbreak.cpp @@ -4,6 +4,7 @@ #include "dbgbreak.h" #include "dbgexcept.h" +#include "pyaux.h" /////////////////////////////////////////////////////////////////////////////// @@ -13,6 +14,8 @@ dbgBreakpointClass::breakpointMap dbgBreakpointClass::m_breakMap; HRESULT dbgBreakpointClass::onBreakpointEvnet( IDebugBreakpoint* bp ) { + PyThread_StateSave( dbgExt->getThreadState() ); + try { breakpointMap::iterator it = m_breakMap.find( bp ); diff --git a/pykd/dbgcmd.h b/pykd/dbgcmd.h index 7a868c1..5453b31 100644 --- a/pykd/dbgcmd.h +++ b/pykd/dbgcmd.h @@ -2,6 +2,7 @@ #include #include +#include "pyaux.h" ///////////////////////////////////////////////////////////////////////////////// @@ -25,11 +26,12 @@ setExecutionStatus() do { - Py_BEGIN_ALLOW_THREADS + { + PyThread_StateRestore state; + + hres = dbgExt->control->WaitForEvent( 0, INFINITE ); - hres = dbgExt->control->WaitForEvent( 0, INFINITE ); - - Py_END_ALLOW_THREADS + } if ( FAILED( hres ) ) throw DbgException( "IDebugControl::SetExecutionStatus failed" ); diff --git a/pykd/dbgevent.cpp b/pykd/dbgevent.cpp index 7794bd4..6d8fbc6 100644 --- a/pykd/dbgevent.cpp +++ b/pykd/dbgevent.cpp @@ -6,13 +6,14 @@ #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" ); @@ -67,6 +68,8 @@ HRESULT debugEvent::LoadModule( queryModuleParams(BaseOffset, moduleName, moduleBase, moduleSize); dbgModuleClass module(moduleName, moduleBase, moduleSize); silentMode.reset(); + + PyThread_StateSave( dbgExt->getThreadState() ); return onLoadModule( module ); } @@ -87,6 +90,8 @@ HRESULT debugEvent::UnloadModule( queryModuleParams(BaseOffset, moduleName, moduleBase, moduleSize); dbgModuleClass module(moduleName, moduleBase, moduleSize); silentMode.reset(); + + PyThread_StateSave( dbgExt->getThreadState() ); return onUnloadModule( module ); } @@ -97,6 +102,8 @@ HRESULT debugEvent::SessionStatus( __in ULONG Status ) { + PyThread_StateSave( dbgExt->getThreadState() ); + return onChangeSessionStatus( Status ); } @@ -107,159 +114,10 @@ HRESULT debugEvent::ChangeDebuggeeState( __in ULONG64 Argument ) { + PyThread_StateSave( dbgExt->getThreadState() ); + return onChangeDebugeeState(); } /////////////////////////////////////////////////////////////////////////////////// - - - - - - - -// -// STDMETHOD(GetInterestMask)( -// __out PULONG Mask -// ); -// -// 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 -// ); -// -//public: -// -// ULONG onLoadModule(const dbgModuleClass &module); -// -// ULONG onUnloadModule(const dbgModuleClass &module); -// - - - - - -//#include -//#include -// -//#include "dbgmodule.h" -//#include "dbgio.h" -//#include "dbgevent.h" -// -/////////////////////////////////////////////////////////////////////////////////// -// -//debugEvent::modCallbacksColl debugEvent::modCallbacks; -//debugEvent::modCallbacksLock debugEvent::modCallbacksMtx; -// -/////////////////////////////////////////////////////////////////////////////////// -// -//debugEvent::debugEvent() -//{ -// modCallbacksScopedLock lock(modCallbacksMtx); -// modCallbacks.insert(this); -//} -// -/////////////////////////////////////////////////////////////////////////////////// -// -//debugEvent::~debugEvent() -//{ -// modCallbacksScopedLock lock(modCallbacksMtx); -// modCallbacks.erase(this); -//} -// -/////////////////////////////////////////////////////////////////////////////////// -// -//ULONG debugEvent::moduleLoaded(__in ULONG64 addr) -//{ -// modCallbacksScopedLock lock(modCallbacksMtx); -// if (modCallbacks.empty()) -// return DEBUG_STATUS_NO_CHANGE; -// -// ULONG64 moduleBase; -// ULONG moduleSize; -// std::string moduleName; -// -// std::auto_ptr silentMode( new OutputReader(dbgExt->client) ); -// queryModuleParams(addr, moduleName, moduleBase, moduleSize); -// dbgModuleClass module(moduleName, moduleBase, moduleSize); -// silentMode.reset(); -// -// modCallbacksColl::iterator itCallback = modCallbacks.begin(); -// while (itCallback != modCallbacks.end()) -// { -// const ULONG retValue = (*itCallback)->onLoadModule(module); -// if (DEBUG_STATUS_NO_CHANGE != retValue) -// return retValue; -// -// ++itCallback; -// } -// return DEBUG_STATUS_NO_CHANGE; -//} -// -/////////////////////////////////////////////////////////////////////////////////// -// -//ULONG debugEvent::moduleUnloaded(__in ULONG64 addr) -//{ -// modCallbacksScopedLock lock(modCallbacksMtx); -// if (modCallbacks.empty()) -// return DEBUG_STATUS_NO_CHANGE; -// -// ULONG64 moduleBase; -// ULONG moduleSize; -// std::string moduleName; -// -// std::auto_ptr silentMode( new OutputReader(dbgExt->client) ); -// queryModuleParams(addr, moduleName, moduleBase, moduleSize); -// dbgModuleClass module(moduleName, moduleBase, moduleSize); -// silentMode.reset(); -// -// modCallbacksColl::iterator itCallback = modCallbacks.begin(); -// while (itCallback != modCallbacks.end()) -// { -// const ULONG retValue = (*itCallback)->onUnloadModule(module); -// if (DEBUG_STATUS_NO_CHANGE != retValue) -// return retValue; -// -// ++itCallback; -// } -// return DEBUG_STATUS_NO_CHANGE; -//} -// -/////////////////////////////////////////////////////////////////////////////////// -// -//ULONG debugEvent::sessionStatus(__in ULONG status ) -//{ -// -//} -// -/////////////////////////////////////////////////////////////////////////////////// -// -//ULONG debugEventWrap::onLoadModule(const dbgModuleClass &module) -//{ -// if (boost::python::override override = get_override("onLoadModule")) -// return override(module); -// -// return debugEvent::onLoadModule(module); -//} -// -/////////////////////////////////////////////////////////////////////////////////// -// -//ULONG debugEventWrap::onUnloadModule(const dbgModuleClass &module) -//{ -// if (boost::python::override override = get_override("onUnloadModule")) -// return override(module); -// -// return debugEvent::onUnloadModule(module); -//} -// -/////////////////////////////////////////////////////////////////////////////////// + diff --git a/pykd/dbgext.cpp b/pykd/dbgext.cpp index a36ae8c..3e40938 100644 --- a/pykd/dbgext.cpp +++ b/pykd/dbgext.cpp @@ -692,6 +692,8 @@ DebugExtensionUninitialize() DbgExt::DbgExt( IDebugClient4 *masterClient ) { + m_threadState = NULL; + client = NULL; masterClient->QueryInterface( __uuidof(IDebugClient), (void **)&client ); diff --git a/pykd/dbgext.h b/pykd/dbgext.h index 8492358..19effe0 100644 --- a/pykd/dbgext.h +++ b/pykd/dbgext.h @@ -31,10 +31,17 @@ public: DbgExt( IDebugClient4 *client ); ~DbgExt(); + + PyThreadState** + getThreadState() { + return &m_threadState; + } private: DbgExt *m_previosExt; + + PyThreadState *m_threadState; }; extern DbgExt *dbgExt; diff --git a/pykd/pyaux.h b/pykd/pyaux.h new file mode 100644 index 0000000..2a1954c --- /dev/null +++ b/pykd/pyaux.h @@ -0,0 +1,68 @@ +#pragma once + +/////////////////////////////////////////////////////////////////////////////// + +// --> call back +// { PyThread_StateSave state( winext->getThreadState() ); +// do_callback(); +// } +// +// Если колбек был вызван и при этом у текщего потока сохранен контекст ( был вызов setExecutionStatus ) +// то перед выполнением питоновского кода нужно восстановить контекст, а после возврата управления, +// снова сохранить его + +class PyThread_StateSave { + +public: + + PyThread_StateSave( PyThreadState **state ) { + if ( *state != NULL ) + { + m_state = state; + PyEval_RestoreThread( *m_state ); + } + } + + ~PyThread_StateSave() { + *m_state =PyEval_SaveThread(); + } + +private: + + PyThreadState **m_state; +}; + +// { PyThread_StateRestore state; +// long_or_block_opreration(); +// } + +class PyThread_StateRestore { + +public: + + explicit PyThread_StateRestore() { + m_state = &m_ownState; + *m_state =PyEval_SaveThread(); + } + + PyThread_StateRestore( PyThreadState **state ) { + if ( *state != NULL ) + { + m_state = state; + *m_state =PyEval_SaveThread(); + } + } + + ~PyThread_StateRestore() { + PyEval_RestoreThread( *m_state ); + } + +private: + + PyThreadState **m_state; + + PyThreadState *m_ownState; + +}; + +/////////////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/pykd/pykd_2008.vcproj b/pykd/pykd_2008.vcproj index a1ce6b3..6a58a96 100644 --- a/pykd/pykd_2008.vcproj +++ b/pykd/pykd_2008.vcproj @@ -1,7 +1,7 @@ + +