scryer-prolog: Excessive memory usage in failure-driven loop

$ scryer-prolog --version
"v0.8.123-557-gebe143d"

$ scryer-prolog
?- use_module(library(between)).
   true.
?- [user].
q(E) :- X is 10^E, (between(1,X,_),false;true).
?- q(6).
Segmentation fault (core dumped)

The issue with this is not the segmentation violation (or the catchability thereof as in issue #16).

It is the excessive amount of memory allocated before the segv happens.

What’s going on?


P.S. I defined q/1 to check if the problem was top-level related or not. It seems it does not.

About this issue

  • Original URL
  • State: open
  • Created 3 years ago
  • Reactions: 2
  • Comments: 15 (8 by maintainers)

Most upvoted comments

It would help here to issue a clean resource error. In this manner one could distinguish between copystack/global heap overflows and call stack/local stack overflows.

$ sh -c 'ulimit -c 0; ulimit -v 100000; ./scryer-prolog -f'
?- [user].
query :-
   repeat,
   loop.

loop :-
   true,
   loop.

?- query.
   % Expected loop.

The variable isn’t needed. In this example the stack (local stack) is maybe growing but tail call optimization should have made this loop with constant memory.

@notoria Your example shows similarly erratic behavior. I can confirm that.

But the rest (why a true makes a difference) is quite puzzling to me…

$ sh -c 'ulimit -c 0; ulimit -v 100000; ./scryer-prolog -f'
?- [user].
query :-
    repeat,
    loop(_).

loop(N) :-
    true,
    loop(N).

?- query.

It should be the same issue.

length(_,_) uses memory for the list. So it is not a good example to draw conclusions from.

@bakaq @UWN I cannot confirm this is fixed with the latest version.

Instead I find the following top-level query working fine:

?- (between(1,100000000,_),false;true).

But doing almost the same in an auxiliary predicate quickly runs out of memory:

?- [user].
q :- between(1,100000000,_),false;true.
?- q.

This here works:

b(A,B,C):-between(A,B,C),false.
b(_,_,_).

qo :- b(1,100000000,_).

?- qo.
   true.                  

I can’t seem to reproduce this in the latest master. Memory usage doesn’t seem to scale with E at all, and there is no SEGV at least until E = 8 (it takes exponentially more time to increase it further, as expected).