From 983bdd609da17b000fa60721d291bafd4bdd67c5 Mon Sep 17 00:00:00 2001 From: "SND\\ussrhero_cp" Date: Mon, 26 Dec 2016 21:24:15 +0000 Subject: [PATCH] [pykd_ext_2.0] fixed : properly cleanup for local interpreter git-svn-id: https://pykd.svn.codeplex.com/svn@91085 9b283d60-5439-405e-af05-b73fd8c4d996 --- pykd_ext/arglist.cpp | 7 ++++++- pykd_ext/pyapi.h | 4 ++++ pykd_ext/pyinterpret.cpp | 32 +++++++++++++++++++++++++++++--- pykd_ext/pykd_ext_vc120.vcxproj | 14 +++----------- pykd_ext/windbgext.cpp | 11 +++++++---- 5 files changed, 49 insertions(+), 19 deletions(-) diff --git a/pykd_ext/arglist.cpp b/pykd_ext/arglist.cpp index 69002c6..c363627 100644 --- a/pykd_ext/arglist.cpp +++ b/pykd_ext/arglist.cpp @@ -34,12 +34,17 @@ static const std::regex versionRe("^-([2,3])(?:\\.(\\d+))?$"); Options::Options(const std::string& cmdline) : pyMajorVersion(-1), pyMinorVersion(-1), - global(true), + global(false), showHelp(false) { args = getArgsList( cmdline ); + if ( args.empty() ) + { + global = true; + } + for (auto it = args.begin(); it != args.end();) { if (*it == "--global" || *it == "-g") diff --git a/pykd_ext/pyapi.h b/pykd_ext/pyapi.h index e928492..d2aa6dd 100644 --- a/pykd_ext/pyapi.h +++ b/pykd_ext/pyapi.h @@ -32,6 +32,7 @@ char* PyString_AsString(PyObject *string); PyObject* PyImport_Import(PyObject *name); PyObject* __stdcall PyImport_ImportModule(const char *name); +PyObject* __stdcall PyImport_AddModule(const char *name); PyObject* __stdcall PyDict_New(); int __stdcall PyDict_SetItemString(PyObject *p, const char *key, PyObject *val); @@ -40,6 +41,7 @@ PyObject* __stdcall PyTuple_New(size_t len); PyObject* __stdcall PyTuple_GetItem(PyObject *p, size_t pos); int __stdcall PyTuple_SetItem(PyObject *p, size_t pos, PyObject *obj); PyObject* __stdcall PyDict_GetItemString(PyObject *p, const char *key); +void __stdcall PyDict_Clear(PyObject *p); size_t __stdcall PyTuple_Size(PyObject *p); size_t PyList_Size(PyObject* list); @@ -98,6 +100,8 @@ void __stdcall PyGILState_Release(PyGILState_STATE); PyObject* __stdcall PyDescr_NewMethod(PyObject* type, struct PyMethodDef *meth); +size_t __stdcall PyGC_Collect(void); + bool IsPy3(); class PyObjectRef; diff --git a/pykd_ext/pyinterpret.cpp b/pykd_ext/pyinterpret.cpp index 40d285d..8be1c66 100644 --- a/pykd_ext/pyinterpret.cpp +++ b/pykd_ext/pyinterpret.cpp @@ -80,6 +80,7 @@ public: PyObject* ( *PyDict_New)(); int( *PyDict_SetItemString)(PyObject *p, const char *key, PyObject *val); PyObject*( *PyDict_GetItemString)(PyObject *p, const char* key); + void ( *PyDict_Clear)(PyObject *p); void( *Py_IncRef)(PyObject* object); void( *Py_DecRef)(PyObject* object); PyObject* ( *PyObject_Call)(PyObject *callable_object, PyObject *args, PyObject *kw); @@ -123,6 +124,8 @@ public: PyGILState_STATE( *PyGILState_Ensure)(); void( *PyGILState_Release)(PyGILState_STATE state); PyObject* ( *PyDescr_NewMethod)(PyObject* type, struct PyMethodDef *meth); + size_t (*PyGC_Collect)(void); + void(*PyImport_Cleanup)(void); HMODULE m_handlePython; PyThreadState* m_globalState; @@ -150,7 +153,12 @@ public: { m_module->PyEval_RestoreThread(m_state); + m_module->PyImport_Cleanup(); + + while (PyGC_Collect() > 0); + m_module->Py_EndInterpreter(m_state); + } PyModule* m_module; @@ -417,6 +425,7 @@ PyModule::PyModule(int majorVesion, int minorVersion) *reinterpret_cast(&PyDict_New) = GetProcAddress(m_handlePython, "PyDict_New"); *reinterpret_cast(&PyDict_SetItemString) = GetProcAddress(m_handlePython, "PyDict_SetItemString"); *reinterpret_cast(&PyDict_GetItemString) = GetProcAddress(m_handlePython, "PyDict_GetItemString"); + *reinterpret_cast(&PyDict_Clear) = GetProcAddress(m_handlePython, "PyDict_Clear"); *reinterpret_cast(&PyObject_Call) = GetProcAddress(m_handlePython, "PyObject_Call"); *reinterpret_cast(&PyObject_GetAttr) = GetProcAddress(m_handlePython, "PyObject_GetAttr"); *reinterpret_cast(&PyObject_GetAttrString) = GetProcAddress(m_handlePython, "PyObject_GetAttrString"); @@ -439,7 +448,8 @@ PyModule::PyModule(int majorVesion, int minorVersion) *reinterpret_cast(&PyErr_SetString) = GetProcAddress(m_handlePython, "PyErr_SetString"); *reinterpret_cast(&PyErr_Clear) = GetProcAddress(m_handlePython, "PyErr_Clear"); *reinterpret_cast(&PyImport_AddModule) = GetProcAddress(m_handlePython, "PyImport_AddModule"); - *reinterpret_cast(&PyImport_ImportModule) = GetProcAddress(m_handlePython, "PyImport_ImportModule"); + *reinterpret_cast(&PyImport_ImportModule) = GetProcAddress(m_handlePython, "PyImport_ImportModule"); + *reinterpret_cast(&PyImport_Cleanup) = GetProcAddress(m_handlePython, "PyImport_Cleanup"); *reinterpret_cast(&PyClass_New) = GetProcAddress(m_handlePython, "PyClass_New"); *reinterpret_cast(&PyInstance_New) = GetProcAddress(m_handlePython, "PyInstance_New"); *reinterpret_cast(&PyMethod_New) = GetProcAddress(m_handlePython, "PyMethod_New"); @@ -449,6 +459,7 @@ PyModule::PyModule(int majorVesion, int minorVersion) *reinterpret_cast(&PyUnicode_FromWideChar) = isPy3 ? GetProcAddress(m_handlePython, "PyUnicode_FromWideChar") : GetProcAddress(m_handlePython, "PyUnicodeUCS2_FromWideChar"); *reinterpret_cast(&PyImport_Import) = GetProcAddress(m_handlePython, "PyImport_Import"); + *reinterpret_cast(&PyImport_AddModule) = GetProcAddress(m_handlePython, "PyImport_AddModule"); *reinterpret_cast(&PyBool_FromLong) = GetProcAddress(m_handlePython, "PyBool_FromLong"); *reinterpret_cast(&PyList_Size) = GetProcAddress(m_handlePython, "PyList_Size"); *reinterpret_cast(&PyList_GetItem) = GetProcAddress(m_handlePython, "PyList_GetItem"); @@ -462,7 +473,9 @@ PyModule::PyModule(int majorVesion, int minorVersion) *reinterpret_cast(&PyGILState_Ensure) = GetProcAddress(m_handlePython, "PyGILState_Ensure"); *reinterpret_cast(&PyGILState_Release) = GetProcAddress(m_handlePython, "PyGILState_Release"); *reinterpret_cast(&PyDescr_NewMethod) = GetProcAddress(m_handlePython, "PyDescr_NewMethod"); - + *reinterpret_cast(&PyGC_Collect) = GetProcAddress(m_handlePython, "PyGC_Collect"); + + Py_Initialize(); PyEval_InitThreads(); @@ -608,6 +621,11 @@ int __stdcall PyDict_SetItemString(PyObject *p, const char *key, PyObject *val) return PythonSingleton::get()->currentInterpreter()->m_module->PyDict_SetItemString(p, key, val); } +void __stdcall PyDict_Clear(PyObject *p) +{ + return PythonSingleton::get()->currentInterpreter()->m_module->PyDict_Clear(p); +} + PyObject* __stdcall PyCFunction_NewEx(PyMethodDef* pydef, PyObject *p1, PyObject *p2) { return PythonSingleton::get()->currentInterpreter()->m_module->PyCFunction_NewEx(pydef, p1, p2); @@ -814,6 +832,11 @@ PyObject* __stdcall PyImport_ImportModule(const char *name) return PythonSingleton::get()->currentInterpreter()->m_module->PyImport_ImportModule(name); } +PyObject* __stdcall PyImport_AddModule(const char *name) +{ + return PythonSingleton::get()->currentInterpreter()->m_module->PyImport_AddModule(name); +} + PyThreadState* __stdcall PyEval_SaveThread() { return PythonSingleton::get()->currentInterpreter()->m_module->PyEval_SaveThread(); @@ -849,7 +872,10 @@ PyObject* __stdcall PyDescr_NewMethod(PyObject* type, struct PyMethodDef *meth) return PythonSingleton::get()->currentInterpreter()->m_module->PyDescr_NewMethod(type, meth); } - +size_t __stdcall PyGC_Collect(void) +{ + return PythonSingleton::get()->currentInterpreter()->m_module->PyGC_Collect(); +} bool IsPy3() { diff --git a/pykd_ext/pykd_ext_vc120.vcxproj b/pykd_ext/pykd_ext_vc120.vcxproj index c734bbd..8d80b39 100644 --- a/pykd_ext/pykd_ext_vc120.vcxproj +++ b/pykd_ext/pykd_ext_vc120.vcxproj @@ -1,14 +1,6 @@  - - Debug - Win32 - - - Debug - x64 - Debug Win32 @@ -67,7 +59,7 @@ - + @@ -196,9 +188,9 @@ false false - + - + false false diff --git a/pykd_ext/windbgext.cpp b/pykd_ext/windbgext.cpp index 9075fb5..2781575 100644 --- a/pykd_ext/windbgext.cpp +++ b/pykd_ext/windbgext.cpp @@ -315,6 +315,10 @@ py( AutoInterpreter autoInterpreter(opts.global, majorVersion, minorVersion); + //PyObjectRef mainName = IsPy3() ? PyUnicode_FromString("__main__") : PyString_FromString("__main__"); + PyObjectRef mainMod = PyImport_ImportModule("__main__"); + PyObjectRef globals = PyObject_GetAttrString(mainMod, "__dict__"); + PyObjectRef dbgOut = make_pyobject(client); PySys_SetObject("stdout", dbgOut); @@ -324,10 +328,6 @@ py( PyObjectRef dbgIn = make_pyobject(client); PySys_SetObject("stdin", dbgIn); - PyObjectRef mainName = IsPy3() ? PyUnicode_FromString("__main__") : PyString_FromString("__main__"); - PyObjectRef mainMod = PyImport_Import(mainName); - PyObjectRef globals = PyObject_GetAttrString(mainMod, "__dict__"); - InterruptWatch interruptWatch(client); if (opts.args.empty()) @@ -387,6 +387,9 @@ py( } handleException(); + + if ( !opts.global ) + PyDict_Clear(globals); } catch (std::exception &e) {