From adridg@cs.kun.nl  Mon Nov 24 11:09:07 2003
Return-Path: <adridg@cs.kun.nl>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id 5601216A4CE
	for <FreeBSD-gnats-submit@freebsd.org>; Mon, 24 Nov 2003 11:09:07 -0800 (PST)
Received: from pandora.cs.kun.nl (pandora.cs.kun.nl [131.174.33.4])
	by mx1.FreeBSD.org (Postfix) with ESMTP id CEF4C43F93
	for <FreeBSD-gnats-submit@freebsd.org>; Mon, 24 Nov 2003 11:09:03 -0800 (PST)
	(envelope-from adridg@cs.kun.nl)
Received: from localhost by pandora.cs.kun.nl
	via odin.cs.kun.nl [131.174.33.33] with ESMTP for <FreeBSD-gnats-submit@freebsd.org>
	id hAOJ8xd5013384 (8.12.10/3.58); Mon, 24 Nov 2003 20:09:01 +0100 (MET)
Message-Id: <200311242008.55699.adridg@cs.kun.nl>
Date: Mon, 24 Nov 2003 20:08:55 +0100
From: adriaan de groot <adridg@cs.kun.nl>
Reply-To: adriaan de groot <adridg@cs.kun.nl>
To: FreeBSD-gnats-submit@freebsd.org
Subject: sprintf() bus errors in non-main thread with %f
X-Send-Pr-Version: 3.113

>Number:         59650
>Category:       amd64
>Synopsis:       sprintf() bus errors in non-main thread with %f
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-amd64
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Nov 24 11:10:17 PST 2003
>Closed-Date:    Tue Dec 02 16:08:22 PST 2003
>Last-Modified:  Tue Dec 02 16:08:22 PST 2003
>Originator:     adridg@cs.kun.nl
>Release:        FreeBSD 5.1-CURRENT amd64
>Organization:
KDE-FreeBSD
>Environment:
System: FreeBSD beans.ebn.kun.nl 5.1-CURRENT FreeBSD 5.1-CURRENT #4: Wed Nov 
19 14:11:35 CET 2003 
root@beans.ebn.kun.nl:/mnt/sys/CURRENT/src/sys/amd64/compile/BEANS amd64


>Description:
	The ogg123 port bus errors on an amd64 machine. This is because
	sprintf() and fprintf() do "something weird" with %f arguments
	in threads that are not the main thread of control.

>How-To-Repeat:
	This program demonstrates the problem:

/* Demonstration program that shows that sprintf() doesn't
   work with double args from threads that aren't the main
   thread of control.
*/

#include <stdio.h>
#include <pthread.h>
#include <time.h>

void slipper(void *p)
{
        fprintf(stderr,"[%lx] d=%d t=%d\n",(long)pthread_self(),3,time(NULL));
	sleep(3);
	fprintf(stderr,"%f\n",22/7);
	fprintf(stderr,"%06.3f\n",0.002462390263402);
}

int main(int argc, char **argv)
{
        pthread_t tid;

	slipper(NULL);

	pthread_create(&tid,NULL,slipper,NULL);

	sleep(6);
	slipper(NULL);

	return 0;
}
						}


	Expected output is something like

[lofi@lofi]:0:~ > ./threadtest
[804c000] d=3 t=1069603991
0.000000
00.002
[804c400] d=3 t=1069603994
0.000000
00.002
[804c000] d=3 t=1069604000
0.000000
00.002

	and on 4-STABLE i386, 5-CURRENT i386, and 5-CURRENT alpha,
	that is exactly what it does. On amd64, however,

beans.ebn.kun.nl$./threadtest
[504000] d=3 t=1069604372
0.000000
00.002
[504800] d=3 t=1069604375
0.000000
Bus error (core dumped)

	Note that the "plain" %f when printing a 0 value works,
	but that sprintf() bus errors in the second call.
	Replacing 22/7 by the constant 0.002462390263402 in the 
	code causes a bus error in the first call to sprintf().

(gdb) bt
#0  0x0000000200841189 in fprintf () from /lib/libc.so.5
#1  0x000000000040086f in slipper ()
#2  0x000000020063c670 in _thread_start () from /usr/lib/libc_r.so.5
Error accessing memory address 0x7fffffeff000: Bad address.

	Possibly relevant disassembly:

0x0000000200841181 <fprintf+125>:       movaps %xmm2,0xffffffffffffffa1(%rax)
0x0000000200841185 <fprintf+129>:       movaps %xmm1,0xffffffffffffff91(%rax)
0x0000000200841189 <fprintf+133>:       movaps %xmm0,0xffffffffffffff81(%rax)
0x000000020084118d <fprintf+137>:       mov    %rsi,0xffffffffffffff40(%rbp)
0x0000000200841194 <fprintf+144>:       movl   $0x10,0xffffffffffffff10(%rbp)
0x000000020084119e <fprintf+154>:       movl   $0x30,0xffffffffffffff14(%rbp)

	(If it's gonna bus error, I'll suspect those odd constants in
	the three movaps instructions.)

>Fix:



>Release-Note:
>Audit-Trail:

From: Adriaan de Groot <adridg@cs.kun.nl>
To: freebsd-gnats-submit@FreeBSD.org
Cc:  
Subject: Re: amd64/59650: passing float parameters in non-main threads bus errors
Date: Wed, 26 Nov 2003 14:23:10 +0100

 Some further debugging shows that it's not even sprintf() of va_start() 
 specific, but just passing float / double arguments to a varargs function in 
 a non-main thread of control triggers bus errors already:
 
 /*
 ** Demonstration program that float parameters to
 ** varargs functions in non-main threads of
 ** control on amd64 does not work properly.
 */
 
 #include <stdio.h>
 #include <pthread.h>
 #include <stdarg.h>
 
 
 /*
 ** This is a varargs function to which we will attempt to pass
 ** a float value in the ... .
 */
 
 int PrintF(int fd, const char *fmt, int i, ...)
 {
         int ret = 2;
         fprintf(stderr,"[%lx]B %d\n",(long)pthread_self(),fd);
         return ret;
 }
 
 
 /*
 ** Demonstration function. Expected output is something like
 **
 ** [504000]B 0
 ** [504000]B 1
 ** [504000]B 2
 ** [504000]B 3
 **
 ** From the 4 calls to PrintF(). This bus errors in the third
 ** call when not in the main thread of control.
 */
 
 void *threadfunc(void *p)
 {
         PrintF(0,"hello",0,0);
         PrintF(1,"hello",0,6);
         PrintF(2,"hello",1,0.00028376223); /* arg4 is a float */
         PrintF(3,"hello",0.00028376223,6); /* arg3 converts to int here */
         return p;
 }
 
 int main(int argc, char **argv)
 {
         pthread_t tid;
 
         threadfunc(NULL);
         pthread_create(&tid,NULL,threadfunc,NULL);
         sleep(4);
         threadfunc(NULL);
 
         return 0;
 }
 
 Now, either I'm doing something totally moronic with threads (and the ogg123 
 port is too) or the argument passing is seriously broken. I might be 
 compiling it wrong, though:
 
 beans.ebn.kun.nl$gcc -o threadtest -g v.c -lc_r && ./threadtest
 [504000]B 0
 [504000]B 1
 [504000]B 2
 [504000]B 3
 [504800]B 0
 [504800]B 1
 Bus error (core dumped)
 
 The machine has been updated in -CURRENT since the original bug report:
 
 FreeBSD beans.ebn.kun.nl 5.2-BETA FreeBSD 5.2-BETA #2: Sun Nov 23 19:48:43 CET 
 2003     root@beans.ebn.kun.nl:/usr/obj/mnt/sys/CURRENT/src/sys/BEANS  amd64
 
 
 -- 
 pub  1024D/FEA2A3FE 2002-06-18 Adriaan de Groot <groot@kde.org>
             If the door is ajar, can we fill it with door-jamb?
State-Changed-From-To: open->closed 
State-Changed-By: jmg 
State-Changed-When: Tue Dec 2 16:07:34 PST 2003 
State-Changed-Why:  
as per Adriaan's request close the PR, Peter has fixed this in libc_r.. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=59650 
>Unformatted:
