[pykd] fixed : PyState save/restore

git-svn-id: https://pykd.svn.codeplex.com/svn@70203 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
SND\kernelnet_cp 2011-10-04 12:20:14 +00:00
parent 43aa5d787c
commit 37ce97f561
3 changed files with 114 additions and 76 deletions

View File

@ -213,8 +213,6 @@ BOOST_PYTHON_MODULE( pykd )
"Return current processor mode as string: X86, ARM, IA64 or X64" ); "Return current processor mode as string: X86, ARM, IA64 or X64" );
boost::python::def( "setProcessorMode", &setProcessorMode, boost::python::def( "setProcessorMode", &setProcessorMode,
"Set current processor mode by string (X86, ARM, IA64 or X64)" ); "Set current processor mode by string (X86, ARM, IA64 or X64)" );
boost::python::def( "getProcessorType", &getProcessorType,
"Returns physical processor type as string: X86, ARM, IA64 or X64");
boost::python::def( "addSynSymbol", &addSyntheticSymbol, boost::python::def( "addSynSymbol", &addSyntheticSymbol,
"Add new synthetic symbol for virtual address" ); "Add new synthetic symbol for virtual address" );
boost::python::def( "delAllSynSymbols", &delAllSyntheticSymbols, boost::python::def( "delAllSynSymbols", &delAllSyntheticSymbols,
@ -615,85 +613,43 @@ BOOST_PYTHON_MODULE( pykd )
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
class WindbgGlobalSession WindbgGlobalSession::WindbgGlobalSession() {
{
public:
static
boost::python::object
global() {
return windbgGlobalSession->main.attr("__dict__");
}
static
VOID
StartWindbgSession() {
if ( 1 == InterlockedIncrement( &sessionCount ) )
{
windbgGlobalSession = new WindbgGlobalSession();
}
}
static
VOID
StopWindbgSession() {
if ( 0 == InterlockedDecrement( &sessionCount ) )
{
delete windbgGlobalSession;
windbgGlobalSession = NULL;
}
}
static
bool isInit() {
return windbgGlobalSession != NULL;
}
private:
WindbgGlobalSession() {
PyImport_AppendInittab("pykd", initpykd ); PyImport_AppendInittab("pykd", initpykd );
PyEval_InitThreads(); PyEval_InitThreads();
Py_Initialize(); Py_Initialize();
main = boost::python::import("__main__"); main = boost::python::import("__main__");
boost::python::object main_namespace = main.attr("__dict__");
// äåëàåì àíàëîã from pykd import *
boost::python::object pykd = boost::python::import( "pykd" );
boost::python::dict pykd_namespace( pykd.attr("__dict__") );
boost::python::list iterkeys( pykd_namespace.iterkeys() );
for (int i = 0; i < boost::python::len(iterkeys); i++)
{
std::string key = boost::python::extract<std::string>(iterkeys[i]);
main_namespace[ key ] = pykd_namespace[ key ];
}
g_dbgClient.startEventsMgr();
}
~WindbgGlobalSession() { boost::python::object main_namespace = main.attr("__dict__");
g_dbgClient.removeEventsMgr();
}
boost::python::object main;
static volatile LONG sessionCount; // äåëàåì àíàëîã from pykd import *
boost::python::object pykd = boost::python::import( "pykd" );
static WindbgGlobalSession *windbgGlobalSession; boost::python::dict pykd_namespace( pykd.attr("__dict__") );
boost::python::list iterkeys( pykd_namespace.iterkeys() );
for (int i = 0; i < boost::python::len(iterkeys); i++)
{
std::string key = boost::python::extract<std::string>(iterkeys[i]);
main_namespace[ key ] = pykd_namespace[ key ];
}
g_dbgClient.startEventsMgr();
}; pyState = PyEval_SaveThread();
}
WindbgGlobalSession::~WindbgGlobalSession() {
g_dbgClient.removeEventsMgr();
}
volatile LONG WindbgGlobalSession::sessionCount = 0; volatile LONG WindbgGlobalSession::sessionCount = 0;
@ -831,7 +787,10 @@ py( PDEBUG_CLIENT4 client, PCSTR args)
{ {
DbgExt ext( client ); DbgExt ext( client );
WindbgGlobalSession::RestorePyState();
PyThreadState *globalInterpreter = PyThreadState_Swap( NULL ); PyThreadState *globalInterpreter = PyThreadState_Swap( NULL );
PyThreadState *localInterpreter = Py_NewInterpreter(); PyThreadState *localInterpreter = Py_NewInterpreter();
try { try {
@ -944,7 +903,10 @@ py( PDEBUG_CLIENT4 client, PCSTR args)
} }
Py_EndInterpreter( localInterpreter ); Py_EndInterpreter( localInterpreter );
PyThreadState_Swap( globalInterpreter ); PyThreadState_Swap( globalInterpreter );
WindbgGlobalSession::SavePyState();
return S_OK; return S_OK;
} }
@ -957,6 +919,8 @@ pycmd( PDEBUG_CLIENT4 client, PCSTR args )
{ {
DbgExt ext( client ); DbgExt ext( client );
WindbgGlobalSession::RestorePyState();
try { try {
// ïåðåíàïðàâëåíèå ñòàíäàðòíûõ ïîòîêîâ ÂÂ // ïåðåíàïðàâëåíèå ñòàíäàðòíûõ ïîòîêîâ ÂÂ
@ -1090,6 +1054,8 @@ pycmd( PDEBUG_CLIENT4 client, PCSTR args )
{ {
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "unexpected error" ); dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "unexpected error" );
} }
WindbgGlobalSession::SavePyState();
return S_OK; return S_OK;
} }

View File

@ -40,4 +40,66 @@ private:
extern DbgExt *dbgExt; extern DbgExt *dbgExt;
class WindbgGlobalSession
{
public:
static
boost::python::object
global() {
return windbgGlobalSession->main.attr("__dict__");
}
static
VOID
StartWindbgSession() {
if ( 1 == InterlockedIncrement( &sessionCount ) )
{
windbgGlobalSession = new WindbgGlobalSession();
}
}
static
VOID
StopWindbgSession() {
if ( 0 == InterlockedDecrement( &sessionCount ) )
{
delete windbgGlobalSession;
windbgGlobalSession = NULL;
}
}
static
bool isInit() {
return windbgGlobalSession != NULL;
}
static
VOID
RestorePyState() {
PyEval_RestoreThread( windbgGlobalSession->pyState );
}
static
VOID
SavePyState() {
windbgGlobalSession->pyState = PyEval_SaveThread();
}
private:
WindbgGlobalSession();
~WindbgGlobalSession();
boost::python::object main;
PyThreadState *pyState;
static volatile LONG sessionCount;
static WindbgGlobalSession *windbgGlobalSession;
};
bool isWindbgExt(); bool isWindbgExt();

View File

@ -17,13 +17,23 @@ public:
} }
void saveState() { void saveState() {
TlsSetValue( m_index, PyEval_SaveThread() ); if ( !isWindbgExt() )
TlsSetValue( m_index, PyEval_SaveThread() );
else
WindbgGlobalSession::SavePyState();
} }
void restoreState() { void restoreState() {
PyThreadState* state = (PyThreadState*)TlsGetValue( m_index ); if ( !isWindbgExt() )
if ( state ) {
PyEval_RestoreThread( state ); PyThreadState* state = (PyThreadState*)TlsGetValue( m_index );
if ( state )
PyEval_RestoreThread( state );
}
else
{
WindbgGlobalSession::RestorePyState();
}
} }
private: private: