Issue #5108 has been updated by Csaba Henk.


Cf. http://sourceware.org/ml/libc-alpha/2011-07/msg00140.html
----------------------------------------
Bug #5108: ruby 1.8.7 fails to build with glibc 2.14
http://redmine.ruby-lang.org/issues/5108

Author: Csaba Henk
Status: Open
Priority: High
Assignee: 
Category: 
Target version: 
ruby -v: ruby 1.8.7 (2011-06-30 patchlevel 352) [x86_64-linux]


On a glibc-2.14 based GNU/Linux system (recent Arch where I've seen;
looking around on the net suggests that Fedora 15 is affected too) you get
the following error in ext/dl when building ruby 1.8.7:

compiling dl
make[1]: Entering directory `/home/csaba/aur/ruby-1.8.7-svn/src/ext/dl'
Generating callback.func
Generating cbtable.func
gcc -I. -I../.. -I../../. -I../.././ext/dl -DHAVE_DLFCN_H -DHAVE_DLOPEN -DHAVE_DLCLOSE -DHAVE_DLSYM -DHAVE_DLERROR    -I. -fPIC -g -O2  -fno-defer-pop -fno-omit-frame-pointer  -c dl.c
In file included from dl.c:104:0:
callback.func:1:1: warning: data definition has no type or storage class [enabled by default]
callback.func:1:7: error: expected identifier or °∆(°« before °∆long°«
In file included from dl.c:104:0:
callback.func:78:33: error: expected °∆)°« before °∆(°« token
callback.func:79:3: warning: data definition has no type or storage class [enabled by default]
callback.func:79:24: error: °∆proc°« undeclared here (not in a function)
callback.func:79:39: error: °∆argc°« undeclared here (not in a function)
callback.func:79:45: error: °∆argv°« undeclared here (not in a function)
callback.func:82:1: error: expected identifier or °∆(°« before °∆}°« token
dl.c:106:1: error: expected °∆;°«, °∆,°« or °∆)°« before °∆static°«
make[1]: *** [dl.o] Error 1
make[1]: Leaving directory `/home/csaba/aur/ruby-1.8.7-svn/src/ext/dl'
make: *** [all] Error 1

This is caused by the fact that the generated file callback.func is corrupt.
The corruption is triggered by a recent glibc change:

  http://sourceware.org/git/?p=glibc.git;a=commitdiff;h=glibc-2.13-161-gfcabc0f

which was to fix a POSIX compatibility issue:

  http://sourceware.org/bugzilla/show_bug.cgi?id=12724

namely, that upon closing a stream (fclose(3)) the underlying file descriptor should
be moved to the position where I/O was done on the stream last time.

How this affects the build?

Upon generating callback.func, mkmf is required. While mkmf.rb is loaded,
a rogue duplicate of $stdout is created:

  https://github.com/ruby/ruby/blob/ruby_1_8_7/lib/mkmf.rb#L205

When the generating script has finishes its work, ruby prepares to terminate and
does a GC. During GC, the rogue duplicate is closed, which, with the above glibc
semantics implies that the output file is seeked to 0 position. The last writeout
of $stdout's buffered data takes places _after_ the seek, so the tail of the generated
code will be written to the beginning of the file, instead of being appended to.

The attached patch makes sure that no long-lived duplicate of $stdout hangs around.

(
NOTE: the POSIX requirement to which glibc tries to adhere seems to have some
ambiguity -- it says: 

"[...] the next operation on the open file description deals with the byte after the last
one read from or written to the stream being closed."

Now, "_the_ last one" read / written seems to have the implicit assumption that there
was actually something read / written. So it's ambiguous in the case when there was
nothing done with the stream in between opening and closing it. Glibc choose to
position the descriptor in this case too, that's why ruby is affected; on the other
OS of which we know that it adheres to this part of the standard (Solaris, as it's
pointed out in the glibc bug report) ruby is not affected because Solaris libc does
not position a file in the no-I/O-fclose case.

I'll check with Glibc folks what's their opinion about this corner case.
)


-- 
http://redmine.ruby-lang.org