kern/80617: floating point registers seem not to be saved after thread preemption.

Marc Olzheim zlo at zlo.nu
Wed May 4 08:40:17 PDT 2005


>Number:         80617
>Category:       kern
>Synopsis:       floating point registers seem not to be saved after thread preemption.
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed May 04 15:40:02 GMT 2005
>Closed-Date:
>Last-Modified:
>Originator:     Marc Olzheim
>Release:        FreeBSD 6.0-CURRENT i386, FreeBSD 5.4-STABLE i386
>Organization:
ilse media
>Environment:
System: FreeBSD office-install1.ilse.net 6.0-CURRENT FreeBSD 6.0-CURRENT #26: Wed May 4 01:52:58 CEST 2005 root at office-install1.ilse.net:/usr/obj/usr/src/sys/CRASH i386


>Description:
	Floating point exception take place where they shouldn't when
	running with KSE threads (-pthread).
>How-To-Repeat:
# This is a shell archive.  Save it in a file, remove anything before
# this line, and then unpack it by entering "sh file".  Note, it may
# create directories; files and directories will be owned by you and
# have default permissions.
#
# This archive contains:
#
#	fpu
#	fpu/Makefile
#	fpu/fpu5.c
#
echo c - fpu
mkdir -p fpu > /dev/null 2>&1
echo x - fpu/Makefile
sed 's/^X//' >fpu/Makefile << 'END-of-fpu/Makefile'
Xall: fpu5 fpu5th
X
Xfpu5th:	fpu5.c
X	cc -O3 -Wall -W -Werror -g -Wcast-qual -DWITH_THR -fstrict-aliasing -pthread fpu5.c -o fpu5th -lm
X
Xfpu5:	fpu5.c
X	cc -O3 -Wall -W -Werror -g -Wcast-qual -fstrict-aliasing fpu5.c -o fpu5 -lm
X
Xclean:
X	rm -f fpu5 fpu5th fpu5th.core core
END-of-fpu/Makefile
echo x - fpu/fpu5.c
sed 's/^X//' >fpu/fpu5.c << 'END-of-fpu/fpu5.c'
X/* Blame it in Marc Olzheim (Zlo) */
X
X#ifdef		WITH_THR
X#include	<pthread.h>
X#endif		/* WITH_THR */
X
X#include	<err.h>
X#include	<math.h>
X#include	<stdio.h>
X#include	<stdlib.h>
X#include	<sysexits.h>
X#include	<unistd.h>
X
Xvoid *
Xcalc_thread(void *arg)
X{
X	long		i;
X	unsigned char	c;
X
X	i = (long)arg + 1;
X
X	for (;;)
X	{
X		i = (i + 1) % 736;
X		if (i > 0)
X		{
X			/* ln(2.0) =~ 0.69 */
X			if (logf((float)1.0 + (float)i) < (float)0.65)
X			{
X				/* Never happens */
X				printf("\n\n\n\ni: %ld\n\n\n\n", i);
X				fflush(NULL);
X			}
X
X			/* Then why does _this_ go wrong ? */
X			c = floorf((float)(1.0 / logf((float)1.0 + (float)i)));
X
X			if (c > 1)	/* Never true, just to use c. */
X				printf("\r%hhu", c);
X		}
X	}
X
X	/* NOTREACHED */
X	return NULL;
X}
X
Xint
Xmain(int argc, char *argv[])
X{
X#ifdef		WITH_THR
X	pthread_t	thread;
X#endif		/* WITH_THR */
X
X	if (1 != argc)
X	{
X		fprintf(stderr, "Usage: %s\n", argv[0]);
X		return(EX_USAGE);
X	}
X
X#ifdef		WITH_THR
X	if (pthread_create(&thread , NULL, calc_thread, (void *)1L))
X		err(1, "pthread_create()");
X#else		/* ! WITH_THR */
X	(void)calc_thread((void *)1L);
X#endif		/* ! WITH_THR */
X
X	for (;;)
X		sleep(60);
X
X	return(EX_OK);
X}
END-of-fpu/fpu5.c
exit

Just compare the th version with the non-th version. The th version will
crash.

This happens on 6-CURRENT and on 5.4-STABLE and I've only been able to
reproduce it on i386, not on amd64. I don't have other test machines atm.

5.3-RELEASE seems unaffected.
>Fix:
>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list