diff --git a/pykd/dbgext.cpp b/pykd/dbgext.cpp index 787ed3a..a428d56 100644 --- a/pykd/dbgext.cpp +++ b/pykd/dbgext.cpp @@ -68,7 +68,6 @@ BOOST_PYTHON_MODULE( pykd ) .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", &pykd::loadDump, @@ -90,7 +89,9 @@ BOOST_PYTHON_MODULE( pykd ) python::class_("typeInfo", "Class representing typeInfo", python::no_init ) .def( "name", &pykd::TypeInfo::getName ) + .def( "size", &pykd::TypeInfo::getSize ) .def( "offset", &pykd::TypeInfo::getOffset ) + .def( "field", &pykd::TypeInfo::getField ) .def( "__getattr__", &pykd::TypeInfo::getField ); python::class_("module", "Class representing executable module", python::no_init ) @@ -328,7 +329,9 @@ WindbgGlobalSession::WindbgGlobalSession() { std::string key = boost::python::extract(iterkeys[i]); main_namespace[ key ] = pykd_namespace[ key ]; - } + } + + pyState = PyEval_SaveThread(); } @@ -370,6 +373,8 @@ py( PDEBUG_CLIENT4 client, PCSTR args ) DebugClientPtr dbgClient = DebugClient::createDbgClient( client ); DebugClientPtr oldClient = DebugClient::setDbgClientCurrent( dbgClient ); + WindbgGlobalSession::RestorePyState(); + PyThreadState *globalInterpreter = PyThreadState_Swap( NULL ); PyThreadState *localInterpreter = Py_NewInterpreter(); @@ -385,6 +390,8 @@ py( PDEBUG_CLIENT4 client, PCSTR args ) Py_EndInterpreter( localInterpreter ); PyThreadState_Swap( globalInterpreter ); + WindbgGlobalSession::SavePyState(); + DebugClient::setDbgClientCurrent( oldClient ); return S_OK; @@ -399,6 +406,8 @@ pycmd( PDEBUG_CLIENT4 client, PCSTR args ) DebugClientPtr dbgClient = DebugClient::createDbgClient( client ); DebugClientPtr oldClient = DebugClient::setDbgClientCurrent( dbgClient ); + WindbgGlobalSession::RestorePyState(); + try { @@ -408,9 +417,9 @@ pycmd( PDEBUG_CLIENT4 client, PCSTR args ) dbgClient->eprintln( "unexpected error" ); } - DebugClient::setDbgClientCurrent( oldClient ); + WindbgGlobalSession::SavePyState(); - return S_OK; + DebugClient::setDbgClientCurrent( oldClient ); return S_OK; } diff --git a/pykd/module.cpp b/pykd/module.cpp index ff30cbf..9ebb13b 100644 --- a/pykd/module.cpp +++ b/pykd/module.cpp @@ -157,7 +157,10 @@ Module::getTypeByName( const std::string typeName ) { pyDia::SymbolPtr typeSym = m_dia->getChildByName( typeName ); - return TypeInfo( typeSym ); + if ( typeSym->getSymTag() == SymTagData ) + return TypeInfo( typeSym->getType() ); + else + return TypeInfo( typeSym ); } /////////////////////////////////////////////////////////////////////////////////// diff --git a/pykd/module.h b/pykd/module.h index 770c958..51fcbec 100644 --- a/pykd/module.h +++ b/pykd/module.h @@ -88,6 +88,11 @@ private: + + + + + //#include //#include // diff --git a/pykd/typeinfo.h b/pykd/typeinfo.h index 9af2ea9..04bd248 100644 --- a/pykd/typeinfo.h +++ b/pykd/typeinfo.h @@ -35,12 +35,17 @@ public: getOffset() { return m_offset; } - + + ULONG64 + getSize() { + return m_dia->getSize(); + } + private: pyDia::SymbolPtr m_dia; - ULONG m_offset; + ULONG m_offset; }; /////////////////////////////////////////////////////////////////////////////////// diff --git a/pykd/windbg.h b/pykd/windbg.h index 88a8c53..c0c98fa 100644 --- a/pykd/windbg.h +++ b/pykd/windbg.h @@ -39,6 +39,18 @@ public: bool isInit() { return windbgGlobalSession != NULL; } + + static + VOID + RestorePyState() { + PyEval_RestoreThread( windbgGlobalSession->pyState ); + } + + static + VOID + SavePyState() { + windbgGlobalSession->pyState = PyEval_SaveThread(); + } private: @@ -50,6 +62,8 @@ private: python::object main; + PyThreadState *pyState; + static volatile LONG sessionCount; static WindbgGlobalSession *windbgGlobalSession; diff --git a/test/scripts/moduletest.py b/test/scripts/moduletest.py index b88d15f..c87087c 100644 --- a/test/scripts/moduletest.py +++ b/test/scripts/moduletest.py @@ -49,3 +49,7 @@ class ModuleTest( unittest.TestCase ): def testSymbol( self ): self.assertEqual( target.module.rva("FuncWithName0"), target.module.offset("FuncWithName0") - target.module.begin() ) self.assertEqual( target.module.rva("FuncWithName0"), target.module.FuncWithName0 - target.module.begin() ) + + def testType( self ): + self.assertEqual( "structTest", target.module.type("structTest").name() ); + self.assertEqual( "structTest", target.module.type("g_structTest").name() ); diff --git a/test/scripts/typeinfo.py b/test/scripts/typeinfo.py index b58ca1c..76b02aa 100644 --- a/test/scripts/typeinfo.py +++ b/test/scripts/typeinfo.py @@ -21,8 +21,8 @@ class TypeInfoTest( unittest.TestCase ): def testGetField( self ): """ get field of the complex type """ ti1 = target.module.type( "structTest" ) - self.assertNotEqual( None, ti1.m_field0 ) # exsisting field - try: ti1.m_field4 # non-exsisting field + self.assertTrue( hasattr( ti1, "m_field0" ) ) + try: hasattr(ti1, "m_field4" ) # non-exsisting field except pykd.DiaException: pass def testName( self ): @@ -36,5 +36,9 @@ class TypeInfoTest( unittest.TestCase ): self.assertEqual( 0, ti1.m_field0.offset() ) self.assertEqual( 4, ti1.m_field1.offset() ) self.assertEqual( 12, ti1.m_field2.offset() ) - self.assertEqual( 14, ti1.m_field3.offset() ) + self.assertEqual( 14, ti1.m_field3.offset() ) + + def testSize( self ): + ti1 = target.module.type( "structTest" ) + self.assertEqual( 16, ti1.size() ) diff --git a/test/targetapp/targetapp.cpp b/test/targetapp/targetapp.cpp index 339e987..befd05c 100644 --- a/test/targetapp/targetapp.cpp +++ b/test/targetapp/targetapp.cpp @@ -46,6 +46,8 @@ struct structTest { USHORT m_field3; }; +structTest g_structTest = { 0, 500, true, 1 }; + class classChild : public classBase { public: int m_childField; @@ -75,6 +77,8 @@ void FuncWithName0() std::cout << g_ushortValue; std::cout << g_ulongValue; std::cout << g_ulonglongValue; + + std::cout << g_structTest.m_field0; } void FuncWithName1(int a)