mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-29 11:53:23 +08:00
[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:
parent
80acef377a
commit
4c6cb85197
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 );
|
||||
|
@ -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();
|
||||
|
@ -35,7 +35,7 @@ public:
|
||||
return m_size;
|
||||
}
|
||||
|
||||
ULONG getOffset() {
|
||||
ULONG64 getOffset() {
|
||||
return m_typeInfo->getOffset();
|
||||
}
|
||||
|
||||
|
@ -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<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,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;
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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 )
|
||||
|
@ -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() )
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user