[GRASS-user] Label crash

Glynn Clements glynn at gclements.plus.com
Sat Apr 18 15:38:15 EDT 2009


Adam Dershowitz, Ph.D., P.E. wrote:

> >>> And I get the following repeated a whole bunch of times:
> >>>
> >>> The process has forked and you cannot use this CoreFoundation  
> >>> functionality
> >>> safely. You MUST exec().
> >>> Break on
> >>> __THE_PROCESS_HAS_FORKED_AND_YOU_CANNOT_USE_THIS_COREFOUNDATION_FUNCTIONALITY___YOU_MUST_EXEC__ 
> >>> ()
> >>> to debug.
> >>>
> >>> The same thing happens if I use d.mon start=PNG.
> >>
> >> could fork() in
> >> lib/driver/main.c
> >> be the problem?
> >
> > Yes. It's basically a symptom of "MacOSX is sort of Unix, but not
> > quite".
> 
> Actually MacOSX is Unix and Linux is almost Unix.

Only if you adopt a very narrow definition of Unix.

Clearly, the behaviour of CoreFoundation doesn't violate any written
Unix standard, as CoreFoundation isn't mentioned in any written Unix
standard.

OTOH, the notion of a library which won't work in a daemon process was
unheard of prior to MacOSX.

> > A similar issue affects libW11 on Cygwin. There, mon.start runs the
> > driver in the background (spawnl(_P_DETACH, ...)) with argv[2] = "-",
> > which prevents it from fork()ing.
> >
> > Something similar could be done for MacOSX. However, this isn't
> > robust, as it relies upon mon.select retrying upon failure. If the
> > driver takes too long to start, mon.select will fail.
> >
> 
> This explains the problem:  http://developer.apple.com/technotes/tn2005/tn2083.html#SECDAEMONVSFRAMEWORKS
> 
> Although I am not sure about the solution.

It may be possible to move the initialisation into the child process
(i.e. after the fork()), however:

1. I don't know whether this will satisfy MacOSX.

It depends upon whether CoreFoundation is automatically initialised
immediately following an exec(), or if it's only initialised by
something in the driver's initialisation routine. Determining whether
it applies only to specific drivers or to all of them might shed some
light on this.

2. It will impact error reporting.

The monitor is assumed to have started successfully if the process
terminates with a zero exit code.

If LIB_Init() (and thus the driver's Graph_set() method) completes
without generating a fatal error, the driver fork()s and the parent
returns a zero exit code. If a fatal error occurs, the process
terminates with a non-zero exit code before the fork() is reached.

If LIB_Init() isn't called until after the fork(), the monitor will be
assumed to have started successfully in almost every case. Other than
LIB_Init(), about the only thing which can realistically fail prior to
the fork() is if the listening socket cannot be created.

Any problems in the driver initialisation (e.g. unable to open display
for XDRIVER) won't be apparent until the first client (usually
mon.select) tries to connect, and finds that the monitor has
terminated.

-- 
Glynn Clements <glynn at gclements.plus.com>


More information about the grass-user mailing list