bpo-46857: Fix refleak in OSError INIT_ALIAS() (GH-31594)

_Py_GetRefTotal() no longer decrements _PySet_Dummy refcount.
This commit is contained in:
Victor Stinner 2022-02-27 00:28:24 +01:00 committed by GitHub
parent e182c660b6
commit ad56919c5e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 7 additions and 18 deletions

View File

@ -1657,15 +1657,11 @@ class MiscTests(EmbeddingTestsMixin, unittest.TestCase):
self.fail(f"unexpected output: {out!a}") self.fail(f"unexpected output: {out!a}")
refs = int(match.group(1)) refs = int(match.group(1))
blocks = int(match.group(2)) blocks = int(match.group(2))
self.assertEqual(refs, 0, out)
if not MS_WINDOWS: if not MS_WINDOWS:
# bpo-46417: Tolerate negative reference count which can occur because
# of bugs in C extensions. It is only wrong if it's greater than 0.
self.assertLessEqual(refs, 0, out)
self.assertEqual(blocks, 0, out) self.assertEqual(blocks, 0, out)
else: else:
# bpo-46857: on Windows, Python still leaks 1 reference and 1 # bpo-46857: on Windows, Python still leaks 1 memory block at exit
# memory block at exit.
self.assertLessEqual(refs, 1, out)
self.assertIn(blocks, (0, 1), out) self.assertIn(blocks, (0, 1), out)

View File

@ -15,10 +15,10 @@
/* Compatibility aliases */ /* Compatibility aliases */
PyObject *PyExc_EnvironmentError = NULL; PyObject *PyExc_EnvironmentError = NULL; // borrowed ref
PyObject *PyExc_IOError = NULL; PyObject *PyExc_IOError = NULL; // borrowed ref
#ifdef MS_WINDOWS #ifdef MS_WINDOWS
PyObject *PyExc_WindowsError = NULL; PyObject *PyExc_WindowsError = NULL; // borrowed ref
#endif #endif
@ -3647,10 +3647,8 @@ _PyBuiltins_AddExceptions(PyObject *bltinmod)
#define INIT_ALIAS(NAME, TYPE) \ #define INIT_ALIAS(NAME, TYPE) \
do { \ do { \
Py_INCREF(PyExc_ ## TYPE); \
Py_XDECREF(PyExc_ ## NAME); \
PyExc_ ## NAME = PyExc_ ## TYPE; \ PyExc_ ## NAME = PyExc_ ## TYPE; \
if (PyDict_SetItemString(mod_dict, # NAME, PyExc_ ## NAME)) { \ if (PyDict_SetItemString(mod_dict, # NAME, PyExc_ ## TYPE)) { \
return -1; \ return -1; \
} \ } \
} while (0) } while (0)

View File

@ -61,12 +61,7 @@ Py_ssize_t _Py_RefTotal;
Py_ssize_t Py_ssize_t
_Py_GetRefTotal(void) _Py_GetRefTotal(void)
{ {
PyObject *o; return _Py_RefTotal;
Py_ssize_t total = _Py_RefTotal;
o = _PySet_Dummy;
if (o != NULL)
total -= Py_REFCNT(o);
return total;
} }
void void