[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
This commit is contained in:
SND\kernelnet_cp 2012-04-18 07:39:33 +00:00 committed by Mikhail I. Izmestev
parent 80acef377a
commit 4c6cb85197
12 changed files with 183 additions and 46 deletions

View File

@ -14,6 +14,7 @@ python::handle<> exceptPyType<SymbolException>::pyExceptType;
python::handle<> exceptPyType<pyDia::Exception>::pyExceptType; python::handle<> exceptPyType<pyDia::Exception>::pyExceptType;
python::handle<> exceptPyType<TypeException>::pyExceptType; python::handle<> exceptPyType<TypeException>::pyExceptType;
python::handle<> exceptPyType<AddSyntheticSymbolException>::pyExceptType; python::handle<> exceptPyType<AddSyntheticSymbolException>::pyExceptType;
python::handle<> exceptPyType<ImplementException>::pyExceptType;
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
}; // end namespace pykd }; // end namespace pykd

View File

@ -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 }; // namespace pykd

View File

@ -107,7 +107,7 @@ void addLocals::appendVar(pyDia::SymbolPtr symData)
case LocIsEnregistered: // FIXME case LocIsEnregistered: // FIXME
default: default:
throw Exception(); throw ImplementException(__FILE__,__LINE__,"Fix ME");
} }
typedVar->setDataKind( symData->getDataKind() ); typedVar->setDataKind( symData->getDataKind() );
m_locals[varName] = typedVar; m_locals[varName] = typedVar;

View File

@ -95,7 +95,14 @@ public:
pyDia::GlobalScopePtr& getDia() { pyDia::GlobalScopePtr& getDia() {
if (!m_dia) if (!m_dia)
{
m_dia = pyDia::GlobalScope::loadPdb( getPdbName() ); m_dia = pyDia::GlobalScope::loadPdb( getPdbName() );
if ( m_dia )
{
m_dia->setLoadAddress( m_base );
}
}
return m_dia; return m_dia;
} }

View File

@ -525,7 +525,7 @@ BOOST_PYTHON_MODULE( pykd )
.def("__init__", python::make_constructor(TypeInfo::getTypeInfoByName ) ) .def("__init__", python::make_constructor(TypeInfo::getTypeInfoByName ) )
.def( "name", &TypeInfo::getName ) .def( "name", &TypeInfo::getName )
.def( "size", &TypeInfo::getSize ) .def( "size", &TypeInfo::getSize )
.def( "offset", &TypeInfo::getOffset ) .def( "offset", &TypeInfo::getTypeOffset )
.def( "bitOffset", &TypeInfo::getBitOffset ) .def( "bitOffset", &TypeInfo::getBitOffset )
.def( "bitWidth", &TypeInfo::getBitWidth ) .def( "bitWidth", &TypeInfo::getBitWidth )
.def( "field", &TypeInfo::getField ) .def( "field", &TypeInfo::getField )
@ -893,6 +893,7 @@ BOOST_PYTHON_MODULE( pykd )
pykd::exception<pyDia::Exception,SymbolException>( "DiaException", "Debug interface access exception" ); pykd::exception<pyDia::Exception,SymbolException>( "DiaException", "Debug interface access exception" );
pykd::exception<TypeException,SymbolException>( "TypeException", "type exception" ); pykd::exception<TypeException,SymbolException>( "TypeException", "type exception" );
pykd::exception<AddSyntheticSymbolException,DbgException>( "AddSynSymbolException", "synthetic symbol exception" ); pykd::exception<AddSyntheticSymbolException,DbgException>( "AddSynSymbolException", "synthetic symbol exception" );
pykd::exception<ImplementException,DbgException>( "ImplementException", "implementation exception" );
DEF_PY_CONST_ULONG( DEBUG_CLASS_UNINITIALIZED ); DEF_PY_CONST_ULONG( DEBUG_CLASS_UNINITIALIZED );
DEF_PY_CONST_ULONG( DEBUG_CLASS_KERNEL ); DEF_PY_CONST_ULONG( DEBUG_CLASS_KERNEL );

View File

