From a452624559331e0b078307f6f41faeada09a7707 Mon Sep 17 00:00:00 2001
From: "SND\\kernelnet_cp"
 <SND\kernelnet_cp@9b283d60-5439-405e-af05-b73fd8c4d996>
Date: Mon, 10 Oct 2011 14:35:43 +0000
Subject: [PATCH] [0.1.x] added : dbgCommand routine

git-svn-id: https://pykd.svn.codeplex.com/svn@70294 9b283d60-5439-405e-af05-b73fd8c4d996
---
 pykd/dbgclient.h                |   4 +
 pykd/dbgcmd.cpp                 | 248 +++++++++++++++++++-------------
 pykd/dbgcmd.h                   | 165 +++++++++++----------
 pykd/dbgext.cpp                 |   9 +-
 pykd/dbgio.h                    |   3 +-
 pykd/pykd_2008.vcproj           |   8 ++
 test/scripts/basetest.py        |   5 +-
 test/scripts/dbgcmd.py          |  10 ++
 test/scripts/pykdtest.py        |   3 +-
 test/targetapp/targetapp.vcproj |   4 +
 10 files changed, 277 insertions(+), 182 deletions(-)
 create mode 100644 test/scripts/dbgcmd.py

diff --git a/pykd/dbgclient.h b/pykd/dbgclient.h
index 7f3a9db..f908867 100644
--- a/pykd/dbgclient.h
+++ b/pykd/dbgclient.h
@@ -48,6 +48,10 @@ public:
 
     static
     DebugClientPtr  setDbgClientCurrent( DebugClientPtr  newDbgClient );
+
+public:
+
+    std::string dbgCommand( const std::wstring  &command );
  
     void loadDump( const std::wstring &fileName );
 
diff --git a/pykd/dbgcmd.cpp b/pykd/dbgcmd.cpp
index 5dc55bd..5c0ece6 100644
--- a/pykd/dbgcmd.cpp
+++ b/pykd/dbgcmd.cpp
@@ -1,132 +1,180 @@
 #include "stdafx.h"
 
-#include <boost/format.hpp>
-
-#include "dbgext.h"
 #include "dbgcmd.h"
-#include "dbgexcept.h"
-#include "dbgio.h"
-#include "dbgsystem.h"
+#include "dbgclient.h"
 
-///////////////////////////////////////////////////////////////////////////////
+namespace pykd {
 
-std::string
-dbgCommand( const std::wstring &command )
+/////////////////////////////////////////////////////////////////////////////////
+
+std::string  DebugClient::dbgCommand( const std::wstring &command )
 {
     HRESULT     hres;
 
-    OutputReader        outReader(  dbgExt->client );
-    {
-        PyThread_StateRestore pyThreadRestore;
+    OutputReader        outReader( m_client );
+
+    PyThreadState   *pystate = PyEval_SaveThread();
+
+    hres = m_control->ExecuteWide( DEBUG_OUTCTL_THIS_CLIENT, command.c_str(), 0 );        
+
+    PyEval_RestoreThread( pystate );
 
-        hres = dbgExt->control4->ExecuteWide( DEBUG_OUTCTL_THIS_CLIENT, command.c_str(), 0 );
-    }
     if ( FAILED( hres ) )
         throw  DbgException( "IDebugControl::Execute  failed" ); 
 
-    return std::string( outReader.Line() );
+    return std::string( outReader.Line() ); 
 }
 
-///////////////////////////////////////////////////////////////////////////////
-
-dbgExtensionClass::dbgExtensionClass( const char* path ) : m_path(path)
+std::string dbgCommand( const std::wstring  &command )
 {
-    HRESULT     hres;
-
-    hres = dbgExt->control->AddExtension( path, 0, &m_handle );
-    if ( FAILED( hres ) )
-        throw DbgException( "IDebugControl::AddExtension failed" );
+    return g_dbgClient->dbgCommand( command );  
 }
 
-///////////////////////////////////////////////////////////////////////////////
-    
-dbgExtensionClass::~dbgExtensionClass()
-{
-    if ( m_handle )
-        dbgExt->control->RemoveExtension( m_handle );
-}
+/////////////////////////////////////////////////////////////////////////////////
 
-///////////////////////////////////////////////////////////////////////////////
+} // end namespace pykd
 
-std::string
-dbgExtensionClass::call( const std::string &command, const std::string params )
-{
-    HRESULT     hres;
 
-    OutputReader        outReader(  dbgExt->client );
 
-    hres = dbgExt->control->CallExtension( m_handle, command.c_str(), params.c_str() );
-    if ( FAILED( hres ) )
-        throw  DbgException( "IDebugControl::CallExtension  failed" ); 
-        
-    return std::string( outReader.Line() );
-}
 
