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
Attachment:
pgpB690dnEp2m.pgp
Description: PGP signature