[0.1.x] added : array field for typedVar class

git-svn-id: https://pykd.svn.codeplex.com/svn@71476 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
SND\kernelnet_cp 2011-11-18 16:00:25 +00:00 committed by Mikhail I. Izmestev
parent 1e57a6df5c
commit 43660d5617
9 changed files with 158 additions and 6 deletions

View File

@ -5,6 +5,32 @@
namespace pykd { namespace pykd {
/////////////////////////////////////////////////////////////////////////////////
class PyException
{
public:
PyException( PyObject* pyObj, const std::string &desc ) :
m_typeObj( pyObj ),
m_desc( desc )
{}
static
void
exceptionTranslate(const PyException &e ) {
PyErr_SetString( e.m_typeObj, e.m_desc.c_str() );
}
private:
PyObject* m_typeObj;
std::string m_desc;
};
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
class DbgException : public std::exception class DbgException : public std::exception

View File

@ -386,7 +386,9 @@ BOOST_PYTHON_MODULE( pykd )
"Return field of structure as an object attribute" ) "Return field of structure as an object attribute" )
.def("__getattr__", &TypedVar::getField, .def("__getattr__", &TypedVar::getField,
"Return field of structure as an object attribute" ) "Return field of structure as an object attribute" )
.def( "__str__", &TypedVar::print ); .def( "__str__", &TypedVar::print )
.def("__len__", &TypedVar::getElementCount )
.def("__getitem__", &TypedVar::getElementByIndex );
python::class_<pykd::Module>("module", "Class representing executable module", python::no_init ) python::class_<pykd::Module>("module", "Class representing executable module", python::no_init )
.def("begin", &pykd::Module::getBase, .def("begin", &pykd::Module::getBase,
@ -625,6 +627,9 @@ BOOST_PYTHON_MODULE( pykd )
// exception: // exception:
// wrapper for standart python exceptions
python::register_exception_translator<pykd::PyException>( &PyException::exceptionTranslate );
// base exception // base exception
python::class_<pykd::DbgException> dbgExceptionClass( "BaseException", python::class_<pykd::DbgException> dbgExceptionClass( "BaseException",
"Pykd base exception class", "Pykd base exception class",

View File

@ -38,6 +38,10 @@ public:
return ss.str(); return ss.str();
} }
template <class T>
bool operator!=(T const& rhs)
{ return getValue() == rhs }
template <class T> template <class T>
intBase& operator+=(T const& rhs) intBase& operator+=(T const& rhs)
{ setValue( getValue() + rhs ); return *this; } { setValue( getValue() + rhs ); return *this; }

View File

@ -7,6 +7,41 @@ namespace pykd {
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
TypedVarPtr TypedVar::getTypedVar( IDebugClient4 *client, const TypeInfoPtr& typeInfo, ULONG64 offset )
{
TypedVarPtr tv;
if ( typeInfo->isBasicType() )
{
tv.reset( new BasicTypedVar( client, typeInfo, offset) );
return tv;
}
if ( typeInfo->isPointer() )
{
tv.reset( new PtrTypedVar( client, typeInfo, offset ) );
return tv;
}
if ( typeInfo->isArray() )
{
tv.reset( new ArrayTypedVar( client, typeInfo, offset ) );
return tv;
}
if ( typeInfo->isUserDefined() )
{
tv.reset( new TypedVar( client, typeInfo, offset ) );
return tv;
}
throw DbgException( "can not get field" );
return tv;
}
///////////////////////////////////////////////////////////////////////////////////
TypedVar::TypedVar ( IDebugClient4 *client, const TypeInfoPtr& typeInfo, ULONG64 offset ) : TypedVar::TypedVar ( IDebugClient4 *client, const TypeInfoPtr& typeInfo, ULONG64 offset ) :
DbgObject( client ), DbgObject( client ),
m_typeInfo( typeInfo ), m_typeInfo( typeInfo ),
@ -46,6 +81,12 @@ TypedVar::getField( const std::string &fieldName )
return tv; return tv;
} }
if ( fieldType->isArray() )
{
tv.reset( new ArrayTypedVar( m_client, fieldType, m_offset + fieldType->getOffset() ) );
return tv;
}
if ( fieldType->isUserDefined() ) if ( fieldType->isUserDefined() )
{ {
tv.reset( new TypedVar( m_client, fieldType, m_offset + fieldType->getOffset() ) ); tv.reset( new TypedVar( m_client, fieldType, m_offset + fieldType->getOffset() ) );

View File

@ -3,6 +3,7 @@
#include "typeinfo.h" #include "typeinfo.h"
#include "intbase.h" #include "intbase.h"
#include "dbgobj.h" #include "dbgobj.h"
#include "dbgexcept.h"
namespace pykd { namespace pykd {
@ -17,6 +18,8 @@ class TypedVar : public intBase, protected DbgObject {
public: public:
static TypedVarPtr getTypedVar( IDebugClient4 *client, const TypeInfoPtr& typeInfo, ULONG64 offset );
TypedVar ( const TypeInfoPtr& typeInfo, ULONG64 offset ); TypedVar ( const TypeInfoPtr& typeInfo, ULONG64 offset );
@ -45,6 +48,14 @@ public:
return "TypeVar"; return "TypeVar";
} }
virtual ULONG getElementCount() {
throw PyException( PyExc_TypeError, "object has no len()" );
}
virtual TypedVarPtr getElementByIndex( ULONG index ) {
throw PyException( PyExc_TypeError, "object is unsubscriptable");
}
protected: protected:
virtual ULONG64 getValue() const { virtual ULONG64 getValue() const {
@ -106,4 +117,29 @@ public:
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
class ArrayTypedVar: public TypedVar {
public:
ArrayTypedVar ( IDebugClient4 *client, const TypeInfoPtr& typeInfo, ULONG64 offset ) : TypedVar(client, typeInfo, offset){}
virtual ULONG getElementCount() {
return m_typeInfo->getCount();
}
virtual TypedVarPtr getElementByIndex( ULONG index ) {
if ( index > m_typeInfo->getCount() )
{
throw PyException( PyExc_IndexError, "Index out of range" );
}
TypeInfoPtr elementType = m_typeInfo->getElementType();
return TypedVar::getTypedVar( m_client, elementType, m_offset + elementType->getSize()*index );
}
};
///////////////////////////////////////////////////////////////////////////////////
} // namespace pykd } // namespace pykd

View File

@ -45,10 +45,22 @@ public:
return false; return false;
} }
virtual bool isArray() {
return false;
}
virtual bool isUserDefined() { virtual bool isUserDefined() {
return false; return false;
} }
virtual ULONG getCount() {
throw DbgException( "there is no element" );
}
virtual TypeInfoPtr getElementType() {
throw DbgException( "there is no element" );
}
ULONG getOffset() { ULONG getOffset() {
return m_offset; return m_offset;
} }
@ -199,6 +211,19 @@ public:
throw DbgException( "there is no such field" ); throw DbgException( "there is no such field" );
} }
virtual bool isArray() {
return true;
}
virtual ULONG getCount() {
return m_count;
}
virtual TypeInfoPtr getElementType() {
return m_derefType;
}
private: private:
TypeInfoPtr m_derefType; TypeInfoPtr m_derefType;

View File

@ -52,8 +52,8 @@ if __name__ == "__main__":
target.module.reload(); target.module.reload();
suite = getTestSuite() suite = getTestSuite()
#suite = getTestSuite( "memtest.MemoryTest.testPtrRead" ) #suite = getTestSuite( "typedvar.TypedVarTest" )
unittest.TextTestRunner(stream=sys.stdout, verbosity=2).run( suite ) unittest.TextTestRunner(stream=sys.stdout, verbosity=2).run( suite )
#a = raw_input("\npress return\n") a = raw_input("\npress return\n")

View File

@ -19,8 +19,8 @@ class TypedVarTest( unittest.TestCase ):
def testGetSize( self ): def testGetSize( self ):
tv1 = target.module.typedVar( "structTest", target.module.g_structTest ) tv1 = target.module.typedVar( "structTest", target.module.g_structTest )
self.assertEqual( 20, tv1.sizeof() ) self.assertEqual( 20, tv1.sizeof() )
#tv2 = target.module.typedVar( "structTest[2]", target.module.g_testArray ) tv2 = target.module.typedVar( "structTest[2]", target.module.g_testArray )
#self.assertEqual( tv1.sizeof()*2, tv2.sizeof() ) self.assertEqual( tv1.sizeof()*2, tv2.sizeof() )
def testByAddress( self ): def testByAddress( self ):
tv1 = target.module.typedVar( "structTest", target.module.g_structTest ) tv1 = target.module.typedVar( "structTest", target.module.g_structTest )
@ -46,3 +46,10 @@ class TypedVarTest( unittest.TestCase ):
self.assertEqual( 0, tv.m_field0.offset() ) self.assertEqual( 0, tv.m_field0.offset() )
self.assertEqual( 4, tv.m_field1.offset() ) self.assertEqual( 4, tv.m_field1.offset() )
self.assertEqual( 16, tv.m_field4.offset() ) self.assertEqual( 16, tv.m_field4.offset() )
def testArrayField(self):
tv = target.module.typedVar( "g_struct3" )
self.assertEqual( 2, len(tv.m_arrayField) )
self.assertEqual( 0, tv.m_arrayField[0] )
self.assertEqual( 2, tv.m_arrayField[1] )
self.assertEqual( 3, tv.m_noArrayField )

View File

@ -95,6 +95,13 @@ struct struct2 {
int m_field; int m_field;
}; };
struct struct3 {
int m_arrayField[2];
int m_noArrayField;
};
struct3 g_struct3 = { { 0, 2 }, 3 };
__int64 g_bigValue = 0x8080808080808080; __int64 g_bigValue = 0x8080808080808080;
void FuncWithName0() void FuncWithName0()
@ -126,6 +133,7 @@ void FuncWithName0()
std::cout << intMatrix[1][1]; std::cout << intMatrix[1][1];
std::cout << strArray[0]; std::cout << strArray[0];
std::cout << (*ptrIntMatrix)[0][1]; std::cout << (*ptrIntMatrix)[0][1];
std::cout << g_struct3.m_noArrayField;
} }
void FuncWithName1(int a) void FuncWithName1(int a)