[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<TypeException>::pyExceptType;
python::handle<> exceptPyType<AddSyntheticSymbolException>::pyExceptType;
python::handle<> exceptPyType<ImplementException>::pyExceptType;
///////////////////////////////////////////////////////////////////////////////////
}; // 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

View File

@ -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;

View File

@ -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;
}

View File

@ -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<pyDia::Exception,SymbolException>( "DiaException", "Debug interface access exception" );
pykd::exception<TypeException,SymbolException>( "TypeException", "type 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_KERNEL );

View File

@ -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;
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();

View File

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

View File

@ -123,6 +123,7 @@ TypeInfoPtr TypeInfo::getTypeInfo( pyDia::SymbolPtr &symScope, pyDia::SymbolPtr
TypeInfoPtr ptr = getTypeInfo( symType );
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 );
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<SymTagData>() )
throw TypeException( m_dia->getName(), ": field not found" );
std::string name = getFieldNameByIndex( index );
pyDia::SymbolPtr field = m_dia->getChildByIndex<SymTagData>(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<SymTagData>() )
throw TypeException( m_dia->getName(), ": field not found" );
ULONG baseClassCount = m_dia->getChildCount<SymTagBaseClass>();
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 )
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<SymTagData>( index )->getName();
}
/////////////////////////////////////////////////////////////////////////////////////
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,7 +563,7 @@ 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();
@ -553,7 +571,15 @@ std::string UdtTypeInfo::print()
{
TypeInfoPtr fieldType = getFieldByIndex(i);
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;

View File

@ -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;
};

View File

@ -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 )

View File

@ -179,3 +179,8 @@ class TypeInfoTest( unittest.TestCase ):
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() )

View File

@ -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;