mirror of
https://github.com/python/cpython.git
synced 2025-07-07 19:35:27 +00:00
GH-130396: Use computed stack limits on linux (GH-130398)
* Implement C recursion protection with limit pointers for Linux, MacOS and Windows * Remove calls to PyOS_CheckStack * Add stack protection to parser * Make tests more robust to low stacks * Improve error messages for stack overflow
This commit is contained in:
parent
99088ab081
commit
014223649c
58 changed files with 1295 additions and 1482 deletions
|
@ -612,12 +612,9 @@ PyObject_Print(PyObject *op, FILE *fp, int flags)
|
|||
int write_error = 0;
|
||||
if (PyErr_CheckSignals())
|
||||
return -1;
|
||||
#ifdef USE_STACKCHECK
|
||||
if (PyOS_CheckStack()) {
|
||||
PyErr_SetString(PyExc_MemoryError, "stack overflow");
|
||||
if (_Py_EnterRecursiveCall(" printing an object")) {
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
clearerr(fp); /* Clear any previous error condition */
|
||||
if (op == NULL) {
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
|
@ -738,12 +735,6 @@ PyObject_Repr(PyObject *v)
|
|||
PyObject *res;
|
||||
if (PyErr_CheckSignals())
|
||||
return NULL;
|
||||
#ifdef USE_STACKCHECK
|
||||
if (PyOS_CheckStack()) {
|
||||
PyErr_SetString(PyExc_MemoryError, "stack overflow");
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
if (v == NULL)
|
||||
return PyUnicode_FromString("<NULL>");
|
||||
if (Py_TYPE(v)->tp_repr == NULL)
|
||||
|
@ -786,12 +777,6 @@ PyObject_Str(PyObject *v)
|
|||
PyObject *res;
|
||||
if (PyErr_CheckSignals())
|
||||
return NULL;
|
||||
#ifdef USE_STACKCHECK
|
||||
if (PyOS_CheckStack()) {
|
||||
PyErr_SetString(PyExc_MemoryError, "stack overflow");
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
if (v == NULL)
|
||||
return PyUnicode_FromString("<NULL>");
|
||||
if (PyUnicode_CheckExact(v)) {
|
||||
|
@ -2900,19 +2885,6 @@ _PyTrash_thread_deposit_object(PyThreadState *tstate, PyObject *op)
|
|||
void
|
||||
_PyTrash_thread_destroy_chain(PyThreadState *tstate)
|
||||
{
|
||||
/* We need to increase c_recursion_remaining here, otherwise,
|
||||
_PyTrash_thread_destroy_chain will be called recursively
|
||||
and then possibly crash. An example that may crash without
|
||||
increase:
|
||||
N = 500000 # need to be large enough
|
||||
ob = object()
|
||||
tups = [(ob,) for i in range(N)]
|
||||
for i in range(49):
|
||||
tups = [(tup,) for tup in tups]
|
||||
del tups
|
||||
*/
|
||||
assert(tstate->c_recursion_remaining > Py_TRASHCAN_HEADROOM);
|
||||
tstate->c_recursion_remaining--;
|
||||
while (tstate->delete_later) {
|
||||
PyObject *op = tstate->delete_later;
|
||||
destructor dealloc = Py_TYPE(op)->tp_dealloc;
|
||||
|
@ -2934,7 +2906,6 @@ _PyTrash_thread_destroy_chain(PyThreadState *tstate)
|
|||
_PyObject_ASSERT(op, Py_REFCNT(op) == 0);
|
||||
(*dealloc)(op);
|
||||
}
|
||||
tstate->c_recursion_remaining++;
|
||||
}
|
||||
|
||||
void _Py_NO_RETURN
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue