I disagree with your "unpredictable" assessment. If I said
"setting SIGFPE to SIG_IGN causes division overflows to return
MAX_INT", this is perfectly predictable.
Now granted, it may violate some conventions about signal generation
(as per your comment at the end of your message).
> Now, you're obviously using inline assembly or something, as I don't
> think gcc will ever compile any division to do the 64/32->32 thing. If
> you're ready to do that kind of thing, then you must be ready to play
> around a bit in a signal handler or play with longjump.
>
> In a signal handler, you could even do
>
> =09#include <asm/sigcontext.h>
>
> =09void sigfpe_handler(int signr, struct sigcontext context)
> =09{
> =09=09fixup(&context);
> =09}
>
> Where the "fixup()" routine does a disassembly of the %eip that faulted,
> and jumps over it. (Depending on how you have written your inline macro,
> you may know that the division is always done with a register, so then
> the "fixup" can be as simple as just doing
>
> =09context.eip += 2;
> =09context.eax = ~0;
> =09context.edx = ~0;
>
> and that's it..
This is very useful to know. (Unfortunately, this second argument
to signal handlers is completely undocumented in the man pages,
even the latest v1.11 man pages. Granted, this is not really
your fault, but it does make life noticeably harder. I knew
from past experience that there were additional arguments to signal
handlers, but there's no standard here: e.g. SunOS uses
void handler(sig, code, scp, addr)
int sig, code;
struct sigcontext *scp;
char *addr;
)
> > Do I REALLY have to set up my own signal handler that looked at
> > the assembly and stepped the program counter over the instruction?
> > Isn't that more than a bit absurd?
>
> "more than a bit absurd"?
>
> That's _exactly_ what you asked _me_ to do in the kernel.. How does it
> feel to have the tables turned on you?
>
> You essentially asked me to do the same "absurd" thing, but for no real
> reason, and from the kernel which is unpageable and where every little
> piece of memory _stays_ in memory even though 99.95% of all programs
> don't care or even _want_ this functionality..
>
> THAT is why I think people have no grip on reality on this thing.
Think for a moment about all the crap that's in the Linux kernel, e.g.
color TTY. Compare that with the small amount of additional code
required to support this feature. Isn't one of the primary purposes
of the kernel to shield programmers from the ugly processor-specific
garbage going on behind the scenes?
Now granted I'm getting myself a bit wet by using inline assembly,
but dipping my foot in the water is not the same as jumping in
head-first (i.e. doing extremely non-portable highly OS-specific
stuff involving signal handlers and assembly code).
Note that exceptions != signals. One of the big things about Unix
signals is that they shield you from the yuckiness of processor
exceptions and such -- i.e. just because the processor gives an
exception, it doesn't mean the kernel has to always send a signal,
especially a misnamed one like SIGFPE. What's so absurd about having
a simple kernel interface to provide you a minimal amount of control
over how signals are issued? SIG_IGN may not be the way to go, but
what about a system call? There are already ways of controlling
*floating-point* SIGFPE's (although under Linux this can only be
done using the horrid and undocumented __setfpucw, I think) and
SIGIO, SIGTTOU, etc.
In any case, thank you for your time in explaining how this stuff
works -- you've provided me with a workable solution.
ben