diff --git a/pykd/dbgclient.cpp b/pykd/dbgclient.cpp index 1946fe1..7191b8b 100644 --- a/pykd/dbgclient.cpp +++ b/pykd/dbgclient.cpp @@ -10,25 +10,6 @@ namespace pykd { DebugClientPtr g_dbgClient( DebugClient::createDbgClient() ); -void loadDump( const std::wstring &fileName ) { - g_dbgClient->loadDump( fileName ); -} - -void startProcess( const std::wstring &processName ) { - g_dbgClient->startProcess( processName ); -} - -void attachProcess( ULONG processId ) { - g_dbgClient->attachProcess( processId ); -} - -void attachKernel( const std::wstring ¶m ) { - g_dbgClient->attachKernel( param ); -} - - -/////////////////////////////////////////////////////////////////////////////////// - DebugClientPtr DebugClient::setDbgClientCurrent( DebugClientPtr newDbgClient ) { DebugClientPtr oldClient = g_dbgClient; g_dbgClient = newDbgClient; @@ -37,6 +18,66 @@ DebugClientPtr DebugClient::setDbgClientCurrent( DebugClientPtr newDbgClient ) /////////////////////////////////////////////////////////////////////////////////// +python::tuple DebugClient::getDebuggeeType() +{ + HRESULT hres; + ULONG debugClass, debugQualifier; + + hres = m_control->GetDebuggeeType( &debugClass, &debugQualifier ); + + if ( FAILED( hres ) ) + throw DbgException( "IDebugControl::GetDebuggeeType failed" ); + + return python::make_tuple( debugClass, debugQualifier ); +} + +python::tuple getDebuggeeType() +{ + return g_dbgClient->getDebuggeeType(); +} + +/////////////////////////////////////////////////////////////////////////////////// + +bool DebugClient::isDumpAnalyzing() +{ + HRESULT hres; + ULONG debugClass, debugQualifier; + + hres = m_control->GetDebuggeeType( &debugClass, &debugQualifier ); + + if ( FAILED( hres ) ) + throw DbgException( "IDebugControl::GetDebuggeeType failed" ); + + return debugQualifier >= DEBUG_DUMP_SMALL; +} + +bool isDumpAnalyzing() +{ + return g_dbgClient->isDumpAnalyzing(); +} + +/////////////////////////////////////////////////////////////////////////////////// + +bool DebugClient::isKernelDebugging() +{ + HRESULT hres; + ULONG debugClass, debugQualifier; + + hres = m_control->GetDebuggeeType( &debugClass, &debugQualifier ); + + if ( FAILED( hres ) ) + throw DbgException( "IDebugControl::GetDebuggeeType failed" ); + + return debugClass == DEBUG_CLASS_KERNEL; +} + +bool isKernelDebugging() +{ + return g_dbgClient->isKernelDebugging(); +} + +////////////////////////////////////////////////////////////////////////////////// + void DebugClient::loadDump( const std::wstring &fileName ) { HRESULT hres; @@ -51,6 +92,10 @@ void DebugClient::loadDump( const std::wstring &fileName ) } +void loadDump( const std::wstring &fileName ) { + g_dbgClient->loadDump( fileName ); +} + /////////////////////////////////////////////////////////////////////////////////// void DebugClient::startProcess( const std::wstring &processName ) @@ -79,6 +124,10 @@ void DebugClient::startProcess( const std::wstring &processName ) throw DbgException( "IDebugControl::WaitForEvent failed" ); } +void startProcess( const std::wstring &processName ) { + g_dbgClient->startProcess( processName ); +} + /////////////////////////////////////////////////////////////////////////////////// void DebugClient::attachProcess( ULONG processId ) @@ -90,6 +139,10 @@ void DebugClient::attachProcess( ULONG processId ) throw DbgException( "IDebugClient::AttachProcess failed" ); } +void attachProcess( ULONG processId ) { + g_dbgClient->attachProcess( processId ); +} + /////////////////////////////////////////////////////////////////////////////////// void DebugClient::attachKernel( const std::wstring ¶m ) @@ -101,6 +154,11 @@ void DebugClient::attachKernel( const std::wstring ¶m ) throw DbgException( "IDebugClient5::AttachKernelWide failed" ); } +void attachKernel( const std::wstring ¶m ) { + g_dbgClient->attachKernel( param ); +} + + /////////////////////////////////////////////////////////////////////////////////// }; // end of namespace pykd \ No newline at end of file diff --git a/pykd/dbgclient.h b/pykd/dbgclient.h index 498f1cb..40f0d8e 100644 --- a/pykd/dbgclient.h +++ b/pykd/dbgclient.h @@ -64,6 +64,12 @@ public: ULONG64 evaluate( const std::wstring &expression ); + python::tuple getDebuggeeType(); + + bool isKernelDebugging(); + + bool isDumpAnalyzing(); + Module loadModule( const std::string &moduleName ) { return Module( m_client, moduleName ); } @@ -128,9 +134,11 @@ void attachProcess( ULONG processId ); void attachKernel( const std::wstring ¶m ); -Module loadModule( const std::string &moduleName ); +python::tuple getDebuggeeType(); -Module findModule( ULONG64 offset ); +bool isKernelDebugging(); + +bool isDumpAnalyzing(); ///////////////////////////////////////////////////////////////////////////////// diff --git a/pykd/dbgext.cpp b/pykd/dbgext.cpp index 313ff46..1472f27 100644 --- a/pykd/dbgext.cpp +++ b/pykd/dbgext.cpp @@ -67,6 +67,12 @@ BOOST_PYTHON_MODULE( pykd ) "Attach debugger to a target's kernel" ) .def( "expr", &pykd::DebugClient::evaluate, "Evaluate windbg expression" ) + .def( "getDebuggeeType", &pykd::DebugClient::getDebuggeeType, + "Return type of the debuggee" ) + .def( "isDumpAnalyzing", &pykd::DebugClient::isDumpAnalyzing, + "Check if it is a dump analyzing ( not living debuggee )" ) + .def( "isKernelDebugging", &pykd::DebugClient::isKernelDebugging, + "Check if kernel dubugging is running" ) .def ( "loadExt", &pykd::DebugClient::loadExtension, "Load a debuger extension" ) .def( "loadModule", &pykd::DebugClient::loadModule, @@ -92,6 +98,12 @@ BOOST_PYTHON_MODULE( pykd ) "Attach debugger to a kernel target" ); python::def( "expr", &pykd::evaluate, "Evaluate windbg expression" ); + python::def( "getDebuggeeType", &pykd::getDebuggeeType, + "Return type of the debuggee" ); + python::def( "isDumpAnalyzing", &pykd::isDumpAnalyzing, + "Check if it is a dump analyzing ( not living debuggee )" ); + python::def( "isKernelDebugging", &pykd::isKernelDebugging, + "Check if kernel dubugging is running" ); python::def( "loadExt", &pykd::loadExtension, "Load a debuger extension" ); python::def( "loadModule", &pykd::loadModule, @@ -327,6 +339,22 @@ BOOST_PYTHON_MODULE( pykd ) pyDia::Exception::setTypeObject( diaException.ptr() ); boost::python::register_exception_translator( &pyDia::Exception::exceptionTranslate ); + + DEF_PY_CONST_ULONG( DEBUG_CLASS_UNINITIALIZED ); + DEF_PY_CONST_ULONG( DEBUG_CLASS_KERNEL ); + DEF_PY_CONST_ULONG( DEBUG_CLASS_USER_WINDOWS ); + + DEF_PY_CONST_ULONG( DEBUG_KERNEL_CONNECTION ); + DEF_PY_CONST_ULONG( DEBUG_KERNEL_LOCAL ); + DEF_PY_CONST_ULONG( DEBUG_KERNEL_EXDI_DRIVER ); + DEF_PY_CONST_ULONG( DEBUG_KERNEL_SMALL_DUMP ); + DEF_PY_CONST_ULONG( DEBUG_KERNEL_DUMP ); + DEF_PY_CONST_ULONG( DEBUG_KERNEL_FULL_DUMP ); + + DEF_PY_CONST_ULONG( DEBUG_USER_WINDOWS_PROCESS ); + DEF_PY_CONST_ULONG( DEBUG_USER_WINDOWS_PROCESS_SERVER ); + DEF_PY_CONST_ULONG( DEBUG_USER_WINDOWS_SMALL_DUMP ); + DEF_PY_CONST_ULONG( DEBUG_USER_WINDOWS_DUMP ); } #undef DEF_PY_CONST_ULONG diff --git a/pykd/module.h b/pykd/module.h index 34e704c..07532f6 100644 --- a/pykd/module.h +++ b/pykd/module.h @@ -81,7 +81,13 @@ private: /////////////////////////////////////////////////////////////////////////////////// -}; +Module loadModule( const std::string &moduleName ); + +Module findModule( ULONG64 offset ); + +/////////////////////////////////////////////////////////////////////////////////// + +}; // end pykd namespace diff --git a/test/scripts/basetest.py b/test/scripts/basetest.py index a218537..a37e657 100644 --- a/test/scripts/basetest.py +++ b/test/scripts/basetest.py @@ -111,6 +111,7 @@ class BaseTest( unittest.TestCase ): """ Branch test: new API 0.1.x what must be available """ self.assertTrue( hasattr(pykd, 'createDbgClient') ) self.assertTrue( hasattr(pykd, 'diaLoadPdb') ) + self.assertTrue( hasattr(pykd, 'getDebuggeeType' ) ) self.assertTrue( hasattr(pykd, 'loadExt') ) self.assertTrue( hasattr(pykd, 'DiaException') ) diff --git a/test/scripts/clienttest.py b/test/scripts/clienttest.py new file mode 100644 index 0000000..c7e656a --- /dev/null +++ b/test/scripts/clienttest.py @@ -0,0 +1,18 @@ + +import unittest +import target +import pykd + +class DbgClientTest( unittest.TestCase ): + + def testGetDebuggeeType( self ): + c, q = pykd.getDebuggeeType() + self.assertEqual( c, pykd.DEBUG_CLASS_USER_WINDOWS ) + self.assertEqual( q, pykd.DEBUG_USER_WINDOWS_PROCESS ) + + def testIsKernelDebugging( self ): + self.assertFalse( pykd.isKernelDebugging() ) + + def testIsDumpAnalyzing( self ): + self.assertFalse( pykd.isDumpAnalyzing() ) + diff --git a/test/scripts/pykdtest.py b/test/scripts/pykdtest.py index 8715cd8..a6abff6 100644 --- a/test/scripts/pykdtest.py +++ b/test/scripts/pykdtest.py @@ -17,6 +17,7 @@ import regtest import moduletest import diatest import dbgcmd +import clienttest def getTestSuite( singleName = "" ): if singleName == "": @@ -25,7 +26,8 @@ def getTestSuite( singleName = "" ): unittest.TestLoader().loadTestsFromTestCase( moduletest.ModuleTest ), unittest.TestLoader().loadTestsFromTestCase( diatest.DiaTest ), unittest.TestLoader().loadTestsFromTestCase( typeinfo.TypeInfoTest ), - unittest.TestLoader().loadTestsFromTestCase( dbgcmd.DbgcmdTest ) + unittest.TestLoader().loadTestsFromTestCase( dbgcmd.DbgcmdTest ), + unittest.TestLoader().loadTestsFromTestCase( clienttest.DbgClientTest ) ] ) else: return unittest.TestSuite( unittest.TestLoader().loadTestsFromName( singleName ) ) diff --git a/test/targetapp/targetapp.vcproj b/test/targetapp/targetapp.vcproj index f1e1fc9..f5ded62 100644 --- a/test/targetapp/targetapp.vcproj +++ b/test/targetapp/targetapp.vcproj @@ -404,6 +404,10 @@ RelativePath="..\scripts\basetest.py" > + +