Gå til innhold

Hvordan få matte-feil til å gi signal?


Anbefalte innlegg

Nedenforstående kode funker ikke. for-løkken burde gi en SIGFPE når f blir inf, burde den ikke?

 

I stedet fortsetter den til raise(...), noe som viser at riktig funksjon kalles. Og AP+SV blir aldri bra :p

 

#include <signal.h>
#include <stdio.h>

void matherror(int e){
puts("Math error!");
exit(0);
}

int main(){
int i;
float f;
void (*os)(int);
os=signal(SIGFPE,matherror);
if (os==SIG_ERR) {puts("Error setting signal function!"); exit(0);}
f=1.0;
for (i=0;i<100000;i++) f=f*1.5;
printf ("Infinte: %f\n",f);
raise(SIGFPE);
puts("AP+SV blir bra!");
return 0;
}

 

Utskrift:

Infinte: inf
Math error!

Lenke til kommentar
Videoannonse
Annonse

Du bør vel først ta en titt på flyttallsmiljøet ditt ved hjelp av fenv:

 

#include <signal.h>
#include <stdio.h>
#include <fenv.h>

static void 
matherror(int e)
{
 fprintf(stderr, "Math error!\n");
 exit(0);
}

int 
main(int argc, char *argv[])
{
 int i;
 float f = 1.0;

 if(!(fegetexcept() & FE_OVERFLOW))
   {
     fprintf(stderr, "FE_OVERFLOW not enabled - tying to enable\n");

     feenableexcept(FE_OVERFLOW);

     if(!(fegetexcept() & FE_OVERFLOW))
{   
  fprintf(stderr, "FE_OVERFLOW could not enable!\n");
  exit(0);
}
   }

 if(signal(SIGFPE, matherror) == SIG_ERR) 
   {
     fprintf(stderr, "Error setting SIGFPE handler!\n"); 
     exit(0);
   }

 for(i = 0; i < 100000; i++) 
   {
     f = f*10.5;
   }

 printf("Infinte: %f(0x%08x)\n", f, f);

 return 0;
}

 

 

EDIT: husk å linke mot math(-lm). Oppdaterte koden til å bruke GNU spesifikke except API som jeg synes er greit nok her :)

Endret av kattemat
Lenke til kommentar
Er ikke signal det samme som interrupt? Og skal vel ærlig talt helst ikke brukes lenger... og tar jeg ikke helt feil, så skal du heller ikke bruke printf, malloc eller lignende i interrupt rutiner.

Hva skal brukes i stedet?

 

Exceptions? Er ikke det C++?

Lenke til kommentar

Signaler er "software interrupts" og det er helt normalt å sette opp egne handlers for disse. Ikke noe i veien for å skrive til stdout i en signal handler heller så vidt meg bekjent... Les mer på:

http://www.cs.cf.ac.uk/Dave/C/node24.html

 

Sikker på at du ikke blander dette med hardware interrupt handlere i kernel mode? SIGFPE er vel i ytterste instans trigget av er hardware interrupt, men signalhandleren en registrerer i userland blir vel ikke kalt før all prossesering av HW interruptet er skjedd.

 

Edit: Men signal handlere er jo asynkrone og en vet fint lite om kontekst når de blir kalt så det er klart en skal være påpasselig. Noen bruker f.eks. alarm signalet som en timer og signalhandleren som en callback for dette. Slike ting bør en vel være veldig forsiktig med. Men somoftest brukes egne signal handlers enten for mer gracefull exit enn hva orginalhandleren gjør eller for å ignorere signalet(typisk SIGHUP).

Signalhandling I multithreadede applikasjoner - det er en helt anna saga ;)

Endret av kattemat
Lenke til kommentar
Hvis du vil gi ut lyd, kan man ikke slenge på /a da?

Ser ikke helt sammenhengen med resten av diskusjonen ;) men jeg går ut i fra at du er ute etter å få terminalen til å ringe i "bjella"?

Ja - du kan skrive "/a" til stdout og om dette havner i en terminal som spiller bjella ved denne escape sekvensen så får du et beep i høytaleren...

 

Om det var SIGALRM(alarm) signalet du tenkte på så er dette noe helt anna og har ingenting med "bjelle" å gjøre.

Lenke til kommentar

Jeg var vel litt upresis, men det jeg lurte på er, dersom man ikke bør bruke signal for å håndtere feil i flyttall, hva bør man bruke?

 

At man ikke bør bruke slik som printf i signal-håndteringsfunksjoner er jeg klar over. Jeg brukte det bare for debugging mens jeg prøvde å fule ut hvorfor ting ikke funka.

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...