mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-21 21:03:23 +08:00
added: evalExpr routine ( Evaluate C++ expression with typed information )
This commit is contained in:
parent
23c1376112
commit
fc90ccc846
2
kdlibcpp
2
kdlibcpp
@ -1 +1 @@
|
||||
Subproject commit f27cdbdaef5f68e6704d24beb208921a0a66da4b
|
||||
Subproject commit 809848cf36172dd3fe4c5781b9009d6bd49ca4c1
|
@ -2,7 +2,7 @@
|
||||
#define PYKD_VERSION_MAJOR 0
|
||||
#define PYKD_VERSION_MINOR 3
|
||||
#define PYKD_VERSION_SUBVERSION 4
|
||||
#define PYKD_VERSION_BUILDNO 2
|
||||
#define PYKD_VERSION_BUILDNO 3
|
||||
|
||||
#define __VER_STR2__(x) #x
|
||||
#define __VER_STR1__(x) __VER_STR2__(x)
|
||||
|
@ -104,6 +104,7 @@ BOOST_PYTHON_FUNCTION_OVERLOADS( TypeInfo_ptrTo, TypeInfoAdapter::ptrTo, 1, 2 );
|
||||
BOOST_PYTHON_FUNCTION_OVERLOADS( getTypeFromSource_, pykd::getTypeFromSource, 2, 3 );
|
||||
BOOST_PYTHON_FUNCTION_OVERLOADS( getTypeInfoProviderFromPdb_, pykd::getTypeInfoProviderFromPdb, 1, 2 );
|
||||
BOOST_PYTHON_FUNCTION_OVERLOADS( getTypeInfoProviderFromSource_, pykd::getTypeInfoProviderFromSource, 1, 2);
|
||||
BOOST_PYTHON_FUNCTION_OVERLOADS(evalExpr_, pykd::evalExpr, 1, 3);
|
||||
|
||||
namespace pykd {
|
||||
|
||||
@ -432,6 +433,9 @@ void pykd_init()
|
||||
"Create typeInfo provider from C/C++ source code") );
|
||||
python::def( "getTypeInfoProviderFromPdb", &pykd::getTypeInfoProviderFromPdb, getTypeInfoProviderFromPdb_( python::args("filePath", "baseOffset"),
|
||||
"Create typeInfo provider from pdb file") );
|
||||
python::def("evalExpr", &pykd::evalExpr, evalExpr_(python::args("expression", "scope", "typeProvider"),
|
||||
"Evaluate C++ expression with typed information"));
|
||||
|
||||
|
||||
// CPU registers
|
||||
python::def( "reg", pykd::getRegisterByName,
|
||||
|
@ -306,5 +306,45 @@ void TypedVarAdapter::setFieldByKey(kdlib::TypedVar& typedVar, const std::wstrin
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
kdlib::TypedVarPtr evalExpr(const std::string expression, python::dict& scope, kdlib::TypeInfoProviderPtr& typeInfoProvider )
|
||||
{
|
||||
std::list < std::pair<std::wstring, kdlib::TypedValue> > scopeList;
|
||||
|
||||
for (auto i = 0; i < python::len(scope); ++i)
|
||||
{
|
||||
auto key = scope.keys()[i];
|
||||
|
||||
std::wstring varName = python::extract<std::wstring>(key);
|
||||
|
||||
try
|
||||
{
|
||||
scopeList.push_back(std::make_pair(varName, getTypdedValueFromPyObj(scope[key])));
|
||||
}
|
||||
catch (kdlib::DbgException&)
|
||||
{ }
|
||||
}
|
||||
|
||||
AutoRestorePyState pystate;
|
||||
|
||||
if (!scopeList.empty() )
|
||||
return kdlib::evalExpr(expression, makeScope(scopeList), typeInfoProvider).get();
|
||||
|
||||
return kdlib::evalExpr(expression).get();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
kdlib::TypedValue getTypdedValueFromPyObj(const python::object& value)
|
||||
{
|
||||
python::extract<kdlib::TypedVarPtr> getTypedVar(value);
|
||||
if (getTypedVar.check())
|
||||
return getTypedVar();
|
||||
|
||||
return NumVariantAdaptor::convertToVariant(value);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
} // namespace pykd
|
||||
|
||||
|
@ -7,6 +7,7 @@
|
||||
namespace python = boost::python;
|
||||
|
||||
#include "kdlib/typedvar.h"
|
||||
#include "kdlib/typeinfo.h"
|
||||
|
||||
#include "stladaptor.h"
|
||||
#include "pythreadstate.h"
|
||||
@ -229,4 +230,9 @@ struct TypedVarAdapter {
|
||||
}
|
||||
};
|
||||
|
||||
kdlib::TypedValue getTypdedValueFromPyObj(const python::object& value);
|
||||
|
||||
kdlib::TypedVarPtr evalExpr(const std::string expression, python::dict& scope = python::dict(), kdlib::TypeInfoProviderPtr& typeInfoProvider = kdlib::getDefaultTypeInfoProvider());
|
||||
|
||||
|
||||
} // end namespace pykd
|
||||
|
@ -291,7 +291,6 @@ python::object callTypedVar(kdlib::TypedVarPtr& funcobj, python::tuple& args)
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if ( python::extract<int>(args[i]).check() )
|
||||
{
|
||||
kdlib::NumVariant var= NumVariantAdaptor::convertToVariant(args[i]);
|
||||
|
@ -411,9 +411,4 @@ struct BaseTypesEnum {
|
||||
static kdlib::TypeInfoPtr getDouble() { return pykd::getTypeInfoByName(L"Double"); }
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
} // end namespace pykd
|
||||
|
@ -14,12 +14,12 @@ class NumVariantAdaptor : public kdlib::NumConvertable
|
||||
|
||||
public:
|
||||
|
||||
static kdlib::NumVariant NumVariantAdaptor::convertToVariant( const python::object &obj)
|
||||
static kdlib::NumVariant convertToVariant(const python::object &obj)
|
||||
{
|
||||
kdlib::NumVariant var;
|
||||
|
||||
python::extract<kdlib::NumConvertable> getNumVar(obj);
|
||||
if ( getNumVar.check() )
|
||||
if (getNumVar.check())
|
||||
{
|
||||
var = getNumVar();
|
||||
return var;
|
||||
@ -49,6 +49,8 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
if (PyLong_Check(obj.ptr()))
|
||||
{
|
||||
if (_PyLong_Sign(obj.ptr()) >= 0)
|
||||
{
|
||||
if (_PyLong_NumBits(obj.ptr()) > 64)
|
||||
@ -64,10 +66,12 @@ public:
|
||||
var.setLongLong(PyLong_AsLongLong(obj.ptr()));
|
||||
}
|
||||
|
||||
|
||||
return var;
|
||||
}
|
||||
|
||||
throw kdlib::TypeException(L"failed convert argument");
|
||||
}
|
||||
|
||||
static python::object NumVariantAdaptor::convertToPython( const kdlib::NumVariant& var )
|
||||
{
|
||||
if ( var.isChar() )
|
||||
|
@ -8,7 +8,7 @@ import sys
|
||||
|
||||
_name = "pykd"
|
||||
_desc = "python windbg extension"
|
||||
_version = '0.3.4.1'
|
||||
_version = '0.3.4.2'
|
||||
|
||||
def getReleaseSrc():
|
||||
return 'Release_%d.%d' % sys.version_info[0:2]
|
||||
|
@ -91,7 +91,7 @@ if __name__ == "__main__":
|
||||
target.moduleName = os.path.splitext(os.path.basename(target.appPath))[0]
|
||||
|
||||
unittest.TextTestRunner(stream=sys.stdout, verbosity=2).run( getTestSuite() )
|
||||
#unittest.TextTestRunner(stream=sys.stdout, verbosity=2).run( getTestSuite("typedvar.TypedVarTest.testAttr") )
|
||||
#unittest.TextTestRunner(stream=sys.stdout, verbosity=2).run( getTestSuite("typedvar.TypedVarTest.testEvalExprScopeLong") )
|
||||
|
||||
try: input = raw_input
|
||||
except NameError: pass
|
||||
|
@ -444,3 +444,26 @@ class TypedVarTest( unittest.TestCase ):
|
||||
self.assertFalse(hasattr(var, "noexisit"))
|
||||
self.assertRaises(AttributeError, getattr, *(var, "noexists"))
|
||||
self.assertRaises(AttributeError, setattr, *(var, "noexists", 0))
|
||||
|
||||
def testEvalExpr(self):
|
||||
self.assertEqual( 2+2, pykd.evalExpr("2+2") )
|
||||
self.assertEqual( target.module.typedVar("g_structTest").m_field1, pykd.evalExpr("g_structTest.m_field1") )
|
||||
self.assertEqual( target.module.typedVar("g_testArray")[1].m_field3, pykd.evalExpr("(g_testArray + 1)->m_field3") )
|
||||
|
||||
def testEvalExprScope(self):
|
||||
|
||||
v1 = target.module.typedVar( "ulongVar" )
|
||||
v2 = target.module.typedVar( "g_structTest" )
|
||||
|
||||
scope = { "v1" : v1, "v2" : v2 }
|
||||
self.assertEqual( v1 + v2.m_field1, pykd.evalExpr("v1 + v2.m_field1", scope) )
|
||||
|
||||
def testEvalExprScopeLong(self):
|
||||
|
||||
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()) )
|
||||
|
||||
|
||||
|
@ -164,10 +164,10 @@ class TypeInfoTest( unittest.TestCase ):
|
||||
self.assertEqual( "structTest", ti.deref().name() )
|
||||
|
||||
ti = pykd.typeInfo("structTest[2]")
|
||||
self.assertRaises( pykd.TypeException, ti.deref );
|
||||
self.assertEqual( "structTest", ti.deref().name() )
|
||||
|
||||
ti = target.module.type("classChild")
|
||||
self.assertRaises( pykd.TypeException, ti.deref );
|
||||
self.assertRaises( pykd.TypeException, ti.deref )
|
||||
|
||||
def testNestedStruct( self ):
|
||||
ti = target.module.type("structWithNested")
|
||||
|
Loading…
Reference in New Issue
Block a user