[GRASS-dev] set_fatal_error
Martin Landa
landa.martin at gmail.com
Fri Jan 18 17:38:22 EST 2008
Hi,
2008/1/16, Glynn Clements <glynn at gclements.plus.com>:
> > > > We already have G_set_error_routine(). However, a fundamental property
> > > > of G_fatal_error() is that it doesn't return (that's why the "fatal"
> > > > is part of the name).
> > >
> > > right, but it doesn't avoid calling exit(EXIT_FAILURE) in G_fatal_error().
> > >
> > > Calling G_fatal_error() causes crashing wxPython GUI e.g. during
> > > digitization. I am not sure how to handle this, since G_fatal_error()
> > > is widely used in Vector library. I guess this could be possible to
> > > solve by using separate thread in Python code(?).
> > >
> > > The second point, I guess it was the reason (crashing e.g. qgis) why
> > > (probably by Radim) Vect_*_fatal_error() were added to Vect library.
> > > But it is used only in open.c and legal_vname.c as far as i know.
> > >
> > > Avoiding calling exit() in G_fatal_error() in the given case would
> > > make sense, maybe.
> >
> > I meant something like:
> >
> > int G_fatal_error (const char *msg,...)
> > {
> > char buffer[2000]; /* No novels to the error logs, OK? */
> > va_list ap;
> >
> > va_start(ap,msg);
> > vsprintf(buffer,msg,ap);
> > va_end(ap);
> >
> > print_error (buffer,ERR);
> >
> > if (ferror == G_FATAL_RETURN) {
> > return EXIT_FAILURE;
> > }
>
> Nope; G_fatal_error() must *never* return; that's the whole point.
>
> > exit (EXIT_FAILURE);
>
> Code which calls G_fatal_error() relies upon it not returning. If it
> were to return, the caller would most likely just crash as a
> consequence of whichever "error" it was using G_fatal_error() to
> report.
>
> E.g. if you have the following code:
>
> struct foo *p = get_foo();
> if (!p)
> G_fatal_error("...");
> if (p->foo)
> ...;
>
> If G_fatal_error() returns, you will just get a segfault when the code
> dereferences the pointer.
>
> Code which calls G_fatal_error() isn't just expecting an error message
> to be printed. More importantly, it expects execution of the remainder
> of the function to be aborted.
>
> Many GRASS functions are written (and used) on the assumption that
> they cannot fail. They either succeed, or they never return (because
> any errors result in a call to G_fatal_error(), which never returns).
>
> The GRASS libraries were designed for use in one-shot utilities.
> Making them useful for persistent applications is going to require a
> substantial re-write. You can't just tweak G_fatal_error(); you have
> to re-write everything which calls it to actually recover from errors
> rather than just terminating the program as soon as anything goes
> wrong.
>
> Even if you take the approach QGIS uses and install an error handler
> which longjmp()s out to the caller, you have to allow for the fact
> that the data structures used by the GRASS libraries may be left in an
> inconsistent state, so subsequent library calls may simply segfault.
well, thanks a lot for the clarification.
Regards, Martin
--
Martin Landa <landa.martin at gmail.com> * http://gama.fsv.cvut.cz/~landa *
More information about the grass-dev
mailing list