From 4c6cb85197c2aad04fed4d173ce3b28171227a16 Mon Sep 17 00:00:00 2001 From: "SND\\kernelnet_cp" Date: Wed, 18 Apr 2012 07:39:33 +0000 Subject: [PATCH] [0.1.x] fixed : working with class static members ( static const is not supported yet ) git-svn-id: https://pykd.svn.codeplex.com/svn@75597 9b283d60-5439-405e-af05-b73fd8c4d996 --- pykd/dbgexcept.cpp | 1 + pykd/dbgexcept.h | 21 ++++++++ pykd/livevar.cpp | 2 +- pykd/module.h | 7 +++ pykd/pymod.cpp | 3 +- pykd/typedvar.cpp | 24 ++++++++- pykd/typedvar.h | 2 +- pykd/typeinfo.cpp | 96 +++++++++++++++++++++++------------- pykd/typeinfo.h | 42 +++++++++++++++- test/scripts/typedvar.py | 6 ++- test/scripts/typeinfo.py | 7 ++- test/targetapp/targetapp.cpp | 18 ++++++- 12 files changed, 183 insertions(+), 46 deletions(-) diff --git a/pykd/dbgexcept.cpp b/pykd/dbgexcept.cpp index 6e07b6a..4ed7e1f 100644 --- a/pykd/dbgexcept.cpp +++ b/pykd/dbgexcept.cpp @@ -14,6 +14,7 @@ python::handle<> exceptPyType::pyExceptType; python::handle<> exceptPyType::pyExceptType; python::handle<> exceptPyType::pyExceptType; python::handle<> exceptPyType::pyExceptType; +python::handle<> exceptPyType::pyExceptType; /////////////////////////////////////////////////////////////////////////////////// }; // end namespace pykd diff --git a/pykd/dbgexcept.h b/pykd/dbgexcept.h index 2fe51be..91b0b28 100644 --- a/pykd/dbgexcept.h +++ b/pykd/dbgexcept.h @@ -210,5 +210,26 @@ private: ///////////////////////////////////////////////////////////////////////////////// +class ImplementException : public DbgException +{ +public: + + ImplementException( const std::string &file, int line, const std::string &msg ) : + DbgException( buildDesc(file,line, msg) ) + {} + +private: + + std::string buildDesc( const std::string &file, int line, const std::string &msg ) + { + std::stringstream sstream; + sstream << "File: " << file << " Line: " << line << " " << msg; + return sstream.str(); + } + +}; + +///////////////////////////////////////////////////////////////////////////////// + }; // namespace pykd diff --git a/pykd/livevar.cpp b/pykd/livevar.cpp index bc57438..a1dc6aa 100644 --- a/pykd/livevar.cpp +++ b/pykd/livevar.cpp @@ -107,7 +107,7 @@ void addLocals::appendVar(pyDia::SymbolPtr symData) case LocIsEnregistered: // FIXME default: - throw Exception(); + throw ImplementException(__FILE__,__LINE__,"Fix ME"); } typedVar->setDataKind( symData->getDataKind() ); m_locals[varName] = typedVar; diff --git a/pykd/module.h b/pykd/module.h index 7fc6573..059a490 100644 --- a/pykd/module.h +++ b/pykd/module.h @@ -95,7 +95,14 @@ public: pyDia::GlobalScopePtr& getDia() { if (!m_dia) + { m_dia = pyDia::GlobalScope::loadPdb( getPdbName() ); + if ( m_dia ) + { + m_dia->setLoadAddress( m_base ); + } + } + return m_dia; } diff --git a/pykd/pymod.cpp b/pykd/pymod.cpp index 1ab5043..2d78b96 100644 --- a/pykd/pymod.cpp +++ b/pykd/pymod.cpp @@ -525,7 +525,7 @@ BOOST_PYTHON_MODULE( pykd ) .def("__init__", python::make_constructor(TypeInfo::getTypeInfoByName ) ) .def( "name", &TypeInfo::getName ) .def( "size", &TypeInfo::getSize ) - .def( "offset", &TypeInfo::getOffset ) + .def( "offset", &TypeInfo::getTypeOffset ) .def( "bitOffset", &TypeInfo::getBitOffset ) .def( "bitWidth", &TypeInfo::getBitWidth ) .def( "field", &TypeInfo::getField ) @@ -893,6 +893,7 @@ BOOST_PYTHON_MODULE( pykd ) pykd::exception( "DiaException", "Debug interface access exception" ); pykd::exception( "TypeException", "type exception" ); pykd::exception( "AddSynSymbolException", "synthetic symbol exception" ); + pykd::exception( "ImplementException", "implementation exception" ); DEF_PY_CONST_ULONG( DEBUG_CLASS_UNINITIALIZED ); DEF_PY_CONST_ULONG( DEBUG_CLASS_KERNEL ); diff --git a/pykd/typedvar.cpp b/pykd/typedvar.cpp index 78c4496..eca34ec 100644 --- a/pykd/typedvar.cpp +++ b/pykd/typedvar.cpp @@ -230,6 +230,14 @@ UdtTypedVar::getField( const std::string &fieldName ) { TypeInfoPtr fieldType = m_typeInfo->getField( fieldName ); + if ( fieldType->isStaticMember() ) + { + if ( fieldType->getStaticOffset() == 0 ) + throw ImplementException( __FILE__, __LINE__, "Fix ME"); + + return TypedVar::getTypedVar( m_client, fieldType, VarDataMemory::factory(m_dataSpaces, fieldType->getStaticOffset() ) ); + } + return TypedVar::getTypedVar( m_client, fieldType, m_varData->fork(fieldType->getOffset()) ); } @@ -244,9 +252,21 @@ std::string UdtTypedVar::print() for ( ULONG i = 0; i < m_typeInfo->getFieldCount(); ++i ) { TypeInfoPtr fieldType = m_typeInfo->getFieldByIndex(i); - TypedVarPtr fieldVar = TypedVar::getTypedVar( m_client, fieldType, m_varData->fork(fieldType->getOffset()) ); + TypedVarPtr fieldVar; - sstr << " +" << std::right << std::setw(4) << std::setfill('0') << std::hex << fieldType->getOffset(); + if ( fieldType->isStaticMember() ) + { + if ( fieldType->getStaticOffset() == 0 ) + throw ImplementException( __FILE__, __LINE__, "Fix ME"); + + fieldVar = TypedVar::getTypedVar( m_client, fieldType, VarDataMemory::factory(m_dataSpaces, fieldType->getStaticOffset() ) ); + sstr << " =" << std::right << std::setw(4) << std::setfill('0') << std::hex << fieldType->getStaticOffset(); + } + else + { + fieldVar = TypedVar::getTypedVar( m_client, fieldType, m_varData->fork(fieldType->getOffset()) ); + sstr << " +" << std::right << std::setw(4) << std::setfill('0') << std::hex << fieldType->getOffset(); + } sstr << " " << std::left << std::setw( 20 ) << std::setfill(' ') << m_typeInfo->getFieldNameByIndex(i) << ':'; sstr << " " << std::left << fieldType->getName(); sstr << " " << fieldVar->printValue(); diff --git a/pykd/typedvar.h b/pykd/typedvar.h index 3226543..01313cf 100644 --- a/pykd/typedvar.h +++ b/pykd/typedvar.h @@ -35,7 +35,7 @@ public: return m_size; } - ULONG getOffset() { + ULONG64 getOffset() { return m_typeInfo->getOffset(); } diff --git a/pykd/typeinfo.cpp b/pykd/typeinfo.cpp index e413424..1bd2833 100644 --- a/pykd/typeinfo.cpp +++ b/pykd/typeinfo.cpp @@ -123,7 +123,8 @@ TypeInfoPtr TypeInfo::getTypeInfo( pyDia::SymbolPtr &symScope, pyDia::SymbolPtr TypeInfoPtr ptr = getTypeInfo( symType ); - ptr->setConstant( constVal ); + if ( constVal.vt != VT_EMPTY ) + ptr->setConstant( constVal ); return ptr; } @@ -419,19 +420,6 @@ TypeInfoPtr TypeInfo::getComplexType( pyDia::SymbolPtr &symScope, const std::str } return getRecurciveComplexType( getTypeInfo( lowestSymbol ), std::string( matchResult[3].first, matchResult[3].second ), ptrSize ); - - - - //ULONG ptrSize = (symScope->getMachineType() == IMAGE_FILE_MACHINE_AMD64) ? 8 : 4; - - //boost::cmatch matchResult; - - //if ( !boost::regex_match( symName.c_str(), matchResult, typeMatch ) ) - // throw TypeException( symName, "type name is invalid" ); - - TypeInfoPtr lowestTypeInfo = getTypeInfo( symScope, std::string( matchResult[1].first, matchResult[1].second ) ); - - //return getRecurciveComplexType( lowestTypeInfo, std::string( matchResult[2].first, matchResult[2].second ), ptrSize ); } ///////////////////////////////////////////////////////////////////////////////////// @@ -496,47 +484,77 @@ TypeInfoPtr UdtTypeInfo::getField( const std::string &fieldName ) throw TypeException( m_dia->getName(), fieldName + ": field not found" ); TypeInfoPtr ti = TypeInfo::getTypeInfo( m_dia, field ); - ti->setOffset( addOffset + field->getOffset() ); + + switch( field->getDataKind() ) + { + case DataIsMember: + ti->setOffset( addOffset + field->getOffset() ); + break; + + case DataIsStaticMember: + ti->setStaticOffset( field->getVa() ); + break; + + default: + throw TypeException(m_dia->getName(), fieldName + ": unknown field type" ); + } + return ti; } + ///////////////////////////////////////////////////////////////////////////////////// TypeInfoPtr UdtTypeInfo::getFieldByIndex( ULONG index ) { - if ( index >= m_dia->getChildCount() ) - throw TypeException( m_dia->getName(), ": field not found" ); + std::string name = getFieldNameByIndex( index ); - pyDia::SymbolPtr field = m_dia->getChildByIndex(index); - - if ( !field ) - throw TypeException( m_dia->getName(), ": field not found" ); - - TypeInfoPtr ti = TypeInfo::getTypeInfo( m_dia, field ); - ti->setOffset( field->getOffset() ); - return ti; + return getField( name ); } ///////////////////////////////////////////////////////////////////////////////////// std::string UdtTypeInfo::getFieldNameByIndex( ULONG index ) { - if ( index >= m_dia->getChildCount() ) - throw TypeException( m_dia->getName(), ": field not found" ); + ULONG baseClassCount = m_dia->getChildCount(); - pyDia::SymbolPtr field = m_dia->getChildByIndex(index); + for ( ULONG i = 0; i < baseClassCount; ++i ) + { + pyDia::SymbolPtr baseSym = m_dia->getChildByIndex( i ); - if ( !field ) - throw TypeException( m_dia->getName(), ": field not found" ); + TypeInfoPtr baseType = TypeInfo::getTypeInfo( baseSym ); - return field->getName(); + ULONG baseFieldCount = baseType->getFieldCount(); + + if ( baseFieldCount > index ) + { + return baseType->getFieldNameByIndex( index ); + } + + index -= baseFieldCount; + } + + return m_dia->getChildByIndex( index )->getName(); } ///////////////////////////////////////////////////////////////////////////////////// ULONG UdtTypeInfo::getFieldCount() { - return m_dia->getChildCount(); + ULONG fieldCount = m_dia->getChildCount(); + + ULONG baseClassCount = m_dia->getChildCount(); + + for ( ULONG i = 0; i < baseClassCount; ++i ) + { + pyDia::SymbolPtr baseSym = m_dia->getChildByIndex( i ); + + TypeInfoPtr baseType = TypeInfo::getTypeInfo( baseSym ); + + fieldCount += baseType->getFieldCount(); + } + + return fieldCount; } ///////////////////////////////////////////////////////////////////////////////////// @@ -545,15 +563,23 @@ std::string UdtTypeInfo::print() { std::stringstream sstr; - sstr << "struct/class: " << getName() << "Size: 0x" << std::hex << getSize() << " (" << std::dec << getSize() << ")" << std::endl; + sstr << "struct/class: " << getName() << " Size: 0x" << std::hex << getSize() << " (" << std::dec << getSize() << ")" << std::endl; ULONG fieldCount = getFieldCount(); for ( ULONG i = 0; i < fieldCount; ++i ) - { + { TypeInfoPtr fieldType = getFieldByIndex(i); - sstr << " +" << std::right << std::setw(4) << std::setfill('0') << std::hex << fieldType->getOffset(); + if ( fieldType->isStaticMember() ) + { + sstr << " =" << std::right << std::setw(4) << std::setfill('0') << std::hex << fieldType->getStaticOffset(); + } + else + { + sstr << " +" << std::right << std::setw(4) << std::setfill('0') << std::hex << fieldType->getOffset(); + } + sstr << " " << std::left << std::setw( 20 ) << std::setfill(' ') << getFieldNameByIndex(i) << ':'; sstr << " " << std::left << fieldType->getName(); sstr << std::endl; diff --git a/pykd/typeinfo.h b/pykd/typeinfo.h index dce1066..6190ba5 100644 --- a/pykd/typeinfo.h +++ b/pykd/typeinfo.h @@ -38,6 +38,16 @@ public: public: + TypeInfo() : + m_offset( 0 ), + m_staticOffset( 0 ), + m_constant( false ), + m_staticMember( false ) + { + m_constantValue.vt = VT_EMPTY; + } + + virtual std::string print() { std::stringstream sstr; sstr << "Type name: " << getName(); @@ -115,8 +125,8 @@ public: throw TypeException( getName(), "type is not a pointer" ); } - ULONG getOffset() { - return m_offset; + ULONG getOffset() const { + return (ULONG)m_offset; } void setOffset( ULONG offset ) { @@ -129,6 +139,30 @@ public: m_constantValue = var; } + bool isConstant() const + { + return m_constant == true; + } + + bool isStaticMember() const + { + return m_staticMember == true; + } + + void setStaticOffset( ULONG64 offset ) { + m_staticOffset = offset; + m_staticMember = true; + } + + ULONG64 getStaticOffset() const { + return m_staticOffset; + } + + ULONG64 getTypeOffset() const { + return m_staticMember ? m_staticOffset : m_offset; + } + + protected: std::string getComplexName(); @@ -141,8 +175,12 @@ protected: ULONG m_offset; + ULONG64 m_staticOffset; + bool m_constant; + bool m_staticMember; + VARIANT m_constantValue; }; diff --git a/test/scripts/typedvar.py b/test/scripts/typedvar.py index ae224e5..9559e99 100644 --- a/test/scripts/typedvar.py +++ b/test/scripts/typedvar.py @@ -215,7 +215,6 @@ class TypedVarTest( unittest.TestCase ): self.assertEqual( tv1, tv2 ) self.assertTrue( tv1 ) - def testPrint(self): self.assertTrue( str(target.module.typedVar( "g_ucharValue" ) ) ) self.assertTrue( str(target.module.typedVar( "g_ushortValue" ) ) ) @@ -236,3 +235,8 @@ class TypedVarTest( unittest.TestCase ): self.assertTrue( str(target.module.typedVar( "g_voidPtr" ) ) ) self.assertTrue( str(target.module.typedVar( "g_arrOfPtrToFunc" ) ) ) self.assertTrue( str(target.module.typedVar( "g_unTypedPtrToFunction" ) ) ) + + def testStaticField(self): + ti = pykd.typedVar( "g_classChild" ) + self.assertEqual( 200, ti.m_staticField ) + self.assertEqual( 100, ti.m_staticConst ) diff --git a/test/scripts/typeinfo.py b/test/scripts/typeinfo.py index 9ca4712..4db44f0 100644 --- a/test/scripts/typeinfo.py +++ b/test/scripts/typeinfo.py @@ -178,4 +178,9 @@ class TypeInfoTest( unittest.TestCase ): def testTypedef(self): self.assertEqual( "structTest", pykd.typeInfo( "g_structTypeDef" ).name() ) self.assertEqual( "structTest", pykd.typeInfo( "structTestTypeDef" ).name() ) - + + def testStaticField(self): + ti = pykd.typeInfo( "g_classChild" ) + self.assertNotEqual( 0, ti.m_staticField.offset() ) + self.assertNotEqual( 0, ti.m_staticConst.offset() ) + self.assertNotEqual( 0, ti.m_stdstr.offset() ) diff --git a/test/targetapp/targetapp.cpp b/test/targetapp/targetapp.cpp index dcf414f..bcc6d04 100644 --- a/test/targetapp/targetapp.cpp +++ b/test/targetapp/targetapp.cpp @@ -58,6 +58,15 @@ public: virtual void virtFunc2() = 0; }; +class anotherBase { + static std::string m_stdstr; + ULONG m_count; +public: + anotherBase() : m_count( 1234 ){} +}; +std::string anotherBase::m_stdstr = "hello"; + + struct structTest { ULONG m_field0; ULONGLONG m_field1; @@ -116,11 +125,13 @@ const enumType g_constEnumThree = THREE; const ULONG g_constUlong = 0xffffff; const ULONGLONG g_constUlonglong = 0xffffff000000; -class classChild : public classBase { +class classChild : public classBase, public anotherBase { public: - static const int m_staticField = 100; + static const int m_staticConst = 100; + + static int m_staticField; public: int m_childField; @@ -136,6 +147,8 @@ public: {} }; +int classChild::m_staticField = 200; + classChild g_classChild; struct struct2 { @@ -307,6 +320,7 @@ void FuncWithName0() std::cout << ptrIntMatrix1; std::cout << g_bigValue; std::cout << g_classChild.m_enumField; + std::cout << g_classChild.m_staticConst; std::cout << g_constEnumThree; std::cout << g_constUlong; std::cout << g_constUlonglong;