-///////////////////////////////////////////////////////////////////////////////
 
-std::string
-dbgExtensionClass::print() const
-{
-    return m_handle ? m_path : "";
-}
 
-/////////////////////////////////////////////////////////////////////////////// 
 
-ULONG64
-evaluate( const std::string  &expression )
-{
-    HRESULT             hres;
-    ULONG64             value = 0;
 
-    DEBUG_VALUE  debugValue = {};
-    ULONG        remainderIndex = 0;
-    
-    if ( is64bitSystem() )
-    {
-        hres = dbgExt->control->Evaluate( 
-            expression.c_str(), 
-            DEBUG_VALUE_INT64,
-            &debugValue,
-            &remainderIndex );
-            
-        if (  FAILED( hres ) )
-            throw  DbgException( "IDebugControl::Evaluate  failed" );
-            
-        if ( remainderIndex == expression.length() )
-            value = debugValue.I64;
-    }
-    else
-    {
-        hres = dbgExt->control->Evaluate( 
-            expression.c_str(), 
-            DEBUG_VALUE_INT32,
-            &debugValue,
-            &remainderIndex );
-            
-        if (  FAILED( hres ) )
-            throw  DbgException( "IDebugControl::Evaluate  failed" );
-            
-        if ( remainderIndex == expression.length() )
-            value = debugValue.I32;
-    }      
 
-    return value;
-}
 
-/////////////////////////////////////////////////////////////////////////////// 
 
-void
-breakin()
-{
-    HRESULT     hres;
+//#include <boost/format.hpp>
+//
+//#include "dbgext.h"
+//#include "dbgcmd.h"
+//#include "dbgexcept.h"
+//#include "dbgio.h"
+//#include "dbgsystem.h"
 
-    {
-        PyThread_StateRestore pyThreadRestore;
-        hres = dbgExt->control->SetInterrupt( DEBUG_INTERRUPT_ACTIVE );
-    }
 
-    if ( FAILED( hres ) )
-        throw DbgException( "IDebugControl::SetInterrupt" );
-}
 
-/////////////////////////////////////////////////////////////////////////////// 
\ No newline at end of file
+
+
+/////////////////////////////////////////////////////////////////////////////////
+//
+//std::string
+//dbgCommand( const std::wstring &command )
+//{
+//    HRESULT     hres;
+//
+//    OutputReader        outReader(  dbgExt->client );
+//    {
+//        PyThread_StateRestore pyThreadRestore;
+//
+//        hres = dbgExt->control4->ExecuteWide( DEBUG_OUTCTL_THIS_CLIENT, command.c_str(), 0 );
+//    }
+//    if ( FAILED( hres ) )
+//        throw  DbgException( "IDebugControl::Execute  failed" ); 
+//
+//    return std::string( outReader.Line() );
+//}
+//
+/////////////////////////////////////////////////////////////////////////////////
+//
+//dbgExtensionClass::dbgExtensionClass( const char* path ) : m_path(path)
+//{
+//    HRESULT     hres;
+//
+//    hres = dbgExt->control->AddExtension( path, 0, &m_handle );
+//    if ( FAILED( hres ) )
+//        throw DbgException( "IDebugControl::AddExtension failed" );
+//}
+//
+/////////////////////////////////////////////////////////////////////////////////
+//    
+//dbgExtensionClass::~dbgExtensionClass()
+//{
+//    if ( m_handle )
+//        dbgExt->control->RemoveExtension( m_handle );
+//}
+//
+/////////////////////////////////////////////////////////////////////////////////
+//
+//std::string
+//dbgExtensionClass::call( const std::string &command, const std::string params )
+//{
+//    HRESULT     hres;
+//
+//    OutputReader        outReader(  dbgExt->client );
+//
+//    hres = dbgExt->control->CallExtension( m_handle, command.c_str(), params.c_str() );
+//    if ( FAILED( hres ) )
+//        throw  DbgException( "IDebugControl::CallExtension  failed" ); 
+//        
+//    return std::string( outReader.Line() );
+//}
+//
+/////////////////////////////////////////////////////////////////////////////////
+//
+//std::string
+//dbgExtensionClass::print() const
+//{
+//    return m_handle ? m_path : "";
+//}
+//
+///////////////////////////////////////////////////////////////////////////////// 
+//
+//ULONG64
+//evaluate( const std::string  &expression )
+//{
+//    HRESULT             hres;
+//    ULONG64             value = 0;
+//
+//    DEBUG_VALUE  debugValue = {};
+//    ULONG        remainderIndex = 0;
+//    
+//    if ( is64bitSystem() )
+//    {
+//        hres = dbgExt->control->Evaluate( 
+//            expression.c_str(), 
+//            DEBUG_VALUE_INT64,
+//            &debugValue,
+//            &remainderIndex );
+//            
+//        if (  FAILED( hres ) )
+//            throw  DbgException( "IDebugControl::Evaluate  failed" );
+//            
+//        if ( remainderIndex == expression.length() )
+//            value = debugValue.I64;
+//    }
+//    else
+//    {
+//        hres = dbgExt->control->Evaluate( 
+//            expression.c_str(), 
+//            DEBUG_VALUE_INT32,
+//            &debugValue,
+//            &remainderIndex );
+//            
+//        if (  FAILED( hres ) )
+//            throw  DbgException( "IDebugControl::Evaluate  failed" );
+//            
+//        if ( remainderIndex == expression.length() )
+//            value = debugValue.I32;
+//    }      
+//
+//    return value;
+//}
+//
+///////////////////////////////////////////////////////////////////////////////// 
+//
+//void
+//breakin()
+//{
+//    HRESULT     hres;
+//
+//    {
+//        PyThread_StateRestore pyThreadRestore;
+//        hres = dbgExt->control->SetInterrupt( DEBUG_INTERRUPT_ACTIVE );
+//    }
+//
+//    if ( FAILED( hres ) )
+//        throw DbgException( "IDebugControl::SetInterrupt" );
+//}
+//
+///////////////////////////////////////////////////////////////////////////////// 
\ No newline at end of file
diff --git a/pykd/dbgcmd.h b/pykd/dbgcmd.h
index 9b361e9..c772573 100644
--- a/pykd/dbgcmd.h
+++ b/pykd/dbgcmd.h
@@ -1,86 +1,103 @@
 #pragma once
 
