pbrady/fastcache

Possible stack overflow bug

Closed this issue · 2 comments

On 3.4 so far, this sympy test leads to an error. Using functools.lru_cache does not.

[ptb@cyrus sympy]$ PYTHONHASHSEED=1756078925 bin/test sympy/core/tests/test_wester.py --seed 45968850
============================= test process starts ==============================
executable:         /home/ptb/miniconda3/bin/python  (3.4.1-final-0) [CPython]
architecture:       64-bit
cache:              yes
ground types:       python 
random seed:        45968850
hash randomization: on (PYTHONHASHSEED=1756078925)

sympy/core/tests/test_wester.py[395] .........fffffffwfffffwffff.fffffffffffffff
ffffffffFatal Python error: Cannot recover from stack overflow.

Current thread 0x00007f0d7f161740 (most recent call first):
  File "/home/ptb/gitrepos/sympy/sympy/core/numbers.py", line 1683 in __eq__
  File "/home/ptb/gitrepos/sympy/sympy/core/basic.py", line 327 in __eq__
  File "/home/ptb/gitrepos/sympy/sympy/core/add.py", line 733 in __neg__
  File "/home/ptb/gitrepos/sympy/sympy/core/power.py", line 844 in as_numer_denom
  File "/home/ptb/gitrepos/sympy/sympy/core/add.py", line 410 in as_numer_denom
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 320 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  File "/home/ptb/gitrepos/sympy/sympy/concrete/products.py", line 322 in _eval_product
  ...
Aborted

The error message is from ceval.c lines 705-742 - appears to be related to recursion (might not be a fastcache bug)

/* the macro Py_EnterRecursiveCall() only calls _Py_CheckRecursiveCall()
   if the recursion_depth reaches _Py_CheckRecursionLimit.
   If USE_STACKCHECK, the macro decrements _Py_CheckRecursionLimit
   to guarantee that _Py_CheckRecursiveCall() is regularly called.
   Without USE_STACKCHECK, there is no need for this. */
int
_Py_CheckRecursiveCall(char *where)
{
    PyThreadState *tstate = PyThreadState_GET();

#ifdef USE_STACKCHECK
    if (PyOS_CheckStack()) {
        --tstate->recursion_depth;
        PyErr_SetString(PyExc_MemoryError, "Stack overflow");
        return -1;
    }
#endif
    _Py_CheckRecursionLimit = recursion_limit;
    if (tstate->recursion_critical)
        /* Somebody asked that we don't check for recursion. */
        return 0;
    if (tstate->overflowed) {
        if (tstate->recursion_depth > recursion_limit + 50) {
            /* Overflowing while handling an overflow. Give up. */
            Py_FatalError("Cannot recover from stack overflow.");
        }
        return 0;
    }
    if (tstate->recursion_depth > recursion_limit) {
        --tstate->recursion_depth;
        tstate->overflowed = 1;
        PyErr_Format(PyExc_RuntimeError,
                     "maximum recursion depth exceeded%s",
                     where);
        return -1;
    }
    return 0;
}

See sympy/sympy#7822. There may be an issue with exception propagation for the "maximum recursion depth exceeded" in 3.4 for some reason as some the tests in test_wester are designed to raise infinte recursion errors.