diff --git a/pykd/dbgclient.cpp b/pykd/dbgclient.cpp new file mode 100644 index 0000000..0d4e3c7 --- /dev/null +++ b/pykd/dbgclient.cpp @@ -0,0 +1,88 @@ +#include "stdafx.h" + +#include "dbgclient.h" +#include + +using namespace pykd; + +/////////////////////////////////////////////////////////////////////////////////// + +DebugClient::DebugClient() +{ + HRESULT hres; + hres = DebugCreate( __uuidof(IDebugClient4), (void **)&m_client ); + if ( FAILED( hres ) ) + throw DbgException("DebugCreate failed"); + + hres = m_client->QueryInterface( __uuidof(IDebugControl4), (void**)&m_control ); + if ( FAILED( hres ) ) + throw DbgException("QueryInterface IDebugControl4 failed"); +} + +/////////////////////////////////////////////////////////////////////////////////// + +void DebugClient::loadDump( const std::wstring &fileName ) +{ + HRESULT hres; + + hres = m_client->OpenDumpFileWide( fileName.c_str(), NULL ); + if ( FAILED( hres ) ) + throw DbgException( "IDebugClient4::OpenDumpFileWide failed" ); + + hres = m_control->WaitForEvent(DEBUG_WAIT_DEFAULT, INFINITE); + if ( FAILED( hres ) ) + throw DbgException( "IDebugControl::WaitForEvent failed" ); + +} + +/////////////////////////////////////////////////////////////////////////////////// + +void DebugClient::startProcess( const std::wstring &processName ) +{ + HRESULT hres; + + ULONG opt; + hres = m_control->GetEngineOptions( &opt ); + if ( FAILED( hres ) ) + throw DbgException( "IDebugControl::GetEngineOptions failed" ); + + opt |= DEBUG_ENGOPT_INITIAL_BREAK; + hres = m_control->SetEngineOptions( opt ); + if ( FAILED( hres ) ) + throw DbgException( "IDebugControl::SetEngineOptions failed" ); + + std::vector< std::wstring::value_type> cmdLine( processName.size() + 1 ); + wcscpy_s( &cmdLine[0], cmdLine.size(), processName.c_str() ); + + hres = m_client->CreateProcessWide( 0, &cmdLine[0], DEBUG_PROCESS | DETACHED_PROCESS ); + if ( FAILED( hres ) ) + throw DbgException( "IDebugClient4::CreateProcessWide failed" ); + + hres = m_control->WaitForEvent(DEBUG_WAIT_DEFAULT, INFINITE); + if ( FAILED( hres ) ) + throw DbgException( "IDebugControl::WaitForEvent failed" ); +} + +/////////////////////////////////////////////////////////////////////////////////// + +void DebugClient::attachProcess( ULONG processId ) +{ + HRESULT hres; + + hres = m_client->AttachProcess( 0, processId, 0 ); + if ( FAILED( hres ) ) + throw DbgException( "IDebugClient::AttachProcess failed" ); +} + +/////////////////////////////////////////////////////////////////////////////////// + +void DebugClient::attachKernel( const std::wstring ¶m ) +{ + HRESULT hres; + + hres = m_client->AttachKernelWide( DEBUG_ATTACH_KERNEL_CONNECTION, param.c_str() ); + if ( FAILED( hres ) ) + throw DbgException( "IDebugClient5::AttachKernelWide failed" ); +} + +/////////////////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/pykd/dbgclient.h b/pykd/dbgclient.h index c971f10..e684d7e 100644 --- a/pykd/dbgclient.h +++ b/pykd/dbgclient.h @@ -1,5 +1,52 @@ #pragma once +#include +#include +#include + +#include "dbgexcept.h" + +///////////////////////////////////////////////////////////////////////////////// + +namespace pykd { + +///////////////////////////////////////////////////////////////////////////////// + +class DebugClient { + +public: + + DebugClient(); + + virtual ~DebugClient() {} + + void loadDump( const std::wstring &fileName ); + + void startProcess( const std::wstring &processName ); + + void attachProcess( ULONG processId ); + + void attachKernel( const std::wstring ¶m ); + +private: + + CComPtr m_client; + CComPtr m_control; +}; + +///////////////////////////////////////////////////////////////////////////////// + +}; // namespace pykd + + + + + + + + + + //#include "dbgext.h" //#include "dbgeventcb.h" // diff --git a/pykd/dbgexcept.cpp b/pykd/dbgexcept.cpp index 35cfeb3..9e7b8bf 100644 --- a/pykd/dbgexcept.cpp +++ b/pykd/dbgexcept.cpp @@ -1,4 +1,9 @@ #include "stdafx.h" + + + + + //#include "dbgexcept.h" // /////////////////////////////////////////////////////////////////////////////////// diff --git a/pykd/dbgexcept.h b/pykd/dbgexcept.h index da906a2..9758371 100644 --- a/pykd/dbgexcept.h +++ b/pykd/dbgexcept.h @@ -1,5 +1,45 @@ #pragma once +#include +#include + +namespace pykd { + +///////////////////////////////////////////////////////////////////////////////// + +class DbgException : public std::exception +{ +public: + + DbgException( const std::string &desc ) : + std::exception( desc.c_str() ) + {} + + const char* getDesc() const { + return what(); + } + + static + void + exceptionTranslate(const DbgException &e ); +}; + +/////////////////////////////////////////////////////////////////////////////////// + +extern PyObject *baseExceptionType; + +/////////////////////////////////////////////////////////////////////////////////// + +}; // namespace pykd + +/////////////////////////////////////////////////////////////////////////////////// + + + + + + + //#include //#include // diff --git a/pykd/dbgext.cpp b/pykd/dbgext.cpp index 99f5ecf..989565f 100644 --- a/pykd/dbgext.cpp +++ b/pykd/dbgext.cpp @@ -2,6 +2,12 @@ #include +#include "module.h" +#include "diawrapper.h" +#include "dbgclient.h" + +namespace python = boost::python; + //////////////////////////////////////////////////////////////////////////////// HRESULT @@ -44,11 +50,18 @@ pycmd( PDEBUG_CLIENT4 client, PCSTR args ) //////////////////////////////////////////////////////////////////////////////// -HRESULT -CALLBACK -info( PDEBUG_CLIENT4 client, PCSTR args ) +BOOST_PYTHON_MODULE( pykd ) { - return S_OK; + python::class_("dbgClient", "Class representing a debugging session" ) + .def( "loadDump", &pykd::DebugClient::loadDump, "Load crash dump" ) + .def( "startProcess", &pykd::DebugClient::startProcess, "Start process for debugging" ) + .def( "attachProcess", &pykd::DebugClient::attachProcess, "Attach debugger to a exsisting process" ) + .def( "attachKernel", &pykd::DebugClient::attachKernel, "Attach debugger to a target's kernel" ); + + python::class_("module", "Class representing executable module", python::no_init ) + .def( python::init( "constructor" ) ); + + // python::class_("dia", "class wrapper for MS DIA" ); } //////////////////////////////////////////////////////////////////////////////// @@ -61,6 +74,9 @@ info( PDEBUG_CLIENT4 client, PCSTR args ) + + + //#include // //#include diff --git a/pykd/dbgmodule.cpp b/pykd/module.cpp similarity index 100% rename from pykd/dbgmodule.cpp rename to pykd/module.cpp diff --git a/pykd/dbgmodule.h b/pykd/module.h similarity index 89% rename from pykd/dbgmodule.h rename to pykd/module.h index cc6e59a..b7ccb6a 100644 --- a/pykd/dbgmodule.h +++ b/pykd/module.h @@ -1,5 +1,22 @@ #pragma once +namespace pykd { + +/////////////////////////////////////////////////////////////////////////////////// + +class Module { + +public: + + Module( const std::string &moduleName ) + {} +}; + +/////////////////////////////////////////////////////////////////////////////////// + +}; + + //#include //#include // diff --git a/pykd/pykd.def b/pykd/pykd.def index 17ee93b..4c23f5e 100644 --- a/pykd/pykd.def +++ b/pykd/pykd.def @@ -1,7 +1,5 @@ EXPORTS DebugExtensionInitialize DebugExtensionUninitialize - - info py pycmd diff --git a/pykd/pykd_2008.vcproj b/pykd/pykd_2008.vcproj index 6e2b4b6..d8c8fb4 100644 --- a/pykd/pykd_2008.vcproj +++ b/pykd/pykd_2008.vcproj @@ -349,10 +349,22 @@ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" > + + + + + + @@ -399,6 +411,22 @@ Filter="h;hpp;hxx;hm;inl;inc;xsd" UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" > + + + + + + + + diff --git a/pykd/stdafx.h b/pykd/stdafx.h index deeb631..52a9e8f 100644 --- a/pykd/stdafx.h +++ b/pykd/stdafx.h @@ -30,20 +30,22 @@ #include #include + // //#ifndef __field_ecount_opt //#define __field_ecount_opt(x) //#endif // __field_ecount_opt // // -//#define BOOST_PYTHON_STATIC_LIB -// -//#pragma warning(push) -//// 'return' : conversion from 'Py_ssize_t' to 'unsigned int', possible loss of data -//#pragma warning(disable:4244) -//#include -//#include -//#pragma warning(pop) +#define BOOST_PYTHON_STATIC_LIB + +#pragma warning(push) +// 'return' : conversion from 'Py_ssize_t' to 'unsigned int', possible loss of data +#pragma warning(disable:4244) +#include +#include +#include +#pragma warning(pop) // //#include // diff --git a/test/scripts/basetest.py b/test/scripts/basetest.py index bc7b552..e0fc3c0 100644 --- a/test/scripts/basetest.py +++ b/test/scripts/basetest.py @@ -4,11 +4,12 @@ import unittest import target +import pykd class BaseTest( unittest.TestCase ): - - def test1( self ): - self.assertNotEqual( target.module, None ) - - - \ No newline at end of file + + def testImport( self ): + self.assertNotEqual( None, pykd.module ) + self.assertNotEqual( None, pykd.dbgClient ) + +# self.assertNotEqual( None, pykd.dia ) diff --git a/test/scripts/pykdtest.py b/test/scripts/pykdtest.py index f0f6820..63d861a 100644 --- a/test/scripts/pykdtest.py +++ b/test/scripts/pykdtest.py @@ -5,7 +5,6 @@ import sys import os import unittest -import fnmatch # Dynamically append current pykd.pyd path to PYTHONPATH sys.path.append(os.path.dirname(sys.argv[1])) @@ -15,11 +14,15 @@ import target import basetest import typeinfo import regtest +import moduletest + +print dir(pykd) def getTestSuite( singleName = "" ): if singleName == "": return unittest.TestSuite( [ unittest.TestLoader().loadTestsFromTestCase( basetest.BaseTest ), + unittest.TestLoader().loadTestsFromTestCase( moduletest.ModuleTest ), # unittest.TestLoader().loadTestsFromTestCase( typeinfo.TypeInfoTest ), # unittest.TestLoader().loadTestsFromTestCase( regtest.CpuRegTest ) ] ) @@ -34,10 +37,12 @@ if __name__ == "__main__": target.moduleName = os.path.splitext(os.path.basename(targetAppPath))[0] print "\nTest module: %s" % targetAppPath - pykd.startProcess( targetAppPath ) - pykd.go() + dbg = pykd.dbgClient() + + dbg.startProcess( targetAppPath ) +# pykd.go() - target.module = pykd.loadModule( target.moduleName ) +# target.module = pykd.loadModule( target.moduleName ) suite = getTestSuite() diff --git a/test/targetapp/targetapp.vcproj b/test/targetapp/targetapp.vcproj index cf9ba53..fbcff0c 100644 --- a/test/targetapp/targetapp.vcproj +++ b/test/targetapp/targetapp.vcproj @@ -404,6 +404,10 @@ RelativePath="..\scripts\basetest.py" > + +