-#include <string>
-#include <map>
-#include "pyaux.h"
 
-/////////////////////////////////////////////////////////////////////////////////
+namespace pykd {
+
+///////////////////////////////////////////////////////////////////////////////////
 
 std::string
-dbgCommand( const std::wstring &command );
+dbgCommand( const std::wstring  &command );
 
-template <ULONG status>
-void
-setExecutionStatus()
-{
-    HRESULT     hres;
+///////////////////////////////////////////////////////////////////////////////////
 
-    hres = dbgExt->control->SetExecutionStatus( status );
-
-    if ( FAILED( hres ) )
-        throw DbgException( "IDebugControl::SetExecutionStatus failed" );
-
-    ULONG    currentStatus;
-
-    do {
-        
-        {
-            PyThread_StateRestore pyThreadRestore;
-            hres = dbgExt->control->WaitForEvent( 0, INFINITE );
-        }
-
-        if ( FAILED( hres ) )
-        {
-            if (E_UNEXPECTED == hres)
-                throw WaitEventException();
-
-            throw  DbgException( "IDebugControl::WaitForEvent  failed" );
-        }
-
-        hres = dbgExt->control->GetExecutionStatus( &currentStatus );
-
-        if ( FAILED( hres ) )
-            throw  DbgException( "IDebugControl::GetExecutionStatus  failed" ); 
-
-    } while( currentStatus != DEBUG_STATUS_BREAK && currentStatus != DEBUG_STATUS_NO_DEBUGGEE );
-
-}
-
-/////////////////////////////////////////////////////////////////////////////////
-
-class dbgExtensionClass {
-
-public:
-
-    dbgExtensionClass() :
-        m_handle( NULL )
-        {}
-    
-    dbgExtensionClass( const char* path );
-    
-    ~dbgExtensionClass();
-    
-    std::string
-    call( const std::string &command, const std::string param );
-
-    std::string
-    print() const;
-    
-private:
-
-    ULONG64         m_handle;  
-	std::string     m_path;
-};
+}; // end of namespace pykd
 
 
-/////////////////////////////////////////////////////////////////////////////////
 
-ULONG64
-evaluate( const std::string  &expression );
-    
-/////////////////////////////////////////////////////////////////////////////////
 
-void
-breakin();
 
