From f21cda28f2924c1bbde416b7350d83054d4795da Mon Sep 17 00:00:00 2001 From: "SND\\kernelnet_cp" Date: Mon, 20 Jan 2014 11:03:43 +0000 Subject: [PATCH] [0.3.x] added : getLocal and getLocals routines git-svn-id: https://pykd.svn.codeplex.com/svn@87094 9b283d60-5439-405e-af05-b73fd8c4d996 --- pykd/dbgexcept.h | 3 ++ pykd/pycpucontext.cpp | 58 +++++++++++++++++++++++++++++++++++++++ pykd/pycpucontext.h | 19 +++++++++++++ pykd/pymod.cpp | 12 ++++++-- test/scripts/stacktest.py | 6 ++++ 5 files changed, 96 insertions(+), 2 deletions(-) diff --git a/pykd/dbgexcept.h b/pykd/dbgexcept.h index e6b4e7d..243f58b 100644 --- a/pykd/dbgexcept.h +++ b/pykd/dbgexcept.h @@ -98,5 +98,8 @@ void printException(); /////////////////////////////////////////////////////////////////////////////////// +#define PYKD_NOT_IMPLEMENTED() throw kdlib::ImplementException( __FILE__, __LINE__, "Not Implemented" ); +#define PYKD_TODO(x) throw kdlib::ImplementException( __FILE__, __LINE__, x ); + }; // namespace pykd diff --git a/pykd/pycpucontext.cpp b/pykd/pycpucontext.cpp index 15141a0..5ec7f1b 100644 --- a/pykd/pycpucontext.cpp +++ b/pykd/pycpucontext.cpp @@ -133,4 +133,62 @@ python::dict StackFrameAdapter::getParamsDict( kdlib::StackFramePtr& frame) /////////////////////////////////////////////////////////////////////////////// +python::list StackFrameAdapter::getLocalsList(kdlib::StackFramePtr& frame) +{ + typedef std::vector< std::pair< std::wstring, kdlib::TypedVarPtr> > LocalVarList; + + LocalVarList localLst; + unsigned long localCount; + + do { + AutoRestorePyState pystate; + localCount = frame->getLocalVarCount(); + for ( unsigned long i = 0; i < localCount; ++i ) + { + kdlib::TypedVarPtr param = frame->getLocalVar(i); + std::wstring paramName = frame->getLocalVarName(i); + + localLst.push_back( std::make_pair( paramName, param) ); + } + } while(false); + + python::list pyLst; + + for ( unsigned long i = 0; i < localCount; ++i ) + pyLst.append( python::make_tuple( localLst[i].first, localLst[i].second ) ); + + return pyLst; +} + +/////////////////////////////////////////////////////////////////////////////// + +python::dict StackFrameAdapter::getLocalsDict(kdlib::StackFramePtr& frame) +{ + typedef std::vector< std::pair< std::wstring, kdlib::TypedVarPtr> > LocalVarList; + + LocalVarList localLst; + unsigned long localCount; + + do { + AutoRestorePyState pystate; + localCount = frame->getLocalVarCount(); + for ( unsigned long i = 0; i < localCount; ++i ) + { + kdlib::TypedVarPtr param = frame->getLocalVar(i); + std::wstring paramName = frame->getLocalVarName(i); + + localLst.push_back( std::make_pair( paramName, param) ); + } + } while(false); + + python::dict pyLst; + + for ( unsigned long i = 0; i < localCount; ++i ) + pyLst[localLst[i].first] = localLst[i].second; + + return pyLst; +} + +/////////////////////////////////////////////////////////////////////////////// + } // end namespace pykd diff --git a/pykd/pycpucontext.h b/pykd/pycpucontext.h index 60711b7..a8ab3a5 100644 --- a/pykd/pycpucontext.h +++ b/pykd/pycpucontext.h @@ -7,6 +7,7 @@ namespace python = boost::python; #include "kdlib/cpucontext.h" #include "kdlib/stack.h" +#include "dbgexcept.h" #include "pythreadstate.h" namespace pykd { @@ -52,6 +53,15 @@ public: AutoRestorePyState pystate; return frame->getTypedParam(paramName); } + + static python::list getLocalsList(kdlib::StackFramePtr& frame); + + static python::dict getLocalsDict(kdlib::StackFramePtr& frame); + + static kdlib::TypedVarPtr getLocal( kdlib::StackFramePtr& frame, const std::wstring ¶mName ) { + AutoRestorePyState pystate; + return frame->getLocalVar(paramName); + } }; /////////////////////////////////////////////////////////////////////////////// @@ -112,6 +122,15 @@ inline kdlib::TypedVarPtr getParam( const std::wstring &name ) { return StackFrameAdapter::getParam( getCurrentFrame(), name ); } +inline python::list getLocals() { + return StackFrameAdapter::getLocalsList( getCurrentFrame() ); +} + +inline kdlib::TypedVarPtr getLocal( const std::wstring &name ) { + return StackFrameAdapter::getLocal( getCurrentFrame(), name ); +} + + class CPUContextAdapter { public: diff --git a/pykd/pymod.cpp b/pykd/pymod.cpp index 9e9c548..d3c95e1 100644 --- a/pykd/pymod.cpp +++ b/pykd/pymod.cpp @@ -317,8 +317,10 @@ BOOST_PYTHON_MODULE( pykd ) "Return a current stack frame" ); // python::def( "getStackWow64", &getCurrentStackWow64, // "Return a stack for wow64 context as a list of stackFrame objects" ); - // python::def( "getLocals", &getLocals, - // "Get list of local variables" ); + python::def( "getLocals", pykd::getLocals, + "Get list of local variables" ); + python::def( "getLocal", pykd::getLocal, + "Get the fucntion's local variable by name" ); python::def( "getParams", pykd::getParams, "Get list of function arguments as list of tuple (name, value ) " ); python::def( "getParam", pykd::getParam, @@ -617,6 +619,12 @@ BOOST_PYTHON_MODULE( pykd ) "return set of function's parameters as a dict (name : value)") .def( "getParam", StackFrameAdapter::getParam, "return function param by it's name") + .def( "getLocals", StackFrameAdapter::getLocalsList, + "return set of function's local variables as a list of tuple (name, value ) ") + .add_property("locals", StackFrameAdapter::getLocalsDict, + "return a set of function's local variables as a dict ( name : value)") + .def( "getLocal", StackFrameAdapter::getLocal, + "return the function's local variable by it's name") .def( "__str__", StackFrameAdapter::print ); python::class_( "cpu", diff --git a/test/scripts/stacktest.py b/test/scripts/stacktest.py index 7ef15bc..eba7d2b 100644 --- a/test/scripts/stacktest.py +++ b/test/scripts/stacktest.py @@ -38,3 +38,9 @@ class StackTest(unittest.TestCase): self.assertEqual( 10, pykd.getStack()[1].params["a"] ) self.assertEqual( 10, pykd.getStack()[1].getParam("a") ) self.assertEqual( 10, dict( pykd.getStack()[1].getParams() )["a"] ) + + def testGetLocals(self): + expectedLocals = ["localDouble", "localFloat", "localChars"] + self.assertEqual( expectedLocals, [name for name, param in pykd.getStack()[1].getLocals() ] ) + self.assertEqual( 0.0, pykd.getStack()[1].locals["localDouble"] ) +