[0.1.x] added : pointer fields output for typedVar class

git-svn-id: https://pykd.svn.codeplex.com/svn@71146 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
SND\kernelnet_cp 2011-11-07 06:46:53 +00:00 committed by Mikhail I. Izmestev
parent cf1c1c5aca
commit d095c9dac0
8 changed files with 126 additions and 16 deletions

View File

@ -282,15 +282,14 @@ BOOST_PYTHON_MODULE( pykd )
"Return virtual address" )
.def("sizeof", &TypedVar::getSize,
"Return size of a variable in the target memory" )
.def("offset", &TypedVar::getOffset,
"Return offset to parent" )
.def("field", &TypedVar::getField,
"Return field of structure as an object attribute" )
.def("__getattr__", &TypedVar::getField,
"Return field of structure as an object attribute" )
.def( "__str__", &TypedVar::print );
//.def("data", &pykd::TypedVar::data,
// "Return raw string object with data stream" );
//.def("__getattr__", &pykd::TypedVar::getFieldWrap,
// "Return field of structure as an object attribute" );
python::class_<pykd::Module>("module", "Class representing executable module", python::no_init )
.def("begin", &pykd::Module::getBase,
"Return start address of the module" )
@ -312,10 +311,14 @@ BOOST_PYTHON_MODULE( pykd )
"Return rva of the symbol" )
.def("type", &pykd::Module::getTypeByName,
"Return typeInfo class by type name" )
.def("typedVar", &pykd::Module::getTypedVarByAddr,
"Return a typedVar class instance" )
//.def("typedVar", &pykd::Module::getTypedVarByAddr,
// "Return a typedVar class instance" )
.def("typedVar",&pykd::Module::getTypedVarByName,
"Return a typedVar class instance" )
.def("typedVar",&pykd::Module::getTypedVarByType,
"Return a typedVar class instance" )
.def("typedVar",&pykd::Module::getTypedVarByTypeName,
"Return a typedVar class instance" )
.def("__getattr__", &pykd::Module::getSymbol,
"Return address of the symbol" );

View File

@ -161,13 +161,21 @@ Module::getTypeByName( const std::string &typeName )
///////////////////////////////////////////////////////////////////////////////////
TypedVar
Module::getTypedVarByAddr( const std::string &typeName, ULONG64 addr )
Module::getTypedVarByTypeName( const std::string &typeName, ULONG64 addr )
{
return TypedVar( TypeInfo( m_dia, typeName ), addr );
}
///////////////////////////////////////////////////////////////////////////////////
TypedVar
Module::getTypedVarByType( const TypeInfo &typeInfo, ULONG64 addr )
{
return TypedVar( typeInfo, addr );
}
///////////////////////////////////////////////////////////////////////////////////
TypedVar
Module::getTypedVarByName( const std::string &symName )
{
@ -178,5 +186,32 @@ Module::getTypedVarByName( const std::string &symName )
///////////////////////////////////////////////////////////////////////////////////
//TypedVar
//Module::getTypedVarByAddr( ULONG64 addr )
//{
// addr = addr64(addr);
//
// if ( addr < m_base || addr > getEnd() )
// throw DbgException("address is out of the module space" );
//
// ULONG rva = (ULONG)(addr - m_base);
//
// for( ULONG i = 0; i < m_dia->getChildCount(); i++ )
// {
// pyDia::SymbolPtr typeSym = m_dia->getChildByIndex(i);
//
// std::string name = m_dia->getName();
//
// if ( typeSym->getSymTag() == SymTagData && typeSym->getRva() == rva )
// {
// return TypedVar( TypeInfo( typeSym->getType() ), typeSym->getRva() + m_base );
// }
// }
//
// throw DbgException("failed to find type info for this offset" );
//}
///////////////////////////////////////////////////////////////////////////////////
}; // end of namespace pykd

View File

@ -69,7 +69,11 @@ public:
TypeInfo getTypeByName( const std::string &typeName );
TypedVar getTypedVarByAddr( const std::string &typeName, ULONG64 addr );
TypedVar getTypedVarByTypeName( const std::string &typeName, ULONG64 addr );
TypedVar getTypedVarByType( const TypeInfo &typeInfo, ULONG64 addr );
TypedVar getTypedVarByAddr( ULONG64 addr );
TypedVar getTypedVarByName( const std::string &symName );

