Skip to content

Commit ed6e376

Browse files
committed
gh-139653: If platform API doesn't give the current stack, use generic fallback
1 parent 69cfad0 commit ed6e376

File tree

1 file changed

+19
-9
lines changed

1 file changed

+19
-9
lines changed

Python/ceval.c

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,7 @@ int pthread_attr_destroy(pthread_attr_t *a)
442442
void
443443
_Py_InitializeRecursionLimits(PyThreadState *tstate)
444444
{
445+
uintptr_t here_addr = _Py_get_machine_stack_pointer();
445446
_PyThreadStateImpl *_tstate = (_PyThreadStateImpl *)tstate;
446447
#ifdef WIN32
447448
ULONG_PTR low, high;
@@ -458,8 +459,8 @@ _Py_InitializeRecursionLimits(PyThreadState *tstate)
458459
_tstate->c_stack_top = (uintptr_t)stack_addr;
459460
_tstate->c_stack_hard_limit = _tstate->c_stack_top - stack_size;
460461
_tstate->c_stack_soft_limit = _tstate->c_stack_hard_limit + _PyOS_STACK_MARGIN_BYTES;
461-
#else
462-
uintptr_t here_addr = _Py_get_machine_stack_pointer();
462+
#else // other platform
463+
_tstate->c_stack_top = 0;
463464
/// XXX musl supports HAVE_PTHRED_GETATTR_NP, but the resulting stack size
464465
/// (on alpine at least) is much smaller than expected and imposes undue limits
465466
/// compared to the old stack size estimation. (We assume musl is not glibc.)
@@ -477,22 +478,31 @@ _Py_InitializeRecursionLimits(PyThreadState *tstate)
477478
if (err == 0) {
478479
uintptr_t base = ((uintptr_t)stack_addr) + guard_size;
479480
_tstate->c_stack_top = base + stack_size;
480-
#ifdef _Py_THREAD_SANITIZER
481+
# ifdef _Py_THREAD_SANITIZER
481482
// Thread sanitizer crashes if we use a bit more than half the stack.
482483
_tstate->c_stack_soft_limit = base + (stack_size / 2);
483-
#else
484+
# else
484485
_tstate->c_stack_soft_limit = base + _PyOS_STACK_MARGIN_BYTES * 2;
485-
#endif
486+
# endif
486487
_tstate->c_stack_hard_limit = base + _PyOS_STACK_MARGIN_BYTES;
487-
assert(_tstate->c_stack_soft_limit < here_addr);
488-
assert(here_addr < _tstate->c_stack_top);
488+
}
489+
# endif // musl
490+
#endif // platform-specific code
491+
492+
/* Check that we currently are inside the discovered stack.
493+
* gh-139653: Boost's make_fcontext (and presumably other stack-switching
494+
* mechanisms) may be incompatible with platform API.
495+
*/
496+
if (_tstate->c_stack_top
497+
&& _tstate->c_stack_soft_limit < here_addr
498+
&& here_addr < _tstate->c_stack_top
499+
) {
489500
return;
490501
}
491-
# endif
502+
// Generic fallback
492503
_tstate->c_stack_top = _Py_SIZE_ROUND_UP(here_addr, 4096);
493504
_tstate->c_stack_soft_limit = _tstate->c_stack_top - Py_C_STACK_SIZE;
494505
_tstate->c_stack_hard_limit = _tstate->c_stack_top - (Py_C_STACK_SIZE + _PyOS_STACK_MARGIN_BYTES);
495-
#endif
496506
}
497507

498508
/* The function _Py_EnterRecursiveCallTstate() only calls _Py_CheckRecursiveCall()

0 commit comments

Comments
 (0)