Re: usine à gaz des .h
Bonjour,
Philippe Deleval wrote:
> J'essaie de construire un récupérateur d'erreurs en assembleur et,
> pour récupérer les erreurs numériques traitées par le signal SIGFPE,
[...]
> J'ai trouvé les symboles souhaités dans
> /usr/include/i386-linux-gnu/sys/ucontext.h (appelé par
> /usr/include/ucontext.h) sous un #ifdef __USE_GNU). Or, alors que les
> identifiants "génériques" comme ucontext_t, mcontext_t, uc_mcontext ou
> gregs, sont bien visibles, les REG_EAX, etc... ne le sont pas, gcc me
> signale un identifiant non déclaré. Ce même si j'essaie d'assurer à la
> main que __USE_GNU est bien défini avant le #include <ucontext.h>.
Je ne sais pas quel est le problème, mais à tout hasard, voici un
exemple rudimentaire qui a l'air de marcher sous Linux alors qu'il fait
référence à REG_RIP.
/* gcc -std=gnu99 -frounding-math sigfpe.c -lm */
#define _GNU_SOURCE
#define __USE_GNU
#include <signal.h>
#include <fenv.h>
#include <stdio.h>
#include <string.h>
#include <ucontext.h>
volatile double a, b, c;
volatile _Decimal64 d, e, f;
static void
handler (int sig, siginfo_t * siginfo, void * ucontext) {
// unsafe
char * descr = "";
if (sig == SIGFPE) {
switch (siginfo->si_code) {
case FPE_INTDIV: descr = "integer divide by zero"; break;
case FPE_INTOVF: descr = "integer overflow"; break;
case FPE_FLTDIV: descr = "floating-point divide by zero"; break;
case FPE_FLTOVF: descr = "floating-point overflow"; break;
case FPE_FLTUND: descr = "floating-point underflow"; break;
case FPE_FLTRES: descr = "floating-point inexact result"; break;
case FPE_FLTINV: descr = "floating-point invalid operation"; break;
case FPE_FLTSUB: descr = "subscript out of range"; break;
}
}
printf ("%s (%s) @ 0x%lx\n", strsignal (sig), descr, siginfo->si_addr);
fflush (stdout);
ucontext_t *uc;
uc = (ucontext_t *) ucontext;
c = 42;
uc->uc_mcontext.gregs[REG_RIP] += 3;
}
int
main (void) {
struct sigaction sa;
sa.sa_sigaction = handler;
sa.sa_flags = SA_SIGINFO;
sigaction (SIGFPE, &sa, NULL);
feenableexcept (FE_ALL_EXCEPT);
d = 0.0DD;
e = 0.0DD;
f = d / e;
a = 1.0;
b = 0.0;
c = a / b;
printf ("back!, %g %g %g\n", a, b, c);
fflush (stdout);
a = 0.0;
b = 0.0;
c = a / b;
printf ("back!, %g %g %g\n", a, b, c);
fflush (stdout);
a = 0.0;
b = 0.0;
c = a / b;
printf ("back!, %g %g %g\n", a, b, c);
fflush (stdout);
return 0;
}
Cordialement,
--
Marc Mezzarobba
Reply to: