Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 23 Oct 1995 16:25:25 +1000
From:      Bruce Evans <bde@zeta.org.au>
To:        freebsd-hackers@freebsd.org, peter@citylink.dinoex.sub.org
Subject:   Re: modf.S (in libc.a): stack access fault
Message-ID:  <199510230625.QAA15714@godzilla.zeta.org.au>

next in thread | raw e-mail | index | archive | help
>The funktion modf() (in libc.a, from lib/libc/i386/gen/modf.S) seems to
>dismangle the program stack. This is the reason why ingres cannot handle
>float values with FreeBSD (and other OS's - i reported that here, somewhen
>about May). If linked with lib/msun/src/s_modf.c instead, it does work.

>To reproduce the error, try the following code:
>----------------------------------------------------------------------
>#include <stdio.h>

>main()
>{
>	double arg = 0.0, fj;
>	int i;
>	char *p, buf[21];

>	p = buf;
>	for(i=0; i < 20; i++) {
>		arg *= 10;
>		(void)modf(arg, &fj);
>		arg -= fj;
>		*p++ = (int)fj + '0';
>	}
>	*p = '\0';
>	printf("%s\n", buf);
>}
>----------------------------------------------------------------------
$ cc -Wall prog.c
prog.c:4: warning: return-type defaults to `int'
prog.c: In function `main':
prog.c:12: warning: implicit declaration of function `modf'
prog.c:18: warning: control reaches end of non-void function

`modf' is not declared and so the compiler has to assume that
it returns `int'.  Since it actually returns double, the behaviour
is undefined.

`modf' is declared in <math.h>  include <math.h> to fix the
problem.

The actual behaviour when the modf() in libc.a is called under
FreeBSD is that each call leaves a double on the floating point
stack.  On the 8th call, the stack has 7 registers full of junk so
there is no space for the 2 registers used by modf() and a stack
exception occurs.  Under FreeBSD, stack exceptions are trapped, so
a SIGFPE is generated on the next floating point instruction after
the one for which the stack exception was recorded.

The behaviour when the modf() in libm.a is called should be
similar.  It is the same here.

The math routines in lib/libc/i386/gen (fabs, frexp, ldexp and
modf) are of lower quality than the ones in lib/msun/src and
probably shouldn't exist.

Bruce



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199510230625.QAA15714>