Skip to content

Commit ad56919

Browse files
authored
bpo-46857: Fix refleak in OSError INIT_ALIAS() (GH-31594)
_Py_GetRefTotal() no longer decrements _PySet_Dummy refcount.
1 parent e182c66 commit ad56919

File tree

3 files changed

+7
-18
lines changed

3 files changed

+7
-18
lines changed

‎Lib/test/test_embed.py‎

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1657,15 +1657,11 @@ def test_no_memleak(self):
16571657
self.fail(f"unexpected output: {out!a}")
16581658
refs = int(match.group(1))
16591659
blocks = int(match.group(2))
1660+
self.assertEqual(refs, 0, out)
16601661
if not MS_WINDOWS:
1661-
# bpo-46417: Tolerate negative reference count which can occur because
1662-
# of bugs in C extensions. It is only wrong if it's greater than 0.
1663-
self.assertLessEqual(refs, 0, out)
16641662
self.assertEqual(blocks, 0, out)
16651663
else:
1666-
# bpo-46857: on Windows, Python still leaks 1 reference and 1
1667-
# memory block at exit.
1668-
self.assertLessEqual(refs, 1, out)
1664+
# bpo-46857: on Windows, Python still leaks 1 memory block at exit
16691665
self.assertIn(blocks, (0, 1), out)
16701666

16711667

‎Objects/exceptions.c‎

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@
1515

1616

1717
/* Compatibility aliases */
18-
PyObject *PyExc_EnvironmentError = NULL;
19-
PyObject *PyExc_IOError = NULL;
18+
PyObject *PyExc_EnvironmentError = NULL; // borrowed ref
19+
PyObject *PyExc_IOError = NULL; // borrowed ref
2020
#ifdef MS_WINDOWS
21-
PyObject *PyExc_WindowsError = NULL;
21+
PyObject *PyExc_WindowsError = NULL; // borrowed ref
2222
#endif
2323

2424

@@ -3647,10 +3647,8 @@ _PyBuiltins_AddExceptions(PyObject *bltinmod)
36473647

36483648
#define INIT_ALIAS(NAME, TYPE) \
36493649
do { \
3650-
Py_INCREF(PyExc_ ## TYPE); \
3651-
Py_XDECREF(PyExc_ ## NAME); \
36523650
PyExc_ ## NAME = PyExc_ ## TYPE; \
3653-
if (PyDict_SetItemString(mod_dict, # NAME, PyExc_ ## NAME)) { \
3651+
if (PyDict_SetItemString(mod_dict, # NAME, PyExc_ ## TYPE)) { \
36543652
return -1; \
36553653
} \
36563654
} while (0)

‎Objects/object.c‎

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,7 @@ Py_ssize_t _Py_RefTotal;
6161
Py_ssize_t
6262
_Py_GetRefTotal(void)
6363
{
64-
PyObject *o;
65-
Py_ssize_t total = _Py_RefTotal;
66-
o = _PySet_Dummy;
67-
if (o != NULL)
68-
total -= Py_REFCNT(o);
69-
return total;
64+
return _Py_RefTotal;
7065
}
7166

7267
void

0 commit comments

Comments
 (0)