bpo-36389: _PyObject_CheckConsistency() available in release mode (GH-16612)

bpo-36389, bpo-38376: The _PyObject_CheckConsistency() function is
now also available in release mode. For example, it can be used to
debug a crash in the visit_decref() function of the GC.

Modify the following functions to also work in release mode:

* _PyDict_CheckConsistency()
* _PyObject_CheckConsistency()
* _PyType_CheckConsistency()
* _PyUnicode_CheckConsistency()

Other changes:

* _PyMem_IsPtrFreed(ptr) now also returns 1 if ptr is NULL
  (equals to 0).
* _PyBytesWriter_CheckConsistency() now returns 1 and is only used
  with assert().
* Reorder _PyObject_Dump() to write safe fields first, and only
  attempt to render repr() at the end.
This commit is contained in:
Victor Stinner 2019-10-07 18:42:01 +02:00 committed by GitHub
parent 321def805a
commit 6876257eaa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 155 additions and 140 deletions

View file

@ -137,22 +137,24 @@ skip_signature(const char *doc)
int
_PyType_CheckConsistency(PyTypeObject *type)
{
#define ASSERT(expr) _PyObject_ASSERT((PyObject *)type, (expr))
#define CHECK(expr) \
do { if (!(expr)) { _PyObject_ASSERT_FAILED_MSG((PyObject *)type, Py_STRINGIFY(expr)); } } while (0)
CHECK(!_PyObject_IsFreed((PyObject *)type));
if (!(type->tp_flags & Py_TPFLAGS_READY)) {
/* don't check types before PyType_Ready() */
/* don't check static types before PyType_Ready() */
return 1;
}
ASSERT(!_PyObject_IsFreed((PyObject *)type));
ASSERT(Py_REFCNT(type) >= 1);
ASSERT(PyType_Check(type));
CHECK(Py_REFCNT(type) >= 1);
CHECK(PyType_Check(type));
ASSERT(!(type->tp_flags & Py_TPFLAGS_READYING));
ASSERT(type->tp_dict != NULL);
CHECK(!(type->tp_flags & Py_TPFLAGS_READYING));
CHECK(type->tp_dict != NULL);
return 1;
#undef ASSERT
#undef CHECK
}
static const char *