Bug 3400 - gcc -Wl,--gc-sections -static build doesn't flush stdout
Summary: gcc -Wl,--gc-sections -static build doesn't flush stdout
Status: RESOLVED DUPLICATE of bug 11133
Alias: None
Product: glibc
Classification: Unclassified
Component: libc (show other bugs)
Version: 2.4
: P2 normal
Target Milestone: ---
Assignee: Ulrich Drepper
Depends on:
Reported: 2006-10-19 18:10 UTC by Denis Vlasenko
Modified: 2018-04-20 14:19 UTC (History)
2 users (show)

See Also:
Host: i386-pc-linux-gnu
Target: i386-pc-linux-gnu
Build: i386-pc-linux-gnu
Last reconfirmed:
fweimer: security-


Note You need to log in before you can comment on or make changes to this bug.
Description Denis Vlasenko 2006-10-19 18:10:00 UTC
#include <stdio.h>
int main() {
    printf("Hello world\n");

# gcc -O2 t.c -o shared
# gcc -O2 t.c -static -o static
# gcc -O2 t.c -Wl,--gc-sections -static -o gc-sect
# ./shared | cat
Hello world
# ./static | cat
Hello world
# ./gc-sect | cat

The last command outputs nothing.
Adding fflush(stdout) after printf makes it work.
(Pipe is needed to make stdout buffered).

IOW: static link with section garbage collection desn't work correctly,
which is a pity because it is such a handy optimization.
This is why:

                 PROVIDE(__start___libc_atexit = .);\
                 __libc_atexit : { *(__libc_atexit) }\
                 PROVIDE(__stop___libc_atexit = .);\


#ifdef text_set_element
text_set_element(__libc_atexit, _IO_cleanup);


#ifdef HAVE_ELF

/* Make SYMBOL, which is in the text segment, an element of SET.  */
# define text_set_element(set, symbol)  _elf_set_element(set, symbol)

/* These are all done the same way in ELF.
   There is a new section created for each set.  */
# ifdef SHARED
/* When building a shared library, make the set section writable,
   because it will need to be relocated at run time anyway.  */
#  define _elf_set_element(set, symbol) \
  static const void *__elf_set_##set##_element_##symbol##__ \
    __attribute__ ((used, section (#set))) = &(symbol)
# else

And of course:

exit (int status)
  RUN_HOOK (__libc_atexit, ());

  _exit (status);

You have to explain to ld that it should never drop __libc_atexit sections...
Comment 1 Ulrich Drepper 2006-10-19 20:20:35 UTC
You simply cannot use that option.  Period.  Static linking is not really
supported.  I'm not closing the bug outright so that somebody with interest can
think of a clean and non-intrusive way to handle this.  But I sure as hell won't
spend a second thinking about static linking.
Comment 2 H.J. Lu 2010-01-07 13:36:59 UTC
It is a linker bug.

*** This bug has been marked as a duplicate of 11133 ***