Skip to content

Commit 3f8a768

Browse files
committed
gh-115124: Use _PyObject_ASSERT() in gc.c
Replace assert() with _PyObject_ASSERT() in gc.c to dump the object when an assertion fails.
1 parent 95ebd45 commit 3f8a768

File tree

1 file changed

+20
-13
lines changed

1 file changed

+20
-13
lines changed

Python/gc.c

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -394,16 +394,17 @@ update_refs(PyGC_Head *containers)
394394

395395
while (gc != containers) {
396396
next = GC_NEXT(gc);
397+
PyObject *op = FROM_GC(gc);
397398
/* Move any object that might have become immortal to the
398399
* permanent generation as the reference count is not accurately
399400
* reflecting the actual number of live references to this object
400401
*/
401-
if (_Py_IsImmortal(FROM_GC(gc))) {
402+
if (_Py_IsImmortal(op)) {
402403
gc_list_move(gc, &get_gc_state()->permanent_generation.head);
403404
gc = next;
404405
continue;
405406
}
406-
gc_reset_refs(gc, Py_REFCNT(FROM_GC(gc)));
407+
gc_reset_refs(gc, Py_REFCNT(op));
407408
/* Python's cyclic gc should never see an incoming refcount
408409
* of 0: if something decref'ed to 0, it should have been
409410
* deallocated immediately at that time.
@@ -422,7 +423,7 @@ update_refs(PyGC_Head *containers)
422423
* so serious that maybe this should be a release-build
423424
* check instead of an assert?
424425
*/
425-
_PyObject_ASSERT(FROM_GC(gc), gc_get_refs(gc) != 0);
426+
_PyObject_ASSERT(op, gc_get_refs(gc) != 0);
426427
gc = next;
427428
}
428429
}
@@ -488,7 +489,7 @@ visit_reachable(PyObject *op, void *arg)
488489
}
489490
// It would be a logic error elsewhere if the collecting flag were set on
490491
// an untracked object.
491-
assert(gc->_gc_next != 0);
492+
_PyObject_ASSERT(op, gc->_gc_next != 0);
492493

493494
if (gc->_gc_next & NEXT_MASK_UNREACHABLE) {
494495
/* This had gc_refs = 0 when move_unreachable got
@@ -660,7 +661,9 @@ static void
660661
move_legacy_finalizers(PyGC_Head *unreachable, PyGC_Head *finalizers)
661662
{
662663
PyGC_Head *gc, *next;
663-
assert((unreachable->_gc_next & NEXT_MASK_UNREACHABLE) == 0);
664+
_PyObject_ASSERT(
665+
FROM_GC(unreachable),
666+
(unreachable->_gc_next & NEXT_MASK_UNREACHABLE) == 0);
664667

665668
/* March over unreachable. Move objects with finalizers into
666669
* `finalizers`.
@@ -683,10 +686,14 @@ static inline void
683686
clear_unreachable_mask(PyGC_Head *unreachable)
684687
{
685688
/* Check that the list head does not have the unreachable bit set */
686-
assert(((uintptr_t)unreachable & NEXT_MASK_UNREACHABLE) == 0);
689+
_PyObject_ASSERT(
690+
FROM_GC(unreachable),
691+
((uintptr_t)unreachable & NEXT_MASK_UNREACHABLE) == 0);
692+
_PyObject_ASSERT(
693+
FROM_GC(unreachable),
694+
(unreachable->_gc_next & NEXT_MASK_UNREACHABLE) == 0);
687695

688696
PyGC_Head *gc, *next;
689-
assert((unreachable->_gc_next & NEXT_MASK_UNREACHABLE) == 0);
690697
for (gc = GC_NEXT(unreachable); gc != unreachable; gc = next) {
691698
_PyObject_ASSERT((PyObject*)FROM_GC(gc), gc->_gc_next & NEXT_MASK_UNREACHABLE);
692699
gc->_gc_next &= ~NEXT_MASK_UNREACHABLE;
@@ -840,7 +847,7 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old)
840847
*/
841848
if (gc_is_collecting(AS_GC((PyObject *)wr))) {
842849
/* it should already have been cleared above */
843-
assert(wr->wr_object == Py_None);
850+
_PyObject_ASSERT((PyObject*)wr, wr->wr_object == Py_None);
844851
continue;
845852
}
846853

@@ -851,9 +858,8 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old)
851858

852859
/* Move wr to wrcb_to_call, for the next pass. */
853860
wrasgc = AS_GC((PyObject *)wr);
854-
assert(wrasgc != next); /* wrasgc is reachable, but
855-
next isn't, so they can't
856-
be the same */
861+
// wrasgc is reachable, but next isn't, so they can't be the same
862+
_PyObject_ASSERT(wr, wrasgc != next);
857863
gc_list_move(wrasgc, &wrcb_to_call);
858864
}
859865
}
@@ -1773,8 +1779,9 @@ _Py_ScheduleGC(PyInterpreterState *interp)
17731779
void
17741780
_PyObject_GC_Link(PyObject *op)
17751781
{
1776-
PyGC_Head *g = AS_GC(op);
1777-
assert(((uintptr_t)g & (sizeof(uintptr_t)-1)) == 0); // g must be correctly aligned
1782+
PyGC_Head *gc = AS_GC(op);
1783+
// gc must be correctly aligned
1784+
_PyObject_ASSERT(op, ((uintptr_t)gc & (sizeof(uintptr_t)-1)) == 0);
17781785

17791786
PyThreadState *tstate = _PyThreadState_GET();
17801787
GCState *gcstate = &tstate->interp->gc;

0 commit comments

Comments
 (0)