mirror of
https://github.com/python/cpython.git
synced 2025-07-23 11:15:24 +00:00
gh-130030: Fix crash on 32-bit Linux with free threading (gh-130043)
The `gc_get_refs` assertion needs to be after we check the alive and unreachable bits. Otherwise, `ob_tid` may store the actual thread id instead of the computed `gc_refs`, which may trigger the assertion if the `ob_tid` looks like a negative value. Also fix a few type warnings on 32-bit systems.
This commit is contained in:
parent
791cdfe141
commit
e09442089e
2 changed files with 13 additions and 11 deletions
|
@ -581,11 +581,13 @@ gc_mark_buffer_len(gc_mark_args_t *args)
|
|||
}
|
||||
|
||||
// Returns number of free entry slots in buffer
|
||||
#ifndef NDEBUG
|
||||
static inline unsigned int
|
||||
gc_mark_buffer_avail(gc_mark_args_t *args)
|
||||
{
|
||||
return BUFFER_SIZE - gc_mark_buffer_len(args);
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline bool
|
||||
gc_mark_buffer_is_empty(gc_mark_args_t *args)
|
||||
|
@ -1074,14 +1076,14 @@ mark_heap_visitor(const mi_heap_t *heap, const mi_heap_area_t *area,
|
|||
return true;
|
||||
}
|
||||
|
||||
_PyObject_ASSERT_WITH_MSG(op, gc_get_refs(op) >= 0,
|
||||
"refcount is too small");
|
||||
|
||||
if (gc_is_alive(op) || !gc_is_unreachable(op)) {
|
||||
// Object was already marked as reachable.
|
||||
return true;
|
||||
}
|
||||
|
||||
_PyObject_ASSERT_WITH_MSG(op, gc_get_refs(op) >= 0,
|
||||
"refcount is too small");
|
||||
|
||||
// GH-129236: If we've seen an active frame without a valid stack pointer,
|
||||
// then we can't collect objects with deferred references because we may
|
||||
// have missed some reference to the object on the stack. In that case,
|
||||
|
@ -1178,10 +1180,10 @@ move_legacy_finalizer_reachable(struct collection_state *state);
|
|||
static void
|
||||
gc_prime_from_spans(gc_mark_args_t *args)
|
||||
{
|
||||
Py_ssize_t space = BUFFER_HI - gc_mark_buffer_len(args);
|
||||
unsigned int space = BUFFER_HI - gc_mark_buffer_len(args);
|
||||
// there should always be at least this amount of space
|
||||
assert(space <= gc_mark_buffer_avail(args));
|
||||
assert(space > 0);
|
||||
assert(space <= BUFFER_HI);
|
||||
gc_span_t entry = args->spans.stack[--args->spans.size];
|
||||
// spans on the stack should always have one or more elements
|
||||
assert(entry.start < entry.end);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue