mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-21 04:13:22 +08:00
added special method __contains__ for typedVar, typeInfo, module classes - support for 'in' operator
This commit is contained in:
parent
d7c18187af
commit
99b48ad0b4
@ -876,6 +876,7 @@ void pykd_init()
|
|||||||
"Return FixedFileInfo" )
|
"Return FixedFileInfo" )
|
||||||
.def("__getattr__", ModuleAdapter::getSymbolVaAttr,
|
.def("__getattr__", ModuleAdapter::getSymbolVaAttr,
|
||||||
"Return address of the symbol" )
|
"Return address of the symbol" )
|
||||||
|
.def("__contains__", ModuleAdapter::isContainedSymbol)
|
||||||
.def( "__str__", &ModuleAdapter::print );
|
.def( "__str__", &ModuleAdapter::print );
|
||||||
|
|
||||||
python::class_<kdlib::TypeInfo, kdlib::TypeInfoPtr, python::bases<kdlib::NumConvertable>, boost::noncopyable >("typeInfo", "Class representing typeInfo", python::no_init )
|
python::class_<kdlib::TypeInfo, kdlib::TypeInfoPtr, python::bases<kdlib::NumConvertable>, boost::noncopyable >("typeInfo", "Class representing typeInfo", python::no_init )
|
||||||
@ -971,6 +972,7 @@ void pykd_init()
|
|||||||
.def( "__getitem__", TypeInfoAdapter::getElementByIndex )
|
.def( "__getitem__", TypeInfoAdapter::getElementByIndex )
|
||||||
.def( "__getitem__", TypeInfoAdapter::getElementByKey )
|
.def( "__getitem__", TypeInfoAdapter::getElementByKey )
|
||||||
.def( "__dir__", TypeInfoAdapter::getElementDir )
|
.def( "__dir__", TypeInfoAdapter::getElementDir )
|
||||||
|
.def("__contains__", TypeInfoAdapter::isContainedField)
|
||||||
#if PY_VERSION_HEX >= 0x03000000
|
#if PY_VERSION_HEX >= 0x03000000
|
||||||
.def("__bool__", TypeInfoAdapter::isZero )
|
.def("__bool__", TypeInfoAdapter::isZero )
|
||||||
#else
|
#else
|
||||||
@ -1044,7 +1046,7 @@ void pykd_init()
|
|||||||
.def("__dir__", TypedVarAdapter::getElementsDir)
|
.def("__dir__", TypedVarAdapter::getElementsDir)
|
||||||
.def("__call__", python::raw_function(pykd::callFunctionByVar, 0) )
|
.def("__call__", python::raw_function(pykd::callFunctionByVar, 0) )
|
||||||
.def("__iter__", TypedVarAdapter::getArrayIter, python::return_value_policy<python::manage_new_object>())
|
.def("__iter__", TypedVarAdapter::getArrayIter, python::return_value_policy<python::manage_new_object>())
|
||||||
//.def("__getitem__", &kdlib::TypedVar::getElementByIndexPtr )
|
.def("__contains__", TypedVarAdapter::isContainedField)
|
||||||
#if PY_VERSION_HEX >= 0x03000000
|
#if PY_VERSION_HEX >= 0x03000000
|
||||||
.def("__bool__", TypedVarAdapter::isNotZero)
|
.def("__bool__", TypedVarAdapter::isNotZero)
|
||||||
#else
|
#else
|
||||||
|
@ -103,6 +103,15 @@ python::list ModuleAdapter::enumTypes(kdlib::Module& module, const std::wstring
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool ModuleAdapter::isContainedSymbol(kdlib::ModulePtr& module, const std::wstring& symbolName)
|
||||||
|
{
|
||||||
|
if (!module->enumSymbols(symbolName).empty())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return !module->enumTypes(symbolName).empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
std::wstring ModuleAdapter::findSymbol( kdlib::Module& module, kdlib::MEMOFFSET_64 offset, bool showDisplacement )
|
std::wstring ModuleAdapter::findSymbol( kdlib::Module& module, kdlib::MEMOFFSET_64 offset, bool showDisplacement )
|
||||||
{
|
{
|
||||||
|
@ -198,6 +198,7 @@ struct ModuleAdapter : public kdlib::Module
|
|||||||
|
|
||||||
static python::list getTypedVarArrayByTypeName( kdlib::Module& module, kdlib::MEMOFFSET_64 offset, const std::wstring &typeName, size_t number );
|
static python::list getTypedVarArrayByTypeName( kdlib::Module& module, kdlib::MEMOFFSET_64 offset, const std::wstring &typeName, size_t number );
|
||||||
|
|
||||||
|
static bool isContainedSymbol(kdlib::ModulePtr& module, const std::wstring& symbolName);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace pykd
|
} // end namespace pykd
|
||||||
|
@ -138,6 +138,22 @@ python::list TypedVarAdapter::getFields( kdlib::TypedVar& typedVar )
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool TypedVarAdapter::isContainedField(kdlib::TypedVarPtr& typedVar, const std::wstring& fieldName)
|
||||||
|
{
|
||||||
|
AutoRestorePyState pystate;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < typedVar->getElementCount(); ++i)
|
||||||
|
{
|
||||||
|
std::wstring name = typedVar->getElementName(i);
|
||||||
|
if (name == fieldName)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
python::list TypedVarAdapter::getElementsDir(kdlib::TypedVar& typedVar)
|
python::list TypedVarAdapter::getElementsDir(kdlib::TypedVar& typedVar)
|
||||||
{
|
{
|
||||||
std::list<std::wstring> lst;
|
std::list<std::wstring> lst;
|
||||||
@ -306,28 +322,40 @@ void TypedVarAdapter::setFieldByKey(kdlib::TypedVar& typedVar, const std::wstrin
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
kdlib::TypedVarPtr evalExpr(const std::string expression, python::dict& scope, kdlib::TypeInfoProviderPtr& typeInfoProvider )
|
class PyScope : public kdlib::Scope
|
||||||
{
|
{
|
||||||
std::list < std::pair<std::wstring, kdlib::TypedValue> > scopeList;
|
public:
|
||||||
|
|
||||||
for (auto i = 0; i < python::len(scope); ++i)
|
kdlib::TypedValue get(const std::wstring& varName) const override
|
||||||
{
|
{
|
||||||
auto key = scope.keys()[i];
|
return getTypdedValueFromPyObj(m_scope[varName]);
|
||||||
|
|
||||||
std::wstring varName = python::extract<std::wstring>(key);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
scopeList.push_back(std::make_pair(varName, getTypdedValueFromPyObj(scope[key])));
|
|
||||||
}
|
|
||||||
catch (kdlib::DbgException&)
|
|
||||||
{ }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AutoRestorePyState pystate;
|
virtual bool find(const std::wstring& varName, kdlib::TypedValue& value) const override
|
||||||
|
{
|
||||||
|
if (!m_scope.contains(varName))
|
||||||
|
return false;
|
||||||
|
|
||||||
if (!scopeList.empty() )
|
value = getTypdedValueFromPyObj(m_scope[varName]);
|
||||||
return kdlib::evalExpr(expression, makeScope(scopeList), typeInfoProvider).get();
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
PyScope(const python::object& scope) :
|
||||||
|
m_scope(scope)
|
||||||
|
{}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
python::object m_scope;
|
||||||
|
};
|
||||||
|
|
||||||
|
kdlib::TypedVarPtr evalExpr(const std::string expression, python::object& scope, kdlib::TypeInfoProviderPtr& typeInfoProvider )
|
||||||
|
{
|
||||||
|
if (scope)
|
||||||
|
{
|
||||||
|
return kdlib::evalExpr(expression, kdlib::ScopePtr(new PyScope(scope)), typeInfoProvider).get();
|
||||||
|
}
|
||||||
|
|
||||||
return kdlib::evalExpr(expression).get();
|
return kdlib::evalExpr(expression).get();
|
||||||
}
|
}
|
||||||
|
@ -228,11 +228,13 @@ struct TypedVarAdapter {
|
|||||||
{
|
{
|
||||||
return new TypedVarIterator(typedVar);
|
return new TypedVarIterator(typedVar);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool isContainedField(kdlib::TypedVarPtr& typedVar, const std::wstring& fieldName);
|
||||||
};
|
};
|
||||||
|
|
||||||
kdlib::TypedValue getTypdedValueFromPyObj(const python::object& value);
|
kdlib::TypedValue getTypdedValueFromPyObj(const python::object& value);
|
||||||
|
|
||||||
kdlib::TypedVarPtr evalExpr(const std::string expression, python::dict& scope = python::dict(), kdlib::TypeInfoProviderPtr& typeInfoProvider = kdlib::getDefaultTypeInfoProvider());
|
kdlib::TypedVarPtr evalExpr(const std::string expression, python::object& scope = python::object(), kdlib::TypeInfoProviderPtr& typeInfoProvider = kdlib::getDefaultTypeInfoProvider());
|
||||||
|
|
||||||
|
|
||||||
} // end namespace pykd
|
} // end namespace pykd
|
||||||
|
@ -103,6 +103,21 @@ python::list TypeInfoAdapter::getFields( kdlib::TypeInfo &typeInfo )
|
|||||||
return pylst;
|
return pylst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TypeInfoAdapter::isContainedField(kdlib::TypeInfoPtr& typeInfo, const std::wstring& fieldName)
|
||||||
|
{
|
||||||
|
|
||||||
|
AutoRestorePyState pystate;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < typeInfo->getElementCount(); ++i)
|
||||||
|
{
|
||||||
|
std::wstring name = typeInfo->getElementName(i);
|
||||||
|
if (name == fieldName)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
python::list TypeInfoAdapter::getMethods(kdlib::TypeInfo &typeInfo)
|
python::list TypeInfoAdapter::getMethods(kdlib::TypeInfo &typeInfo)
|
||||||
{
|
{
|
||||||
typedef boost::tuple<std::wstring, kdlib::TypeInfoPtr> FieldTuple;
|
typedef boost::tuple<std::wstring, kdlib::TypeInfoPtr> FieldTuple;
|
||||||
|
@ -334,6 +334,8 @@ struct TypeInfoAdapter : public kdlib::TypeInfo {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool isContainedField(kdlib::TypeInfoPtr& typedVar, const std::wstring& fieldName);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -139,4 +139,9 @@ class ModuleTest( unittest.TestCase ):
|
|||||||
def testModuleList(self):
|
def testModuleList(self):
|
||||||
self.assertTrue( [] != pykd.getModulesList() )
|
self.assertTrue( [] != pykd.getModulesList() )
|
||||||
|
|
||||||
|
def testContain(self):
|
||||||
|
self.assertTrue("voidPtr" in target.module)
|
||||||
|
self.assertTrue("structTest" in target.module)
|
||||||
|
self.assertFalse("NotExist" in target.module)
|
||||||
|
self.assertRaises(Exception, lambda md : 2 in md, target.module)
|
||||||
|
|
||||||
|
@ -443,7 +443,6 @@ class TypedVarTest( unittest.TestCase ):
|
|||||||
|
|
||||||
self.assertFalse(hasattr(var, "noexisit"))
|
self.assertFalse(hasattr(var, "noexisit"))
|
||||||
self.assertRaises(AttributeError, getattr, *(var, "noexists"))
|
self.assertRaises(AttributeError, getattr, *(var, "noexists"))
|
||||||
self.assertRaises(AttributeError, setattr, *(var, "noexists", 0))
|
|
||||||
|
|
||||||
def testEvalExpr(self):
|
def testEvalExpr(self):
|
||||||
self.assertEqual( 2+2, pykd.evalExpr("2+2") )
|
self.assertEqual( 2+2, pykd.evalExpr("2+2") )
|
||||||
@ -459,11 +458,21 @@ class TypedVarTest( unittest.TestCase ):
|
|||||||
self.assertEqual( v1 + v2.m_field1, pykd.evalExpr("v1 + v2.m_field1", scope) )
|
self.assertEqual( v1 + v2.m_field1, pykd.evalExpr("v1 + v2.m_field1", scope) )
|
||||||
|
|
||||||
def testEvalExprScopeLong(self):
|
def testEvalExprScopeLong(self):
|
||||||
|
|
||||||
v1 = 100
|
v1 = 100
|
||||||
v2 = -500
|
v2 = -500
|
||||||
scope = { "v1" : v1, "v2" : v2 }
|
scope = { "v1" : v1, "v2" : v2 }
|
||||||
self.assertEqual( v1 + v2, pykd.evalExpr("v1 + v2", scope) )
|
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", locals()) )
|
||||||
|
|
||||||
|
def testEvalExprScopeStruct(self):
|
||||||
|
var = pykd.typedVar("g_structTest1")
|
||||||
|
self.assertEqual(var.m_field1, pykd.evalExpr("m_field1", var))
|
||||||
|
self.assertEqual(var.m_field4.deref().m_field1, pykd.evalExpr("m_field4->m_field1", var))
|
||||||
|
|
||||||
|
def testContain(self):
|
||||||
|
var = pykd.typedVar("g_structTest")
|
||||||
|
self.assertTrue("m_field1" in var)
|
||||||
|
self.assertFalse("NotExist" in var)
|
||||||
|
self.assertRaises(Exception, lambda var : 2 in var, var)
|
||||||
|
|
||||||
|
|
||||||
|
@ -351,7 +351,6 @@ class TypeInfoTest( unittest.TestCase ):
|
|||||||
self.assertEqual( classChild.baseClassOffset(0), classChild.baseClassOffset('classBase1'))
|
self.assertEqual( classChild.baseClassOffset(0), classChild.baseClassOffset('classBase1'))
|
||||||
self.assertEqual(classChild.baseClassOffset(1), classChild.baseClassOffset('classBase2'))
|
self.assertEqual(classChild.baseClassOffset(1), classChild.baseClassOffset('classBase2'))
|
||||||
|
|
||||||
|
|
||||||
def testPdbTypeProvider(self):
|
def testPdbTypeProvider(self):
|
||||||
pdb = target.module.symfile()
|
pdb = target.module.symfile()
|
||||||
typeProvider = pykd.getTypeInfoProviderFromPdb(pdb)
|
typeProvider = pykd.getTypeInfoProviderFromPdb(pdb)
|
||||||
@ -363,5 +362,8 @@ class TypeInfoTest( unittest.TestCase ):
|
|||||||
self.assertEqual( target.module.name(), pykd.typeInfo( "structTest" ).scopeName() )
|
self.assertEqual( target.module.name(), pykd.typeInfo( "structTest" ).scopeName() )
|
||||||
self.assertEqual( target.module.name(), pykd.typeInfo( "structWithNested::Nested" ).scopeName() )
|
self.assertEqual( target.module.name(), pykd.typeInfo( "structWithNested::Nested" ).scopeName() )
|
||||||
|
|
||||||
|
def testContain(self):
|
||||||
|
ti = target.module.type( "structTest" )
|
||||||
|
self.assertTrue("m_field1" in ti)
|
||||||
|
self.assertFalse("NotExist" in ti)
|
||||||
|
self.assertRaises(Exception, lambda t : 2 in t, ti)
|
||||||
|
Loading…
Reference in New Issue
Block a user