mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-21 04:13:22 +08:00
[0.1.x] fixed : issue #10767 ( typeInfo raises symbolException for classes with diamond virtual inheritance )
git-svn-id: https://pykd.svn.codeplex.com/svn@76514 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
parent
2527901eed
commit
d1a30dc6b0
@ -174,10 +174,27 @@ ULONG Symbol::getCount()
|
||||
|
||||
int Symbol::getVirtualBasePointerOffset()
|
||||
{
|
||||
return callSymbol( get_virtualBasePointerOffset);
|
||||
return callSymbol(get_virtualBasePointerOffset);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ULONG Symbol::getVirtualBaseDispIndex()
|
||||
{
|
||||
return callSymbol(get_virtualBaseDispIndex);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ULONG Symbol::getVirtualBaseDispSize()
|
||||
{
|
||||
SymbolPtr baseTableType = SymbolPtr( new Symbol( callSymbol(get_virtualBaseTableType), m_machineType ) );
|
||||
|
||||
return (ULONG)baseTableType->getType()->getSize();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Symbol::getValueImpl(IDiaSymbol *_symbol, VARIANT &vtValue)
|
||||
{
|
||||
HRESULT hres = _symbol->get_value(&vtValue);
|
||||
|
@ -162,6 +162,10 @@ public:
|
||||
|
||||
int getVirtualBasePointerOffset();
|
||||
|
||||
ULONG getVirtualBaseDispIndex();
|
||||
|
||||
ULONG getVirtualBaseDispSize();
|
||||
|
||||
public:
|
||||
typedef std::pair<ULONG, const char *> ValueNameEntry;
|
||||
|
||||
|
@ -238,7 +238,34 @@ UdtTypedVar::getField( const std::string &fieldName )
|
||||
return TypedVar::getTypedVar( m_client, fieldType, VarDataMemory::factory(m_dataSpaces, fieldType->getStaticOffset() ) );
|
||||
}
|
||||
|
||||
return TypedVar::getTypedVar( m_client, fieldType, m_varData->fork(fieldType->getOffset()) );
|
||||
ULONG fieldOffset = 0;
|
||||
|
||||
fieldOffset = fieldType->getOffset();
|
||||
|
||||
if ( fieldType->isVirtualMember() )
|
||||
{
|
||||
fieldOffset += getVirtualBaseDisplacement( fieldType );
|
||||
}
|
||||
|
||||
return TypedVar::getTypedVar( m_client, fieldType, m_varData->fork(fieldOffset) );
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
LONG UdtTypedVar::getVirtualBaseDisplacement( TypeInfoPtr& typeInfo )
|
||||
{
|
||||
ULONG virtualBasePtr, virtualDispIndex, virtualDispSize;
|
||||
typeInfo->getVirtualDisplacement( virtualBasePtr, virtualDispIndex, virtualDispSize );
|
||||
|
||||
ULONG64 vbtableOffset = m_varData->fork( virtualBasePtr )->readPtr();
|
||||
|
||||
VarDataPtr vbtable = VarDataMemory::factory(m_dataSpaces, vbtableOffset);
|
||||
|
||||
LONG displacement = 0;
|
||||
|
||||
vbtable->read( &displacement, sizeof(displacement), virtualDispIndex*virtualDispSize );
|
||||
|
||||
return virtualBasePtr + displacement;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
@ -264,8 +291,15 @@ std::string UdtTypedVar::print()
|
||||
}
|
||||
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();
|
||||
ULONG fieldOffset = fieldType->getOffset();
|
||||
|
||||
if ( fieldType->isVirtualMember() )
|
||||
{
|
||||
fieldOffset += getVirtualBaseDisplacement( fieldType );
|
||||
}
|
||||
|
||||
fieldVar = TypedVar::getTypedVar( m_client, fieldType, m_varData->fork(fieldOffset) );
|
||||
sstr << " +" << std::right << std::setw(4) << std::setfill('0') << std::hex << fieldOffset;
|
||||
sstr << " " << std::left << std::setw(24) << std::setfill(' ') << m_typeInfo->getFieldNameByIndex(i) << ':';
|
||||
}
|
||||
|
||||
|
@ -177,6 +177,8 @@ public:
|
||||
virtual std::string printValue();
|
||||
|
||||
virtual TypedVarPtr getField( const std::string &fieldName );
|
||||
|
||||
LONG getVirtualBaseDisplacement( TypeInfoPtr& typeInfo );
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -475,10 +475,39 @@ TypeInfoPtr TypeInfo::getRecurciveComplexType( TypeInfoPtr &lowestType, std::str
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ULONG64 TypeInfo::getStaticOffset() {
|
||||
if ( !m_staticMember )
|
||||
throw TypeException( getName(), "This is not a static member" );
|
||||
|
||||
return m_staticOffset;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ULONG TypeInfo::getOffset() {
|
||||
|
||||
if ( m_staticOffset )
|
||||
throw TypeException( getName(), "This is a static member" );
|
||||
|
||||
return m_offset;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ULONG64 TypeInfo::getTypeOffset()
|
||||
{
|
||||
return m_staticMember ? m_staticOffset : m_offset;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TypeInfoPtr UdtTypeInfo::getField( const std::string &fieldName )
|
||||
{
|
||||
if ( m_fields.empty() )
|
||||
getFields( m_dia );
|
||||
{
|
||||
getFields( m_dia, pyDia::SymbolPtr() );
|
||||
getVirtualFields();
|
||||
}
|
||||
|
||||
FieldList::reverse_iterator it;
|
||||
|
||||
@ -495,7 +524,10 @@ TypeInfoPtr UdtTypeInfo::getField( const std::string &fieldName )
|
||||
TypeInfoPtr UdtTypeInfo::getFieldByIndex( ULONG index )
|
||||
{
|
||||
if ( m_fields.empty() )
|
||||
getFields( m_dia );
|
||||
{
|
||||
getFields( m_dia, pyDia::SymbolPtr() );
|
||||
getVirtualFields();
|
||||
}
|
||||
|
||||
return m_fields[ index ].second;
|
||||
}
|
||||
@ -505,7 +537,10 @@ TypeInfoPtr UdtTypeInfo::getFieldByIndex( ULONG index )
|
||||
std::string UdtTypeInfo::getFieldNameByIndex( ULONG index )
|
||||
{
|
||||
if ( m_fields.empty() )
|
||||
getFields( m_dia);
|
||||
{
|
||||
getFields( m_dia, pyDia::SymbolPtr() );
|
||||
getVirtualFields();
|
||||
}
|
||||
|
||||
return m_fields[ index ].first;
|
||||
}
|
||||
@ -515,14 +550,23 @@ std::string UdtTypeInfo::getFieldNameByIndex( ULONG index )
|
||||
ULONG UdtTypeInfo::getFieldCount()
|
||||
{
|
||||
if ( m_fields.empty() )
|
||||
getFields( m_dia );
|
||||
{
|
||||
getFields( m_dia, pyDia::SymbolPtr() );
|
||||
getVirtualFields();
|
||||
}
|
||||
|
||||
return (ULONG)m_fields.size();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void UdtTypeInfo::getFields( pyDia::SymbolPtr &rootSym, ULONG startOffset )
|
||||
void UdtTypeInfo::getFields(
|
||||
pyDia::SymbolPtr &rootSym,
|
||||
pyDia::SymbolPtr &baseVirtualSym,
|
||||
ULONG startOffset,
|
||||
LONG virtualBasePtr,
|
||||
ULONG virtualDispIndex,
|
||||
ULONG virtualDispSize )
|
||||
{
|
||||
ULONG childCount = rootSym->getChildCount();
|
||||
|
||||
@ -536,18 +580,29 @@ void UdtTypeInfo::getFields( pyDia::SymbolPtr &rootSym, ULONG startOffset )
|
||||
{
|
||||
if ( !childSym->isVirtualBaseClass() )
|
||||
{
|
||||
getFields( childSym, startOffset + childSym->getOffset() );
|
||||
getFields( childSym, pyDia::SymbolPtr(), startOffset + childSym->getOffset() );
|
||||
}
|
||||
}
|
||||
else
|
||||
if ( symTag == SymTagData )
|
||||
{
|
||||
TypeInfoPtr ti = TypeInfo::getTypeInfo( m_dia, childSym );
|
||||
TypeInfoPtr ti = TypeInfo::getTypeInfo( rootSym, childSym );
|
||||
|
||||
switch ( childSym->getDataKind() )
|
||||
{
|
||||
case DataIsMember:
|
||||
|
||||
if ( baseVirtualSym )
|
||||
{
|
||||
ti->setVirtualBase(
|
||||
TypeInfo::getTypeInfo(baseVirtualSym),
|
||||
virtualBasePtr,
|
||||
virtualDispIndex,
|
||||
virtualDispSize );
|
||||
}
|
||||
|
||||
ti->setOffset( startOffset + childSym->getOffset() );
|
||||
|
||||
break;
|
||||
|
||||
case DataIsStaticMember:
|
||||
@ -560,15 +615,41 @@ void UdtTypeInfo::getFields( pyDia::SymbolPtr &rootSym, ULONG startOffset )
|
||||
else
|
||||
if ( symTag == SymTagVTable )
|
||||
{
|
||||
TypeInfoPtr ti = TypeInfo::getTypeInfo( m_dia, childSym );
|
||||
if ( !baseVirtualSym )
|
||||
{
|
||||
TypeInfoPtr ti = TypeInfo::getTypeInfo( rootSym, childSym );
|
||||
|
||||
m_fields.push_back( std::make_pair( "__VFN_table", ti ) );
|
||||
m_fields.push_back( std::make_pair( "__VFN_table", ti ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void UdtTypeInfo::getVirtualFields()
|
||||
{
|
||||
ULONG childCount = m_dia->getChildCount<SymTagBaseClass>();
|
||||
|
||||
for ( ULONG i = 0; i < childCount; ++i )
|
||||
{
|
||||
pyDia::SymbolPtr childSym = m_dia->getChildByIndex( i );
|
||||
|
||||
if ( !childSym->isVirtualBaseClass() )
|
||||
continue;
|
||||
|
||||
getFields(
|
||||
childSym,
|
||||
childSym,
|
||||
0,
|
||||
childSym->getVirtualBasePointerOffset(),
|
||||
childSym->getVirtualBaseDispIndex(),
|
||||
childSym->getVirtualBaseDispSize() );
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::string UdtTypeInfo::print()
|
||||
{
|
||||
std::stringstream sstr;
|
||||
@ -587,6 +668,16 @@ std::string UdtTypeInfo::print()
|
||||
sstr << " " << std::left << std::setw(18) << std::setfill(' ') << getFieldNameByIndex(i) << ':';
|
||||
}
|
||||
else
|
||||
if ( fieldType->isVirtualMember() )
|
||||
{
|
||||
ULONG virtualBasePtr, virtualDispIndex, virtualDispSize;
|
||||
fieldType->getVirtualDisplacement( virtualBasePtr, virtualDispIndex, virtualDispSize );
|
||||
|
||||
sstr << " virtual base " << fieldType->getVirtualBase()->getName();
|
||||
sstr << " +" << std::right << std::setw(4) << std::setfill('0') << std::hex << fieldType->getOffset();
|
||||
sstr << " " << getFieldNameByIndex(i) << ':';
|
||||
}
|
||||
else
|
||||
{
|
||||
sstr << " +" << std::right << std::setw(4) << std::setfill('0') << std::hex << fieldType->getOffset();
|
||||
sstr << " " << std::left << std::setw(24) << std::setfill(' ') << getFieldNameByIndex(i) << ':';
|
||||
|
@ -42,12 +42,15 @@ public:
|
||||
m_offset( 0 ),
|
||||
m_staticOffset( 0 ),
|
||||
m_constant( false ),
|
||||
m_staticMember( false )
|
||||
m_staticMember( false ),
|
||||
m_virtualMember( false ),
|
||||
m_virtualBasePtr( 0 ),
|
||||
m_virtualDispIndex( 0 ),
|
||||
m_virtualDispSize( 0 )
|
||||
{
|
||||
m_constantValue.vt = VT_EMPTY;
|
||||
}
|
||||
|
||||
|
||||
virtual std::string print() {
|
||||
std::stringstream sstr;
|
||||
sstr << "Type name: " << getName();
|
||||
@ -125,10 +128,6 @@ public:
|
||||
throw TypeException( getName(), "type is not a pointer" );
|
||||
}
|
||||
|
||||
ULONG getOffset() const {
|
||||
return (ULONG)m_offset;
|
||||
}
|
||||
|
||||
void setOffset( ULONG offset ) {
|
||||
m_offset = offset;
|
||||
}
|
||||
@ -138,7 +137,6 @@ public:
|
||||
m_constant = true;
|
||||
m_constantValue = var;
|
||||
}
|
||||
|
||||
bool isConstant() const
|
||||
{
|
||||
return m_constant == true;
|
||||
@ -149,19 +147,40 @@ public:
|
||||
return m_staticMember == true;
|
||||
}
|
||||
|
||||
bool isVirtualMember() const
|
||||
{
|
||||
return m_virtualMember == true;
|
||||
}
|
||||
|
||||
void setStaticOffset( ULONG64 offset ) {
|
||||
m_staticOffset = offset;
|
||||
m_staticMember = true;
|
||||
}
|
||||
|
||||
ULONG64 getStaticOffset() const {
|
||||
return m_staticOffset;
|
||||
void setVirtualBase( TypeInfoPtr virtualBase, LONG virtualBasePtr, ULONG virtualDispIndex, ULONG virtualDispSize )
|
||||
{
|
||||
m_virtualMember = true;
|
||||
m_virtualBaseType = virtualBase;
|
||||
m_virtualBasePtr = virtualBasePtr;
|
||||
m_virtualDispIndex = virtualDispIndex;
|
||||
m_virtualDispSize = virtualDispSize;
|
||||
}
|
||||
|
||||
ULONG64 getTypeOffset() const {
|
||||
return m_staticMember ? m_staticOffset : m_offset;
|
||||
}
|
||||
ULONG64 getTypeOffset();
|
||||
|
||||
ULONG getOffset();
|
||||
|
||||
ULONG64 getStaticOffset();
|
||||
|
||||
void getVirtualDisplacement( ULONG &virtualBasePtr, ULONG &virtualDispIndex, ULONG &virtualDispSize ) {
|
||||
virtualBasePtr = m_virtualBasePtr;
|
||||
virtualDispIndex = m_virtualDispIndex;
|
||||
virtualDispSize = m_virtualDispSize;
|
||||
};
|
||||
|
||||
TypeInfoPtr getVirtualBase() {
|
||||
return m_virtualBaseType;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
@ -181,7 +200,17 @@ protected:
|
||||
|
||||
bool m_staticMember;
|
||||
|
||||
bool m_virtualMember;
|
||||
|
||||
VARIANT m_constantValue;
|
||||
|
||||
LONG m_virtualBasePtr;
|
||||
|
||||
ULONG m_virtualDispIndex;
|
||||
|
||||
ULONG m_virtualDispSize;
|
||||
|
||||
TypeInfoPtr m_virtualBaseType;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
@ -290,7 +319,16 @@ protected:
|
||||
|
||||
FieldList m_fields;
|
||||
|
||||
void getFields( pyDia::SymbolPtr &rootSym, ULONG startOffset = 0 );
|
||||
void getFields(
|
||||
pyDia::SymbolPtr &rootSym,
|
||||
pyDia::SymbolPtr &baseVirtualSym,
|
||||
ULONG startOffset = 0,
|
||||
LONG virtualBasePtr = 0,
|
||||
ULONG virtualDispIndex = 0,
|
||||
ULONG m_virtualDispSize = 0 );
|
||||
|
||||
|
||||
void getVirtualFields();
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -248,7 +248,6 @@ class TypedVarTest( unittest.TestCase ):
|
||||
|
||||
def testDiamondVirtualInherit(self):
|
||||
tv = pykd.typedVar( "g_virtChild" )
|
||||
print tv
|
||||
self.assertEqual( -100, tv.m_baseField )
|
||||
|
||||
def testDinkumwareMap(self):
|
||||
|
@ -335,10 +335,12 @@ public:
|
||||
virtual void virtFunc2() {}
|
||||
};
|
||||
|
||||
class VirtualChildClass : public VirtualBaseClass1, public VirtualBaseClass2, public virtual classBase
|
||||
class VirtualChildClass : public VirtualBaseClass1, public VirtualBaseClass2
|
||||
{
|
||||
void virtFunc() {}
|
||||
void virtFunc2() {}
|
||||
|
||||
void virtual virtFunc3() {}
|
||||
};
|
||||
|
||||
VirtualChildClass g_virtChild;
|
||||
@ -426,7 +428,7 @@ void FuncWithName0()
|
||||
|
||||
std::cout << g_structTypeDef.m_field0;
|
||||
|
||||
std::cout << g_virtChild.VirtualBaseClass1::m_baseField;
|
||||
//std::cout << g_virtChild.VirtualBaseClass1::m_baseField;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
Loading…
Reference in New Issue
Block a user