View File

@ -37,9 +37,22 @@ TypedVar::getField( const std::string &fieldName )
if ( fieldType.isBasicType() )
{
tv.reset( new BasicTypedVar( m_client, fieldType, m_offset + fieldType.getOffset() ) );
return tv;
}
else
throw DbgException( "can not get field" );
if ( fieldType.isPointer() )
{
tv.reset( new PtrTypedVar( m_client, fieldType, m_offset + fieldType.getOffset() ) );
return tv;
}
if ( fieldType.isUserDefined() )
{
tv.reset( new TypedVar( m_client, fieldType, m_offset + fieldType.getOffset() ) );
return tv;
}
throw DbgException( "can not get field" );
return tv;
}
@ -62,4 +75,19 @@ BasicTypedVar::getValue() const
///////////////////////////////////////////////////////////////////////////////////
ULONG64
PtrTypedVar::getValue() const
{
HRESULT hres;
ULONG64 val = 0;
hres = m_dataSpaces->ReadPointersVirtual( 1, m_offset, &val );
if ( FAILED( hres ) )
throw MemoryException( m_offset, false );
return val;
}
///////////////////////////////////////////////////////////////////////////////////
} // end pykd namespace

View File

@ -30,6 +30,10 @@ public:
return m_size;
}
ULONG getOffset() {
return m_typeInfo.getOffset();
}
TypeInfo
getType() const {
return m_typeInfo;
@ -81,4 +85,25 @@ public:
///////////////////////////////////////////////////////////////////////////////////
class PtrTypedVar : public TypedVar {
public:
PtrTypedVar ( IDebugClient4 *client, const TypeInfo& typeInfo, ULONG64 offset ) : TypedVar(client, typeInfo, offset){}
TypedVarPtr
virtual getField( const std::string &fieldName ) {
throw DbgException("no fields");
}
virtual std::string print() {
return "PtrTypedVar";
}
virtual ULONG64 getValue() const;
};
///////////////////////////////////////////////////////////////////////////////////
} // namespace pykd

View File

@ -18,13 +18,26 @@ class TypedVarTest( unittest.TestCase ):
def testGetSize( self ):
tv1 = target.module.typedVar( "structTest", target.module.g_structTest )
self.assertEqual( 16, tv1.sizeof() )
self.assertEqual( 20, tv1.sizeof() )
#tv2 = target.module.typedVar( "structTest[2]", target.module.g_testArray )
#self.assertEqual( tv1.sizeof()*2, tv2.sizeof() )
def testStruct(self):
tv1 = target.module.typedVar( "structTest", target.module.g_structTest )
self.assertEqual( 0, tv1.m_field0 + 0 )
self.assertEqual( 0, tv1.m_field0 )
self.assertEqual( 500, tv1.m_field1 )
self.assertEqual( True, tv1.m_field2 )
self.assertEqual( 1, tv1.m_field3 )
self.assertEqual( 1, tv1.m_field3 )
def testPtrField(self):
tv = target.module.typedVar( "g_structTest" )
self.assertEqual( 0, tv.m_field4 )
tv1 = target.module.typedVar( "g_structTest1" )
self.assertEqual( tv.getAddress(), tv1.m_field4 )
def testFieldOffset(self):
tv = target.module.typedVar( "g_structTest" )
self.assertEqual( 0, tv.m_field0.offset() )
self.assertEqual( 4, tv.m_field1.offset() )
self.assertEqual( 16, tv.m_field4.offset() )

View File

@ -48,5 +48,5 @@ class TypeInfoTest( unittest.TestCase ):
def testSize( self ):
ti1 = target.module.type( "structTest" )
self.assertEqual( 16, ti1.size() )
self.assertEqual( 20, ti1.size() )

View File

@ -44,9 +44,11 @@ struct structTest {
ULONGLONG m_field1;
bool m_field2;
USHORT m_field3;
structTest* m_field4;
};
structTest g_structTest = { 0, 500, true, 1 };
structTest g_structTest = { 0, 500, true, 1, NULL };
structTest g_structTest1 = { 0, 500, true, 1, &g_structTest };
structTest g_testArray[2] = { { 0, 500, true, 1 }, { 2, 1500, false, 1 } };