From 080b705c5a9604c62352ca30ff856254fade58fb Mon Sep 17 00:00:00 2001 From: "SND\\kernelnet_cp" Date: Mon, 15 Oct 2012 12:35:06 +0000 Subject: [PATCH] [0.2.x] added : dbgCommand routine git-svn-id: https://pykd.svn.codeplex.com/svn@80216 9b283d60-5439-405e-af05-b73fd8c4d996 --- pykd/dbgengine.h | 1 + pykd/pymod.cpp | 2 ++ pykd/win/dbgeng.cpp | 18 ++++++++++++ pykd/win/dbgio.h | 71 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 92 insertions(+) diff --git a/pykd/dbgengine.h b/pykd/dbgengine.h index de2bbb6..9d14f4f 100644 --- a/pykd/dbgengine.h +++ b/pykd/dbgengine.h @@ -19,6 +19,7 @@ void debugGo(); void debugStep(); void debugStepIn(); void debugBreak(); +std::string debugCommand( const std::wstring &command ); ULONG64 evaluate( const std::wstring &expression ); // debug output diff --git a/pykd/pymod.cpp b/pykd/pymod.cpp index 9a8b437..03ec690 100644 --- a/pykd/pymod.cpp +++ b/pykd/pymod.cpp @@ -87,6 +87,8 @@ BOOST_PYTHON_MODULE( pykd ) "Break into debugger" ); python::def( "expr", &evaluate, "Evaluate windbg expression" ); + python::def( "dbgCommand", &debugCommand, + "Run a debugger's command and return it's result as a string" ); python::def( "go", &debugGo, "Go debugging" ); python::def( "step", &debugStep, diff --git a/pykd/win/dbgeng.cpp b/pykd/win/dbgeng.cpp index e5c0d2e..58d9bed 100644 --- a/pykd/win/dbgeng.cpp +++ b/pykd/win/dbgeng.cpp @@ -3,6 +3,7 @@ #include #include "win/dbgeng.h" +#include "win/dbgio.h" #include "dbgexcept.h" namespace pykd { @@ -290,6 +291,23 @@ ULONG64 evaluate( const std::wstring &expression ) /////////////////////////////////////////////////////////////////////////////// +std::string debugCommand( const std::wstring &command ) +{ + PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate ); + + HRESULT hres; + OutputReader outReader( g_dbgEng->client ); + + hres = g_dbgEng->control->ExecuteWide( DEBUG_OUTCTL_THIS_CLIENT, command.c_str(), 0 ); + + if ( FAILED( hres ) ) + throw DbgException( "IDebugControl::Execute failed" ); + + return std::string( outReader.Line() ); +} + +/////////////////////////////////////////////////////////////////////////////// + ULONG64 findModuleBase( const std::string &moduleName ) { PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate ); diff --git a/pykd/win/dbgio.h b/pykd/win/dbgio.h index db11b38..ebab51c 100644 --- a/pykd/win/dbgio.h +++ b/pykd/win/dbgio.h @@ -1,6 +1,8 @@ #pragma once +#include #include "dbgengine.h" +#include "dbgexcept.h" namespace pykd { @@ -46,4 +48,73 @@ public: /////////////////////////////////////////////////////////////////////////////// +class OutputReader : public IDebugOutputCallbacks, private boost::noncopyable { + +public: + + explicit OutputReader( IDebugClient4 *client ) + { + HRESULT hres; + + m_client = client; + + hres = m_client->GetOutputCallbacks( &m_previousCallback ); + if ( FAILED( hres ) ) + throw DbgException( "IDebugClient::GetOutputCallbacks failed" ); + + hres = m_client->SetOutputCallbacks( this ); + if ( FAILED( hres ) ) + throw DbgException( "IDebugClient::GetOutputCallbacks failed" ); + } + + ~OutputReader() + { + m_client->SetOutputCallbacks( m_previousCallback ); + } + + 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; + + CComPtr m_previousCallback; + + CComPtr m_client; +}; + +/////////////////////////////////////////////////////////////////////////////// + } // end pykd namespace