diff --git a/pykd/dbgext.cpp b/pykd/dbgext.cpp index ba51150..cc2d941 100644 --- a/pykd/dbgext.cpp +++ b/pykd/dbgext.cpp @@ -116,19 +116,24 @@ BOOST_PYTHON_MODULE( pykd ) "Return instance of the Module class which posseses specified address" ); python::class_("module", "Class representing executable module", python::no_init ) - .def("begin", &pykd::Module::getBase, + .def("begin", &pykd::Module::getBase, "Return start address of the module" ) - .def("end", &pykd::Module::getEnd, + .def("end", &pykd::Module::getEnd, "Return end address of the module" ) - .def("size", &pykd::Module::getSize, + .def("size", &pykd::Module::getSize, "Return size of the module" ) - .def("name", &pykd::Module::getName, - "Return name of the module" ) - .def("pdb", &pykd::Module::getPdbName, + .def("name", &pykd::Module::getName, + "Return name of the module" ) + .def("image", &pykd::Module::getImageName, + "Return name of the image of the module" ) + .def("pdb", &pykd::Module::getPdbName, "Return the full path to the module's pdb file ( symbol information )" ) - .def("reload", &pykd::Module::reloadSymbols, - "(Re)load symbols for the module" ); + .def("reload", &pykd::Module::reloadSymbols, + "(Re)load symbols for the module" ) + .def("symbols", &pykd::Module::getSymbols, + "Return list of all symbols of the module" ); + python::def( "diaLoadPdb", &pyDia::GlobalScope::loadPdb, "Open pdb file for quering debug symbols. Return DiaSymbol of global scope"); diff --git a/pykd/module.cpp b/pykd/module.cpp index c5739bb..5f48876 100644 --- a/pykd/module.cpp +++ b/pykd/module.cpp @@ -36,6 +36,21 @@ Module::Module( IDebugClient5 *client, const std::string& moduleName ) : DbgObje throw DbgException( "IDebugSymbol::GetModuleParameters failed" ); m_size = moduleParam.Size; + + char imageName[0x100]; + + hres = m_symbols->GetModuleNameString( + DEBUG_MODNAME_IMAGE, + DEBUG_ANY_ID, + m_base, + imageName, + sizeof( imageName ), + NULL ); + + if ( FAILED( hres ) ) + throw DbgException( "IDebugSymbol::GetModuleNameString failed" ); + + m_imageName = std::string( imageName ); } /////////////////////////////////////////////////////////////////////////////////// @@ -66,6 +81,21 @@ Module::Module( IDebugClient5 *client, ULONG64 offset ) : DbgObject( client ) m_name = std::string( moduleName ); + char imageName[0x100]; + + hres = m_symbols->GetModuleNameString( + DEBUG_MODNAME_IMAGE, + DEBUG_ANY_ID, + m_base, + imageName, + sizeof( imageName ), + NULL ); + + if ( FAILED( hres ) ) + throw DbgException( "IDebugSymbol::GetModuleNameString failed" ); + + m_imageName = std::string( imageName ); + DEBUG_MODULE_PARAMETERS moduleParam = { 0 }; hres = m_symbols->GetModuleParameters( 1, &m_base, 0, &moduleParam ); if ( FAILED( hres ) ) @@ -76,7 +106,7 @@ Module::Module( IDebugClient5 *client, ULONG64 offset ) : DbgObject( client ) /////////////////////////////////////////////////////////////////////////////////// -std::wstring +std::string Module::getPdbName() { HRESULT hres; @@ -97,7 +127,10 @@ Module::getPdbName() if ( FAILED( hres ) ) throw DbgException( "IDebugAdvanced2::GetSymbolInformation failed" ); - return std::wstring( moduleInfo.LoadedPdbName ); + char pdbName[ 256 ]; + WideCharToMultiByte( CP_ACP, 0, moduleInfo.LoadedPdbName, 256, pdbName, 256, NULL, NULL ); + + return std::string( pdbName ); } /////////////////////////////////////////////////////////////////////////////////// @@ -107,10 +140,14 @@ Module::reloadSymbols() { HRESULT hres; - hres = m_symbols->Reload( "/f" ); - if ( FAILED( hres ) ) - throw DbgException("IDebugSymbols::Reload failed" ); + std::string param = "/f "; + param += m_imageName; + hres = m_symbols->Reload( param.c_str() ); + if ( FAILED( hres ) ) + throw DbgException("IDebugSymbols::Reload failed" ); + + m_dia = pyDia::GlobalScope::loadPdb( getPdbName() ); } /////////////////////////////////////////////////////////////////////////////////// diff --git a/pykd/module.h b/pykd/module.h index e571c88..514a231 100644 --- a/pykd/module.h +++ b/pykd/module.h @@ -3,6 +3,7 @@ #include #include "dbgobj.h" +#include "diawrapper.h" namespace pykd { @@ -20,6 +21,10 @@ public: return m_name; } + std::string getImageName() { + return m_imageName; + } + ULONG64 getBase() { return m_base; } @@ -32,17 +37,28 @@ public: return m_size; } - std::wstring + std::string getPdbName(); void reloadSymbols(); + python::list + getSymbols() { + if ( !m_dia ) + m_dia = pyDia::GlobalScope::loadPdb( getPdbName() ); + + return m_dia->findChildrenEx( SymTagNull, "*", nsRegularExpression ); + } + private: - std::string m_name; - ULONG64 m_base; - ULONG m_size; + std::string m_name; + std::string m_imageName; + ULONG64 m_base; + ULONG m_size; + pyDia::GlobalScopePtr m_dia; + }; diff --git a/test/scripts/diatest.py b/test/scripts/diatest.py index ce3a16d..8b932f4 100644 --- a/test/scripts/diatest.py +++ b/test/scripts/diatest.py @@ -7,6 +7,12 @@ import target import pykd class DiaTest( unittest.TestCase ): + + def testCtor(self): + """ DiaSymbol can not be created direct """ + try: pykd.DiaSymbol() + except RuntimeError: pass + def testFind(self): try: gScope = pykd.diaLoadPdb( str(target.module.pdb()) ) diff --git a/test/scripts/moduletest.py b/test/scripts/moduletest.py index 3780ede..79cc3d2 100644 --- a/test/scripts/moduletest.py +++ b/test/scripts/moduletest.py @@ -9,34 +9,43 @@ import pykd class ModuleTest( unittest.TestCase ): def testCtor( self ): - self.assertRaises( RuntimeError, pykd.module ) + " module class can not be created direct """ + try: pykd.module() + except RuntimeError: pass def testName( self ): - self.assertEqual( target.moduleName, target.module.name() ) + self.assertEqual( target.moduleName, target.module.name() ) def testSize( self ): - self.assertNotEqual( 0, target.module.size() ) + self.assertNotEqual( 0, target.module.size() ) def testBegin( self ): - self.assertNotEqual( 0, target.module.begin() ) + self.assertNotEqual( 0, target.module.begin() ) def testEnd( self ): - self.assertEqual( target.module.size(), target.module.end() - target.module.begin() ) + self.assertEqual( target.module.size(), target.module.end() - target.module.begin() ) def testPdb( self ): - self.assertNotEqual( "", target.module.pdb() ); + self.assertNotEqual( "", target.module.pdb() ) + def testImage( self ): + self.assertEqual( target.module.name() + ".exe", target.module.image() ) + def testFindModule( self ): - try: pykd.findModule( target.module.begin() - 0x10 ) - except pykd.BaseException: pass - #self.assertRaises( pykd.BaseException, pykd.findModule, target.module.begin() - 0x10 ) - - self.assertNotEqual( None, pykd.findModule( target.module.begin() ) ) - self.assertNotEqual( None, pykd.findModule( target.module.begin() + 0x10) ) - - try: pykd.findModule( target.module.end() ) - except pykd.BaseException: pass + try: pykd.findModule( target.module.begin() - 0x10 ) + except pykd.BaseException: pass + #self.assertRaises( pykd.BaseException, pykd.findModule, target.module.begin() - 0x10 ) + + self.assertNotEqual( None, pykd.findModule( target.module.begin() ) ) + self.assertNotEqual( None, pykd.findModule( target.module.begin() + 0x10) ) + + try: pykd.findModule( target.module.end() ) + except pykd.BaseException: pass - try: pykd.findModule( target.module.end() + 0x10) - except pykd.BaseException: pass + try: pykd.findModule( target.module.end() + 0x10) + except pykd.BaseException: pass + + def testSymbols( self ): + syms = target.module.symbols() + self.assertNotEqual( 0, len( syms ) )