[mercury-users] Stack overflow, because I don't use unique modes?

Fergus Henderson fjh at cs.mu.OZ.AU
Mon Feb 11 12:29:43 AEDT 2002

On 10-Feb-2002, Ondrej Bojar <oboj7042 at ss1000.ms.mff.cuni.cz> wrote:
> I want Mercury to walk over very big files and get some statistics about
> the files. I walk line by line, perform (not too simple, but
> from the outside deterministic) calculation and accumulate the
> statistics. The problem is that the stack overflows after parsing more
> than about 50000 lines of input (and succeeds if the input is shorter).
> I'm afraid the thing is I do not use di and uo modes for the stats
> accumulator.

That won't have any effect on stack overflow.

Because of some limitations in Mercury's current mode system,
unique modes should in general only be used for io__states.

The stack overflow problem is likely to be that you have a main loop
with a recursive procedure that is not tail recursive.

The `fold_lines2' predicate that you posted looks like it should
be tail recursive, so I don't think that is the problem.
Maybe the problem is in part of the source code that you
didn't post.

In order to solve the problem, you really need to find out
which procedure(s) are on the stack when it overflows.
Unfortunately the Mercury debugger will not be very useful here,
because although you can certainly get a stack trace with mdb, in our
current implementation compiling with tracing enabled will prevent tail
call optimization, even if you use the `--trace-optimized' option.

So, probably the best way to debug the problem is get a C stack trace,
which you can do by building with

	GRADEFLAGS = --high-level-code
	MGNUCFLAGS = --c-debug --no-c-optimize
	MLFLAGS = --c-debug

in your Mmakefile, and then running your program with gdb,
and using gdb's `backtrace' command.

Note that compiling with GRADEFLAGS = --high-level-code will change the
stack limit, since it will mean that Mercury uses the C stack, rather
than a separate Mercury stack.  So this may affect the size of the
input for which the stack overflow occurs.  (Currently it also means
you get a less informative error message on stack overflow.)

> Unfortunately, I do not understand unique modes well enough,
> and when I try to replace 'in' and 'out' with 'di' and 'uo', I get strange
> errors I cannot solve, such as:
> For :- mode parse_line(in, di, uo) instead of (in, in, out):
> countvjv.m:047: In clause for `parse_line(in, di, uo)':
> countvjv.m:047:   mode error: argument 3 did not get sufficiently instantiated.
> countvjv.m:047:   Final instantiatedness of `HeadVar__3' was `ground',
> countvjv.m:047:   expected final instantiatedness was `unique'.

The error message is a bit misleading -- it should say "was not
sufficiently unique" rather than "did not get sufficiently
instantiated".  The problem here is that the compiler has
inferred that the third argument might not be uniquely referenced.
Looking at the source code, I think the problem will be
that one or more of the procedures called by parse_line/3 to
compute OutMem -- count/3 and do_sentence/5 --
have not been declared with a unique mode for that argument.

Compiling with `-VN' (a.k.a. `--very-verbose --debug-modes')
will give more information that may help you to see exactly
which sub-goal of parse_line/3 caused Outmem to have inst
`ground' rather than `unique'.

However, fixing that would lead you to the problem
that count/3 calls bag__insert/3 in the Mercury standard
library, and there's no unique mode for bag__insert/3.

And trying to fix that, e.g. by adding a unique mode for bag__insert,
would eventually run into the problem (mentioned in the LIMITATIONS file)
that the current Mercury implementation doesn't supported nested unique modes.
This means that you can't use unique modes for recursive data structures
such as lists or trees.

Hence the advice that unique modes should only be used for io__states.

Fergus Henderson <fjh at cs.mu.oz.au>  |  "I have always known that the pursuit
The University of Melbourne         |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  |     -- the last words of T. S. Garp.
mercury-users mailing list
post:  mercury-users at cs.mu.oz.au
administrative address: owner-mercury-users at cs.mu.oz.au
unsubscribe: Address: mercury-users-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-users-request at cs.mu.oz.au Message: subscribe

More information about the users mailing list