Bug 50916 - -Os, -D_FORTIFY_SOURCE breaks strcpy & others if inlined
Summary: -Os, -D_FORTIFY_SOURCE breaks strcpy & others if inlined
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: other (show other bugs)
Version: 4.6.2
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-10-29 23:33 UTC by Tuomas Tynkkynen
Modified: 2011-10-30 10:46 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments
The preprocessed source (5.54 KB, application/octet-stream)
2011-10-29 23:33 UTC, Tuomas Tynkkynen
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Tuomas Tynkkynen 2011-10-29 23:33:32 UTC
Created attachment 25665 [details]
The preprocessed source

Not totally sure if a glibc or gcc bug, but anyway: GCC 4.6.2 causes the following code to get into an infinite loop in strcpy if compiled with
gcc -std=c99 -Os -D_FORTIFY_SOURCE=2

#include <argp.h>
#include <string.h>

int main (void) {
    char buf[1024];
    char* str = "hello";
    strcpy (buf, str);
    return 0;
}

It seems that something in the #includes is pulling in the following definition for strcpy:

extern __inline char *
 strcpy (char *__restrict __dest, const char *__restrict __src)
{
  return __builtin___strcpy_chk (__dest, __src, __builtin_object_size (__dest, 2 > 1));
}
...and then the __builtin_strcpy_chk seems to turn back into strcpy (due to -Os?):

00000035 <strcpy>:
  35:   55                      push   %ebp
  36:   89 e5                   mov    %esp,%ebp
  38:   5d                      pop    %ebp
  39:   e9 fc ff ff ff          jmp    3a <strcpy+0x5>
                        3a: R_386_PC32  strcpy
...which then causes the infinite loop.

gcc -v:

Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/i486-linux-gnu/4.6/lto-wrapper
Target: i486-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Debian 4.6.2-2' --with-bugurl=file:///usr/share/doc/gcc-4.6/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++,go --prefix=/usr --program-suffix=-4.6 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.6 --libdir=/usr/lib --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-plugin --enable-objc-gc --enable-targets=all --with-arch-32=i586 --with-tune=generic --enable-checking=release --build=i486-linux-gnu --host=i486-linux-gnu --target=i486-linux-gnu
Thread model: posix
gcc version 4.6.2 (Debian 4.6.2-2)
Comment 1 Richard Biener 2011-10-30 09:12:28 UTC
extern __inline char *
 strcpy (char *__restrict __dest, const char *__restrict __src)

this should be marked with __attribute__((gnu_inline)), otherwise
it won't work with -std=c99.  GCC fix-includes glibc headers for this,
so this is a packaging bug on the debian side, please file it there.
Comment 2 Aurelien Jarno 2011-10-30 10:21:29 UTC
Maybe GCC fixes the GLIBC headers, but how is it supposed to work if the GLIBC is reinstalled after GCC? This solution doesn't really seem to scale very well given the chicken and egg problem between GCC and GLIBC.
Comment 3 Arkadiusz Miskiewicz 2011-10-30 10:33:49 UTC
$ pwd
/home/users/arekm/gcc-4.6.2/host-x86_64-unknown-linux-gnu/stage1-gcc/include-fixed
$ LC_ALL=C grep -r strcpy .
./nss/secport.h:#define PORT_Strcpy     strcpy
grep: ./qt4/phonon: No such file or directory
./slang/slang.h:SL_EXTERN char *SLstrcpy(register char *, register char *);

Actually I don't see gcc fixincl fixing these glibc headers.
Comment 4 Pawel Sikora 2011-10-30 10:46:48 UTC
(In reply to comment #3)
> $ pwd
> /home/users/arekm/gcc-4.6.2/host-x86_64-unknown-linux-gnu/stage1-gcc/include-fixed
> $ LC_ALL=C grep -r strcpy .
> ./nss/secport.h:#define PORT_Strcpy     strcpy
> grep: ./qt4/phonon: No such file or directory
> ./slang/slang.h:SL_EXTERN char *SLstrcpy(register char *, register char *);
> 
> Actually I don't see gcc fixincl fixing these glibc headers.

gcc's fixincl doesn't touch <bits/string3.h> which redefines some str* functions.