5.7 d.what.vect form problems [was: Re: [GRASS5] d.legend and d.out.png]

Glynn Clements glynn at gclements.plus.com
Fri Oct 22 15:22:17 EDT 2004

Moritz Lennert wrote:

> >> > If the form window never appears, that suggests that it dies shortly
> >> > after startup, which is going to make it hard to debug. The only thing
> >> > which I can suggest is to add a sleep() call to the top of main() in
> >> > lib/form/form.c, so that you get a chance to attach a debugger to it.
> >>
> >> Ok, I tried using sleep, but now I can't reproduce the error, except
> >> when
> >> using sleep(0). sleep(1) and upward all make the error disappear. This
> >> does not solve my problem on how to debug ;-), but might it be an
> >> explanation by itself ?
> >
> > Another option is to re-compile lib/gis with GDEBUG defined, then set
> > the DEBUG and GRASS_DEBUG_FILE environment variables (see
> > lib/gis/debug.c).
> >
> > One thing which stands out is that lib/form/form.c reads from stdin
> > using both read() and the ANSI stdio functions, which may well result
> > in timing-dependent bugs. Also, I'm unsure whether Tcl may use the
> > descriptor itself.
> I've finally gotten around to recompiling grass and setting the debug
> variable to 3.
> I've attached the output. Hope this helps to debug the problem.

Not really. Right at the end of the log, there is a single message
from the child:

	D2/3: Form: main()

This corresponds to the very first statement in main() in form.c. At
least we know that the form program actually gets as far as main().
However, it doesn't appear to get very far, otherwise we would expect
another message:

    G_debug ( 2, "Form: main()" );
    setlocale(LC_CTYPE, "");
    child_recv = stdin;
    child_send = stdout;

    fcntl ( fileno(child_recv), F_SETFL, O_NONBLOCK); /* Don't wait if pipe is empty */
    while ( 1 ) {
	ret = read ( fileno(stdin) , &(buf[0]), 1);
	if ( ret == 0 ) break; /* Pipe was closed by parent -> quit */
	if ( ret == 1 ) {
	    G_debug ( 3, "Form: received = '%c'", buf[0] );

The (ret == 1) case accounts for the bulk of the loop, which ends

	Tcl_Eval(interp, "update");

My suspicion is that the initial read() call returns -1 (and sets
errno to EAGAIN), so the next thing that happens is that Tcl's update
procedure is called, at which point the program crashes.

Essentially, I suspect that the problem boils down to the program
doing something which Tcl isn't particularly happy about. I have no
idea what, though.

Glynn Clements <glynn.clements at virgin.net>

More information about the grass-dev mailing list