diff options
author | Eric Snow <ericsnowcurrently@gmail.com> | 2017-09-11 17:59:22 -0700 |
---|---|---|
committer | Victor Stinner <victor.stinner@gmail.com> | 2017-09-11 17:59:22 -0700 |
commit | 8728018624f257c7cfe44014742ae46134047f49 (patch) | |
tree | d3465549106d04472cb05f70b317f20dd7fc77f6 /Python | |
parent | ba6d5d1defd7a281c8c8804e4b4cfd7370886236 (diff) | |
download | cpython-git-8728018624f257c7cfe44014742ae46134047f49.tar.gz |
bpo-30860: Fix a refleak. (#3506)
* Drop warnoptions from PyInterpreterState.
* Drop xoptions from PyInterpreterState.
* Don't set warnoptions and _xoptions again.
* Decref after adding to sys.__dict__.
* Drop an unused macro.
* Check sys.xoptions *before* we delete it.
Diffstat (limited to 'Python')
-rw-r--r-- | Python/pylifecycle.c | 10 | ||||
-rw-r--r-- | Python/pystate.c | 2 | ||||
-rw-r--r-- | Python/pythonrun.c | 5 | ||||
-rw-r--r-- | Python/sysmodule.c | 41 |
4 files changed, 31 insertions, 27 deletions
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index caa324e3af..3265d70181 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -1006,6 +1006,11 @@ Py_FinalizeEx(void) while (_PyGC_CollectIfEnabled() > 0) /* nothing */; #endif + +#ifdef Py_REF_DEBUG + PyObject *showrefcount = _PyDebug_XOptionShowRefCount(); +#endif + /* Destroy all modules */ PyImport_Cleanup(); @@ -1053,7 +1058,10 @@ Py_FinalizeEx(void) /* dump hash stats */ _PyHash_Fini(); - _PY_DEBUG_PRINT_TOTAL_REFS(); +#ifdef Py_REF_DEBUG + if (showrefcount == Py_True) + _PyDebug_PrintTotalRefs(); +#endif #ifdef Py_TRACE_REFS /* Display all objects still alive -- this can invoke arbitrary diff --git a/Python/pystate.c b/Python/pystate.c index be012d7d46..0804842861 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -96,8 +96,6 @@ PyInterpreterState_New(void) interp->builtins_copy = NULL; interp->tstate_head = NULL; interp->check_interval = 100; - interp->warnoptions = NULL; - interp->xoptions = NULL; interp->num_threads = 0; interp->pythread_stacksize = 0; interp->codec_search_path = NULL; diff --git a/Python/pythonrun.c b/Python/pythonrun.c index d1d4a69a8d..df814fbed9 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -113,7 +113,10 @@ PyRun_InteractiveLoopFlags(FILE *fp, const char *filename_str, PyCompilerFlags * err = -1; for (;;) { ret = PyRun_InteractiveOneObject(fp, filename, flags); - _PY_DEBUG_PRINT_TOTAL_REFS(); +#ifdef Py_REF_DEBUG + if (_PyDebug_XOptionShowRefCount() == Py_True) + _PyDebug_PrintTotalRefs(); +#endif if (ret == E_EOF) { err = 0; break; diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 3ecd7fca54..5bde4b7b70 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -36,12 +36,14 @@ extern const char *PyWin_DLLVersionString; _Py_IDENTIFIER(_); _Py_IDENTIFIER(__sizeof__); +_Py_IDENTIFIER(_xoptions); _Py_IDENTIFIER(buffer); _Py_IDENTIFIER(builtins); _Py_IDENTIFIER(encoding); _Py_IDENTIFIER(path); _Py_IDENTIFIER(stdout); _Py_IDENTIFIER(stderr); +_Py_IDENTIFIER(warnoptions); _Py_IDENTIFIER(write); PyObject * @@ -1479,13 +1481,17 @@ list_builtin_module_names(void) static PyObject * get_warnoptions(void) { - PyObject *warnoptions = PyThreadState_GET()->interp->warnoptions; + PyObject *warnoptions = _PySys_GetObjectId(&PyId_warnoptions); if (warnoptions == NULL || !PyList_Check(warnoptions)) { Py_XDECREF(warnoptions); warnoptions = PyList_New(0); if (warnoptions == NULL) return NULL; - PyThreadState_GET()->interp->warnoptions = warnoptions; + if (_PySys_SetObjectId(&PyId_warnoptions, warnoptions)) { + Py_DECREF(warnoptions); + return NULL; + } + Py_DECREF(warnoptions); } return warnoptions; } @@ -1493,7 +1499,7 @@ get_warnoptions(void) void PySys_ResetWarnOptions(void) { - PyObject *warnoptions = PyThreadState_GET()->interp->warnoptions; + PyObject *warnoptions = _PySys_GetObjectId(&PyId_warnoptions); if (warnoptions == NULL || !PyList_Check(warnoptions)) return; PyList_SetSlice(warnoptions, 0, PyList_GET_SIZE(warnoptions), NULL); @@ -1522,20 +1528,24 @@ PySys_AddWarnOption(const wchar_t *s) int PySys_HasWarnOptions(void) { - PyObject *warnoptions = PyThreadState_GET()->interp->warnoptions; + PyObject *warnoptions = _PySys_GetObjectId(&PyId_warnoptions); return (warnoptions != NULL && (PyList_Size(warnoptions) > 0)) ? 1 : 0; } static PyObject * get_xoptions(void) { - PyObject *xoptions = PyThreadState_GET()->interp->xoptions; + PyObject *xoptions = _PySys_GetObjectId(&PyId__xoptions); if (xoptions == NULL || !PyDict_Check(xoptions)) { Py_XDECREF(xoptions); xoptions = PyDict_New(); if (xoptions == NULL) return NULL; - PyThreadState_GET()->interp->xoptions = xoptions; + if (_PySys_SetObjectId(&PyId__xoptions, xoptions)) { + Py_DECREF(xoptions); + return NULL; + } + Py_DECREF(xoptions); } return xoptions; } @@ -2084,16 +2094,6 @@ _PySys_BeginInit(void) #undef SET_SYS_FROM_STRING_BORROW /* Updating the sys namespace, returning integer error codes */ -#define SET_SYS_FROM_STRING_BORROW_INT_RESULT(key, value) \ - do { \ - PyObject *v = (value); \ - if (v == NULL) \ - return -1; \ - res = PyDict_SetItemString(sysdict, key, v); \ - if (res < 0) { \ - return res; \ - } \ - } while (0) #define SET_SYS_FROM_STRING_INT_RESULT(key, value) \ do { \ PyObject *v = (value); \ @@ -2138,15 +2138,11 @@ _PySys_EndInit(PyObject *sysdict) SET_SYS_FROM_STRING_INT_RESULT("base_exec_prefix", PyUnicode_FromWideChar(Py_GetExecPrefix(), -1)); - PyObject *warnoptions = get_warnoptions(); - if (warnoptions == NULL) + if (get_warnoptions() == NULL) return -1; - SET_SYS_FROM_STRING_BORROW_INT_RESULT("warnoptions", warnoptions); - PyObject *xoptions = get_xoptions(); - if (xoptions == NULL) + if (get_xoptions() == NULL) return -1; - SET_SYS_FROM_STRING_BORROW_INT_RESULT("_xoptions", xoptions); if (PyErr_Occurred()) return -1; @@ -2154,7 +2150,6 @@ _PySys_EndInit(PyObject *sysdict) } #undef SET_SYS_FROM_STRING_INT_RESULT -#undef SET_SYS_FROM_STRING_BORROW_INT_RESULT static PyObject * makepathobject(const wchar_t *path, wchar_t delim) |