[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
This commit is contained in:
SND\ussrhero_cp 2016-12-26 21:24:15 +00:00 committed by Mikhail I. Izmestev
parent 933e3e650d
commit 983bdd609d
5 changed files with 49 additions and 19 deletions

View File

@ -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")

View File

@ -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;

View File

@ -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<FARPROC*>(&PyDict_New) = GetProcAddress(m_handlePython, "PyDict_New");
*reinterpret_cast<FARPROC*>(&PyDict_SetItemString) = GetProcAddress(m_handlePython, "PyDict_SetItemString");
*reinterpret_cast<FARPROC*>(&PyDict_GetItemString) = GetProcAddress(m_handlePython, "PyDict_GetItemString");
*reinterpret_cast<FARPROC*>(&PyDict_Clear) = GetProcAddress(m_handlePython, "PyDict_Clear");
*reinterpret_cast<FARPROC*>(&PyObject_Call) = GetProcAddress(m_handlePython, "PyObject_Call");
*reinterpret_cast<FARPROC*>(&PyObject_GetAttr) = GetProcAddress(m_handlePython, "PyObject_GetAttr");
*reinterpret_cast<FARPROC*>(&PyObject_GetAttrString) = GetProcAddress(m_handlePython, "PyObject_GetAttrString");
@ -439,7 +448,8 @@ PyModule::PyModule(int majorVesion, int minorVersion)
*reinterpret_cast<FARPROC*>(&PyErr_SetString) = GetProcAddress(m_handlePython, "PyErr_SetString");
*reinterpret_cast<FARPROC*>(&PyErr_Clear) = GetProcAddress(m_handlePython, "PyErr_Clear");
*reinterpret_cast<FARPROC*>(&PyImport_AddModule) = GetProcAddress(m_handlePython, "PyImport_AddModule");
*reinterpret_cast<FARPROC*>(&PyImport_ImportModule) = GetProcAddress(m_handlePython, "PyImport_ImportModule");
*reinterpret_cast<FARPROC*>(&PyImport_ImportModule) = GetProcAddress(m_handlePython, "PyImport_ImportModule");
*reinterpret_cast<FARPROC*>(&PyImport_Cleanup) = GetProcAddress(m_handlePython, "PyImport_Cleanup");
*reinterpret_cast<FARPROC*>(&PyClass_New) = GetProcAddress(m_handlePython, "PyClass_New");
*reinterpret_cast<FARPROC*>(&PyInstance_New) = GetProcAddress(m_handlePython, "PyInstance_New");
*reinterpret_cast<FARPROC*>(&PyMethod_New) = GetProcAddress(m_handlePython, "PyMethod_New");
@ -449,6 +459,7 @@ PyModule::PyModule(int majorVesion, int minorVersion)
*reinterpret_cast<FARPROC*>(&PyUnicode_FromWideChar) = isPy3 ? GetProcAddress(m_handlePython, "PyUnicode_FromWideChar") :
GetProcAddress(m_handlePython, "PyUnicodeUCS2_FromWideChar");
*reinterpret_cast<FARPROC*>(&PyImport_Import) = GetProcAddress(m_handlePython, "PyImport_Import");
*reinterpret_cast<FARPROC*>(&PyImport_AddModule) = GetProcAddress(m_handlePython, "PyImport_AddModule");
*reinterpret_cast<FARPROC*>(&PyBool_FromLong) = GetProcAddress(m_handlePython, "PyBool_FromLong");
*reinterpret_cast<FARPROC*>(&PyList_Size) = GetProcAddress(m_handlePython, "PyList_Size");
*reinterpret_cast<FARPROC*>(&PyList_GetItem) = GetProcAddress(m_handlePython, "PyList_GetItem");
@ -462,7 +473,9 @@ PyModule::PyModule(int majorVesion, int minorVersion)
*reinterpret_cast<FARPROC*>(&PyGILState_Ensure) = GetProcAddress(m_handlePython, "PyGILState_Ensure");
*reinterpret_cast<FARPROC*>(&PyGILState_Release) = GetProcAddress(m_handlePython, "PyGILState_Release");
*reinterpret_cast<FARPROC*>(&PyDescr_NewMethod) = GetProcAddress(m_handlePython, "PyDescr_NewMethod");
*reinterpret_cast<FARPROC*>(&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()
{

View File

@ -1,14 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug_2.7|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug_2.7|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
@ -67,7 +59,7 @@
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
@ -196,9 +188,9 @@
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsManaged>
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsManaged>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
</PrecompiledHeader>
</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
</PrecompiledHeader>
</PrecompiledHeader>
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsManaged>
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsManaged>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">

View File

@ -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<DbgOut>(client);
PySys_SetObject("stdout", dbgOut);
@ -324,10 +328,6 @@ py(
PyObjectRef dbgIn = make_pyobject<DbgIn>(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)
{