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 - -#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 +// +//#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 -#include -#include "pyaux.h" -///////////////////////////////////////////////////////////////////////////////// +namespace pykd { + +/////////////////////////////////////////////////////////////////////////////////// std::string -dbgCommand( const std::wstring &command ); +dbgCommand( const std::wstring &command ); -template -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( ¤tStatus ); - - 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 +//#include +//#include "pyaux.h" + +/////////////////////////////////////////////////////////////////////////////////// +// +//std::string +//dbgCommand( const std::wstring &command ); +// +//template +//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( ¤tStatus ); +// +// 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_("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" > + + @@ -439,6 +443,10 @@ RelativePath=".\dbgclient.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" > + +