Varargs issues

Adriaan de Groot adridg at cs.kun.nl
Mon Dec 1 15:18:06 PST 2003


On Yaum al-Ithnain 06 Shawwal 1424 23:36, Peter Wemm wrote:
> James Van Artsdalen wrote:
> > The trick is that gcc 3.3 doesn't seem to try to keep the stack
> > aligned to 16-bytes, so on entry to a function the stack may be 8-byte
> > aligned, 16-byte aligned, etc.  If the AMD book is not out-of-date
> > then a fault is bound to happen on MOVAPS at some point.
>
> If anything hoses the alignment, it all comes crashing down...  the movaps
> stuff can and will blow up, as you point out.  Varargs is a very good
> litmus test to see if the stack got misaligned somewhere since gcc does
> strange stuff to pass the xmm registers.

Attached the relevant test program (compiled with 
	gcc -o threadtest -g v.c -lc_r
) and here's a sample gdb session:

beans.ebn.kun.nl$uname -a
FreeBSD beans.ebn.kun.nl 5.2-BETA FreeBSD 5.2-BETA #9: Mon Dec  1 23:16:26 CET 
2003     root at beans.ebn.kun.nl:/usr/obj/mnt/sys/CURRENT/src/sys/BEANS  amd64
beans.ebn.kun.nl$gcc --version
gcc (GCC) 3.3.3 [FreeBSD] 20031106
Copyright (C) 2003 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

beans.ebn.kun.nl$gcc -o threadtest -g v.c -lc_r
beans.ebn.kun.nl$gdb threadtest
GNU gdb 20031116
Copyright 2003 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "x86_64-freebsd"...
(gdb) break PrintF
Breakpoint 1 at 0x40084c: file v.c, line 19.
(gdb) run
Starting program: /tmp/thread/threadtest

Breakpoint 1, PrintF (fd=0, fmt=0x4009fc "hello", i=0) at v.c:19
19              int ret = 2;
(gdb) print $rsp
$1 = (void *) 0x7fffffffe6f0
(gdb) cont
Continuing.
[504000]B 0

Breakpoint 1, PrintF (fd=1, fmt=0x4009fc "hello", i=0) at v.c:19
19              int ret = 2;
(gdb) cont
Continuing.
[504000]B 1

Breakpoint 1, PrintF (fd=2, fmt=0x4009fc "hello", i=1) at v.c:19
19              int ret = 2;
(gdb) print $rsp
$2 = (void *) 0x7fffffffe6f0
(gdb) cont
Continuing.
[504000]B 2

Breakpoint 1, PrintF (fd=3, fmt=0x4009fc "hello", i=0) at v.c:19
19              int ret = 2;
(gdb) cont
Continuing.
[504000]B 3

Breakpoint 1, PrintF (fd=0, fmt=0x4009fc "hello", i=0) at v.c:19
19              int ret = 2;
(gdb) cont
Continuing.
[504800]B 0

Breakpoint 1, PrintF (fd=1, fmt=0x4009fc "hello", i=0) at v.c:19
19              int ret = 2;


### NOTE here we're not in the original main thread anymore, but
### in the second thread (you can tell by the printed value [504800],
### which is pthread_self()).

(gdb) print $rsp
$3 = (void *) 0x7fffffefeed8
(gdb) print $rbp
$4 = (void *) 0x7fffffefefb8

### NOTE this is only 8-aligned.

(gdb) cont
Continuing.
[504800]B 1

