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