diff --git a/pykd/dbgclient.h b/pykd/dbgclient.h index 1d8ec6b..ba52408 100644 --- a/pykd/dbgclient.h +++ b/pykd/dbgclient.h @@ -57,6 +57,14 @@ public: ULONG64 addr64( ULONG64 addr ); + void dprint( const std::string &str, bool dml = false ); + + void dprintln( const std::string &str, bool dml = false ); + + void eprint( const std::string &str ); + + void eprintln( const std::string &str ); + private: DebugClient(); diff --git a/pykd/dbgext.cpp b/pykd/dbgext.cpp index 3e4d1ac..ccc31bb 100644 --- a/pykd/dbgext.cpp +++ b/pykd/dbgext.cpp @@ -4,9 +4,11 @@ #include <dia2.h> +#include "windbg.h" #include "module.h" #include "diawrapper.h" #include "dbgclient.h" +#include "dbgio.h" using namespace pykd; @@ -60,22 +62,32 @@ BOOST_PYTHON_MODULE( pykd ) .def( "loadModule", &pykd::DebugClient::loadModule, "Return instance of Module class" ) .def( "findModule", &pykd::DebugClient::findModule, - "Return instance of the Module class which posseses specified address" ); + "Return instance of the Module class which posseses specified address" ) + .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, + "Print out string and insert end of line symbol. If dml = True string is printed with dml highlighting ( only for windbg )" ); + // python::def( "createDbgClient", pykd::DebugClient::createDbgClient, // "create a new instance of the dbgClient class" ); - python::def( "loadDump", &loadDump, + python::def( "loadDump", &pykd::loadDump, "Load crash dump (only for console)"); - python::def( "startProcess", &startProcess, + python::def( "startProcess", &pykd::startProcess, "Start process for debugging (only for console)"); - python::def( "attachProcess", &attachProcess, + python::def( "attachProcess", &pykd::attachProcess, "Attach debugger to a exsisting process" ); - python::def( "attachKernel", &attachKernel, + python::def( "attachKernel", &pykd::attachKernel, "Attach debugger to a kernel target" ); - python::def( "loadModule", &loadModule, + python::def( "loadModule", &pykd::loadModule, "Return instance of Module class" ); - python::def( "findModule", &findModule, + python::def( "findModule", &pykd::findModule, "Return instance of the Module class which posseses specified address" ); + python::def( "dprint", &pykd::dprint, + "Print out string. If dml = True string is printed with dml highlighting ( only for windbg )" ); + python::def( "dprintln", &pykd::dprintln, + "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 ); @@ -297,80 +309,33 @@ 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__"); - - python::object main_namespace = main.attr("__dict__"); - - // ������ ������ from pykd import * - python::object pykd = boost::python::import( "pykd" ); - - python::dict pykd_namespace( pykd.attr("__dict__") ); - - 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 ]; - } - } + main = boost::python::import("__main__"); - ~WindbgGlobalSession() { - } - - python::object main; + python::object main_namespace = main.attr("__dict__"); - static volatile LONG sessionCount; + // ������ ������ from pykd import * + python::object pykd = boost::python::import( "pykd" ); - static WindbgGlobalSession *windbgGlobalSession; + python::dict pykd_namespace( pykd.attr("__dict__") ); + + 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 ]; + } +} -}; volatile LONG WindbgGlobalSession::sessionCount = 0; @@ -419,7 +384,7 @@ py( PDEBUG_CLIENT4 client, PCSTR args ) } catch(...) { - // dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "unexpected error" ); + dbgClient->eprintln( "unexpected error" ); } Py_EndInterpreter( localInterpreter ); @@ -436,6 +401,22 @@ HRESULT CALLBACK pycmd( PDEBUG_CLIENT4 client, PCSTR args ) { + DebugClientPtr dbgClient = DebugClient::createDbgClient( client ); + DebugClientPtr oldClient = DebugClient::setDbgClientCurrent( dbgClient ); + + try { + + + } + catch(...) + { + dbgClient->eprintln( "unexpected error" ); + } + + DebugClient::setDbgClientCurrent( oldClient ); + + return S_OK; + return S_OK; } diff --git a/pykd/dbgio.cpp b/pykd/dbgio.cpp index bf9944a..b79ab08 100644 --- a/pykd/dbgio.cpp +++ b/pykd/dbgio.cpp @@ -1,59 +1,158 @@ #include "stdafx.h" #include <iostream> -#include <Fcntl.h> #include "dbgio.h" -#include "dbgext.h" +#include "dbgclient.h" +#include "windbg.h" -using namespace std; +namespace pykd { -///////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////// -void dbgPrint::dprint( const boost::python::object& obj, bool dml ) +void DebugClient::dprint( const std::string &str, bool dml ) { - std::wstring str = boost::python::extract<std::wstring>( obj ); - - if ( isWindbgExt() ) + if ( WindbgGlobalSession::isInit() ) { - for ( size_t i = 0; i < str.size() / 100 + 1; ++i ) { - dbgExt->control4->ControlledOutputWide( + m_control->ControlledOutputWide( dml ? DEBUG_OUTCTL_AMBIENT_DML : DEBUG_OUTCTL_AMBIENT_TEXT, DEBUG_OUTPUT_NORMAL, - L"%ws", + L"%s", str.substr( i*100, min( str.size() - i*100, 100 ) ).c_str() ); } } else { - std::wcout << str; + std::cout << str; } } -///////////////////////////////////////////////////////////////////////////////// - -void dbgPrint::dprintln( const boost::python::object& obj, bool dml ) +void dprint( const std::string &str, bool dml ) { - std::wstring str = boost::python::extract<std::wstring>( obj ); - str += L"\r\n"; + g_dbgClient->dprint( str, dml ); +} - if ( isWindbgExt() ) + +/////////////////////////////////////////////////////////////////////////////////// + +void DebugClient::dprintln( const std::string &str, bool dml ) +{ + this->dprint( str + "\r\n", dml ); +} + +void dprintln( const std::string &str, bool dml ) +{ + g_dbgClient->dprintln( str, dml ); +} + +/////////////////////////////////////////////////////////////////////////////////// + +void DebugClient::eprint( const std::string &str ) +{ + if ( WindbgGlobalSession::isInit() ) { for ( size_t i = 0; i < str.size() / 100 + 1; ++i ) { - dbgExt->control4->ControlledOutputWide( - dml ? DEBUG_OUTCTL_AMBIENT_DML : DEBUG_OUTCTL_AMBIENT_TEXT, DEBUG_OUTPUT_NORMAL, - L"%ws", + m_control->OutputWide( + DEBUG_OUTPUT_ERROR, + L"%s", str.substr( i*100, min( str.size() - i*100, 100 ) ).c_str() ); } } else { - std::wcout << str; - } + std::cerr << str; + } } -///////////////////////////////////////////////////////////////////////////////// +void eprint( const std::string &str ) +{ + g_dbgClient->eprint( str ); +} + +/////////////////////////////////////////////////////////////////////////////////// + +void DebugClient::eprintln( const std::string &str ) +{ + this->eprint( str + "\r\n"); +} + +void eprintln( const std::string &str ) +{ + g_dbgClient->eprintln( str ); +} + +/////////////////////////////////////////////////////////////////////////////////// + +}; // namesapce pykd + + + + + + + + + + + + + + + + + + + + +// +//void dbgPrint::dprint( const boost::python::object& obj, bool dml ) +//{ +// std::wstring str = boost::python::extract<std::wstring>( obj ); +// +// if ( isWindbgExt() ) +// { +// +// for ( size_t i = 0; i < str.size() / 100 + 1; ++i ) +// { +// dbgExt->control4->ControlledOutputWide( +// dml ? DEBUG_OUTCTL_AMBIENT_DML : DEBUG_OUTCTL_AMBIENT_TEXT, DEBUG_OUTPUT_NORMAL, +// L"%ws", +// str.substr( i*100, min( str.size() - i*100, 100 ) ).c_str() +// ); +// } +// } +// else +// { +// std::wcout << str; +// } +//} +// +/////////////////////////////////////////////////////////////////////////////////// +// +//void dbgPrint::dprintln( const boost::python::object& obj, bool dml ) +//{ +// std::wstring str = boost::python::extract<std::wstring>( obj ); +// str += L"\r\n"; +// +// if ( isWindbgExt() ) +// { +// for ( size_t i = 0; i < str.size() / 100 + 1; ++i ) +// { +// dbgExt->control4->ControlledOutputWide( +// dml ? DEBUG_OUTCTL_AMBIENT_DML : DEBUG_OUTCTL_AMBIENT_TEXT, DEBUG_OUTPUT_NORMAL, +// L"%ws", +// str.substr( i*100, min( str.size() - i*100, 100 ) ).c_str() +// ); +// } +// } +// else +// { +// std::wcout << str; +// } +//} +// +/////////////////////////////////////////////////////////////////////////////////// diff --git a/pykd/dbgio.h b/pykd/dbgio.h index 5294afb..aa1fc1a 100644 --- a/pykd/dbgio.h +++ b/pykd/dbgio.h @@ -1,224 +1,238 @@ #pragma once -#include <string> -#include <dbgeng.h> -#include "dbgext.h" +namespace pykd { +/////////////////////////////////////////////////////////////////////////////////// + +void dprint( const std::string &str, bool dml = false ); + +void dprintln( const std::string &str, bool dml = false ); + +void eprint( const std::string &str ); + +void eprintln( const std::string &str ); + +/////////////////////////////////////////////////////////////////////////////////// + +}; + + + + +// +//class dbgPrint { +// +//public: +// +// static void dprint( const boost::python::object& obj, bool dml = false ); +// +// static void dprintln( const boost::python::object& obj, bool dml = false ); +// +//}; +// ///////////////////////////////////////////////////////////////////////////////// - -class dbgPrint { - -public: - - static void dprint( const boost::python::object& obj, bool dml = false ); - - static void dprintln( const boost::python::object& obj, bool dml = false ); - -}; - -/////////////////////////////////////////////////////////////////////////////// - -// ����� ��� ��������� ������ � �������� - -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; -}; - -/////////////////////////////////////////////////////////////////////////////// - -class InputReader : public IDebugInputCallbacks { - -public: - - InputReader( IDebugClient *debugClient ) - { - HRESULT hres; - - try { - - m_debugClient = debugClient; - m_debugClient->AddRef(); - - hres = m_debugClient->GetInputCallbacks( &m_previousCallback ); - if ( FAILED( hres ) ) - { - throw hres; - } - - hres = m_debugClient->SetInputCallbacks( this ); - if ( FAILED( hres ) ) - { - throw hres; - } - - } catch( ... ) - { - m_debugClient->Release(); - m_debugClient = NULL; - } - } - - ~InputReader() - { - if ( m_debugClient ) - { - m_debugClient->SetInputCallbacks( m_previousCallback ); - m_debugClient->Release(); - } - } - - -private: - - // IUnknown. - STDMETHOD(QueryInterface)( - __in REFIID InterfaceId, - __out PVOID* Interface ) { - return E_NOINTERFACE; - } - - STDMETHOD_(ULONG, AddRef)() { - return 1L; - } - - - STDMETHOD_(ULONG, Release)() { - return 0L; - } - - STDMETHOD( EndInput )() { - return S_OK; - } - - STDMETHOD( StartInput )( - IN ULONG BufferSize ) { - return S_OK; - } - -private: - - IDebugClient *m_debugClient; - - IDebugInputCallbacks *m_previousCallback; - -}; - - -///////////////////////////////////////////////////////////////////////////////// - -class dbgOut { - -public: - - void - write( const boost::python::object &str ) { - dbgPrint::dprint( str ); - } - -}; - -///////////////////////////////////////////////////////////////////////////////// - -class dbgIn { - -public: - - std::string - readline() { - - char str[100]; - ULONG inputSize; - - OutputReader outputReader( dbgExt->client ); - - dbgExt->control->Input( str, sizeof(str), &inputSize ); - - return std::string( str ); - } - -}; - +// +//// ����� ��� ��������� ������ � �������� +// +//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; +//}; +// ///////////////////////////////////////////////////////////////////////////////// +// +//class InputReader : public IDebugInputCallbacks { +// +//public: +// +// InputReader( IDebugClient *debugClient ) +// { +// HRESULT hres; +// +// try { +// +// m_debugClient = debugClient; +// m_debugClient->AddRef(); +// +// hres = m_debugClient->GetInputCallbacks( &m_previousCallback ); +// if ( FAILED( hres ) ) +// { +// throw hres; +// } +// +// hres = m_debugClient->SetInputCallbacks( this ); +// if ( FAILED( hres ) ) +// { +// throw hres; +// } +// +// } catch( ... ) +// { +// m_debugClient->Release(); +// m_debugClient = NULL; +// } +// } +// +// ~InputReader() +// { +// if ( m_debugClient ) +// { +// m_debugClient->SetInputCallbacks( m_previousCallback ); +// m_debugClient->Release(); +// } +// } +// +// +//private: +// +// // IUnknown. +// STDMETHOD(QueryInterface)( +// __in REFIID InterfaceId, +// __out PVOID* Interface ) { +// return E_NOINTERFACE; +// } +// +// STDMETHOD_(ULONG, AddRef)() { +// return 1L; +// } +// +// +// STDMETHOD_(ULONG, Release)() { +// return 0L; +// } +// +// STDMETHOD( EndInput )() { +// return S_OK; +// } +// +// STDMETHOD( StartInput )( +// IN ULONG BufferSize ) { +// return S_OK; +// } +// +//private: +// +// IDebugClient *m_debugClient; +// +// IDebugInputCallbacks *m_previousCallback; +// +//}; +// +// +/////////////////////////////////////////////////////////////////////////////////// +// +//class dbgOut { +// +//public: +// +// void +// write( const boost::python::object &str ) { +// dbgPrint::dprint( str ); +// } +// +//}; +// +/////////////////////////////////////////////////////////////////////////////////// +// +//class dbgIn { +// +//public: +// +// std::string +// readline() { +// +// char str[100]; +// ULONG inputSize; +// +// OutputReader outputReader( dbgExt->client ); +// +// dbgExt->control->Input( str, sizeof(str), &inputSize ); +// +// return std::string( str ); +// } +// +//}; +// +/////////////////////////////////////////////////////////////////////////////////// diff --git a/pykd/pykd_2008.vcproj b/pykd/pykd_2008.vcproj index 7bbbe8a..78ad19c 100644 --- a/pykd/pykd_2008.vcproj +++ b/pykd/pykd_2008.vcproj @@ -361,6 +361,10 @@ RelativePath=".\dbgext.cpp" > </File> + <File + RelativePath=".\dbgio.cpp" + > + </File> <File RelativePath=".\dbgmem.cpp" > @@ -435,6 +439,10 @@ RelativePath=".\dbgexcept.h" > </File> + <File + RelativePath=".\dbgio.h" + > + </File> <File RelativePath=".\dbgmem.h" > @@ -475,6 +483,10 @@ RelativePath=".\utils.h" > </File> + <File + RelativePath=".\windbg.h" + > + </File> </Filter> <Filter Name="Resource Files" diff --git a/pykd/windbg.h b/pykd/windbg.h new file mode 100644 index 0000000..88a8c53 --- /dev/null +++ b/pykd/windbg.h @@ -0,0 +1,62 @@ +#pragma once + + +namespace 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() { + } + + python::object main; + + static volatile LONG sessionCount; + + static WindbgGlobalSession *windbgGlobalSession; + +}; + +/////////////////////////////////////////////////////////////////////////////////// + + +}; // namespace pykd \ No newline at end of file diff --git a/test/scripts/basetest.py b/test/scripts/basetest.py index e0fc3c0..c10ddac 100644 --- a/test/scripts/basetest.py +++ b/test/scripts/basetest.py @@ -11,5 +11,4 @@ class BaseTest( unittest.TestCase ): def testImport( self ): self.assertNotEqual( None, pykd.module ) self.assertNotEqual( None, pykd.dbgClient ) - -# self.assertNotEqual( None, pykd.dia ) +