[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

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: