Skip to content

Commit 468de57

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 60375a3 commit 468de57

File tree

1 file changed

+23
-16
lines changed

1 file changed

+23
-16
lines changed

Python/gc.c

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -473,8 +473,9 @@ update_refs(PyGC_Head *containers)
473473

474474
while (gc != containers) {
475475
next = GC_NEXT(gc);
476-
assert(!_Py_IsImmortal(FROM_GC(gc)));
477-
gc_reset_refs(gc, Py_REFCNT(FROM_GC(gc)));
476+
PyObject *op = FROM_GC(gc);
477+
_PyObject_ASSERT(op, !_Py_IsImmortal(op));
478+
gc_reset_refs(gc, Py_REFCNT(op));
478479
/* Python's cyclic gc should never see an incoming refcount
479480
* of 0: if something decref'ed to 0, it should have been
480481
* deallocated immediately at that time.
@@ -493,7 +494,7 @@ update_refs(PyGC_Head *containers)
493494
* so serious that maybe this should be a release-build
494495
* check instead of an assert?
495496
*/
496-
_PyObject_ASSERT(FROM_GC(gc), gc_get_refs(gc) != 0);
497+
_PyObject_ASSERT(op, gc_get_refs(gc) != 0);
497498
gc = next;
498499
}
499500
}
@@ -559,7 +560,7 @@ visit_reachable(PyObject *op, void *arg)
559560
}
560561
// It would be a logic error elsewhere if the collecting flag were set on
561562
// an untracked object.
562-
assert(gc->_gc_next != 0);
563+
_PyObject_ASSERT(op, gc->_gc_next != 0);
563564

564565
if (gc->_gc_next & NEXT_MASK_UNREACHABLE) {
565566
/* This had gc_refs = 0 when move_unreachable got
@@ -736,7 +737,9 @@ static void
736737
move_legacy_finalizers(PyGC_Head *unreachable, PyGC_Head *finalizers)
737738
{
738739
PyGC_Head *gc, *next;
739-
assert((unreachable->_gc_next & NEXT_MASK_UNREACHABLE) == 0);
740+
_PyObject_ASSERT(
741+
FROM_GC(unreachable),
742+
(unreachable->_gc_next & NEXT_MASK_UNREACHABLE) == 0);
740743

741744
/* March over unreachable. Move objects with finalizers into
742745
* `finalizers`.
@@ -759,10 +762,14 @@ static inline void
759762
clear_unreachable_mask(PyGC_Head *unreachable)
760763
{
761764
/* Check that the list head does not have the unreachable bit set */
762-
assert(((uintptr_t)unreachable & NEXT_MASK_UNREACHABLE) == 0);
765+
_PyObject_ASSERT(
766+
FROM_GC(unreachable),
767+
((uintptr_t)unreachable & NEXT_MASK_UNREACHABLE) == 0);
763768

764769
PyGC_Head *gc, *next;
765-
assert((unreachable->_gc_next & NEXT_MASK_UNREACHABLE) == 0);
770+
_PyObject_ASSERT(
771+
FROM_GC(unreachable),
772+
(unreachable->_gc_next & NEXT_MASK_UNREACHABLE) == 0);
766773
for (gc = GC_NEXT(unreachable); gc != unreachable; gc = next) {
767774
_PyObject_ASSERT((PyObject*)FROM_GC(gc), gc->_gc_next & NEXT_MASK_UNREACHABLE);
768775
next = GC_NEXT(gc);
@@ -916,7 +923,7 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old)
916923
*/
917924
if (gc_is_collecting(AS_GC((PyObject *)wr))) {
918925
/* it should already have been cleared above */
919-
assert(wr->wr_object == Py_None);
926+
_PyObject_ASSERT((PyObject*)wr, wr->wr_object == Py_None);
920927
continue;
921928
}
922929

@@ -927,9 +934,8 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old)
927934

928935
/* Move wr to wrcb_to_call, for the next pass. */
929936
wrasgc = AS_GC((PyObject *)wr);
930-
assert(wrasgc != next); /* wrasgc is reachable, but
931-
next isn't, so they can't
932-
be the same */
937+
// wrasgc is reachable, but next isn't, so they can't be the same
938+
_PyObject_ASSERT(wr, wrasgc != next);
933939
gc_list_move(wrasgc, &wrcb_to_call);
934940
}
935941
}
@@ -1317,7 +1323,7 @@ visit_add_to_container(PyObject *op, void *arg)
13171323
PyGC_Head *gc = AS_GC(op);
13181324
if (_PyObject_GC_IS_TRACKED(op) &&
13191325
gc_old_space(gc) != visited) {
1320-
assert(!_Py_IsImmortal(op));
1326+
_PyObject_ASSERT(op, !_Py_IsImmortal(op));
13211327
gc_flip_old_space(gc);
13221328
gc_list_move(gc, cf->container);
13231329
}
@@ -1965,13 +1971,14 @@ _Py_ScheduleGC(PyInterpreterState *interp)
19651971
void
19661972
_PyObject_GC_Link(PyObject *op)
19671973
{
1968-
PyGC_Head *g = AS_GC(op);
1969-
assert(((uintptr_t)g & (sizeof(uintptr_t)-1)) == 0); // g must be correctly aligned
1974+
PyGC_Head *gc = AS_GC(op);
1975+
// gc must be correctly aligned
1976+
_PyObject_ASSERT(op, ((uintptr_t)gc & (sizeof(uintptr_t)-1)) == 0);
19701977

19711978
PyThreadState *tstate = _PyThreadState_GET();
19721979
GCState *gcstate = &tstate->interp->gc;
1973-
g->_gc_next = 0;
1974-
g->_gc_prev = 0;
1980+
gc->_gc_next = 0;
1981+
gc->_gc_prev = 0;
19751982
gcstate->young.count++; /* number of allocated GC objects */
19761983
if (gcstate->young.count > gcstate->young.threshold &&
19771984
gcstate->enabled &&

0 commit comments

Comments
 (0)