Program received signal SIGBUS, Bus error.
0x0000000000400842 in PrintF (fd=2, fmt=0x4009fc "hello", i=0) at v.c:18
18      {
(gdb) bt
#0  0x0000000000400842 in PrintF (fd=2, fmt=0x4009fc "hello", i=0) at v.c:18
#1  0x00000000004008f7 in threadfunc (p=0x0) at v.c:40
#2  0x000000020063c670 in _thread_start () from /usr/lib/libc_r.so.5
Error accessing memory address 0x7fffffeff000: Bad address.
(gdb) disassemble
Dump of assembler code for function PrintF:
0x00000000004007c0 <PrintF+0>:  push   %rbp
0x00000000004007c1 <PrintF+1>:  mov    %rsp,%rbp
0x00000000004007c4 <PrintF+4>:  push   %rbx
0x00000000004007c5 <PrintF+5>:  sub    $0xd8,%rsp
0x00000000004007cc <PrintF+12>: mov    %edi,0xffffffffffffff3c(%rbp)
0x00000000004007d2 <PrintF+18>: mov    %rsi,0xffffffffffffff30(%rbp)
0x00000000004007d9 <PrintF+25>: mov    %rcx,0xffffffffffffff58(%rbp)
0x00000000004007e0 <PrintF+32>: mov    %r8,0xffffffffffffff60(%rbp)
0x00000000004007e7 <PrintF+39>: mov    %r9,0xffffffffffffff68(%rbp)
0x00000000004007ee <PrintF+46>: movzbl %al,%eax
0x00000000004007f1 <PrintF+49>: mov    %rax,0xffffffffffffff20(%rbp)
0x00000000004007f8 <PrintF+56>: mov    0xffffffffffffff20(%rbp),%rcx
0x00000000004007ff <PrintF+63>: lea    0x0(,%rcx,4),%rax
0x0000000000400807 <PrintF+71>: movq   $0x400846,0xffffffffffffff20(%rbp)
0x0000000000400812 <PrintF+82>: sub    %rax,0xffffffffffffff20(%rbp)
0x0000000000400819 <PrintF+89>: lea    0xffffffffffffffef(%rbp),%rax
0x000000000040081d <PrintF+93>: mov    0xffffffffffffff20(%rbp),%rcx
0x0000000000400824 <PrintF+100>:        jmpq   *%ecx
0x0000000000400826 <PrintF+102>:        movaps %xmm7,0xfffffffffffffff1(%rax)
0x000000000040082a <PrintF+106>:        movaps %xmm6,0xffffffffffffffe1(%rax)
0x000000000040082e <PrintF+110>:        movaps %xmm5,0xffffffffffffffd1(%rax)
0x0000000000400832 <PrintF+114>:        movaps %xmm4,0xffffffffffffffc1(%rax)
0x0000000000400836 <PrintF+118>:        movaps %xmm3,0xffffffffffffffb1(%rax)
0x000000000040083a <PrintF+122>:        movaps %xmm2,0xffffffffffffffa1(%rax)
0x000000000040083e <PrintF+126>:        movaps %xmm1,0xffffffffffffff91(%rax)
0x0000000000400842 <PrintF+130>:        movaps %xmm0,0xffffffffffffff81(%rax)
0x0000000000400846 <PrintF+134>:        mov    %edx,0xffffffffffffff2c(%rbp)
0x000000000040084c <PrintF+140>:        movl   $0x2,0xffffffffffffff28(%rbp)
0x0000000000400856 <PrintF+150>:        mov    0xffffffffffffff3c(%rbp),%ebx
0x000000000040085c <PrintF+156>:        callq  0x400634
0x0000000000400861 <PrintF+161>:        mov    %ebx,%ecx
0x0000000000400863 <PrintF+163>:        mov    %rax,%rdx
0x0000000000400866 <PrintF+166>:        mov    $0x4009f1,%esi
0x000000000040086b <PrintF+171>:        mov    1049870(%rip),%rdi        # 
0x500d80 <__stderrp>
0x0000000000400872 <PrintF+178>:        mov    $0x0,%al
0x0000000000400874 <PrintF+180>:        callq  0x400614
0x0000000000400879 <PrintF+185>:        mov    0xffffffffffffff28(%rbp),%eax
0x000000000040087f <PrintF+191>:        add    $0xd8,%rsp
0x0000000000400886 <PrintF+198>:        pop    %rbx
0x0000000000400887 <PrintF+199>:        leaveq
0x0000000000400888 <PrintF+200>:        retq
End of assembler dump.
(gdb) print /x$rax
$8 = 0x7fffffefefa7
(gdb) print /x$rax + 0xffffffffffffff81
$10 = 0x7fffffefef28

So that kind of wraps it up for me, as far as I can understand amd64 assembly. 
Something in the threading libs isn't setting up the stack pointer properly 
in secondary threads .. or I've been a tupping moron again in letting world 
and the kernel get out of sync by a week. Will try that for style (although 
this problem cropped up when both were in sync on the 23rd).

-- 
pub  1024D/FEA2A3FE 2002-06-18 Adriaan de Groot <groot at kde.org>
            If the door is ajar, can we fill it with door-jamb?


More information about the freebsd-amd64 mailing list