@@ -1091,18 +1091,14 @@ faulthandler_fatal_error_py(PyObject *self, PyObject *args)
1091
1091
#if defined(HAVE_SIGALTSTACK ) && defined(HAVE_SIGACTION )
1092
1092
#define FAULTHANDLER_STACK_OVERFLOW
1093
1093
1094
- #ifdef __INTEL_COMPILER
1095
- /* Issue #23654: Turn off ICC's tail call optimization for the
1096
- * stack_overflow generator. ICC turns the recursive tail call into
1097
- * a loop. */
1098
- # pragma intel optimization_level 0
1099
- #endif
1100
- static
1101
- uintptr_t
1094
+ static uintptr_t
1102
1095
stack_overflow (uintptr_t min_sp , uintptr_t max_sp , size_t * depth )
1103
1096
{
1104
- /* allocate 4096 bytes on the stack at each call */
1105
- unsigned char buffer [4096 ];
1097
+ /* Allocate (at least) 4096 bytes on the stack at each call.
1098
+
1099
+ bpo-23654, bpo-38965: use volatile keyword to prevent tail call
1100
+ optimization. */
1101
+ volatile unsigned char buffer [4096 ];
1106
1102
uintptr_t sp = (uintptr_t )& buffer ;
1107
1103
* depth += 1 ;
1108
1104
if (sp < min_sp || max_sp < sp )
@@ -1333,7 +1329,11 @@ int _PyFaulthandler_Init(void)
1333
1329
* be able to allocate memory on the stack, even on a stack overflow. If it
1334
1330
* fails, ignore the error. */
1335
1331
stack .ss_flags = 0 ;
1336
- stack .ss_size = SIGSTKSZ ;
1332
+ /* bpo-21131: allocate dedicated stack of SIGSTKSZ*2 bytes, instead of just
1333
+ SIGSTKSZ bytes. Calling the previous signal handler in faulthandler
1334
+ signal handler uses more than SIGSTKSZ bytes of stack memory on some
1335
+ platforms. */
1336
+ stack .ss_size = SIGSTKSZ * 2 ;
1337
1337
stack .ss_sp = PyMem_Malloc (stack .ss_size );
1338
1338
if (stack .ss_sp != NULL ) {
1339
1339
err = sigaltstack (& stack , & old_stack );
0 commit comments