Skip to content

Commit 030abcd

Browse files
committed
gh-135106: Randomly return 1 in _Py_RecursionLimit_GetMargin
Returns `1` a little less than 1% of the time in _Py_RecursionLimit_GetMargin() to force the use of the trashcan mechanism.
1 parent d8994b0 commit 030abcd

File tree

3 files changed

+16
-0
lines changed

3 files changed

+16
-0
lines changed

Include/cpython/pystate.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,8 @@ struct _ts {
208208
*/
209209
PyObject *threading_local_sentinel;
210210
_PyRemoteDebuggerSupport remote_debugger_support;
211+
212+
uint64_t prng;
211213
};
212214

213215
/* other API */

Include/internal/pycore_pystate.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,16 @@ _Py_RecursionLimit_GetMargin(PyThreadState *tstate)
325325
_PyThreadStateImpl *_tstate = (_PyThreadStateImpl *)tstate;
326326
assert(_tstate->c_stack_hard_limit != 0);
327327
intptr_t here_addr = _Py_get_machine_stack_pointer();
328+
329+
// splitmix64 from https://prng.di.unimi.it/splitmix64.c
330+
uint64_t z = (tstate->prng += 0x9e3779b97f4a7c15);
331+
z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
332+
z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
333+
uint64_t r = z ^ (z >> 31);
334+
if ((r & 0xFF) < 2) { // 2/256 chance = ~ 0.8% chance
335+
return 1;
336+
}
337+
328338
return Py_ARITHMETIC_RIGHT_SHIFT(intptr_t, here_addr - (intptr_t)_tstate->c_stack_soft_limit, PYOS_STACK_MARGIN_SHIFT);
329339
}
330340

Python/pystate.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1486,6 +1486,10 @@ init_threadstate(_PyThreadStateImpl *_tstate,
14861486
tstate->state = _Py_THREAD_SUSPENDED;
14871487
}
14881488

1489+
PyTime_t now;
1490+
PyTime_MonotonicRaw(&now);
1491+
tstate->prng = (uint64_t)now;
1492+
14891493
tstate->_status.initialized = 1;
14901494
}
14911495

0 commit comments

Comments
 (0)