Raphael Quinet wrote:
> [ a cool summary of signals which i'm thinking about to copy for my students :) ]

> - SIGILL: one some processors that do not deliver SIGBUS in all cases,
>   you can get a SIGILL if a pointer to a callback function was
>   overwritten with garbage.  If the pointer is still referencing some
>   area inside a code segment (so that you don't get a SIGSEGV) but not
>   pointing to the start of a valid instruction, you will get the SIGILL.
>   By the way, the Gimp does not catch this one.  Why?

Dunno, most likely it was just forgotten in the first place.

> - SIGABRT: usually triggered by the application calling abort() or by a
>   user who wants to get a core dump from a running process.  It can be
>   caught by an application that wants to perform some specific cleanup
>   tasks, but in most cases it should not be caught by a generic error
>   handler.  I don't understand why the Gimp maps this to the generic
>   gimp_fatal_error() function???

Yep, we should not catch it but let the kernel do it's job. If the user
wants a core dump, she should get one.

> - SIGCHLD or SIGCLD: a child process died.  This signal can be
>   delivered at any time.  Some systems do not provide a reliable way
>   to know how many processes exited (if they do not support SA_NODEFER
>   or if their waitpid() or wait3() calls are broken), so it is usually
>   better to simply set a flag in the signal handler (without calling
>   any wait*() function) and to check the status of the children outside
>   the signal handler, until some wait*() function reports that there
>   are no more dead processes.  For example:
>     while ((pid = waitpid (-1, &status, WNOHANG)) > 0)
>       { ... /* check WIFEXITED(status) and other things */ }

This is what currently happens (ok, it happens in the handler, but WNOHANG
*should* be absolutely safe).
However, a signal handler can do whatever it likes with the app's structures
as long as it uses atomic data access (which can be a pointer, as pointers
have the same size as integers, which are atomic. This is true at least on
all processors which have a GNU libc port and finding a processor
where pointers are not atomic looks very unlikely to me).
The usage of SIGCLD is strongly discouraged by Stevens and some Solaris
document I fould recently. But Gimp uses SIGCHLD anyway.

> In most of the applications that I wrote, the signal handlers do
> nothing directly: they only set a flag that is checked by the main
> loop (in an idle function for GTK+ apps, or after poll() or select()
> for applications that use low-level calls).  I define one flag for
> each signal (got_sigchld, got_sigterm, ...) and a master flag that
> tells if any of the signal-specific flags have been set.  Sometimes I
> also use counters instead of boolean flags, but on some systems the
> counters are not reliable (especially if there is no SA_NODEFER) so
> most of the time they are meaningless.
> In one application that wanted to catch SIGSEGV, SIGBUS, SIGILL and
> SIGFPE, I created a handler that uses a direct call to write() on an
> fd that was previously obtained from fileno(stderr) (this fd is saved
> early so that the write() call can work even if the FILE *stderr is
> overwritten with garbage).  Doing this is safe, AFAIK.

Yep, write() is safe. Gimp uses g_print() which is not really safe, but
then we call g_on_error_query() which definitely does a bit more than
what's allowed :)

>From glib/gerror.c:

 * MT safe ; except for g_on_error_stack_trace, but who wants thread safety 
 * then

> In most cases, I ignore SIGPIPE (or I only increment a counter for
> debugging purposes) because the best way to deal with this is to check
> the return value of the write() or send() calls, or to check if a
> read() returns 0 later.

This is what Gimp does now. Still mysterious why it worked all the time
with SIGPIPE being fatal.

> Just my 0.02 Euro.  But you probably knew all of this already...

Almost all... But thanks a lot for writing this summary I've been to lazy to
write for years now :):):)

And... please torture the new code.

I was not able to crash gimp or make it spinning, even when sending
SIGSEGV's to plugins while they were heavily using the wire.

OTOH I'm almost sure that I'm again the one who introduced the worst
bug of the next release...


killall -SIGGIMP ps

Reply via email to