From 0d7d74677867efedba6afd0b9853ef4a415985dd Mon Sep 17 00:00:00 2001 From: "SND\\kernelnet_cp" Date: Tue, 4 Oct 2011 07:00:54 +0000 Subject: [PATCH] [0.1.x] added : typeInfo.name(), typeInfo.offset() git-svn-id: https://pykd.svn.codeplex.com/svn@70197 9b283d60-5439-405e-af05-b73fd8c4d996 --- pykd/dbgext.cpp | 15 +++++---------- pykd/diadata.cpp | 15 +++++++++++++++ pykd/diawrapper.cpp | 3 +++ pykd/diawrapper.h | 2 ++ pykd/typeinfo.h | 30 ++++++++++++++++++++++++++---- test/scripts/diatest.py | 23 ++++++++++++++++++++++- test/scripts/typeinfo.py | 22 +++++++++++++++++++++- test/targetapp/targetapp.cpp | 5 +++++ test/targetapp/targetapp.vcproj | 2 +- 9 files changed, 100 insertions(+), 17 deletions(-) diff --git a/pykd/dbgext.cpp b/pykd/dbgext.cpp index ccc31bb..787ed3a 100644 --- a/pykd/dbgext.cpp +++ b/pykd/dbgext.cpp @@ -87,10 +87,11 @@ BOOST_PYTHON_MODULE( pykd ) "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_("typeInfo", "Class representing typeInfo", python::no_init ); + + python::class_("typeInfo", "Class representing typeInfo", python::no_init ) + .def( "name", &pykd::TypeInfo::getName ) + .def( "offset", &pykd::TypeInfo::getOffset ) + .def( "__getattr__", &pykd::TypeInfo::getField ); python::class_("module", "Class representing executable module", python::no_init ) .def("begin", &pykd::Module::getBase, @@ -115,12 +116,6 @@ BOOST_PYTHON_MODULE( pykd ) "Return typeInfo class by type name" ) .def("__getattr__", &pykd::Module::getSymbol, "Return address of the symbol" ); - - - - //.def("symbols", &pykd::Module::getSymbols, - // "Return list of all symbols of the module" ); - python::def( "diaLoadPdb", &pyDia::GlobalScope::loadPdb, "Open pdb file for quering debug symbols. Return DiaSymbol of global scope"); diff --git a/pykd/diadata.cpp b/pykd/diadata.cpp index e8bd333..c29e75a 100644 --- a/pykd/diadata.cpp +++ b/pykd/diadata.cpp @@ -88,6 +88,21 @@ const Symbol::ValueNameEntry Symbol::basicTypeName[] = { const size_t Symbol::cntBasicTypeName = _countof(Symbol::basicTypeName); +std::string Symbol::getBasicTypeName( ULONG basicType ) +{ + for ( size_t i = 0; i < Symbol::cntBasicTypeName; ++i ) + { + if ( basicType == Symbol::basicTypeName[i].first ) + return std::string( Symbol::basicTypeName[i].second ); + } + + std::stringstream sstr; + + sstr << "faild to find basic type with index %d" << basicType; + + throw Exception( sstr.str() ); +} + //////////////////////////////////////////////////////////////////////////////// #define _DEF_UDT_KIND(x) Symbol::ValueNameEntry(Udt##x, #x) diff --git a/pykd/diawrapper.cpp b/pykd/diawrapper.cpp index d13bcbf..bdad74c 100644 --- a/pykd/diawrapper.cpp +++ b/pykd/diawrapper.cpp @@ -100,6 +100,9 @@ std::string Symbol::getName() return retValue.asStr(); } +std::string getBasicName(); + + //////////////////////////////////////////////////////////////////////////////// SymbolPtr Symbol::getType() diff --git a/pykd/diawrapper.h b/pykd/diawrapper.h index 3768cfd..93b0e85 100644 --- a/pykd/diawrapper.h +++ b/pykd/diawrapper.h @@ -160,6 +160,8 @@ public: static const ValueNameEntry amd64RegName[]; static const size_t cntAmd64RegName; + static std::string getBasicTypeName( ULONG basicType ); + protected: // Check symbols loop diff --git a/pykd/typeinfo.h b/pykd/typeinfo.h index 68abd9d..9af2ea9 100644 --- a/pykd/typeinfo.h +++ b/pykd/typeinfo.h @@ -12,13 +12,35 @@ class TypeInfo { public: TypeInfo( pyDia::SymbolPtr dia ) : - m_dia( dia ) + m_dia( dia ), + m_offset( 0 ) {} - + + TypeInfo + getField( const std::string &fieldName ) { + pyDia::SymbolPtr field = m_dia->getChildByName( fieldName ); + TypeInfo ti( field->getType() ); + ti.m_offset = field->getOffset(); + return ti; + } + + std::string + getName() { + return m_dia->isBasicType() ? + m_dia->getBasicTypeName( m_dia->getBaseType() ) : + m_dia->getName(); + } + + ULONG + getOffset() { + return m_offset; + } + private: - pyDia::SymbolPtr m_dia; - + pyDia::SymbolPtr m_dia; + + ULONG m_offset; }; /////////////////////////////////////////////////////////////////////////////////// diff --git a/test/scripts/diatest.py b/test/scripts/diatest.py index 8b932f4..ea5c835 100644 --- a/test/scripts/diatest.py +++ b/test/scripts/diatest.py @@ -93,7 +93,7 @@ class DiaTest( unittest.TestCase ): except pykd.DiaException as diaExcept: print diaExcept self.assertTrue(False) - + def testBasicType(self): try: gScope = pykd.diaLoadPdb( str(target.module.pdb()) ) @@ -102,9 +102,30 @@ class DiaTest( unittest.TestCase ): gScope["g_constBoolValue"].type().baseType() ) self.assertEqual( pykd.btULong, gScope["g_ulongValue"].type().baseType() ) + except pykd.DiaException as diaExcept: print diaExcept self.assertTrue(False) + + def testBasicName(self): + self.assertEqual( "NoType", pykd.diaBasicType[ pykd.btNoType ] ) + self.assertEqual( "Void", pykd.diaBasicType[ pykd.btVoid ] ) + self.assertEqual( "Char", pykd.diaBasicType[ pykd.btChar ] ) + self.assertEqual( "WChar", pykd.diaBasicType[ pykd.btWChar ] ) + self.assertEqual( "Int", pykd.diaBasicType[ pykd.btInt ] ) + self.assertEqual( "UInt", pykd.diaBasicType[ pykd.btUInt ] ) + self.assertEqual( "Float", pykd.diaBasicType[ pykd.btFloat ] ) + self.assertEqual( "BCD", pykd.diaBasicType[ pykd.btBCD ] ) + self.assertEqual( "Bool", pykd.diaBasicType[ pykd.btBool ] ) + self.assertEqual( "Long", pykd.diaBasicType[ pykd.btLong ] ) + self.assertEqual( "ULong", pykd.diaBasicType[ pykd.btULong ] ) + self.assertEqual( "Currency", pykd.diaBasicType[ pykd.btCurrency ] ) + self.assertEqual( "Date", pykd.diaBasicType[ pykd.btDate ] ) + self.assertEqual( "Variant", pykd.diaBasicType[ pykd.btVariant ] ) + self.assertEqual( "Complex", pykd.diaBasicType[ pykd.btComplex ] ) + self.assertEqual( "Bit", pykd.diaBasicType[ pykd.btBit ] ) + self.assertEqual( "BSTR", pykd.diaBasicType[ pykd.btBSTR ] ) + self.assertEqual( "Hresult", pykd.diaBasicType[ pykd.btHresult ] ) def testBits(self): try: diff --git a/test/scripts/typeinfo.py b/test/scripts/typeinfo.py index a9d0ef5..b58ca1c 100644 --- a/test/scripts/typeinfo.py +++ b/test/scripts/typeinfo.py @@ -17,4 +17,24 @@ class TypeInfoTest( unittest.TestCase ): """ creating typeInfo by the type name """ ti1 = target.module.type( "structTest" ) ti2 = target.module.type( "classChild" ) - + + 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 + except pykd.DiaException: pass + + def testName( self ): + ti1 = target.module.type( "classChild" ) + self.assertEqual( "classChild", ti1.name() ) + self.assertEqual( "Int", ti1.m_childField.name() ) + self.assertEqual( "structTest", ti1.m_childField3.name() ) + + def testOffset( self ): + ti1 = target.module.type( "structTest" ) + 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() ) + diff --git a/test/targetapp/targetapp.cpp b/test/targetapp/targetapp.cpp index e7ec9eb..339e987 100644 --- a/test/targetapp/targetapp.cpp +++ b/test/targetapp/targetapp.cpp @@ -7,6 +7,8 @@ #include "utils.h" +#pragma pack( push, 4 ) + const ULONG g_constNumValue = 0x5555; const bool g_constBoolValue = true; @@ -48,6 +50,7 @@ class classChild : public classBase { public: int m_childField; int m_childField2; + structTest m_childField3; void childMethod() const {} virtual void virtFunc() {} virtual void virtFunc2() {} @@ -89,6 +92,8 @@ void FuncWithName1(int a) std::cout << g_string; } +#pragma pack( pop ) + int _tmain(int argc, _TCHAR* argv[]) { try diff --git a/test/targetapp/targetapp.vcproj b/test/targetapp/targetapp.vcproj index ce54717..8f294ce 100644 --- a/test/targetapp/targetapp.vcproj +++ b/test/targetapp/targetapp.vcproj @@ -1,7 +1,7 @@