@ -230,6 +230,14 @@ UdtTypedVar::getField( const std::string &fieldName )
{ {
TypeInfoPtr fieldType = m_typeInfo->getField( 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()) ); 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 ) for ( ULONG i = 0; i < m_typeInfo->getFieldCount(); ++i )
{ {
TypeInfoPtr fieldType = m_typeInfo->getFieldByIndex(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 << std::setw( 20 ) << std::setfill(' ') << m_typeInfo->getFieldNameByIndex(i) << ':';
sstr << " " << std::left << fieldType->getName(); sstr << " " << std::left << fieldType->getName();
sstr << " " << fieldVar->printValue(); sstr << " " << fieldVar->printValue();

View File

@ -35,7 +35,7 @@ public:
return m_size; return m_size;
} }
ULONG getOffset() { ULONG64 getOffset() {
return m_typeInfo->getOffset(); return m_typeInfo->getOffset();
} }

View File

@ -123,7 +123,8 @@ TypeInfoPtr TypeInfo::getTypeInfo( pyDia::SymbolPtr &symScope, pyDia::SymbolPtr
TypeInfoPtr ptr = getTypeInfo( symType ); TypeInfoPtr ptr = getTypeInfo( symType );
ptr->setConstant( constVal ); if ( constVal.vt != VT_EMPTY )
ptr->setConstant( constVal );
return ptr; 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 ); 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" ); throw TypeException( m_dia->getName(), fieldName + ": field not found" );
TypeInfoPtr ti = TypeInfo::getTypeInfo( m_dia, field ); 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; return ti;
} }
///////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////
TypeInfoPtr UdtTypeInfo::getFieldByIndex( ULONG index ) TypeInfoPtr UdtTypeInfo::getFieldByIndex( ULONG index )
{ {
if ( index >= m_dia->getChildCount<SymTagData>() ) std::string name = getFieldNameByIndex( index );
throw TypeException( m_dia->getName(), ": field not found" );
pyDia::SymbolPtr field = m_dia->getChildByIndex<SymTagData>(index); return getField( name );
if ( !field )
throw TypeException( m_dia->getName(), ": field not found" );
TypeInfoPtr ti = TypeInfo::getTypeInfo( m_dia, field );
ti->setOffset( field->getOffset() );
return ti;
} }
///////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////
std::string UdtTypeInfo::getFieldNameByIndex( ULONG index ) std::string UdtTypeInfo::getFieldNameByIndex( ULONG index )
{ {
if ( index >= m_dia->getChildCount<SymTagData>() ) ULONG baseClassCount = m_dia->getChildCount<SymTagBaseClass>();
throw TypeException( m_dia->getName(), ": field not found" );
pyDia::SymbolPtr field = m_dia->getChildByIndex<SymTagData>(index); for ( ULONG i = 0; i < baseClassCount; ++i )
{
pyDia::SymbolPtr baseSym = m_dia->getChildByIndex<SymTagBaseClass>( i );
if ( !field ) TypeInfoPtr baseType = TypeInfo::getTypeInfo( baseSym );
throw TypeException( m_dia->getName(), ": field not found" );
return field->getName(); ULONG baseFieldCount = baseType->getFieldCount();
if ( baseFieldCount > index )
{
return baseType->getFieldNameByIndex( index );
}
index -= baseFieldCount;
}
return m_dia->getChildByIndex<SymTagData>( index )->getName();
} }
///////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////
ULONG UdtTypeInfo::getFieldCount() ULONG UdtTypeInfo::getFieldCount()
{ {
return m_dia->getChildCount<SymTagData>(); ULONG fieldCount = m_dia->getChildCount<SymTagData>();
ULONG baseClassCount = m_dia->getChildCount<SymTagBaseClass>();
for ( ULONG i = 0; i < baseClassCount; ++i )
{
pyDia::SymbolPtr baseSym = m_dia->getChildByIndex<SymTagBaseClass>( i );
TypeInfoPtr baseType = TypeInfo::getTypeInfo( baseSym );
fieldCount += baseType->getFieldCount();
}
return fieldCount;
} }
///////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////
@ -545,15 +563,23 @@ std::string UdtTypeInfo::print()
{ {
std::stringstream sstr; 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(); ULONG fieldCount = getFieldCount();
for ( ULONG i = 0; i < fieldCount; ++i ) for ( ULONG i = 0; i < fieldCount; ++i )
{ {
TypeInfoPtr fieldType = getFieldByIndex(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 << std::setw( 20 ) << std::setfill(' ') << getFieldNameByIndex(i) << ':';
sstr << " " << std::left << fieldType->getName(); sstr << " " << std::left << fieldType->getName();
sstr << std::endl; sstr << std::endl;

View File

@ -38,6 +38,16 @@ public:
public: public:
TypeInfo() :
m_offset( 0 ),
m_staticOffset( 0 ),
m_constant( false ),
m_staticMember( false )
{
m_constantValue.vt = VT_EMPTY;
}
virtual std::string print() { virtual std::string print() {
std::stringstream sstr; std::stringstream sstr;
sstr << "Type name: " << getName(); sstr << "Type name: " << getName();
@ -115,8 +125,8 @@ public:
throw TypeException( getName(), "type is not a pointer" ); throw TypeException( getName(), "type is not a pointer" );
} }
ULONG getOffset() { ULONG getOffset() const {
return m_offset; return (ULONG)m_offset;
} }
void setOffset( ULONG offset ) { void setOffset( ULONG offset ) {
@ -129,6 +139,30 @@ public:
m_constantValue = var; 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: protected:
std::string getComplexName(); std::string getComplexName();
@ -141,8 +175,12 @@ protected:
ULONG m_offset; ULONG m_offset;
ULONG64 m_staticOffset;
bool m_constant; bool m_constant;
bool m_staticMember;
VARIANT m_constantValue; VARIANT m_constantValue;
}; };

View File

@ -215,7 +215,6 @@ class TypedVarTest( unittest.TestCase ):
self.assertEqual( tv1, tv2 ) self.assertEqual( tv1, tv2 )
self.assertTrue( tv1 ) self.assertTrue( tv1 )
def testPrint(self): def testPrint(self):
self.assertTrue( str(target.module.typedVar( "g_ucharValue" ) ) ) self.assertTrue( str(target.module.typedVar( "g_ucharValue" ) ) )
self.assertTrue( str(target.module.typedVar( "g_ushortValue" ) ) ) 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_voidPtr" ) ) )
self.assertTrue( str(target.module.typedVar( "g_arrOfPtrToFunc" ) ) ) self.assertTrue( str(target.module.typedVar( "g_arrOfPtrToFunc" ) ) )
self.assertTrue( str(target.module.typedVar( "g_unTypedPtrToFunction" ) ) ) 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 )

View File

@ -178,4 +178,9 @@ class TypeInfoTest( unittest.TestCase ):
def testTypedef(self): def testTypedef(self):
self.assertEqual( "structTest", pykd.typeInfo( "g_structTypeDef" ).name() ) self.assertEqual( "structTest", pykd.typeInfo( "g_structTypeDef" ).name() )
self.assertEqual( "structTest", pykd.typeInfo( "structTestTypeDef" ).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() )

View File

@ -58,6 +58,15 @@ public:
virtual void virtFunc2() = 0; 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 { struct structTest {
ULONG m_field0; ULONG m_field0;
ULONGLONG m_field1; ULONGLONG m_field1;
@ -116,11 +125,13 @@ const enumType g_constEnumThree = THREE;
const ULONG g_constUlong = 0xffffff; const ULONG g_constUlong = 0xffffff;
const ULONGLONG g_constUlonglong = 0xffffff000000; const ULONGLONG g_constUlonglong = 0xffffff000000;
class classChild : public classBase { class classChild : public classBase, public anotherBase {
public: public:
static const int m_staticField = 100; static const int m_staticConst = 100;
static int m_staticField;
public: public:
int m_childField; int m_childField;
@ -136,6 +147,8 @@ public:
{} {}
}; };
int classChild::m_staticField = 200;
classChild g_classChild; classChild g_classChild;
struct struct2 { struct struct2 {
@ -307,6 +320,7 @@ void FuncWithName0()
std::cout << ptrIntMatrix1; std::cout << ptrIntMatrix1;
std::cout << g_bigValue; std::cout << g_bigValue;
std::cout << g_classChild.m_enumField; std::cout << g_classChild.m_enumField;
std::cout << g_classChild.m_staticConst;
std::cout << g_constEnumThree; std::cout << g_constEnumThree;
std::cout << g_constUlong; std::cout << g_constUlong;
std::cout << g_constUlonglong; std::cout << g_constUlonglong;