Pull request: Raise SIGFPE instead of abort in __gmp_exception`

Yichao Yu yyc1992 at gmail.com
Thu Jan 28 20:44:41 UTC 2016


> I don't fully understand the consequences, but if raise ever returns for
> any reason, __gmp_exception will go on and divide by zero, and if that

If I read the patch[1] correctly, the divide by zero is nor performed
if SIGFPE exists.

[1] https://gmplib.org/repo/gmp/rev/c59c3879f982

> doesn't cause program termination, it will next call abort.
>
> Posix seems pretty clear that raise must deliver the signal to the
> thread executing raise.
> http://pubs.opengroup.org/onlinepubs/009695399/functions/raise.html. And

Not really. I was also confused at first but the POSIX standard you
linked states that the signal is delivered to either `thread or
process` and if the thread didn't choose the `Threads` option, the
effect is the same with `kill(getpid(), sig)`, which will deliver the
signal to an arbitrary thread in the process. Apparently linux choose
to implement the thread option and osx choose to implement the process
option.

> It's possible to add som OSX workaround, say
>
>   #if defined (SIGFPE) && defined (MAC_SOMETHING)
>
> But I'd prefer to do that only if there's any real problem. After all,

There is. And we've (julia) seen similar issue (when calling
`raise(SIGINT)`) in our test caused by exactly this.

> the typical action is that the program is terminated, and if a signal
> handler is installed, it typically just adds a friendlier error message
> before termination.
>
>> Unconditionally trying the old approach first should solve this issue.
>
> You mean, first try divide by zero, and in case that doesn't crash the

Right.

> program, raise a signal? If we want the specific signal SIGFPE, then I
> think using raise is preferable, because it has a reasonably well
> defined meaning in C. While division by zero is undefined behaviour.

For a thread-safe version without undefined behavior on OSX, I think
the right way is to conditionally (on osx) use `pthread_kill` (and
link to pthread).


I think another difference that worth clarifying between what we want
and what is currently assumed in gmp is that we don't really want the
program to terminate if there's some arithmetic error. (Especially
since things like dividing by zero is typically/conceptually something
one can recover from, different from segfault which is often a sign of
memory corruption and is hard to recover). This is why we care about
which thread the signal is delivered to if a signal is to be used to
report the error. (If what we do is simply terminate the program after
printing some error message, we would care less about the thread we
run the signal handler on although running on the wrong thread can
still mess up the back trace).

Of course, using a callback to report the error would be even better.
However, as you (or someone else) mentioned, having such API would
probably imply that GMP should still be in a consistent state after an
error is thrown (and handled) so I imagine that will be harder to
implement. Adding such API and refine it later would still be strictly
better than the current situation though.


More information about the gmp-devel mailing list