From 82a744d1be424783a74afa3ee54eb2e3a5784b8e Mon Sep 17 00:00:00 2001 From: "SND\\EreTIk_cp" Date: Tue, 8 Nov 2011 10:53:07 +0000 Subject: [PATCH] [+, 0.1.x] get symbol by address from module git-svn-id: https://pykd.svn.codeplex.com/svn@71164 9b283d60-5439-405e-af05-b73fd8c4d996 --- pykd/dbgext.cpp | 6 ++--- pykd/module.cpp | 49 ++++++++++++++++-------------------- pykd/module.h | 19 +++++++------- test/scripts/typedvar.py | 19 ++++++++------ test/scripts/typeinfo.py | 14 +++++------ test/targetapp/targetapp.cpp | 3 ++- 6 files changed, 54 insertions(+), 56 deletions(-) diff --git a/pykd/dbgext.cpp b/pykd/dbgext.cpp index 8468951..c8880e7 100644 --- a/pykd/dbgext.cpp +++ b/pykd/dbgext.cpp @@ -334,8 +334,8 @@ 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, @@ -347,7 +347,7 @@ BOOST_PYTHON_MODULE( pykd ) python::class_( "dout", "dout", python::no_init ) .def( "write", &pykd::DbgOut::write ); - + python::class_( "din", "din", python::no_init ) .def( "readline", &pykd::DbgIn::readline ); diff --git a/pykd/module.cpp b/pykd/module.cpp index 5bb1f13..77fe40b 100644 --- a/pykd/module.cpp +++ b/pykd/module.cpp @@ -127,7 +127,7 @@ Module::getPdbName() if ( FAILED( hres ) ) throw DbgException( "IDebugAdvanced2::GetSymbolInformation failed" ); - char pdbName[ 256 ]; + char pdbName[ 256 ]; WideCharToMultiByte( CP_ACP, 0, moduleInfo.LoadedPdbName, 256, pdbName, 256, NULL, NULL ); return std::string( pdbName ); @@ -147,6 +147,7 @@ Module::reloadSymbols() if ( FAILED( hres ) ) throw DbgException("IDebugSymbols::Reload failed" ); + m_dia.reset(); m_dia = pyDia::GlobalScope::loadPdb( getPdbName() ); } @@ -155,7 +156,7 @@ Module::reloadSymbols() TypeInfo Module::getTypeByName( const std::string &typeName ) { - return TypeInfo( m_dia, typeName ); + return TypeInfo( getDia(), typeName ); } /////////////////////////////////////////////////////////////////////////////////// @@ -163,7 +164,7 @@ Module::getTypeByName( const std::string &typeName ) TypedVar Module::getTypedVarByTypeName( const std::string &typeName, ULONG64 addr ) { - return TypedVar( TypeInfo( m_dia, typeName ), addr ); + return TypedVar( TypeInfo( getDia(), typeName ), addr ); } /////////////////////////////////////////////////////////////////////////////////// @@ -179,37 +180,29 @@ Module::getTypedVarByType( const TypeInfo &typeInfo, ULONG64 addr ) TypedVar Module::getTypedVarByName( const std::string &symName ) { - pyDia::SymbolPtr typeSym = m_dia->getChildByName( symName ); + pyDia::SymbolPtr typeSym = getDia()->getChildByName( symName ); return TypedVar( TypeInfo( typeSym->getType() ), typeSym->getRva() + m_base ); } /////////////////////////////////////////////////////////////////////////////////// -//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" ); -//} +TypedVar +Module::getTypedVarByAddr( ULONG64 addr ) +{ + addr = addr64(addr); + + if ( addr < m_base || addr > getEnd() ) + throw DbgException( "address is out of the module space" ); + + LONG displacement; + pyDia::SymbolPtr diaSym = + getDia()->findByRvaImpl((ULONG)(addr - m_base), SymTagData, displacement); + if (displacement) + throw DbgException( "not exactly match by RVA" ); + + return TypedVar( TypeInfo( diaSym->getType() ), addr ); +} /////////////////////////////////////////////////////////////////////////////////// diff --git a/pykd/module.h b/pykd/module.h index cf38870..bee7e00 100644 --- a/pykd/module.h +++ b/pykd/module.h @@ -47,22 +47,14 @@ public: ULONG64 getSymbol( const std::string &symbolname ) { - - if ( !m_dia ) - m_dia = pyDia::GlobalScope::loadPdb( getPdbName() ); - - pyDia::SymbolPtr sym = m_dia->getChildByName( symbolname ); + pyDia::SymbolPtr sym = getDia()->getChildByName( symbolname ); return m_base + sym->getRva(); } ULONG getSymbolRva( const std::string &symbolname ) { - - if ( !m_dia ) - m_dia = pyDia::GlobalScope::loadPdb( getPdbName() ); - - pyDia::SymbolPtr sym = m_dia->getChildByName( symbolname ); + pyDia::SymbolPtr sym = getDia()->getChildByName( symbolname ); return sym->getRva(); } @@ -79,6 +71,13 @@ public: private: + pyDia::GlobalScopePtr getDia() { + if (!m_dia) + m_dia = pyDia::GlobalScope::loadPdb( getPdbName() ); + return m_dia; + } + + std::string m_name; std::string m_imageName; ULONG64 m_base; diff --git a/test/scripts/typedvar.py b/test/scripts/typedvar.py index 6770827..635c6cd 100644 --- a/test/scripts/typedvar.py +++ b/test/scripts/typedvar.py @@ -11,31 +11,36 @@ class TypedVarTest( unittest.TestCase ): def testCtor( self ): tv = target.module.typedVar( "structTest", target.module.g_structTest ) tv = target.module.typedVar( "g_structTest" ) - + def testGetAddress( self ): tv = target.module.typedVar( "structTest", target.module.g_structTest ) self.assertEqual( tv.getAddress(), target.module.g_structTest ) - + def testGetSize( self ): tv1 = target.module.typedVar( "structTest", target.module.g_structTest ) self.assertEqual( 20, tv1.sizeof() ) #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 ): + tv1 = target.module.typedVar( "structTest", target.module.g_structTest ) + tv2 = target.module.typedVar( tv1.getAddress() ) + self.assertEqual( tv2.getAddress(), tv1.getAddress() ) + def testStruct(self): tv1 = target.module.typedVar( "structTest", target.module.g_structTest ) self.assertEqual( 0, tv1.m_field0 ) self.assertEqual( 500, tv1.m_field1 ) self.assertEqual( True, tv1.m_field2 ) 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() ) diff --git a/test/scripts/typeinfo.py b/test/scripts/typeinfo.py index 35fa52f..ff14cf2 100644 --- a/test/scripts/typeinfo.py +++ b/test/scripts/typeinfo.py @@ -12,32 +12,32 @@ class TypeInfoTest( unittest.TestCase ): """ typeInfo class can not be created direct """ try: pykd.typeInfo() except RuntimeError: pass - + def testCreateByName( self ): """ creating typeInfo by the type name """ ti1 = target.module.type( "structTest" ) ti2 = target.module.type( "classChild" ) - + def testGetField( self ): """ get field of the complex type """ ti1 = target.module.type( "structTest" ) self.assertTrue( hasattr( ti1, "m_field0" ) ) try: hasattr(ti1, "m_field4" ) # non-exsisting field except pykd.DiaException: pass - + def testName( self ): ti1 = target.module.type( "classChild" ) self.assertEqual( "classChild", ti1.name() ) self.assertEqual( "Int", ti1.m_childField.name() ) self.assertEqual( "structTest", ti1.m_childField3.name() ) self.assertEqual( "structTest", target.module.type("g_structTest").name() ) - + def testArrayName( self ): self.assertEqual( "structTest[2]", target.module.type("g_testArray").name() ) - + def testPtrName( self ): self.assertEqual( "structTest*", target.module.type("g_structTestPtr").name() ) - self.assertEqual( "structTest**", target.module.type("g_structTestPtrPtr").name() ) + self.assertEqual( "structTest**", target.module.type("g_structTestPtrPtr").name() ) def testOffset( self ): ti1 = target.module.type( "structTest" ) @@ -49,4 +49,4 @@ class TypeInfoTest( unittest.TestCase ): def testSize( self ): ti1 = target.module.type( "structTest" ) self.assertEqual( 20, ti1.size() ) - + diff --git a/test/targetapp/targetapp.cpp b/test/targetapp/targetapp.cpp index 8afdca0..1003ae0 100644 --- a/test/targetapp/targetapp.cpp +++ b/test/targetapp/targetapp.cpp @@ -24,7 +24,6 @@ struct structWithBits { ULONG m_bit5 : 1; ULONG m_bit6_7 : 2; }; -structWithBits g_structWithBits = {0}; union unionTest { ULONG m_value; @@ -47,6 +46,8 @@ struct structTest { structTest* m_field4; }; +structWithBits g_structWithBits = {0}; + structTest g_structTest = { 0, 500, true, 1, NULL }; structTest g_structTest1 = { 0, 500, true, 1, &g_structTest };