diff --git a/kdlibcpp b/kdlibcpp index 8d28d97..b4c87ce 160000 --- a/kdlibcpp +++ b/kdlibcpp @@ -1 +1 @@ -Subproject commit 8d28d97eaa231f1c7c8147e9a54d71344deeea21 +Subproject commit b4c87cee2d2b6e373c4cc35bde49c60a777d0ecb diff --git a/pykd/pykdver.h b/pykd/pykdver.h index 3559c32..18ee4ea 100644 --- a/pykd/pykdver.h +++ b/pykd/pykdver.h @@ -2,7 +2,7 @@ #define PYKD_VERSION_MAJOR 0 #define PYKD_VERSION_MINOR 3 #define PYKD_VERSION_SUBVERSION 3 -#define PYKD_VERSION_BUILDNO 3 +#define PYKD_VERSION_BUILDNO 4 #define __VER_STR2__(x) #x #define __VER_STR1__(x) __VER_STR2__(x) diff --git a/pykd/pymod.cpp b/pykd/pymod.cpp index ce6a8d8..fafb1ba 100644 --- a/pykd/pymod.cpp +++ b/pykd/pymod.cpp @@ -878,6 +878,8 @@ BOOST_PYTHON_MODULE( pykd ) .def("__init__", python::make_constructor( pykd::getTypeInfoByName ) ) .def( "name", TypeInfoAdapter::getName, "Return type name" ) + .def("scopeName", TypeInfoAdapter::getScopeName, + "Return name of type scope ( module name )" ) .def( "size", TypeInfoAdapter::getSize, "Return type size" ) .def( "staticOffset", TypeInfoAdapter::getStaticOffset, @@ -1229,10 +1231,25 @@ BOOST_PYTHON_MODULE( pykd ) "Change the current instruction" ) .def( "__str__", DisasmAdapter::instruction ); + + python::class_("typeInfoProviderIterator", "iterator for type provider", python::no_init) + .def("__iter__", &TypeInfoProviderIterator::self) +#if PY_VERSION_HEX < 0x03000000 + .def("next", &TypeInfoProviderIterator::next) +#else + .def("__next__", &TypeInfoProviderIterator::next) +#endif + ; + + python::class_("typeInfoProvider", "Get abstaract access to different type info sources", python::no_init) .def( "getTypeByName", TypeInfoProviderAdapter::getTypeByName, "Get type info by it's name" ) + .def( "typeIterator", TypeInfoProviderAdapter::getTypeIterWithMask, python::return_value_policy(), + "Return type iterator with specified mask") + .def("__iter__", TypeInfoProviderAdapter::getTypeIter, python::return_value_policy()) + .def( "__getattr__", TypeInfoProviderAdapter::getTypeAsAttr ) ; python::enum_("eventResult", "Return value of event handler") @@ -1378,7 +1395,7 @@ BOOST_PYTHON_MODULE( pykd ) .value("FinalBreak", kdlib::FinalBreak) .value("PreferDml", kdlib::PreferDml) ; - + python::enum_("breakpointAccess", "Breakpoint access types") .value("Read", kdlib::Read) .value("Write", kdlib::Write) diff --git a/pykd/pytypeinfo.cpp b/pykd/pytypeinfo.cpp index 3f22af5..ab004a0 100644 --- a/pykd/pytypeinfo.cpp +++ b/pykd/pytypeinfo.cpp @@ -356,5 +356,21 @@ python::object callFunctionRaw( python::tuple& args, python::dict& kwargs) /////////////////////////////////////////////////////////////////////////////// +kdlib::TypeInfoPtr TypeInfoProviderAdapter::getTypeAsAttr(kdlib::TypeInfoProvider &typeInfoProvider, const std::wstring& name) +{ + + try { + AutoRestorePyState pystate; + return typeInfoProvider.getTypeByName(name); + } + catch (kdlib::TypeException&) + {} + + std::wstringstream sstr; + sstr << L'\'' << name << L'\'' << L" not found"; + throw AttributeException(std::string(_bstr_t(sstr.str().c_str())).c_str()); +} + +/////////////////////////////////////////////////////////////////////////////// } // pykd namespace diff --git a/pykd/pytypeinfo.h b/pykd/pytypeinfo.h index 2483bc3..de6ed01 100644 --- a/pykd/pytypeinfo.h +++ b/pykd/pytypeinfo.h @@ -83,6 +83,12 @@ struct TypeInfoAdapter : public kdlib::TypeInfo { return typeInfo.getName(); } + static std::wstring getScopeName( kdlib::TypeInfo &typeInfo ) + { + AutoRestorePyState pystate; + return typeInfo.getScopeName(); + } + static size_t getSize( kdlib::TypeInfo &typeInfo ) { AutoRestorePyState pystate; @@ -309,6 +315,38 @@ struct TypeInfoAdapter : public kdlib::TypeInfo { }; +class TypeInfoProviderIterator { + +public: + + TypeInfoProviderIterator(kdlib::TypeInfoEnumeratorPtr typeInfoEnum) : + m_typeInfoEnum(typeInfoEnum) + {} + + static python::object self(const python::object& obj) + { + return obj; + } + + kdlib::TypeInfoPtr next() + { + AutoRestorePyState pystate; + + kdlib::TypeInfoPtr typeInfo = m_typeInfoEnum->Next(); + + if (!typeInfo) + throw StopIteration("No more data."); + + return typeInfo; + } + + +private: + + kdlib::TypeInfoEnumeratorPtr m_typeInfoEnum; + +}; + struct TypeInfoProviderAdapter : public kdlib::TypeInfoProvider { @@ -317,6 +355,19 @@ struct TypeInfoProviderAdapter : public kdlib::TypeInfoProvider AutoRestorePyState pystate; return typeInfoProvider.getTypeByName(name); } + + static TypeInfoProviderIterator* getTypeIter( kdlib::TypeInfoProvider &typeInfoProvider ) + { + return new TypeInfoProviderIterator( typeInfoProvider.getTypeEnumerator() ); + }; + + static TypeInfoProviderIterator* getTypeIterWithMask( kdlib::TypeInfoProvider &typeInfoProvider, const std::wstring& mask) + { + return new TypeInfoProviderIterator( typeInfoProvider.getTypeEnumerator(mask) ); + } + + static kdlib::TypeInfoPtr getTypeAsAttr(kdlib::TypeInfoProvider &typeInfoProvider, const std::wstring& name); + }; struct BaseTypesEnum { @@ -338,4 +389,9 @@ struct BaseTypesEnum { static kdlib::TypeInfoPtr getDouble() { return pykd::getTypeInfoByName(L"Double"); } }; + + + + + } // end namespace pykd diff --git a/setup/setup.py b/setup/setup.py index 7723564..c2f35f7 100644 --- a/setup/setup.py +++ b/setup/setup.py @@ -8,7 +8,7 @@ import sys _name = "pykd" _desc = "python windbg extension" -_version = '0.3.3.2' +_version = '0.3.3.4' def getReleaseSrc(): return 'Release_%d.%d' % sys.version_info[0:2] diff --git a/snippets/stkwalk.py b/snippets/stkwalk.py index e04e3c1..12e6ed0 100644 --- a/snippets/stkwalk.py +++ b/snippets/stkwalk.py @@ -150,11 +150,13 @@ def printProcess(process,processFilter,threadFilter,moduleFilter,funcFilter,prin try: - setCPUMode(CPUType.I386) + dbgCommand(".thread /w %x" % thread) + #setCPUMode(CPUType.I386) - if not wow64reloaded: - dbgCommand( ".reload /user" ) - wow64reloaded = True + #if not wow64reloaded: + dbgCommand( ".reload /user" ) + # wow64reloaded = True + stkWow64 = getStack() except DbgException: diff --git a/test/scripts/typeinfo.py b/test/scripts/typeinfo.py index 9bfe190..94dd680 100644 --- a/test/scripts/typeinfo.py +++ b/test/scripts/typeinfo.py @@ -342,3 +342,16 @@ class TypeInfoTest( unittest.TestCase ): classChild = target.module.type("classChild") self.assertEqual( ["classBase1", "classBase2"], [ classChild.baseClass(i).name() for i in range(classChild.getNumberBaseClasses()) ] ) + def testPdbTypeProvider(self): + pdb = target.module.symfile() + typeProvider = pykd.getTypeInfoProviderFromPdb(pdb) + self.assertEqual("structTest", typeProvider.getTypeByName("structTest").name()) + self.assertEqual("structTest", typeProvider.structTest.name()) + self.assertEqual(22, len(list(typeProvider.typeIterator("*struct*")))) + + def testScopeName(self): + self.assertEqual( target.module.name(), pykd.typeInfo( "structTest" ).scopeName() ) + self.assertEqual( target.module.name(), pykd.typeInfo( "structWithNested::Nested" ).scopeName() ) + + +