amd64/59650: sprintf() bus errors in non-main thread with %f

adriaan de groot adridg at cs.kun.nl
Mon Nov 24 11:10:20 PST 2003


>Number:         59650
>Category:       amd64
>Synopsis:       sprintf() bus errors in non-main thread with %f
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-amd64
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Nov 24 11:10:17 PST 2003
>Closed-Date:
>Last-Modified:
>Originator:     adridg at 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 at 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 at 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:
>Unformatted:


More information about the freebsd-amd64 mailing list