mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-21 04:13:22 +08:00
[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:
parent
1e57a6df5c
commit
43660d5617
@ -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
|
||||||
|
@ -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",
|
||||||
|
@ -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; }
|
||||||
|
@ -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() ) );
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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")
|
@ -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 )
|
||||||
|
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user