mirror of
https://github.com/python/cpython.git
synced 2025-09-28 03:13:48 +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
|
@ -3297,12 +3297,12 @@ static bool _collect_alloc_stats(
|
||||||
static void
|
static void
|
||||||
py_mimalloc_print_stats(FILE *out)
|
py_mimalloc_print_stats(FILE *out)
|
||||||
{
|
{
|
||||||
fprintf(out, "Small block threshold = %zd, in %u size classes.\n",
|
fprintf(out, "Small block threshold = %zu, in %u size classes.\n",
|
||||||
MI_SMALL_OBJ_SIZE_MAX, MI_BIN_HUGE);
|
(size_t)MI_SMALL_OBJ_SIZE_MAX, MI_BIN_HUGE);
|
||||||
fprintf(out, "Medium block threshold = %zd\n",
|
fprintf(out, "Medium block threshold = %zu\n",
|
||||||
MI_MEDIUM_OBJ_SIZE_MAX);
|
(size_t)MI_MEDIUM_OBJ_SIZE_MAX);
|
||||||
fprintf(out, "Large object max size = %zd\n",
|
fprintf(out, "Large object max size = %zu\n",
|
||||||
MI_LARGE_OBJ_SIZE_MAX);
|
(size_t)MI_LARGE_OBJ_SIZE_MAX);
|
||||||
|
|
||||||
mi_heap_t *heap = mi_heap_get_default();
|
mi_heap_t *heap = mi_heap_get_default();
|
||||||
struct _alloc_stats stats;
|
struct _alloc_stats stats;
|
||||||
|
|
|
@ -581,11 +581,13 @@ gc_mark_buffer_len(gc_mark_args_t *args)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns number of free entry slots in buffer
|
// Returns number of free entry slots in buffer
|
||||||
|
#ifndef NDEBUG
|
||||||
static inline unsigned int
|
static inline unsigned int
|
||||||
gc_mark_buffer_avail(gc_mark_args_t *args)
|
gc_mark_buffer_avail(gc_mark_args_t *args)
|
||||||
{
|
{
|
||||||
return BUFFER_SIZE - gc_mark_buffer_len(args);
|
return BUFFER_SIZE - gc_mark_buffer_len(args);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
gc_mark_buffer_is_empty(gc_mark_args_t *args)
|
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;
|
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)) {
|
if (gc_is_alive(op) || !gc_is_unreachable(op)) {
|
||||||
// Object was already marked as reachable.
|
// Object was already marked as reachable.
|
||||||
return true;
|
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,
|
// 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
|
// 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,
|
// 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
|
static void
|
||||||
gc_prime_from_spans(gc_mark_args_t *args)
|
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
|
// there should always be at least this amount of space
|
||||||
assert(space <= gc_mark_buffer_avail(args));
|
assert(space <= gc_mark_buffer_avail(args));
|
||||||
assert(space > 0);
|
assert(space <= BUFFER_HI);
|
||||||
gc_span_t entry = args->spans.stack[--args->spans.size];
|
gc_span_t entry = args->spans.stack[--args->spans.size];
|
||||||
// spans on the stack should always have one or more elements
|
// spans on the stack should always have one or more elements
|
||||||
assert(entry.start < entry.end);
|
assert(entry.start < entry.end);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue