mirror of
https://github.com/python/cpython.git
synced 2025-08-30 21:48:47 +00:00
bpo-36389: _PyObject_IsFreed() now also detects uninitialized memory (GH-12770)
Replace _PyMem_IsFreed() function with _PyMem_IsPtrFreed() inline function. The function is now way more efficient, it became a simple comparison on integers, rather than a short loop. It detects also uninitialized bytes and "forbidden bytes" filled by debug hooks on memory allocators. Add unit tests on _PyObject_IsFreed().
This commit is contained in:
parent
57b1a2862a
commit
2b00db6855
6 changed files with 113 additions and 27 deletions
|
@ -425,18 +425,17 @@ _Py_BreakPoint(void)
|
|||
int
|
||||
_PyObject_IsFreed(PyObject *op)
|
||||
{
|
||||
uintptr_t ptr = (uintptr_t)op;
|
||||
if (_PyMem_IsFreed(&ptr, sizeof(ptr))) {
|
||||
if (_PyMem_IsPtrFreed(op) || _PyMem_IsPtrFreed(op->ob_type)) {
|
||||
return 1;
|
||||
}
|
||||
int freed = _PyMem_IsFreed(&op->ob_type, sizeof(op->ob_type));
|
||||
/* ignore op->ob_ref: the value can have be modified
|
||||
/* ignore op->ob_ref: its value can have be modified
|
||||
by Py_INCREF() and Py_DECREF(). */
|
||||
#ifdef Py_TRACE_REFS
|
||||
freed &= _PyMem_IsFreed(&op->_ob_next, sizeof(op->_ob_next));
|
||||
freed &= _PyMem_IsFreed(&op->_ob_prev, sizeof(op->_ob_prev));
|
||||
if (_PyMem_IsPtrFreed(op->_ob_next) || _PyMem_IsPtrFreed(op->_ob_prev)) {
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
return freed;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -453,7 +452,7 @@ _PyObject_Dump(PyObject* op)
|
|||
if (_PyObject_IsFreed(op)) {
|
||||
/* It seems like the object memory has been freed:
|
||||
don't access it to prevent a segmentation fault. */
|
||||
fprintf(stderr, "<freed object>\n");
|
||||
fprintf(stderr, "<Freed object>\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue