From marcolz@office-install1.ilse.net  Wed May  4 15:36:52 2005
Return-Path: <marcolz@office-install1.ilse.net>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id 890CC16A4CE
	for <FreeBSD-gnats-submit@freebsd.org>; Wed,  4 May 2005 15:36:52 +0000 (GMT)
Received: from office-install1.ilse.net (ipv6-router.ilse.nl [62.69.162.169])
	by mx1.FreeBSD.org (Postfix) with ESMTP id 86BD743D60
	for <FreeBSD-gnats-submit@freebsd.org>; Wed,  4 May 2005 15:36:50 +0000 (GMT)
	(envelope-from marcolz@office-install1.ilse.net)
Received: from office-install1.ilse.net (localhost [127.0.0.1])
	by office-install1.ilse.net (8.13.1/8.13.1) with ESMTP id j44FZsUi002382
	for <FreeBSD-gnats-submit@freebsd.org>; Wed, 4 May 2005 17:35:54 +0200 (CEST)
	(envelope-from marcolz@office-install1.ilse.net)
Received: (from marcolz@localhost)
	by office-install1.ilse.net (8.13.1/8.13.1/Submit) id j44FZrwK002381;
	Wed, 4 May 2005 17:35:53 +0200 (CEST)
	(envelope-from marcolz)
Message-Id: <200505041535.j44FZrwK002381@office-install1.ilse.net>
Date: Wed, 4 May 2005 17:35:53 +0200 (CEST)
From: Marc Olzheim <zlo@zlo.nu>
Reply-To: Marc Olzheim <zlo@zlo.nu>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: floating point registers seem not to be saved after thread preemption.
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>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:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed May 04 15:40:02 GMT 2005
>Closed-Date:    Fri May 06 15:52:23 GMT 2005
>Last-Modified:  Wed May 25 11:40:01 GMT 2005
>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@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:

From: Marc Olzheim <zlo@zlo.nu>
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/80617: floating point registers seem not to be saved after thread preemption.
Date: Wed, 4 May 2005 21:56:28 +0200

 --A6N2fC+uXW/VQSAv
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: inline
 
 It seems to have to do something with floorf(). Leaving it out, I can't
 get it to crash atm.
 
 --A6N2fC+uXW/VQSAv
 Content-Type: application/pgp-signature
 Content-Disposition: inline
 
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.2.4 (FreeBSD)
 
 iD8DBQFCeSjsezjnobFOgrERAr99AJ90d3SApHypj3I9SM1W36yu3U3Z3gCcCRqK
 YtGinvr/ALpTOCPe5hwvwyc=
 =WLpY
 -----END PGP SIGNATURE-----
 
 --A6N2fC+uXW/VQSAv--

From: Marc Olzheim <zlo@zlo.nu>
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/80617: floating point registers seem not to be saved after thread preemption.
Date: Wed, 4 May 2005 22:28:39 +0200

 floorf() and ceilf() are the only functions where this happens. When
 replacing the code with doubles and using floor() and ceil() no problems
 arise.
 
 Both floorf() and ceilf() crash in "flds   0x8(%ebp)".

From: Marc Olzheim <marcolz@ilse.net>
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/80617: floating point registers seem not to be saved after thread preemption.
Date: Thu, 5 May 2005 00:58:25 +0200

 The following probably fixes it (thanks to the hint das@ provided).
 For FreeBSD 5.4, just ignore the truncf() part, since that file hasn't
 been MFC'd yet.
 
 --- lib/msun/i387/s_ceilf.S	Thu Jan 13 19:58:25 2005
 +++ lib/msun/i387/s_ceilf.S	Thu May  5 00:54:18 2005
 @@ -13,17 +13,17 @@
  	movl	%esp,%ebp
  	subl	$8,%esp
  
 -	fstcw	-12(%ebp)		/* store fpu control word */
 -	movw	-12(%ebp),%dx
 +	fstcw	-4(%ebp)		/* store fpu control word */
 +	movw	-4(%ebp),%dx
  	orw	$0x0800,%dx		/* round towards +oo */
  	andw	$0xfbff,%dx
 -	movw	%dx,-16(%ebp)
 -	fldcw	-16(%ebp)		/* load modfied control word */
 +	movw	%dx,-8(%ebp)
 +	fldcw	-8(%ebp)		/* load modfied control word */
  
  	flds	8(%ebp);		/* round */
  	frndint
  
 -	fldcw	-12(%ebp)		/* restore original control word */
 +	fldcw	-4(%ebp)		/* restore original control word */
  
  	leave
  	ret
 --- lib/msun/i387/s_floorf.S	Thu Jan 13 19:58:25 2005
 +++ lib/msun/i387/s_floorf.S	Thu May  5 00:54:29 2005
 @@ -13,17 +13,17 @@
  	movl	%esp,%ebp
  	subl	$8,%esp
  
 -	fstcw	-12(%ebp)		/* store fpu control word */
 -	movw	-12(%ebp),%dx
 +	fstcw	-4(%ebp)		/* store fpu control word */
 +	movw	-4(%ebp),%dx
  	orw	$0x0400,%dx		/* round towards -oo */
  	andw	$0xf7ff,%dx
 -	movw	%dx,-16(%ebp)
 -	fldcw	-16(%ebp)		/* load modfied control word */
 +	movw	%dx,-8(%ebp)
 +	fldcw	-8(%ebp)		/* load modfied control word */
  
  	flds	8(%ebp);		/* round */
  	frndint
  
 -	fldcw	-12(%ebp)		/* restore original control word */
 +	fldcw	-4(%ebp)		/* restore original control word */
  
  	leave
  	ret
 --- lib/msun/i387/s_truncf.S	Sat Apr 16 23:12:55 2005
 +++ lib/msun/i387/s_truncf.S	Thu May  5 00:54:35 2005
 @@ -11,16 +11,16 @@
  	movl	%esp,%ebp
  	subl	$8,%esp
  
 -	fstcw	-12(%ebp)		/* store fpu control word */
 -	movw	-12(%ebp),%dx
 +	fstcw	-4(%ebp)		/* store fpu control word */
 +	movw	-4(%ebp),%dx
  	orw	$0x0c00,%dx		/* round towards -oo */
 -	movw	%dx,-16(%ebp)
 -	fldcw	-16(%ebp)		/* load modfied control word */
 +	movw	%dx,-8(%ebp)
 +	fldcw	-8(%ebp)		/* load modfied control word */
  
  	flds	8(%ebp)			/* round */
  	frndint
  
 -	fldcw	-12(%ebp)		/* restore original control word */
 +	fldcw	-4(%ebp)		/* restore original control word */
  
  	leave
  	ret
State-Changed-From-To: open->closed 
State-Changed-By: deischen 
State-Changed-When: Fri May 6 15:51:40 GMT 2005 
State-Changed-Why:  
The problem was in libm (src/lib/msun) and fix was committed in -current. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=80617 

From: Marc Olzheim <marcolz@stack.nl>
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/80617: floating point registers seem not to be saved after thread preemption.
Date: Wed, 25 May 2005 13:39:04 +0200

 Could this be MFC'd, please, pretty please, with sugar on top ?
>Unformatted:
