fdo 37341 MAXRECURSION reached in ScFormulaCell::Interpret

Eike Rathke erack at redhat.com
Fri Jul 26 13:43:53 PDT 2013


Hi Winfried,

On Wednesday, 2013-07-24 11:34:27 +0200, Winfried Donkers wrote:

> I set MAXRECURSION to 4, made a simple spreadsheet (A2:=A1+1, A3:=A2=1, etc.) and started 'Goal Seeking'.
> With the target at A5 and the variable cell at A1, the recursion count reached 4 every time Interpret() was called from BackSolver(); BackSolver() was called once and a valid solution was found (as expected).
> With the target at A6 and the variable cell at A1, the recursion count reached 5 every time Interpret() was called from BackSolver(); Interpret() was called a zillion times and I aborted the application (more or less as expected).
> I changed a littel bit in the code of ScFormulaCell::Interpret():
>     if (rRecursionHelper.GetRecursionCount() > MAXRECURSION)
>      {
>          bRunning = true;
>          rRecursionHelper.SetInRecursionReturn( true);
>         return; //line added for testing
>      }
> I changed this so that Interpret does not continue its recursive work, as it seems to do.
> With the target at A6 and the variable cell at A1, the recursion count reached 5, Interpret() was called once from BackSolver(); BackSolver() was called twice; Goal Seek reported a failure (circular reference), but (better than expected).

Inserting a return at that place of course eliminates the entire
recursion/circular handling.

> To me, it _seems_ as if reaching the maximum recusrion count is not handled correctly in ScFormulaCell::Interpret().
> Before I start digging in the wrong direction and messing up things that I shouldn't touch I would very much like your expert opinion ;-)

The recursion itself is handled correctly, the added problem here is
1) we also have a circular dependency (which standalone combined with
   recursion should be handled gracefully)
2) the goal seek is triggered by ScDocument::Solver() creating an
   ScFormulaCell and start Interpret() on it, in
   ScInterpreter::ScBackSolver() the goal seek's defined formula cell is
   set dirty over and over again until the confifuration's limit is
   reached

The "zillion times" Interpret() was called probably were from
ScBackSolver() and if each results in a recursion with circular
references the calls to Interpret() multiply.

I'd investigate first why the loop in ScInterpreter::ScBackSolver()
isn't terminated, i.e. why changing the start value does not alter the
result. If it is correct that it doesn't change anymore than
ScBackSolver() will have to detect that.

If the culprit seems to be within ScFormulaCell::Interpret() then, well,
... I can't say much else would help than stepping through these calls
and keeping track of what called which in what state. The old code had
some debugging/tracing facilities that generated a .dot file from within
ScFormulaCell::Interpret() but unfortunately got completely removed with
5ff49e8ce958deb8217880b2aaf2bd41a567e8a1 (these are the cases where
I don't understand blind removal of #ifdef'ed code) so for testing
purposes you might want to revive the part of
sc/source/core/data/cell.cxx of that change into
sc/source/core/data/formulacell.cxx

Note that that debug code was unmaintained for a long while even before
its removal and needs (probably heavy) adaption to the current code, but
it may be a starting point for how to generate a track of the call
chain.

  Eike

-- 
LibreOffice Calc developer. Number formatter stricken i18n transpositionizer.
GPG key ID: 0x65632D3A - 2265 D7F3 A7B0 95CC 3918  630B 6A6C D5B7 6563 2D3A
For key transition see http://erack.de/key-transition-2013-01-10.txt.asc
Support the FSFE, care about Free Software! https://fsfe.org/support/?erack
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: <http://lists.freedesktop.org/archives/libreoffice/attachments/20130726/af469e6a/attachment.pgp>


More information about the LibreOffice mailing list