[New-bugs-announce] [issue45061] [C API] Detect refcount bugs on True/False in C extensions
STINNER Victor
report at bugs.python.org
Tue Aug 31 09:17:39 EDT 2021
New submission from STINNER Victor <vstinner at python.org>:
Writing C extensions using directly the C API is error prone. It's easy to add or forget a Py_INCREF or Py_DECREF. Adding Py_DECREF(Py_True) or Py_DECREF(Py_False) by mistake causes a surprising crash at Python exit:
---
Debug memory block at address p=0x8a6e80: API ''
0 bytes originally requested
The 7 pad bytes at p-7 are not all FORBIDDENBYTE (0xfd):
at p-7: 0x00 *** OUCH
at p-6: 0x00 *** OUCH
at p-5: 0x00 *** OUCH
at p-4: 0x00 *** OUCH
at p-3: 0x00 *** OUCH
at p-2: 0x00 *** OUCH
at p-1: 0x00 *** OUCH
Because memory is corrupted at the start, the count of bytes requested
may be bogus, and checking the trailing pad bytes may segfault.
The 8 pad bytes at tail=0x8a6e80 are not all FORBIDDENBYTE (0xfd):
at tail+0: 0x00 *** OUCH
at tail+1: 0x00 *** OUCH
at tail+2: 0x00 *** OUCH
at tail+3: 0x00 *** OUCH
at tail+4: 0x00 *** OUCH
at tail+5: 0x00 *** OUCH
at tail+6: 0x00 *** OUCH
at tail+7: 0x00 *** OUCH
Enable tracemalloc to get the memory block allocation traceback
Fatal Python error: _PyMem_DebugRawFree: bad ID: Allocated using API '', verified using API 'o'
Python runtime state: finalizing (tstate=0x0000000001f43c50)
Current thread 0x00007f3f562fa740 (most recent call first):
Garbage-collecting
<no Python frame>
Abandon (core dumped)
---
In my case, the bug occurs at Python exit, in code_dealloc(): "Py_XDECREF(co->co_consts);" destroys a tuple which contains True. It calls object_dealloc() which calls PyBool_Type.tp_dealloc(Py_True), but this object is allocated statically, and so its memory must not deallocated by the Python dynamic memory allocator. In debug mode, PyObject_Free() triggers a fatal error.
Concrete example of such bug in PySide with Python 3.10 which is now stricter on reference counting (thanks to the work made in bpo-1635741 and for Python subinterpreters):
https://bugreports.qt.io/browse/PYSIDE-1436
I propose to add a specific deallocator functions on bool to detect such bug, to ease debugging. There is already a similar deallocator for the None singleton.
----------
components: Extension Modules
messages: 400728
nosy: vstinner
priority: normal
severity: normal
status: open
title: [C API] Detect refcount bugs on True/False in C extensions
versions: Python 3.11
_______________________________________
Python tracker <report at bugs.python.org>
<https://bugs.python.org/issue45061>
_______________________________________
More information about the New-bugs-announce
mailing list