Morning everybody,
Is there any way to catch, or ignore, a SIGFPE ? This isn't for
any practical reason, just to satisfy curiosity.
I've attached two c proggies, one that tries catching, one that
tries ignoring. I can catch the exception but the exception just gets
raised again immediately - on my box it gets raised around 130,000 times
before a 1 second timer cuts in. I can't ignore the signal, for some
reason ...
Anyways, if someone knows how to catch/ignore SIGFPE successfully,
I'd love to hear it.
Cheers
-kev
/* == File: ignoring_SIGFPE.c ==================================== */
/* ignoring_SIGFPE.c sets SIGFPE to be ignored, then causes
* a divide-by-zero error.
*/
/* Headers. */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
/* Function prototypes. */
void register_sig_handlers (); /* Registers handler for SIGFPE. /*
int generate_fpe (); /* Returns result of a division by zero. */
/* On with the show. */
int main (int argc, char *argv[])
{
register_sig_handlers ();
/* Should print garbage, I guess.
* Instead a floating point exception causes termination.
*/
printf ("generate_fpe returned with value %d !\n", generate_fpe ());
return 0;
}
void register_sig_handlers ()
{
struct sigaction sigfpe;
/* Setting SIGFPE to be ignored. */
sigfpe.sa_handler = SIG_IGN;
sigemptyset (&sigfpe.sa_mask);
sigfpe.sa_flags = 0;
sigaction (SIGFPE, &sigfpe, NULL);
}
int generate_fpe ()
{
return (3 / 0);
}
/* == End of file ================================================= */
/* == File: catching_SIGFPE.c ==================================== */
/* catching_SIGFPE.c causes a divide-by-zero, and counts
* the number of times it catches SIGFPE over the next
* second.
*/
/* Headers */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
/* Global variables */
unsigned alarm_secs = 1; /* Secs to allow generate_fpe() to run. */
unsigned n_fpe = 0; /* Number of times SIGFPE caught. */
/* Function prototypes */
void register_sig_handlers (); /* Registers handlers for SIGALRM & SIGFPE */
void sigfpe_handler (); /* Increments n_fpe when SIGFPE caught. */
void sigalrm_handler (); /* Prints n_fpe to stdout. */
int generate_fpe (); /* Returns result of a division by zero. */
int main (int argc, char *argv[])
{
register_sig_handlers ();
alarm (alarm_secs);
generate_fpe ();
return 0;
}
void register_sig_handlers ()
{
struct sigaction sigfpe, sigalrm;
sigfpe.sa_handler = sigfpe_handler;
sigemptyset (&sigfpe.sa_mask);
sigfpe.sa_flags = 0;
sigaction (SIGFPE, &sigfpe, NULL);
sigalrm.sa_handler = sigalrm_handler;
sigemptyset (&sigalrm.sa_mask);
sigalrm.sa_flags = 0;
sigaction (SIGALRM, &sigalrm, NULL);
}
void sigfpe_handler ()
{
n_fpe++;
}
void sigalrm_handler ()
{
/* The printf(3) manpage says '%l' should print a long, or unsigned
* long, but I just get a '%' character instead. So I'm using %u.
*/
printf ("over %u seconds, SIGFPE was caught %u times\n",
alarm_secs, n_fpe);
_exit (0);
}
int generate_fpe ()
{
return (3 / 0);
}
/* == End of file ================================================= */
--
Writing a haiku
Is much harder than it looks.
These lines fall short.
Maintained by the ILUG website team. The aim of Linux.ie is to
support and help commercial and private users of Linux in Ireland. You can
display ILUG news in your own webpages, read backend
information to find out how. Networking services kindly provided by HEAnet, server kindly donated by
Dell. Linux is a trademark of Linus Torvalds,
used with permission. No penguins were harmed in the production or maintenance
of this highly praised website. Looking for the
Indian Linux Users' Group? Try here. If you've read all this and aren't a lawyer: you should be!