This is the mail archive of the libc-alpha@sourceware.cygnus.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

FP exception problem?



Hi, All

glibc-2.1.2 on debian linux/ia32.

GNU C Library stable release version 2.1.2, by Roland McGrath et al.
Copyright (C) 1992, 93, 94, 95, 96, 97, 98, 99 Free Software Foundation,
Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Compiled by GNU CC version 2.95.2 19991109 (Debian GNU/Linux).
Compiled on a Linux 2.2.12 system on 1999-12-25.
Available extensions:
        GNU libio by Per Bothner
        crypt add-on version 2.1 by Michael Glad and others
        linuxthreads-0.8 by Xavier Leroy
        BIND-4.9.7-REL
        NIS(YP)/NIS+ NSS modules 0.19 by Thorsten Kukuk
        NSS V1 modules 2.0.2
        libthread_db work sponsored by Alpha Processor Inc


basically, i told system to send SIGFPE each time floating
point exception occurs. The question is how to distinguish
what kind of exception (invalid op, div by zero etc) caused
the signal.

tried:

1. set SIGFPE handler and ask for exception bit. Didn't
   work - looks like all bits are cleared.

2. from glibc info

   BSD systems provide the `SIGFPE' handler with an extra argument that
distinguishes various causes of the exception.  In order to access this
argument, you must define the handler to accept two arguments, which
means you must cast it to a one-argument function type in order to
establish the handler.  The GNU library does provide this extra
argument, but the value is meaningful only on operating systems that
provide the information (BSD systems and GNU systems).

ok, set 2 params handler, but second parameter is always 0.

any other ways to recover the FPE information?

if there is no written yet but design already done i could try
to write the code...

thank you

OK

------------------------------------ cut here -----------------------

#define _GNU_SOURCE

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

typedef void (*sighndl)(int);

static double
divide_by_zero( const double* z ) {

  double x;

  x = 1.0 / (*z);
  return x;
}

static double
invalid_op( const double* z ) {

  double x;

  x = 0.0 / (*z);
  return x;
}

static double
overflow( void ) {

  double x = DBL_MAX;

  x = x*x;
  return x;
}

void
fpe_handler( int signum, int what ) {
  
  fprintf( stderr, "Entering fpe_handler: %d\n", what );

  if ( fetestexcept( FE_INEXACT ) ) {
    fprintf( stderr, "INEXACT\n" );
  }
  if ( fetestexcept( FE_DIVBYZERO ) ) {
    fprintf( stderr, "DIVBYZERO\n" );
  }
  if ( fetestexcept( FE_UNDERFLOW ) ) {
    fprintf( stderr, "UNDERFLOW\n" );
  }
  if ( fetestexcept( FE_OVERFLOW ) ) {
    fprintf( stderr, "OVERFLOW\n" );
  }
  if ( fetestexcept( FE_INVALID ) ) {
    fprintf( stderr, "INVALID\n" );
  }
  
  signal( SIGFPE, SIG_DFL );
}

int
main( void ) {

  fenv_t fe;
  double z = 0.0;

  if ( signal( SIGFPE, (sighndl)fpe_handler ) == SIG_IGN ) {
    signal( SIGFPE, SIG_IGN );
  }

     /*
       setting traps for FP exceptions
      */
  fegetenv( &fe );
  fesetenv( FE_NOMASK_ENV );

  z = invalid_op( &z );
  z = divide_by_zero( &z );
     /*
  z = invalid_op( &z );
  z = overflow();  
     */
  
  return 0;
}




Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]