-
-
Notifications
You must be signed in to change notification settings - Fork 30.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
bpo-29941: Assert fixes #886
Conversation
…means making sure helper functions are defiend when NDEBUG is not defined, not just when Py_DEBUG is defined. Also fix a division-by-zero in obmalloc.c: in Py_DEBUG mode, elsize is never 0, so this assert is never triggered.
…Unlike other asserts this is easy to trigger indirectly, and the assertion failure will not point to the actual problem.
@Yhg1s, thanks for your PR! By analyzing the history of the files in this pull request, we identified @benjaminp, @serhiy-storchaka and @tim-one to be potential reviewers. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I support making assertions without Py_DEBUG
work. We should add an easy way to do this with --configure
and add a buildbot for it.
It seems like many of your changes would be simplified if there was a Py_DEBUG_ASSERT
macro.
Objects/obmalloc.c
Outdated
@@ -1227,7 +1227,7 @@ _PyObject_Alloc(int use_calloc, void *ctx, size_t nelem, size_t elsize) | |||
|
|||
_Py_AllocatedBlocks++; | |||
|
|||
assert(nelem <= PY_SSIZE_T_MAX / elsize); | |||
assert(elsize == 0 || nelem <= PY_SSIZE_T_MAX / elsize); | |||
nbytes = nelem * elsize; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably this whole block should go under after line 1242 instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved line 1242 up instead.
… build." This reverts commit 7333298.
Dropped the change to add Py_DEBUG guards around dubious asserts, as Tim doesn't think the're dubious enough :) |
Make a non-Py_DEBUG, asserts-enabled build of CPython possible. This means making sure helper functions are defined when NDEBUG is not defined, not just when Py_DEBUG is defined. Also fix a division-by-zero in obmalloc.c that went unnoticed because in Py_DEBUG mode, elsize is never zero. (cherry picked from commit a00c3fd and 06bb487)
Make a non-Py_DEBUG, asserts-enabled build of CPython possible. This means making sure helper functions are defined when NDEBUG is not defined, not just when Py_DEBUG is defined. Also fix a division-by-zero in obmalloc.c that went unnoticed because in Py_DEBUG mode, elsize is never zero. (cherry picked from commit a00c3fd and 06bb487)
I wrote most _PyXXX_CheckConsistency() methods. To be clear: these methods are not written for performances, but to catch bugs earlier. Be careful on slowdown if you enable assertions on production ;-) |
We enable them for tests (which we run a lot, all the time, but that's okay), not for deployed code. |
Make a non-Py_DEBUG, asserts-enabled build of CPython possible. This means making sure helper functions are defined when NDEBUG is not defined, not just when Py_DEBUG is defined. Also fix a division-by-zero in obmalloc.c that went unnoticed because in Py_DEBUG mode, elsize is never zero. (cherry picked from commit a00c3fd and 06bb487)
Make a non-Py_DEBUG, asserts-enabled build of CPython possible. This means making sure helper functions are defined when NDEBUG is not defined, not just when Py_DEBUG is defined. Also fix a division-by-zero in obmalloc.c that went unnoticed because in Py_DEBUG mode, elsize is never zero. (cherry picked from commit a00c3fd and 06bb487)
Make a non-Py_DEBUG, asserts-enabled build of CPython possible. This means making sure helper functions are defined when NDEBUG is not defined, not just when Py_DEBUG is defined. Also fix a division-by-zero in obmalloc.c that went unnoticed because in Py_DEBUG mode, elsize is never zero. (cherry picked from commit a00c3fd and 06bb487)
There is a bit of confusion in the CPython source between
Py_DEBUG
and (C) asserts. By default Python builds withoutPy_DEBUG
and without asserts (defininingNDEBUG
to disable them). Turning onPy_DEBUG
also enables asserts. However, it is possible to turn on asserts without turning onPy_DEBUG
, and at Google we routinely build CPython that way. (Doing this with the regularconfigure
/make
process can be done by settingCFLAGS=-UNDEBUG
when runningconfigure
.) This happens to highlight two different problems:Code being defined in
Py_DEBUG
blocks but used in assertions:_PyDict_CheckConsistency()
is defined in dictobject.c in an#ifdef Py_DEBUG
, but then used in assert without a check forPy_DEBUG
. This is a compile-time error.Assertions checking for things that are outside of CPython's control, like whether an exception is set before calling something that might clobber it. Generally speaking assertions should be for internal invariants; things that should be a specific way, and it's an error in CPython itself when it's not (I think Tim Peters originally expressed this view of C asserts). For example, PyObject_Call() (and various other flavours of it) does
assert(!PyErr_Occurred())
, which is easily triggered and the cause of which is not always apparent.The second case is useful, mind you, as it exposes bugs in extension modules, but the way it does it is not very helpful (it displays no traceback), and if the intent is to only do this when
Py_DEBUG
is enabled it would be better to check for that. This PR fixes both issues.I think what our codebase does (enable assertions by default, without enabling
Py_DEBUG
) is useful, even when applied to CPython, and I would like CPython to keep working that way. However, if it's deemed more appropriate to make assertions only work inPy_DEBUG
mode, that's fine too -- but please make it explicit, by making non-Py_DEBUG
builds requireNDEBUG
.