From 37ce97f561ff1bfb274b2b43ec4c54497b8851c6 Mon Sep 17 00:00:00 2001
From: "SND\\kernelnet_cp"
 <SND\kernelnet_cp@9b283d60-5439-405e-af05-b73fd8c4d996>
Date: Tue, 4 Oct 2011 12:20:14 +0000
Subject: [PATCH] [pykd] fixed : PyState save/restore

git-svn-id: https://pykd.svn.codeplex.com/svn@70203 9b283d60-5439-405e-af05-b73fd8c4d996
---
 pykd/dbgext.cpp | 110 +++++++++++++++++-------------------------------
 pykd/dbgext.h   |  62 +++++++++++++++++++++++++++
 pykd/pyaux.h    |  18 ++++++--
 3 files changed, 114 insertions(+), 76 deletions(-)

diff --git a/pykd/dbgext.cpp b/pykd/dbgext.cpp
index 1958efb..42a9658 100644
--- a/pykd/dbgext.cpp
+++ b/pykd/dbgext.cpp
@@ -213,8 +213,6 @@ BOOST_PYTHON_MODULE( pykd )
         "Return current processor mode as string: X86, ARM, IA64 or X64" );
     boost::python::def( "setProcessorMode", &setProcessorMode, 
         "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,
         "Add new synthetic symbol for virtual address" );
     boost::python::def( "delAllSynSymbols", &delAllSyntheticSymbols, 
@@ -615,85 +613,43 @@ BOOST_PYTHON_MODULE( pykd )
 
 /////////////////////////////////////////////////////////////////////////////////
 
-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;
-    }
-    
-
-private:
-
-    WindbgGlobalSession() {
+WindbgGlobalSession::WindbgGlobalSession() {
                  
-        PyImport_AppendInittab("pykd", initpykd ); 
+    PyImport_AppendInittab("pykd", initpykd ); 
 
-        PyEval_InitThreads();
+    PyEval_InitThreads();
 
-        Py_Initialize();    
+    Py_Initialize();    
 
-        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();
-     }
+    main = boost::python::import("__main__");
     
-    ~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;
 
@@ -831,7 +787,10 @@ py( PDEBUG_CLIENT4 client, PCSTR args)
 {
     DbgExt      ext( client );
 
+    WindbgGlobalSession::RestorePyState();
+
     PyThreadState   *globalInterpreter = PyThreadState_Swap( NULL );
+   
     PyThreadState   *localInterpreter = Py_NewInterpreter();
 
     try {
@@ -944,7 +903,10 @@ py( PDEBUG_CLIENT4 client, PCSTR args)
     }     
     
     Py_EndInterpreter( localInterpreter ); 
+
     PyThreadState_Swap( globalInterpreter );
+
+    WindbgGlobalSession::SavePyState();
     
     return S_OK;  
 }
@@ -957,6 +919,8 @@ pycmd( PDEBUG_CLIENT4 client, PCSTR args )
 {
     DbgExt      ext( client );
 
+    WindbgGlobalSession::RestorePyState();
+
     try {
         
         // ��������������� ����������� ������� ��
@@ -1090,6 +1054,8 @@ pycmd( PDEBUG_CLIENT4 client, PCSTR args )
     {
         dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "unexpected error" );
     }
+
+    WindbgGlobalSession::SavePyState();
     
     return S_OK;    
 }
diff --git a/pykd/dbgext.h b/pykd/dbgext.h
index 39c0f55..bee1a26 100644
--- a/pykd/dbgext.h
+++ b/pykd/dbgext.h
@@ -40,4 +40,66 @@ private:
 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();
diff --git a/pykd/pyaux.h b/pykd/pyaux.h
index b18cdcb..8e85f5c 100644
--- a/pykd/pyaux.h
+++ b/pykd/pyaux.h
@@ -17,13 +17,23 @@ public:
     }
 
     void saveState() {
-        TlsSetValue( m_index, PyEval_SaveThread() );
+        if ( !isWindbgExt() )
+            TlsSetValue( m_index, PyEval_SaveThread() );
+        else
+            WindbgGlobalSession::SavePyState();                
     }
 
     void restoreState() {
-        PyThreadState*      state = (PyThreadState*)TlsGetValue( m_index );
-        if ( state )
-            PyEval_RestoreThread( state );
+        if ( !isWindbgExt() )
+        {
+            PyThreadState*      state = (PyThreadState*)TlsGetValue( m_index );
+            if ( state )
+                PyEval_RestoreThread( state );
+        }
+        else
+        {
+            WindbgGlobalSession::RestorePyState();
+        }
     }
 
 private: