From 0398c9358e1ed035f0a45f917005fc8b954f8fd1 Mon Sep 17 00:00:00 2001 From: "SND\\kernelnet_cp" Date: Tue, 11 Feb 2014 07:52:59 +0000 Subject: [PATCH] [0.2.x] fixed : issue #12739 ( How to use getParams()? ) git-svn-id: https://pykd.svn.codeplex.com/svn@87274 9b283d60-5439-405e-af05-b73fd8c4d996 --- pykd/pykdver.h | 2 +- pykd/python/pymod.cpp | 5 +- pykd/stkframe.cpp | 168 ++++++++++++++++++++++++++++++++++--- pykd/stkframe.h | 13 +++ pykd/variant.h | 8 +- test/scripts/intbase.py | 4 + test/scripts/localstest.py | 9 +- test/scripts/pykdtest.py | 2 +- 8 files changed, 192 insertions(+), 19 deletions(-) diff --git a/pykd/pykdver.h b/pykd/pykdver.h index 3081774..1e7a057 100644 --- a/pykd/pykdver.h +++ b/pykd/pykdver.h @@ -2,7 +2,7 @@ #define PYKD_VERSION_MAJOR 0 #define PYKD_VERSION_MINOR 2 #define PYKD_VERSION_SUBVERSION 0 -#define PYKD_VERSION_BUILDNO 27 +#define PYKD_VERSION_BUILDNO 28 #define __VER_STR2__(x) #x diff --git a/pykd/python/pymod.cpp b/pykd/python/pymod.cpp index 4eb7fa4..0e0c723 100644 --- a/pykd/python/pymod.cpp +++ b/pykd/python/pymod.cpp @@ -77,7 +77,7 @@ BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( Module_findSymbol, Module::getSymbolName BOOST_PYTHON_MODULE( pykd ) { - python::scope().attr("version") = pykdVersion; + python::scope().attr("__version__") = pykdVersion; // DbgEng services python::def( "setSymSrvDir", &setSymSrvDir, @@ -574,7 +574,8 @@ BOOST_PYTHON_MODULE( pykd ) "Class for access to local vars", python::no_init ) .def("__len__", &ScopeVars::getVarCount ) .def("__getitem__", &ScopeVars::getVarByIndex ) - .def("__getitem__", &ScopeVars::getVarByName ); + .def("__getitem__", &ScopeVars::getVarByName ) + .def("__contains__", &ScopeVars::isContainsVar ); python::class_( "stackFrame", "Class representing a frame of the call stack", python::no_init ) diff --git a/pykd/stkframe.cpp b/pykd/stkframe.cpp index f66d594..fbc1488 100644 --- a/pykd/stkframe.cpp +++ b/pykd/stkframe.cpp @@ -260,15 +260,20 @@ python::object StackFrame::getParamByName( const std::string& name ) //////////////////////////////////////////////////////////////////////////////// -ULONG StackFrame::getLocalCount() +bool StackFrame::isContainsLocal( const std::string& name ) { - ULONG count = 0; - - ModulePtr mod; - mod = Module::loadModuleByOffset( m_instructionOffset); + ModulePtr mod = Module::loadModuleByOffset( m_instructionOffset); LONG displacemnt; - SymbolPtr func = mod->getSymbolByVa( m_instructionOffset, SymTagFunction, &displacemnt ); + SymbolPtr func; + + try { + func = mod->getSymbolByVa( m_instructionOffset, SymTagFunction, &displacemnt ); + } + catch(SymbolException&) + { + return false; + } #ifdef _DEBUG std::string funcName; @@ -277,7 +282,120 @@ ULONG StackFrame::getLocalCount() if (!IsInDebugRange(func, static_cast( m_instructionOffset - mod->getBase()))) { - throw DbgException("is not debug range"); + return false; + } + + // find var in current scope + SymbolPtrList symList = func->findChildren(SymTagData); + SymbolPtrList::iterator itVar = symList.begin(); + for (; itVar != symList.end(); ++itVar) + { + if ( (*itVar)->getName() == name ) + { + return true; + } + } + + if ( itVar == symList.end() ) + { + // find inners scopes + SymbolPtrList scopeList = func->findChildren(SymTagBlock); + SymbolPtrList::iterator itScope = scopeList.begin(); + + ULONG ipRva = static_cast( m_instructionOffset - mod->getBase()); + + for (; itScope != scopeList.end(); ++itScope) + { + SymbolPtr scope = *itScope; + ULONG scopeRva = scope->getRva(); + if (scopeRva <= ipRva && (scopeRva + scope->getSize()) > ipRva) + { + SymbolPtrList symList = scope->findChildren(SymTagData); + SymbolPtrList::iterator itVar = symList.begin(); + + for (; itVar != symList.end(); ++itVar) + { + if ( (*itVar)->getName() == name ) + { + return true; + } + } + } + } + } + + return false; +} + +//////////////////////////////////////////////////////////////////////////////// + +bool StackFrame::isContainsParam( const std::string& name ) +{ + ModulePtr mod = Module::loadModuleByOffset( m_instructionOffset); + + LONG displacemnt; + SymbolPtr func; + + try { + func = mod->getSymbolByVa( m_instructionOffset, SymTagFunction, &displacemnt ); + } + catch(SymbolException&) + { + return false; + } + +#ifdef _DEBUG + std::string funcName; + funcName = func->getName(); +#endif // _DEBUG + + if (!IsInDebugRange(func, static_cast( m_instructionOffset - mod->getBase()))) + { + return false; + } + + // find var in current scope + SymbolPtrList symList = func->findChildren(SymTagData); + SymbolPtrList::iterator itVar = symList.begin(); + for (; itVar != symList.end(); ++itVar) + { + if ( (*itVar)->getDataKind() == DataIsParam && (*itVar)->getName() == name ) + { + return true; + } + } + + return false; +} + +//////////////////////////////////////////////////////////////////////////////// + +ULONG StackFrame::getLocalCount() +{ + ULONG count = 0; + + ModulePtr mod; + mod = Module::loadModuleByOffset( m_instructionOffset); + + LONG displacemnt; + SymbolPtr func; + + try { + func = mod->getSymbolByVa( m_instructionOffset, SymTagFunction, &displacemnt ); + } + catch(SymbolException&) + { + return 0; + } + +#ifdef _DEBUG + std::string funcName; + funcName = func->getName(); +#endif // _DEBUG + + if (!IsInDebugRange(func, static_cast( m_instructionOffset - mod->getBase()))) + { + return 0; } // find var in current scope @@ -320,7 +438,15 @@ ULONG StackFrame::getParamCount() mod = Module::loadModuleByOffset( m_instructionOffset); LONG displacemnt; - SymbolPtr func = mod->getSymbolByVa( m_instructionOffset, SymTagFunction, &displacemnt ); + SymbolPtr func; + + try { + func = mod->getSymbolByVa( m_instructionOffset, SymTagFunction, &displacemnt ); + } + catch(SymbolException&) + { + return 0; + } #ifdef _DEBUG std::string funcName; @@ -329,7 +455,7 @@ ULONG StackFrame::getParamCount() if (!IsInDebugRange(func, static_cast( m_instructionOffset - mod->getBase()))) { - throw DbgException("is not debug range"); + return 0; } // find var in current scope @@ -352,7 +478,15 @@ python::object StackFrame::getLocalByIndex( ULONG index ) ModulePtr mod = Module::loadModuleByOffset( m_instructionOffset); LONG displacemnt; - SymbolPtr func = mod->getSymbolByVa( m_instructionOffset, SymTagFunction, &displacemnt ); + SymbolPtr func; + + try { + func = mod->getSymbolByVa( m_instructionOffset, SymTagFunction, &displacemnt ); + } + catch(SymbolException&) + { + throw PyException( PyExc_IndexError, "index out of range" ); + } #ifdef _DEBUG std::string funcName; @@ -361,7 +495,7 @@ python::object StackFrame::getLocalByIndex( ULONG index ) if (!IsInDebugRange(func, static_cast( m_instructionOffset - mod->getBase()))) { - throw DbgException("is not debug range"); + throw PyException( PyExc_IndexError, "index out of range" ); } // find var in current scope @@ -445,7 +579,15 @@ python::object StackFrame::getParamByIndex( ULONG index ) ModulePtr mod = Module::loadModuleByOffset( m_instructionOffset); LONG displacemnt; - SymbolPtr func = mod->getSymbolByVa( m_instructionOffset, SymTagFunction, &displacemnt ); + SymbolPtr func; + + try { + func = mod->getSymbolByVa( m_instructionOffset, SymTagFunction, &displacemnt ); + } + catch(SymbolException&) + { + throw PyException( PyExc_IndexError, "index out of range" ); + } #ifdef _DEBUG std::string funcName; @@ -454,7 +596,7 @@ python::object StackFrame::getParamByIndex( ULONG index ) if (!IsInDebugRange(func, static_cast( m_instructionOffset - mod->getBase()))) { - throw DbgException("is not debug range"); + throw PyException( PyExc_IndexError, "index out of range" ); } // find var in current scope diff --git a/pykd/stkframe.h b/pykd/stkframe.h index 0afa784..6d56f48 100644 --- a/pykd/stkframe.h +++ b/pykd/stkframe.h @@ -46,6 +46,10 @@ public: python::object getParamByName( const std::string& name ); + bool isContainsLocal( const std::string& name ); + + bool isContainsParam( const std::string& name ); + python::object getLocalByIndex( ULONG index ); python::object getParamByIndex( ULONG index ); @@ -71,6 +75,7 @@ public: virtual ULONG getVarCount() const = 0; virtual python::object getVarByName( const std::string &name ) = 0; virtual python::object getVarByIndex(ULONG index) const = 0 ; + virtual bool isContainsVar( const std::string &name ) = 0; protected: @@ -100,6 +105,10 @@ private: python::object getVarByIndex(ULONG index) const { return m_frame->getLocalByIndex( index ); } + + bool isContainsVar( const std::string &name ) { + return m_frame->isContainsLocal(name); + } }; @@ -124,6 +133,10 @@ private: python::object getVarByIndex(ULONG index) const { return m_frame->getParamByIndex(index); } + + bool isContainsVar( const std::string &name ) { + return m_frame->isContainsParam(name); + } }; /////////////////////////////////////////////////////////////////////////////// diff --git a/pykd/variant.h b/pykd/variant.h index 9162db9..82c9144 100644 --- a/pykd/variant.h +++ b/pykd/variant.h @@ -231,7 +231,13 @@ public: } python::object nonzero() { - return boost::apply_visitor( VariantToPyobj(), getValue() ) != 0; + try { + return boost::apply_visitor( VariantToPyobj(), getValue() ) != 0; + } + catch( DbgException& ) + {} + + return python::object(true); } operator ULONG64() { diff --git a/test/scripts/intbase.py b/test/scripts/intbase.py index 557fc9e..b00d200 100644 --- a/test/scripts/intbase.py +++ b/test/scripts/intbase.py @@ -47,6 +47,10 @@ class IntBaseTest( unittest.TestCase ): self.assertTrue( -0x8000000000000000 - 1 != intBase(-0x8000000000000000) ) self.assertTrue( intBase(1) != intBase(2) ) + def testIs( self ): + a = b = intBase(0x1) + self.assertTrue( a is b ) + def testLtGt( self ): self.assertTrue( 0xFE < intBase(0xFF) and intBase(0xFE) < 0xFF ) self.assertFalse( -99 < intBase(-100) and intBase(-99) < - 100 ) diff --git a/test/scripts/localstest.py b/test/scripts/localstest.py index 403e748..1857aae 100644 --- a/test/scripts/localstest.py +++ b/test/scripts/localstest.py @@ -46,4 +46,11 @@ class LocalVarsTest(unittest.TestCase): funcParams = pykd.getParams() self.assertEqual( len(funcParams), 2 ) self.assertTrue( funcParams[0] == 7 or funcParams[1] == 7 ) - + + def testNoLocals(self): + """Start new process and test local variables""" + _locProcessId = pykd.startProcess( target.appPath + " -testEnumWindows" ) + with testutils.ContextCallIt( testutils.KillProcess(_locProcessId) ) as killStartedProcess : + #initial break + self.assertEqual(0, len(pykd.getLocals())) + self.assertEqual(0, len(pykd.getParams())) diff --git a/test/scripts/pykdtest.py b/test/scripts/pykdtest.py index 25f7517..ffa3f7e 100644 --- a/test/scripts/pykdtest.py +++ b/test/scripts/pykdtest.py @@ -70,7 +70,7 @@ def getTestSuite( singleName = "" ): if __name__ == "__main__": - print "\nTesting PyKd ver. " + pykd.version + print "\nTesting PyKd ver. " + pykd.__version__ target.appPath = sys.argv[1] target.moduleName = os.path.splitext(os.path.basename(target.appPath))[0]