Re: EPIPE

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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 :)


[Index of Archives]     [Video For Linux]     [Photo]     [Yosemite News]     [gtk]     [GIMP for Windows]     [KDE]     [GEGL]     [Gimp's Home]     [Gimp on GUI]     [Gimp on Windows]     [Steve's Art]

  Powered by Linux