diff --git a/pykd/dbgext.cpp b/pykd/dbgext.cpp index 0333b06..12be766 100644 --- a/pykd/dbgext.cpp +++ b/pykd/dbgext.cpp @@ -129,7 +129,7 @@ BOOST_PYTHON_MODULE( pykd ) .def("reload", &pykd::Module::reloadSymbols, "(Re)load symbols for the module" ); - python::def( "diaOpenPdb", &pyDia::GlobalScope::openPdb, + python::def( "diaLoadPdb", &pyDia::GlobalScope::loadPdb, "Open pdb file for quering debug symbols. Return DiaSymbol of global scope"); python::class_("DiaSymbol", "class wrapper for MS DIA Symbol" ) @@ -177,7 +177,9 @@ BOOST_PYTHON_MODULE( pykd ) .def("machineType", &pyDia::GlobalScope::getMachineType, "Retrieves the type of the target CPU: IMAGE_FILE_MACHINE_XXX") .def("findByRva", &pyDia::GlobalScope::findByRva, - "Find symbol by RVA. Return tuple: (DiaSymbol, offset)"); + "Find symbol by RVA. Return tuple: (DiaSymbol, offset)") + .def("symbolById", &pyDia::GlobalScope::getSymbolById, + "Retrieves a symbol by its unique identifier: DiaSymbol::indexId()"); // CPU type: DEF_PY_CONST_ULONG(IMAGE_FILE_MACHINE_I386); diff --git a/pykd/diawrapper.cpp b/pykd/diawrapper.cpp index 0d54ef9..101c3d9 100644 --- a/pykd/diawrapper.cpp +++ b/pykd/diawrapper.cpp @@ -349,7 +349,7 @@ GlobalScope::GlobalScope( //////////////////////////////////////////////////////////////////////////////// -GlobalScope GlobalScope::openPdb(const std::string &filePath) +GlobalScope GlobalScope::loadPdb(const std::string &filePath) { DiaDataSourcePtr _scope; @@ -400,4 +400,18 @@ Symbol GlobalScope::findByRvaImpl( //////////////////////////////////////////////////////////////////////////////// +Symbol GlobalScope::getSymbolById(ULONG symId) +{ + DiaSymbolPtr _symbol; + HRESULT hres = m_session->symbolById(symId, &_symbol); + if (S_OK != hres) + throw Exception("Call IDiaSession::findSymbolByRVAEx", hres); + if (!_symbol) + throw Exception("Call IDiaSession::findSymbolByRVAEx", E_UNEXPECTED); + + return Symbol( _symbol, m_machineType ); +} + +//////////////////////////////////////////////////////////////////////////////// + } diff --git a/pykd/diawrapper.h b/pykd/diawrapper.h index 1bfe2ac..f288ca2 100644 --- a/pykd/diawrapper.h +++ b/pykd/diawrapper.h @@ -217,7 +217,7 @@ public: GlobalScope() {} // GlobalScope factory - static GlobalScope openPdb(const std::string &filePath); + static GlobalScope loadPdb(const std::string &filePath); ULONG getMachineType() const { return m_machineType; @@ -239,6 +239,8 @@ public: __out LONG &displacement ); + // get symbol by unique index + Symbol getSymbolById(ULONG symId); private: diff --git a/test/scripts/diatest.py b/test/scripts/diatest.py index 97ea559..1b549d2 100644 --- a/test/scripts/diatest.py +++ b/test/scripts/diatest.py @@ -8,7 +8,7 @@ import pykd class DiaTest( unittest.TestCase ): def testFind(self): - gScope = pykd.diaOpenPdb( str(target.module.pdb()) ) + gScope = pykd.diaLoadPdb( str(target.module.pdb()) ) self.assertNotEqual(0, len(gScope)) symFunction = gScope.find("FuncWithName0") self.assertTrue(1 == len( symFunction )) @@ -18,24 +18,24 @@ class DiaTest( unittest.TestCase ): self.assertTrue(len(symFunction) > 1) def testSize(self): - gScope = pykd.diaOpenPdb( str(target.module.pdb()) ) + gScope = pykd.diaLoadPdb( str(target.module.pdb()) ) self.assertEqual(1, gScope["g_ucharValue"].type().size()) self.assertEqual(2, gScope["g_ushortValue"].type().size()) self.assertEqual(4, gScope["g_ulongValue"].type().size()) self.assertEqual(8, gScope["g_ulonglongValue"].type().size()) def testValue(self): - gScope = pykd.diaOpenPdb( str(target.module.pdb()) ) + gScope = pykd.diaLoadPdb( str(target.module.pdb()) ) self.assertEqual(0x5555, gScope["g_constNumValue"].value()) self.assertEqual(True, gScope["g_constBoolValue"].value()) def testName(self): - gScope = pykd.diaOpenPdb( str(target.module.pdb()) ) + gScope = pykd.diaLoadPdb( str(target.module.pdb()) ) self.assertEqual("g_constNumValue", gScope["g_constNumValue"].name()) self.assertEqual("FuncWithName0", gScope["FuncWithName0"].name()) def testRva(self): - gScope = pykd.diaOpenPdb( str(target.module.pdb()) ) + gScope = pykd.diaLoadPdb( str(target.module.pdb()) ) _rva = gScope["FuncWithName0"].rva() self.assertNotEqual(0, _rva) self.assertTrue( _rva < (target.module.end() - target.module.begin()) ) @@ -44,23 +44,23 @@ class DiaTest( unittest.TestCase ): self.assertTrue( _rva < (target.module.end() - target.module.begin()) ) def testSymTag(self): - gScope = pykd.diaOpenPdb( str(target.module.pdb()) ) + gScope = pykd.diaLoadPdb( str(target.module.pdb()) ) self.assertEqual(pykd.SymTagFunction, gScope["FuncWithName0"].symTag()) self.assertEqual(pykd.SymTagData, gScope["g_string"].symTag()) def testLocType(self): - gScope = pykd.diaOpenPdb( str(target.module.pdb()) ) + gScope = pykd.diaLoadPdb( str(target.module.pdb()) ) self.assertEqual(pykd.LocIsConstant, gScope["g_constNumValue"].locType()) self.assertEqual(pykd.LocIsStatic, gScope["FuncWithName1"].locType()) def testBasicType(self): - gScope = pykd.diaOpenPdb( str(target.module.pdb()) ) + gScope = pykd.diaLoadPdb( str(target.module.pdb()) ) self.assertFalse(gScope["g_string"].type().isBasic()) self.assertEqual(pykd.btBool, gScope["g_constBoolValue"].type().baseType()) self.assertEqual(pykd.btULong, gScope["g_ulongValue"].type().baseType()) def testBits(self): - gScope = pykd.diaOpenPdb( str(target.module.pdb()) ) + gScope = pykd.diaLoadPdb( str(target.module.pdb()) ) structWithBits = gScope["structWithBits"] bitField = structWithBits["m_bit0_4"] self.assertEqual(pykd.LocIsBitField, bitField.locType()) @@ -76,20 +76,20 @@ class DiaTest( unittest.TestCase ): self.assertEqual(2, bitField.size()) def testIndexId(self): - gScope = pykd.diaOpenPdb( str(target.module.pdb()) ) + gScope = pykd.diaLoadPdb( str(target.module.pdb()) ) self.assertNotEqual( gScope["classChild"].indexId(), gScope["classBase"].indexId() ) self.assertNotEqual( gScope["FuncWithName0"].indexId(), gScope["FuncWithName1"].indexId() ) def testUdtKind(self): - gScope = pykd.diaOpenPdb( str(target.module.pdb()) ) + gScope = pykd.diaLoadPdb( str(target.module.pdb()) ) self.assertEqual(pykd.UdtStruct, gScope["structWithBits"].udtKind()) self.assertEqual(pykd.UdtUnion, gScope["unionTest"].udtKind()) self.assertEqual(pykd.UdtClass, gScope["classBase"].udtKind()) def testOffset(self): - gScope = pykd.diaOpenPdb( str(target.module.pdb()) ) + gScope = pykd.diaLoadPdb( str(target.module.pdb()) ) structTest = gScope["structTest"] self.assertEqual( 0, structTest["m_field0"].offset() ) self.assertTrue( structTest["m_field0"].offset() < @@ -101,12 +101,12 @@ class DiaTest( unittest.TestCase ): self.assertTrue(structTest["m_field3"].offset() < structTest.size()) def testMachine(self): - gScope = pykd.diaOpenPdb( str(target.module.pdb()) ) + gScope = pykd.diaLoadPdb( str(target.module.pdb()) ) self.assertTrue( (gScope.machineType() == pykd.IMAGE_FILE_MACHINE_I386) or (gScope.machineType() == pykd.IMAGE_FILE_MACHINE_AMD64) ) def testFindByRva(self): - gScope = pykd.diaOpenPdb( str(target.module.pdb()) ) + gScope = pykd.diaLoadPdb( str(target.module.pdb()) ) func = gScope["FuncWithName0"] tplSymOffset = gScope.findByRva(func.rva(), pykd.SymTagFunction) @@ -117,3 +117,8 @@ class DiaTest( unittest.TestCase ): self.assertEqual(tplSymOffset[0].indexId(), func.indexId()) self.assertEqual(tplSymOffset[1], 2) + def testSymbolById(self): + gScope = pykd.diaLoadPdb( str(target.module.pdb()) ) + func = gScope["FuncWithName0"] + self.assertEqual( gScope.symbolById(func.indexId()).indexId(), + func.indexId())