Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 8 Dec 2003 03:18:40 -0700
From:      "Scott Kissel" <00civic@comcast.net>
To:        <freebsd-current@freebsd.org>
Subject:   Apparent i386 alloca.S bug (was: adsl/pppoe no longer connecting on 5.1) 
Message-ID:  <000501c3bd74$a73748a0$6701a8c0@Scratch>

next in thread | raw e-mail | index | archive | help
On Thu, 12 Jun 2003, Tim Robbins wrote:

>> On Thu, Jun 12, 2003 at 06:29:44PM +1000, Tim Robbins wrote:
>>
>> > Here's a test program for the i386 alloca() bug. Compile with
-std=gnu89 (or
>> > no -std option) and it works fine. Compile with -std=c99 or
-std=c89 and it
>> > breaks like this:
>> >
>> > corruption: 05 should be 0xcc at offset 0
>> > corruption: 00 should be 0xcc at offset 1
>> > corruption: 00 should be 0xcc at offset 2
>> > corruption: 00 should be 0xcc at offset 3
>> >
>> > Interestingly, gcc -std=c89 on FreeBSD 4.8 doesn't trigger the bug.
>>
>> I should mention that you need to compile with -march=pentiumpro to
trigger
>> the bug. It's related to the way gcc 3 uses "movl x,y(%esp)" instead
of
>> "pushl x" when passing arguments to a function. I suggest backing out
the
>> commit that made CSTD=c99 the default, so that we go back to using
gcc's
>> builtin alloca() until we figure out how to fix the one in libc.

>I understand this now.  This method of passing args is completely
incompatible
>with any implementation of the libc alloca like the current one.  gcc
>prepares space for storing the args by subtracting from %esp.  Then
>the libc alloca() points %esp to the allocated space, but gcc thinks
that
>%esp still points to the space that it has reserved for the args, so it
>clobbers the allocated space when it stores the args.
>
>BTW, the optimization of using "movl x,y(%esp)" instead of "pushl x"
>has the following benefits and costs:
>
>pentiumpro-like machine (old Celeron):     +26%
>   (4.05 seconds reduced to 2.99 seconds)
>pentiumpro-like machine (PIII (freefall)): +25%
>   (1.82 seconds reduced to 1.37 seconds)
>AthlonXP:                                  -45%
>   (0.58 seconds increaded to 0.84 seconds)
>
>The times are for 10^8 calls to somefunc(1, 2, 3, 4, 5) in a loop.
>
>Bruce


Sorry for bringing up an old message but I received a seg fault core
dump when performing a make buildworld after cvsuping. The exit was at:
cc -O -pipe -march=pentium2 -I/usr/src/lib/libc/include
-I/usr/src/lib/libc/../../include -I/usr/src/lib/libc/i386
-D__DBINTERFACE_PRIVATE -I/usr/src/lib/libc/../../contrib/gdtoa -DINET6
-I/usr/obj/usr/src/lib/libc -DPOSIX_MISTAKE -I/usr/src/lib/libc/locale
-DBROKEN_DES -DPORTMAP -DDES_BUILTIN -I/usr/src/lib/libc/rpc -DYP
-DHESIOD -Wsystem-headers -Werror  -c
/usr/src/lib/libc/i386/gen/alloca.S
Segmentation fault (core dumped)
*** Error code 139

In an attempt to search why it's happening, I ran across these messages
and couldn't help but wonder if there was a fix or work around ever
figured out. While I am somewhat understanding what is being said in the
above messages, I wasn't sure if I was supposed to edit the alloca.S
file to resolve the issue, and how exactly to go about making changes in
that file. For reference, here's what it looks like:

#if !defined(__GNUC__) && !defined(__INTEL_COMPILER)
#error Please add alloca support for this compiler on FreeBSD.
        
#if defined(LIBC_SCCS) && !defined(lint)
        .asciz "@(#)alloca.s    5.2 (Berkeley) 5/14/90"
#endif /* LIBC_SCCS and not lint */
#include <machine/asm.h>
__FBSDID("$FreeBSD: src/lib/libc/i386/gen/alloca.S,v 1.12 2003/06/25
19:06:40 obrien Exp $");
 
 
/* like alloc, but automatic automatic free in return */
 
ENTRY(alloca)
        popl    %edx            /*  pop return addr */
        popl    %eax            /*  pop amount to allocate */
        movl    %esp,%ecx
        addl    $3,%eax         /*  round up to next word */
        andl    $0xfffffffc,%eax
        subl    %eax,%esp
        movl    %esp,%eax       /* base of newly allocated space */
        pushl   8(%ecx)         /* copy possible saved registers */
        pushl   4(%ecx)
        pushl   0(%ecx)
        pushl   %eax            /* dummy to pop at callsite */
        jmp     *%edx           /* "return" */
#endif  /*!__GNUC__*/


Some info about my box: FreeBSD demon.somedomain.com 5.1-RELEASE FreeBSD
5.1-RELEASE #0:
root@demon.somedomain.com:/usr/obj/usr/src/sys/dualdemon  i386

Please let me know what your suggestions are for resolving this issue,
if it's possible.

Thanks!



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?000501c3bd74$a73748a0$6701a8c0>