diff --git a/pykd/pymod.cpp b/pykd/pymod.cpp index ccab5af..c712171 100644 --- a/pykd/pymod.cpp +++ b/pykd/pymod.cpp @@ -887,7 +887,7 @@ void pykd_init() .def("getFixedFileInfo", ModuleAdapter::getFixedFileInfo, "Return FixedFileInfo" ) .def("hasSymbol", ModuleAdapter::isContainedSymbol, - "Check if module has the specified symbol") + "Check if a module has the specified symbol") .def("__getattr__", ModuleAdapter::getAttrByName, "Return symbol offset or type as attribute" ) .def("__getitem__", ModuleAdapter::getItemByKey, @@ -1037,13 +1037,17 @@ void pykd_init() "Set field of structure") .def("setField", TypedVarAdapter::setElementByIndex, "Set field of a structire or an element od array") + .def("hasField", TypedVarAdapter::hasField, + "Check if a typedVar object has the specified field") .def( "fields", TypedVarAdapter::getFields, "Return list of tuple ( filedName, fieldOffset, fieldValue )" ) .def( "fieldName", TypedVarAdapter::getElementName, "Return name of struct field by index" ) .def("method", TypedVarAdapter::getMethodByName, ( python::arg("name"), python::arg("prototype") = "" ), "Return method of class as an object attribute" ) - .def("deref",TypedVarAdapter::deref, + .def("hasMethod", TypedVarAdapter::hasMethod, + "Check if a typedVar object has the specified method") + .def("deref",TypedVarAdapter::deref, "Return value by pointer" ) .def("rawBytes", TypedVarAdapter::getRawBytes, "Return list of bytes" ) @@ -1066,7 +1070,7 @@ void pykd_init() .def("__dir__", TypedVarAdapter::getElementsDir) .def("__call__", python::raw_function(pykd::callFunctionByVar, 0) ) .def("__iter__", TypedVarAdapter::getArrayIter, python::return_value_policy()) - .def("__contains__", TypedVarAdapter::isContainedField) + .def("__contains__", TypedVarAdapter::hasField) #if PY_VERSION_HEX >= 0x03000000 .def("__bool__", TypedVarAdapter::isNotZero) #else diff --git a/pykd/pytypedvar.cpp b/pykd/pytypedvar.cpp index 5ef12c9..2b6d915 100644 --- a/pykd/pytypedvar.cpp +++ b/pykd/pytypedvar.cpp @@ -138,7 +138,7 @@ python::list TypedVarAdapter::getFields( kdlib::TypedVar& typedVar ) /////////////////////////////////////////////////////////////////////////////// -bool TypedVarAdapter::isContainedField(kdlib::TypedVarPtr& typedVar, const std::wstring& fieldName) +bool TypedVarAdapter::hasField(kdlib::TypedVarPtr& typedVar, const std::wstring &fieldName) { AutoRestorePyState pystate; @@ -154,6 +154,23 @@ bool TypedVarAdapter::isContainedField(kdlib::TypedVarPtr& typedVar, const std:: /////////////////////////////////////////////////////////////////////////////// +bool TypedVarAdapter::hasMethod(kdlib::TypedVarPtr& typedVar, const std::wstring &name) +{ + AutoRestorePyState pystate; + + try { + typedVar->getMethod(name); + return true; + } + catch (kdlib::DbgException&) + { + } + + return false; +} + +/////////////////////////////////////////////////////////////////////////////// + python::list TypedVarAdapter::getElementsDir(kdlib::TypedVar& typedVar) { std::list lst; @@ -197,32 +214,8 @@ kdlib::TypedVarPtr TypedVarAdapter::getFieldAttr(kdlib::TypedVar& typedVar, cons {} 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()); } - /////////////////////////////////////////////////////////////////////////////// python::list TypedVarAdapter::getRawBytes(kdlib::TypedVar& typedVar) @@ -291,7 +284,6 @@ void TypedVarAdapter::setFieldAttr(kdlib::TypedVar& typedVar, const std::wstring kdlib::TypedVarPtr TypedVarAdapter::getFieldByKey(kdlib::TypedVar& typedVar, const std::wstring &name) { { - AutoRestorePyState pystate; try diff --git a/pykd/pytypedvar.h b/pykd/pytypedvar.h index 1e20cf8..53e485b 100644 --- a/pykd/pytypedvar.h +++ b/pykd/pytypedvar.h @@ -143,6 +143,10 @@ struct TypedVarAdapter { static void setField(kdlib::TypedVar& typedVar, const std::wstring &name, python::object& object); + static bool hasField(kdlib::TypedVarPtr& typedVar, const std::wstring &name); + + static bool hasMethod(kdlib::TypedVarPtr& typedVar, const std::wstring &name); + static kdlib::TypedVarPtr getFieldAttr(kdlib::TypedVar& typedVar, const std::wstring &name); static void setFieldAttr(kdlib::TypedVar& typedVar, const std::wstring &name, python::object& object); @@ -229,7 +233,6 @@ struct TypedVarAdapter { return new TypedVarIterator(typedVar); } - static bool isContainedField(kdlib::TypedVarPtr& typedVar, const std::wstring& fieldName); }; kdlib::TypedValue getTypdedValueFromPyObj(const python::object& value); diff --git a/test/scripts/typedvar.py b/test/scripts/typedvar.py index 1d96eff..251fef7 100644 --- a/test/scripts/typedvar.py +++ b/test/scripts/typedvar.py @@ -437,11 +437,8 @@ class TypedVarTest( unittest.TestCase ): def testAttr(self): var = target.module.typedVar("structTest", [0x55] * 20 ) - self.assertTrue(hasattr(var, "m_field3")) setattr(var, "m_field1", 11) self.assertEqual(11, getattr(var, "m_field1")) - - self.assertFalse(hasattr(var, "noexisit")) self.assertRaises(pykd.SymbolException, lambda x: getattr(x, "noexists"), var) def testEvalPyScope(self): @@ -465,8 +462,8 @@ class TypedVarTest( unittest.TestCase ): v1 = 100 v2 = -500 scope = { "v1" : v1, "v2" : v2 } - self.assertEqual( v1 + v2, pykd.evalExpr("v1 + v2", scope) ) - self.assertEqual( v1 * v2, pykd.evalExpr("v1 * v2", locals()) ) + self.assertEqual( v1 + v2, pykd.evalExpr("v1 + v2", scope)) + self.assertEqual( v1 * v2, pykd.evalExpr("v1 * v2", locals())) def testEvalExprScopeStruct(self): var = pykd.typedVar("g_structTest1") @@ -485,4 +482,15 @@ class TypedVarTest( unittest.TestCase ): self.assertFalse("NotExist" in var) self.assertRaises(Exception, lambda var : 2 in var, var) + def testHasField(self): + var = pykd.typedVar("g_structTest") + self.assertTrue(var.hasField("m_field1")) + self.assertFalse(var.hasField("NotExist")) + def testHasMethod(self): + var = pykd.typedVar("g_classChild") + self.assertTrue(var.hasMethod("childMethod")) + self.assertTrue(var.hasMethod("staticMethod")) + self.assertTrue(var.hasMethod("virtMethod1")) + self.assertFalse(var.hasMethod("notExist")) +