]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-45061: Detect Py_DECREF(Py_True) bug (GH-28089)
authorVictor Stinner <vstinner@python.org>
Tue, 31 Aug 2021 16:05:15 +0000 (18:05 +0200)
committerGitHub <noreply@github.com>
Tue, 31 Aug 2021 16:05:15 +0000 (18:05 +0200)
Add a deallocator to the bool type to detect refcount bugs in C
extensions which call Py_DECREF(Py_True) or Py_DECREF(Py_False) by
mistake.

Misc/NEWS.d/next/C API/2021-08-31-15-21-36.bpo-45061.ZH0HVe.rst [new file with mode: 0644]
Objects/boolobject.c
Objects/object.c

diff --git a/Misc/NEWS.d/next/C API/2021-08-31-15-21-36.bpo-45061.ZH0HVe.rst b/Misc/NEWS.d/next/C API/2021-08-31-15-21-36.bpo-45061.ZH0HVe.rst
new file mode 100644 (file)
index 0000000..58bd534
--- /dev/null
@@ -0,0 +1,3 @@
+Add a deallocator to the :class:`bool` type to detect refcount bugs in C
+extensions which call ``Py_DECREF(Py_True);`` or ``Py_DECREF(Py_False);`` by
+mistake. Patch by Victor Stinner.
index b786966533e1d6a320a4ec95f06f6f16c42ce941..bc1666f55717c19044443738c4891bdf932e5d4e 100644 (file)
@@ -153,6 +153,13 @@ static PyNumberMethods bool_as_number = {
     0,                          /* nb_index */
 };
 
+static void _Py_NO_RETURN
+bool_dealloc(PyObject* Py_UNUSED(ignore))
+{
+    Py_FatalError("deallocating True or False likely caused by "
+                  "a refcount bug in a C extension");
+}
+
 /* The type object for bool.  Note that this cannot be subclassed! */
 
 PyTypeObject PyBool_Type = {
@@ -160,7 +167,7 @@ PyTypeObject PyBool_Type = {
     "bool",
     sizeof(struct _longobject),
     0,
-    0,                                          /* tp_dealloc */
+    bool_dealloc,                               /* tp_dealloc */
     0,                                          /* tp_vectorcall_offset */
     0,                                          /* tp_getattr */
     0,                                          /* tp_setattr */
index 446c974f8e614bae875f32811b452c9273b20fb6..026262b54484953503305357a537b55811eeae4d 100644 (file)
@@ -1560,14 +1560,11 @@ none_repr(PyObject *op)
     return PyUnicode_FromString("None");
 }
 
-/* ARGUSED */
 static void _Py_NO_RETURN
-none_dealloc(PyObject* ignore)
+none_dealloc(PyObject* Py_UNUSED(ignore))
 {
-    /* This should never get called, but we also don't want to SEGV if
-     * we accidentally decref None out of existence.
-     */
-    Py_FatalError("deallocating None");
+    Py_FatalError("deallocating None likely caused by a refcount bug "
+                  "in a C extension");
 }
 
 static PyObject *