diff --git a/pykd/pykdver.h b/pykd/pykdver.h index a2324d2..f15c478 100644 --- a/pykd/pykdver.h +++ b/pykd/pykdver.h @@ -2,7 +2,7 @@ #define PYKD_VERSION_MAJOR 0 #define PYKD_VERSION_MINOR 3 #define PYKD_VERSION_SUBVERSION 4 -#define PYKD_VERSION_BUILDNO 6 +#define PYKD_VERSION_BUILDNO 7 #define __VER_STR2__(x) #x #define __VER_STR1__(x) __VER_STR2__(x) diff --git a/pykd/pymod.cpp b/pykd/pymod.cpp index 7663d02..90f32a9 100644 --- a/pykd/pymod.cpp +++ b/pykd/pymod.cpp @@ -886,8 +886,10 @@ void pykd_init() "Return tuple of the module's file version") .def("getFixedFileInfo", ModuleAdapter::getFixedFileInfo, "Return FixedFileInfo" ) - .def("__getattr__", ModuleAdapter::getSymbolVaAttr, - "Return address of the symbol" ) + .def("__getattr__", ModuleAdapter::getAttrByName, + "Return symbol offset or type as attribute" ) + .def("__getitem__", ModuleAdapter::getItemByKey, + "Return symbol offset or type as item" ) .def("__contains__", ModuleAdapter::isContainedSymbol) .def( "__str__", &ModuleAdapter::print ); diff --git a/pykd/pymodule.h b/pykd/pymodule.h index fe86987..1a5b1b2 100644 --- a/pykd/pymodule.h +++ b/pykd/pymodule.h @@ -82,19 +82,41 @@ struct ModuleAdapter : public kdlib::Module return module.getSymbolVa(symbolName); } - static kdlib::MEMOFFSET_64 getSymbolVaAttr(kdlib::Module& module, const std::wstring &symbolName) + static python::object getAttrByName(kdlib::Module& module, const std::wstring &symbolName) { AutoRestorePyState pystate; try { - return module.getSymbolVa(symbolName); + return python::object(module.getSymbolVa(symbolName)); + } + catch (kdlib::DbgException&) + { } + + return python::object(module.getTypeByName(symbolName)); + } + + static python::object getItemByKey(kdlib::Module& module, const std::wstring &symbolName) + { + AutoRestorePyState pystate; + + try { + return python::object(module.getSymbolVa(symbolName)); } catch (kdlib::DbgException&) { - std::wstringstream sstr; - sstr << L'\'' << module.getName() << L'\'' << L" module has no symbol " << L'\'' << symbolName << L'\''; - throw AttributeException(std::string(_bstr_t(sstr.str().c_str())).c_str()); } + + try { + return python::object(module.getTypeByName(symbolName)); + } + catch (kdlib::DbgException&) + { + } + + std::wstringstream sstr; + sstr << L"module hase symbol " << L'\'' << symbolName << L'\''; + throw KeyException(std::string(_bstr_t(sstr.str().c_str())).c_str()); } + static kdlib::MEMOFFSET_32 getSymbolRva( kdlib::Module& module, const std::wstring &symbolName ) { diff --git a/pykd/pytypedvar.cpp b/pykd/pytypedvar.cpp index 7bc3240..ed448f6 100644 --- a/pykd/pytypedvar.cpp +++ b/pykd/pytypedvar.cpp @@ -184,28 +184,39 @@ python::list TypedVarAdapter::getElementsDir(kdlib::TypedVar& typedVar) kdlib::TypedVarPtr TypedVarAdapter::getFieldAttr(kdlib::TypedVar& typedVar, const std::wstring &name) { + AutoRestorePyState pystate; + + try { - - AutoRestorePyState pystate; - - try - { - return typedVar.getElement( name ); - } - catch (kdlib::TypeException&) - {} - - try - { - return typedVar.getMethod( name ); - } - catch (kdlib::TypeException&) - {} + return typedVar.getElement( name ); } + catch (kdlib::TypeException&) + {} - std::wstringstream sstr; - sstr << L"typed var has no field " << L'\'' << name << L'\''; - throw AttributeException(std::string(_bstr_t(sstr.str().c_str())).c_str()); + return typedVar.getMethod(name); + + //{ + + // AutoRestorePyState pystate; + + // try + // { + // return typedVar.getElement( name ); + // } + // catch (kdlib::TypeException&) + // {} + + // try + // { + // return typedVar.getMethod( name ); + // } + // catch (kdlib::TypeException&) + // {} + //} + + //std::wstringstream sstr; + //sstr << L"typed var has no field " << L'\'' << name << L'\''; + //throw AttributeException(std::string(_bstr_t(sstr.str().c_str())).c_str()); } diff --git a/pykd/pytypeinfo.cpp b/pykd/pytypeinfo.cpp index c38d22f..ea6b194 100644 --- a/pykd/pytypeinfo.cpp +++ b/pykd/pytypeinfo.cpp @@ -179,46 +179,36 @@ python::list TypeInfoAdapter::getBaseClasses(kdlib::TypeInfo &typeInfo) kdlib::TypeInfoPtr TypeInfoAdapter::getElementAttr(kdlib::TypeInfo &typeInfo, const std::wstring &name) { - { - AutoRestorePyState pystate; + AutoRestorePyState pystate; - try { - return typeInfo.getElement(name); - } - catch (kdlib::TypeException&) - {} - - try { - return typeInfo.getMethod(name); - } - catch (kdlib::TypeException&) - {} + try { + return typeInfo.getElement(name); } + catch (kdlib::TypeException&) + {} - std::wstringstream sstr; - sstr << L'\'' << typeInfo.getName() << L'\'' << L" type has no field " << L'\'' << name << L'\''; - throw AttributeException(std::string(_bstr_t(sstr.str().c_str())).c_str()); + return typeInfo.getMethod(name); } /////////////////////////////////////////////////////////////////////////////// kdlib::TypeInfoPtr TypeInfoAdapter::getElementByKey(kdlib::TypeInfo &typeInfo, const std::wstring &name) { - { - AutoRestorePyState pystate; - try { - return typeInfo.getElement(name); - } - catch (kdlib::TypeException&) - {} + AutoRestorePyState pystate; - try { - return typeInfo.getMethod(name); - } - catch (kdlib::TypeException&) - {} + try { + return typeInfo.getElement(name); } + catch (kdlib::TypeException&) + {} + + try { + return typeInfo.getMethod(name); + } + catch (kdlib::TypeException&) + {} + std::wstringstream sstr; sstr << L'\'' << typeInfo.getName() << L'\'' << L" type has no field " << L'\'' << name << L'\''; diff --git a/test/scripts/moduletest.py b/test/scripts/moduletest.py index 2dd035f..7e35ca7 100644 --- a/test/scripts/moduletest.py +++ b/test/scripts/moduletest.py @@ -145,6 +145,20 @@ class ModuleTest( unittest.TestCase ): self.assertFalse("NotExist" in target.module) self.assertRaises(Exception, lambda md : 2 in md, target.module) + def testHasAttr(self): + self.assertTrue(hasattr(target.module, "voidPtr")) + self.assertTrue(hasattr(target.module, "structTest")) + self.assertFalse(hasattr(target.module, "NotExist")) + self.assertRaises(Exception, lambda md : hasattr(2, target.module), target.module) + + def testGetByKey(self): + self.assertFalse(None == target.module["voidPtr"]) + self.assertFalse(None == target.module["structTest"] ) + self.assertRaises(KeyError, lambda md : target.module["Not Exist"], target.module) + + def testEvalInModuleScope(self): + self.assertEqual( target.module.rva('voidPtr'), eval("voidPtr - %#x" % target.module.begin(), globals(), target.module) ) + def testPrint(self): modAsStr = str(target.module) diff --git a/test/scripts/typedvar.py b/test/scripts/typedvar.py index 7c25d19..1d96eff 100644 --- a/test/scripts/typedvar.py +++ b/test/scripts/typedvar.py @@ -87,7 +87,7 @@ class TypedVarTest( unittest.TestCase ): self.assertEqual( True, tv1.m_field2 ) self.assertEqual( 1, tv1.m_field3 ) self.assertEqual( 1, tv1["m_field3"] ) - self.assertRaises( AttributeError, lambda t: t.not_exists, tv1) # non-exsisting field + self.assertRaises( pykd.SymbolException, lambda t: t.not_exists, tv1) # non-exsisting field self.assertRaises( KeyError, lambda t: t["not_exists"], tv1) # non-exsisting field def testPtrField(self): @@ -442,7 +442,11 @@ class TypedVarTest( unittest.TestCase ): self.assertEqual(11, getattr(var, "m_field1")) self.assertFalse(hasattr(var, "noexisit")) - self.assertRaises(AttributeError, getattr, *(var, "noexists")) + self.assertRaises(pykd.SymbolException, lambda x: getattr(x, "noexists"), var) + + def testEvalPyScope(self): + var = target.module.typedVar("structTest", [0x55] * 20 ) + self.assertEqual( var.m_field1 * 17, eval("m_field1 * 17", globals(), var) ) def testEvalExpr(self): self.assertEqual( 2+2, pykd.evalExpr("2+2") ) diff --git a/test/scripts/typeinfo.py b/test/scripts/typeinfo.py index 26156ec..aea9cd4 100644 --- a/test/scripts/typeinfo.py +++ b/test/scripts/typeinfo.py @@ -40,11 +40,11 @@ class TypeInfoTest( unittest.TestCase ): """ get field of the complex type """ ti1 = target.module.type( "structTest" ) self.assertTrue( "UInt4B", ti1.m_field0.name() ) - self.assertTrue( "UInt4B", ti1["m_field0"].name() ) + #self.assertTrue( "UInt4B", ti1["m_field0"].name() ) self.assertTrue( hasattr( ti1, "m_field0" ) ) self.assertFalse( hasattr( ti1, "not_exists" ) ) - self.assertRaises( AttributeError, lambda t: t.not_exists, ti1) # non-exsisting field - self.assertRaises( KeyError, lambda t: t["not_exists"], ti1) # non-exsisting field + self.assertRaises( pykd.SymbolException, lambda t: t.not_exists, ti1) # non-exsisting field + #self.assertRaises( KeyError, lambda t: t["not_exists"], ti1) # non-exsisting field def testBaseTypes( self ):