-/////////////////////////////////////////////////////////////////////////////////
\ No newline at end of file
+
+//#include <string>
+//#include <map>
+//#include "pyaux.h"
+
+///////////////////////////////////////////////////////////////////////////////////
+//
+//std::string
+//dbgCommand( const std::wstring &command );
+//
+//template <ULONG status>
+//void
+//setExecutionStatus()
+//{
+//    HRESULT     hres;
+//
+//    hres = dbgExt->control->SetExecutionStatus( status );
+//
+//    if ( FAILED( hres ) )
+//        throw DbgException( "IDebugControl::SetExecutionStatus failed" );
+//
+//    ULONG    currentStatus;
+//
+//    do {
+//        
+//        {
+//            PyThread_StateRestore pyThreadRestore;
+//            hres = dbgExt->control->WaitForEvent( 0, INFINITE );
+//        }
+//
+//        if ( FAILED( hres ) )
+//        {
+//            if (E_UNEXPECTED == hres)
+//                throw WaitEventException();
+//
+//            throw  DbgException( "IDebugControl::WaitForEvent  failed" );
+//        }
+//
+//        hres = dbgExt->control->GetExecutionStatus( &currentStatus );
+//
+//        if ( FAILED( hres ) )
+//            throw  DbgException( "IDebugControl::GetExecutionStatus  failed" ); 
+//
+//    } while( currentStatus != DEBUG_STATUS_BREAK && currentStatus != DEBUG_STATUS_NO_DEBUGGEE );
+//
+//}
+//
+///////////////////////////////////////////////////////////////////////////////////
+//
+//class dbgExtensionClass {
+//
+//public:
+//
+//    dbgExtensionClass() :
+//        m_handle( NULL )
+//        {}
+//    
+//    dbgExtensionClass( const char* path );
+//    
+//    ~dbgExtensionClass();
+//    
+//    std::string
+//    call( const std::string &command, const std::string param );
+//
+//    std::string
+//    print() const;
+//    
+//private:
+//
+//    ULONG64         m_handle;  
+//	std::string     m_path;
+//};
+//
+//
+///////////////////////////////////////////////////////////////////////////////////
+//
+//ULONG64
+//evaluate( const std::string  &expression );
+//    
+///////////////////////////////////////////////////////////////////////////////////
+//
+//void
+//breakin();
+//
+///////////////////////////////////////////////////////////////////////////////////
\ No newline at end of file
diff --git a/pykd/dbgext.cpp b/pykd/dbgext.cpp
index 8f8123f..2789e74 100644
--- a/pykd/dbgext.cpp
+++ b/pykd/dbgext.cpp
@@ -11,6 +11,7 @@
 #include "dbgclient.h"
 #include "dbgio.h"
 #include "dbgpath.h"
+#include "dbgcmd.h"
 
 using namespace pykd;
 
@@ -68,6 +69,8 @@ BOOST_PYTHON_MODULE( pykd )
             "Return instance of Module class" )
         .def( "findModule", &pykd::DebugClient::findModule, 
             "Return instance of the Module class which posseses specified address" )
+        .def( "dbgCommand", &pykd::DebugClient::dbgCommand,
+             "Run a debugger's command and return it's result as a string" )
         .def( "dprint", &pykd::DebugClient::dprint,
             "Print out string. If dml = True string is printed with dml highlighting ( only for windbg )" )
         .def( "dprintln", &pykd::DebugClient::dprintln,
@@ -87,10 +90,12 @@ BOOST_PYTHON_MODULE( pykd )
         "Return instance of Module class"  );
     python::def( "findModule", &pykd::findModule,
         "Return instance of the Module class which posseses specified address" );
+    python::def( "dbgCommand", &pykd::dbgCommand,    
+        "Run a debugger's command and return it's result as a string" ),
     python::def( "dprint", &pykd::dprint, dprint_( boost::python::args( "str", "dml" ), 
-            "Print out string. If dml = True string is printed with dml highlighting ( only for windbg )" ) );
+        "Print out string. If dml = True string is printed with dml highlighting ( only for windbg )" ) );
     python::def( "dprintln", &pykd::dprintln, dprintln_( boost::python::args( "str", "dml" ), 
-            "Print out string and insert end of line symbol. If dml = True string is printed with dml highlighting ( only for windbg )" ) );
+        "Print out string and insert end of line symbol. If dml = True string is printed with dml highlighting ( only for windbg )" ) );
     
     python::class_<pykd::TypeInfo>("typeInfo", "Class representing typeInfo", python::no_init )
         .def( "name", &pykd::TypeInfo::getName )
diff --git a/pykd/dbgio.h b/pykd/dbgio.h
index 51d770c..aaf7e59 100644
--- a/pykd/dbgio.h
+++ b/pykd/dbgio.h
@@ -65,8 +65,7 @@ public:
 
 	~OutputReader() 
 	{
-        if ( m_previousCallback )
-	        m_client->SetOutputCallbacks( m_previousCallback );
+	    m_client->SetOutputCallbacks( m_previousCallback );
 	}
 
 	const std::string&
