[0.1.x] added : containingRecord method of the module class

git-svn-id: https://pykd.svn.codeplex.com/svn@72131 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
SND\kernelnet_cp 2011-12-09 06:45:12 +00:00 committed by Mikhail I. Izmestev
parent 1609c0cac6
commit 3058af91a7
8 changed files with 74 additions and 25 deletions

View File

@ -388,46 +388,49 @@ BOOST_PYTHON_MODULE( pykd )
.def("__len__", &TypedVar::getElementCount ) .def("__len__", &TypedVar::getElementCount )
.def("__getitem__", &TypedVar::getElementByIndex ); .def("__getitem__", &TypedVar::getElementByIndex );
python::class_<pykd::Module>("module", "Class representing executable module", python::no_init ) python::class_<Module>("module", "Class representing executable module", python::no_init )
.def("begin", &pykd::Module::getBase, .def("begin", &Module::getBase,
"Return start address of the module" ) "Return start address of the module" )
.def("end", &pykd::Module::getEnd, .def("end", &Module::getEnd,
"Return end address of the module" ) "Return end address of the module" )
.def("size", &pykd::Module::getSize, .def("size", &Module::getSize,
"Return size of the module" ) "Return size of the module" )
.def("name", &pykd::Module::getName, .def("name", &Module::getName,
"Return name of the module" ) "Return name of the module" )
.def("image", &pykd::Module::getImageName, .def("image", &Module::getImageName,
"Return name of the image of the module" ) "Return name of the image of the module" )
.def("pdb", &pykd::Module::getPdbName, .def("pdb", &Module::getPdbName,
"Return the full path to the module's pdb file ( symbol information )" ) "Return the full path to the module's pdb file ( symbol information )" )
.def("reload", &pykd::Module::reloadSymbols, .def("reload", &Module::reloadSymbols,
"(Re)load symbols for the module" ) "(Re)load symbols for the module" )
.def("offset", &pykd::Module::getSymbol, .def("offset", &Module::getSymbol,
"Return offset of the symbol" ) "Return offset of the symbol" )
.def("rva", &pykd::Module::getSymbolRva, .def("rva", &Module::getSymbolRva,
"Return rva of the symbol" ) "Return rva of the symbol" )
.def("type", &pykd::Module::getTypeByName, .def("type", &Module::getTypeByName,
"Return typeInfo class by type name" ) "Return typeInfo class by type name" )
.def("typedVar", &pykd::Module::getTypedVarByAddr, .def("typedVar", &Module::getTypedVarByAddr,
"Return a typedVar class instance" ) "Return a typedVar class instance" )
.def("typedVar",&pykd::Module::getTypedVarByName, .def("typedVar",&Module::getTypedVarByName,
"Return a typedVar class instance" ) "Return a typedVar class instance" )
.def("typedVar",&pykd::Module::getTypedVarByType, .def("typedVar",&Module::getTypedVarByType,
"Return a typedVar class instance" ) "Return a typedVar class instance" )
.def("typedVar",&pykd::Module::getTypedVarByTypeName, .def("typedVar",&Module::getTypedVarByTypeName,
"Return a typedVar class instance" ) "Return a typedVar class instance" )
.def("__getattr__", &pykd::Module::getSymbol, .def("containingRecord", &Module::contaningRecord,
"Return instance of the typedVar class. It's value are loaded from the target memory."
"The start address is calculated by the same method as the standard macro CONTAINING_RECORD does" )
.def("__getattr__", &Module::getSymbol,
"Return address of the symbol" ); "Return address of the symbol" );
python::class_<DbgOut>( "dout", "dout", python::no_init ) python::class_<DbgOut>( "dout", "dout", python::no_init )
.def( "write", &pykd::DbgOut::write ); .def( "write", &DbgOut::write );
python::class_<DbgIn>( "din", "din", python::no_init ) python::class_<DbgIn>( "din", "din", python::no_init )
.def( "readline", &pykd::DbgIn::readline ); .def( "readline", &DbgIn::readline );
python::class_<DbgExtension, pykd::DbgExtensionPtr>("ext", python::no_init ) python::class_<DbgExtension, DbgExtensionPtr>("ext", python::no_init )
.def( "call", &pykd::DbgExtension::call, .def( "call", &DbgExtension::call,
"Call debug extension command end return it's result as a string" ); "Call debug extension command end return it's result as a string" );
python::class_<EventHandlerWrap, boost::noncopyable>( python::class_<EventHandlerWrap, boost::noncopyable>(

View File

@ -219,5 +219,41 @@ ULONG Module::getRvaByName(const std::string &symName)
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
TypedVarPtr Module::contaningRecord( ULONG64 address, const std::string &typeName, const std::string &fieldName )
{
address = addr64(address);
TypeInfoPtr typeInfo = getTypeByName( typeName );
TypeInfoPtr fieldTypeInfo = typeInfo->getField( fieldName );
return TypedVar::getTypedVar( m_client, typeInfo, address - fieldTypeInfo->getOffset() );
//HRESULT hres;
//ULONG64 moduleBase;
//hres = dbgExt->symbols->GetModuleByModuleName( moduleName.c_str(), 0, NULL, &moduleBase );
//if ( FAILED( hres ) )
// throw TypeException();
//ULONG typeId;
//hres = dbgExt->symbols->GetTypeId( moduleBase, typeName.c_str(), &typeId );
//if ( FAILED( hres ) )
// throw TypeException();
//ULONG fieldTypeId;
//ULONG fieldOffset;
//hres = dbgExt->symbols3->GetFieldTypeAndOffset( moduleBase, typeId, fieldName.c_str(), &fieldTypeId, &fieldOffset );
//if ( FAILED( hres ) )
// throw TypeException();
//
//TypedVar var( moduleName, typeName, address - fieldOffset );
//
//return boost::python::object( var );
}
///////////////////////////////////////////////////////////////////////////////////
}; // end of namespace pykd }; // end of namespace pykd

View File

@ -68,6 +68,8 @@ public:
TypedVarPtr getTypedVarByName( const std::string &symName ); TypedVarPtr getTypedVarByName( const std::string &symName );
TypedVarPtr contaningRecord( ULONG64 addr, const std::string &typeName, const std::string &fieldName );
private: private:
ULONG getRvaByName(const std::string &symName); ULONG getRvaByName(const std::string &symName);

View File

@ -17,7 +17,6 @@ class BaseTest( unittest.TestCase ):
self.assertTrue( hasattr(pykd, 'addr64') ) self.assertTrue( hasattr(pykd, 'addr64') )
self.assertTrue( hasattr(pykd, 'breakin') ) self.assertTrue( hasattr(pykd, 'breakin') )
self.assertTrue( hasattr(pykd, 'compareMemory') ) self.assertTrue( hasattr(pykd, 'compareMemory') )
self.assertTrue( hasattr(pykd, 'containingRecord') )
self.assertTrue( hasattr(pykd, 'dbgCommand') ) self.assertTrue( hasattr(pykd, 'dbgCommand') )
self.assertTrue( hasattr(pykd, 'dprint') ) self.assertTrue( hasattr(pykd, 'dprint') )
self.assertTrue( hasattr(pykd, 'dprintln') ) self.assertTrue( hasattr(pykd, 'dprintln') )
@ -104,6 +103,7 @@ class BaseTest( unittest.TestCase ):
def testOldRemovedApi( self ): def testOldRemovedApi( self ):
""" Branch test: old API 0.0.x what should be removed """ """ Branch test: old API 0.0.x what should be removed """
self.assertFalse( hasattr(pykd, 'containingRecord') )
self.assertFalse( hasattr(pykd, 'cpuReg') ) self.assertFalse( hasattr(pykd, 'cpuReg') )
self.assertFalse( hasattr(pykd, 'dbgModuleClass') ) self.assertFalse( hasattr(pykd, 'dbgModuleClass') )
self.assertFalse( hasattr(pykd, 'debugEvent') ) self.assertFalse( hasattr(pykd, 'debugEvent') )

View File

@ -59,9 +59,7 @@ if __name__ == "__main__":
suite = getTestSuite() suite = getTestSuite()
#suite = getTestSuite( "typeinfo.TypeInfoTest.testCreateBySymbol" ) #suite = getTestSuite( "typeinfo.TypeInfoTest.testCreateBySymbol" )
#suite = getTestSuite( "intbase.IntBaseTest.testLongConvert" )
#suite = getTestSuite( "typedvar.TypedVarTest.testStruct" )
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

@ -62,4 +62,9 @@ class TypedVarTest( unittest.TestCase ):
self.assertEqual( -100000, target.module.typedVar( "longArray" )[3]) self.assertEqual( -100000, target.module.typedVar( "longArray" )[3])
self.assertEqual( -10000000000, target.module.typedVar( "longlongArray" )[4]) self.assertEqual( -10000000000, target.module.typedVar( "longlongArray" )[4])
self.assertEqual( target.module.g_structTest, target.module.typedVar( "g_structTestPtr" ) ) self.assertEqual( target.module.g_structTest, target.module.typedVar( "g_structTestPtr" ) )
def testContainingRecord(self):
off1 = target.module.type( "structTest" ).m_field2.offset()
off2 = target.module.offset( "g_structTest" )
tv = target.module.containingRecord( off2 + off1, "structTest", "m_field2" )
self.assertEqual( True, tv.m_field2 )

View File

@ -19,6 +19,7 @@ class TypeInfoTest( unittest.TestCase ):
self.assertEqual( "structTest**", target.module.type( "structTest**" ).name() ) self.assertEqual( "structTest**", target.module.type( "structTest**" ).name() )
self.assertEqual( "Int4B[2][3]", target.module.type("Int4B[2][3]").name() ) self.assertEqual( "Int4B[2][3]", target.module.type("Int4B[2][3]").name() )
self.assertEqual( "Int4B(*[4])[2][3]", target.module.type("Int4B(*[4])[2][3]").name() ) self.assertEqual( "Int4B(*[4])[2][3]", target.module.type("Int4B(*[4])[2][3]").name() )
self.assertEqual( "Int4B(*)[2][3]", target.module.type("Int4B((*))[2][3]").name() )
def testCreateBySymbol(self): def testCreateBySymbol(self):
""" creating typeInfo by the symbol name """ """ creating typeInfo by the symbol name """
@ -29,6 +30,8 @@ class TypeInfoTest( unittest.TestCase ):
self.assertEqual( "Char*[2]", target.module.type("strArray").name() ) self.assertEqual( "Char*[2]", target.module.type("strArray").name() )
self.assertEqual( "Char*(*)[2]", target.module.type("ptrStrArray").name() ) self.assertEqual( "Char*(*)[2]", target.module.type("ptrStrArray").name() )
self.assertEqual( "Int4B(*[4])[2][3]", target.module.type("arrIntMatrixPtrs").name() ) self.assertEqual( "Int4B(*[4])[2][3]", target.module.type("arrIntMatrixPtrs").name() )
self.assertEqual( "Int4B(*)[2][3]", target.module.type("ptrIntMatrix1").name() )
def testGetField( self ): def testGetField( self ):
""" get field of the complex type """ """ get field of the complex type """

View File

@ -79,6 +79,8 @@ int (* arrIntMatrixPtrs[4])[2][3] = {
&intMatrix, &intMatrix2, &intMatrix3, &intMatrix4 &intMatrix, &intMatrix2, &intMatrix3, &intMatrix4
}; };
int ((*ptrIntMatrix1))[2][3] = &intMatrix;
char *(*ptrStrArray)[2] = &strArray; char *(*ptrStrArray)[2] = &strArray;
class classChild : public classBase { class classChild : public classBase {