diff --git a/pykd/dbgcmd.cpp b/pykd/dbgcmd.cpp index 236d7e0..bc0cd5f 100644 --- a/pykd/dbgcmd.cpp +++ b/pykd/dbgcmd.cpp @@ -3,96 +3,7 @@ #include "dbgext.h" #include "dbgcmd.h" #include "dbgexcept.h" - -/////////////////////////////////////////////////////////////////////////////// - -// класс для перехвата вывода в отладчик - -class OutputReader : public IDebugOutputCallbacks { - -public: - - OutputReader( IDebugClient *debugClient ) - { - HRESULT hres; - - try { - - m_debugClient = debugClient; - m_debugClient->AddRef(); - - hres = m_debugClient->GetOutputCallbacks( &m_previousCallback ); - if ( FAILED( hres ) ) - { - throw hres; - } - - hres = m_debugClient->SetOutputCallbacks( this ); - if ( FAILED( hres ) ) - { - throw hres; - } - - } catch( ... ) - { - m_debugClient->Release(); - m_debugClient = NULL; - } - } - - ~OutputReader() - { - if ( m_debugClient ) - { - m_debugClient->SetOutputCallbacks( m_previousCallback ); - m_debugClient->Release(); - } - } - - const std::string& - Line() const { - return m_readLine; - } - -private: - - // IUnknown. - STDMETHOD(QueryInterface)( - __in REFIID InterfaceId, - __out PVOID* Interface ) { - return E_NOINTERFACE; - } - - STDMETHOD_(ULONG, AddRef)() { - return 1L; - } - - - STDMETHOD_(ULONG, Release)() { - return 0L; - } - - STDMETHOD(Output)( - __in ULONG Mask, - __in PCSTR Text ) - { - if ( Mask == DEBUG_OUTPUT_NORMAL ) - { - m_readLine += std::string( Text ); - } - - return S_OK; - } - -private: - - std::string m_readLine; - - IDebugClient *m_debugClient; - - IDebugOutputCallbacks *m_previousCallback; -}; - +#include "dbgcallback.h" /////////////////////////////////////////////////////////////////////////////// @@ -103,12 +14,12 @@ dbgCommand( const std::string &command ) try { - OutputReader outReader( dbgExt->client ); - + OutputReader outReader( dbgExt->client ); + hres = dbgExt->control->Execute( DEBUG_OUTCTL_THIS_CLIENT, command.c_str(), 0 ); if ( FAILED( hres ) ) throw DbgException( "IDebugControl::Execute failed" ); - + return std::string( outReader.Line() ); } catch( std::exception &e ) @@ -123,4 +34,4 @@ dbgCommand( const std::string &command ) return "error"; } -/////////////////////////////////////////////////////////////////////////////// \ No newline at end of file +/////////////////////////////////////////////////////////////////////////////// diff --git a/pykd/dbgcmd.h b/pykd/dbgcmd.h index 21969cf..24369d6 100644 --- a/pykd/dbgcmd.h +++ b/pykd/dbgcmd.h @@ -10,5 +10,8 @@ std::string dbgCommand( const std::string &command ); +void +dbgGoCommand(); + ///////////////////////////////////////////////////////////////////////////////// diff --git a/pykd/dbgext.cpp b/pykd/dbgext.cpp index 62f7640..c71abb7 100644 --- a/pykd/dbgext.cpp +++ b/pykd/dbgext.cpp @@ -23,11 +23,38 @@ #include "dbgdump.h" #include "dbgexcept.h" #include "dbgsession.h" +#include "dbgcallback.h" ///////////////////////////////////////////////////////////////////////////////// +// указатель на текущйи интерфейс DbgExt *dbgExt = NULL; + +///////////////////////////////////////////////////////////////////////////////// + +class WindbgGlobalSession +{ +public: + + WindbgGlobalSession() { + interactiveMode = false; + main = boost::python::import("__main__"); + } + + boost::python::object + global() { + return main.attr("__dict__"); + } + +private: + + boost::python::object main; + +}; + +WindbgGlobalSession *windbgGlobalSession = NULL; + ///////////////////////////////////////////////////////////////////////////////// BOOST_PYTHON_MODULE( pykd ) @@ -94,6 +121,8 @@ DebugExtensionInitialize( Py_Initialize(); + windbgGlobalSession = new WindbgGlobalSession(); + dbgSessionStarted = true; return S_OK; @@ -104,6 +133,9 @@ VOID CALLBACK DebugExtensionUninitialize() { + delete windbgGlobalSession; + windbgGlobalSession = NULL; + Py_Finalize(); } @@ -215,3 +247,104 @@ py( PDEBUG_CLIENT4 client, PCSTR args) ///////////////////////////////////////////////////////////////////////////////// +HRESULT +CALLBACK +pycmd( PDEBUG_CLIENT4 client, PCSTR args ) +{ + try { + + DbgExt ext = { 0 }; + + SetupDebugEngine( client, &ext ); + dbgExt = &ext; + + if ( !std::string( args ).empty() ) + { + try { + boost::python::exec( args, windbgGlobalSession->global(), windbgGlobalSession->global() ); + } + catch( boost::python::error_already_set const & ) + { + // ошибка в скрипте + PyObject *errtype = NULL, *errvalue = NULL, *traceback = NULL; + + PyErr_Fetch( &errtype, &errvalue, &traceback ); + + if(errvalue != NULL) + { + PyObject *s = PyObject_Str(errvalue); + + DbgPrint::dprintln( PyString_AS_STRING( s ) ); + + Py_DECREF(s); + } + + Py_XDECREF(errvalue); + Py_XDECREF(errtype); + Py_XDECREF(traceback); + } + } + else + { + char str[100]; + ULONG inputSize; + bool stopInput = false; + + do { + + std::string output; + + dbgExt->control->Output( DEBUG_OUTPUT_NORMAL, ">>>" ); + + do { + + OutputReader outputReader( dbgExt->client ); + + HRESULT hres = dbgExt->control->Input( str, sizeof(str), &inputSize ); + + if ( FAILED( hres ) || std::string( str ) == "" ) + { + stopInput = true; + break; + } + + } while( FALSE ); + + if ( !stopInput ) + try { + boost::python::exec( str, windbgGlobalSession->global(), windbgGlobalSession->global() ); + } + catch( boost::python::error_already_set const & ) + { + // ошибка в скрипте + PyObject *errtype = NULL, *errvalue = NULL, *traceback = NULL; + + PyErr_Fetch( &errtype, &errvalue, &traceback ); + + if(errvalue != NULL) + { + PyObject *s = PyObject_Str(errvalue); + + DbgPrint::dprintln( PyString_AS_STRING( s ) ); + + Py_DECREF(s); + } + + Py_XDECREF(errvalue); + Py_XDECREF(errtype); + Py_XDECREF(traceback); + } + + } while( !stopInput ); + } + } + + catch(...) + { + } + + return S_OK; + +} + +///////////////////////////////////////////////////////////////////////////////// diff --git a/pykd/dbgext.h b/pykd/dbgext.h index 4923453..8188ff9 100644 --- a/pykd/dbgext.h +++ b/pykd/dbgext.h @@ -16,8 +16,6 @@ struct DbgExt { IDebugSymbols3 *symbols3; IDebugDataSpaces *dataSpaces; - - }; extern DbgExt *dbgExt; diff --git a/pykd/pykd.def b/pykd/pykd.def index 53386c2..327eb31 100644 --- a/pykd/pykd.def +++ b/pykd/pykd.def @@ -3,4 +3,5 @@ EXPORTS DebugExtensionUninitialize info - py \ No newline at end of file + py + pycmd \ No newline at end of file diff --git a/pykd/pykd.vcproj b/pykd/pykd.vcproj index 63edf08..47e8e3a 100644 --- a/pykd/pykd.vcproj +++ b/pykd/pykd.vcproj @@ -445,6 +445,10 @@ Filter="h;hpp;hxx;hm;inl;inc;xsd" UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" > + +