diff --git a/pykd/pykd_2008.vcproj b/pykd/pykd_2008.vcproj
index 6817165..420a45f 100644
--- a/pykd/pykd_2008.vcproj
+++ b/pykd/pykd_2008.vcproj
@@ -353,6 +353,10 @@
 				RelativePath=".\dbgclient.cpp"
 				>
 			</File>
+			<File
+				RelativePath=".\dbgcmd.cpp"
+				>
+			</File>
 			<File
 				RelativePath=".\dbgexcept.cpp"
 				>
@@ -439,6 +443,10 @@
 				RelativePath=".\dbgclient.h"
 				>
 			</File>
+			<File
+				RelativePath=".\dbgcmd.h"
+				>
+			</File>
 			<File
 				RelativePath=".\dbgexcept.h"
 				>
diff --git a/test/scripts/basetest.py b/test/scripts/basetest.py
index 9d30375..eeb7c7b 100644
--- a/test/scripts/basetest.py
+++ b/test/scripts/basetest.py
@@ -18,7 +18,6 @@ class BaseTest( unittest.TestCase ):
         self.assertTrue( hasattr(pykd, 'breakin') )
         self.assertTrue( hasattr(pykd, 'compareMemory') )
         self.assertTrue( hasattr(pykd, 'containingRecord') )
-        self.assertTrue( hasattr(pykd, 'createSession') )
         self.assertTrue( hasattr(pykd, 'dbgCommand') )
         self.assertTrue( hasattr(pykd, 'dprint') )
         self.assertTrue( hasattr(pykd, 'dprintln') )
@@ -101,12 +100,12 @@ class BaseTest( unittest.TestCase ):
         self.assertTrue( hasattr(pykd, 'intBase') )
         self.assertTrue( hasattr(pykd, 'typeInfo') )
         self.assertTrue( hasattr(pykd, 'typedVar') )
-        self.assertTrue( hasattr(pykd, 'windbgIn') )
-        self.assertTrue( hasattr(pykd, 'windbgOut') )
         
     def testOldRemovedApi( self ):
         """ Branch test: old API 0.0.x what should be removed """
         self.assertFalse( hasattr(pykd, 'dbgModuleClass') )
+        self.assertFalse( hasattr(pykd, 'windbgIn') )
+        self.assertFalse( hasattr(pykd, 'windbgOut') )        
         
     def testNewAddededApi( self ):
         """ Branch test: new API 0.1.x what must be available """
diff --git a/test/scripts/dbgcmd.py b/test/scripts/dbgcmd.py
new file mode 100644
index 0000000..82aeeae
--- /dev/null
+++ b/test/scripts/dbgcmd.py
@@ -0,0 +1,10 @@
+
+import unittest
+import target
+import pykd
+
+class DbgcmdTest( unittest.TestCase ):
+
+    def testDbgCommand( self ):
+        self.assertNotEqual( "", pykd.dbgCommand("lm") )
+
diff --git a/test/scripts/pykdtest.py b/test/scripts/pykdtest.py
index 4ad88cd..8715cd8 100644
--- a/test/scripts/pykdtest.py
+++ b/test/scripts/pykdtest.py
@@ -16,6 +16,7 @@ import typeinfo
 import regtest
 import moduletest
 import diatest
+import dbgcmd
 
 def getTestSuite( singleName = "" ):
     if singleName == "":
@@ -24,7 +25,7 @@ def getTestSuite( singleName = "" ):
                unittest.TestLoader().loadTestsFromTestCase( moduletest.ModuleTest ),
                unittest.TestLoader().loadTestsFromTestCase( diatest.DiaTest ),
                unittest.TestLoader().loadTestsFromTestCase( typeinfo.TypeInfoTest ),
-#               unittest.TestLoader().loadTestsFromTestCase( regtest.CpuRegTest )
+               unittest.TestLoader().loadTestsFromTestCase( dbgcmd.DbgcmdTest )
            ] ) 
     else:
        return unittest.TestSuite( unittest.TestLoader().loadTestsFromName( singleName ) )
diff --git a/test/targetapp/targetapp.vcproj b/test/targetapp/targetapp.vcproj
index 8f294ce..f1e1fc9 100644
--- a/test/targetapp/targetapp.vcproj
+++ b/test/targetapp/targetapp.vcproj
@@ -404,6 +404,10 @@
 				RelativePath="..\scripts\basetest.py"
 				>
 			</File>
+			<File
+				RelativePath="..\scripts\dbgcmd.py"
+				>
+			</File>
 			<File
 				RelativePath="..\scripts\diatest.py"
 				>