| Summary: | sprintf() bus errors in non-main thread with %f | ||
|---|---|---|---|
| Product: | Base System | Reporter: | Adriaan de Groot <adridg> |
| Component: | amd64 | Assignee: | freebsd-amd64 (Nobody) <amd64> |
| Status: | Closed FIXED | ||
| Severity: | Affects Only Me | ||
| Priority: | Normal | ||
| Version: | 5.1-CURRENT | ||
| Hardware: | Any | ||
| OS: | Any | ||
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 as per Adriaan's request close the PR, Peter has fixed this in libc_r.. |
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.)