Bug #5108
closedruby 1.8.7 fails to build with glibc 2.14
Description
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.
)
Files
Updated by csabahenk (Csaba Henk) over 13 years ago
Updated by kridtek (Andreas Krüger) almost 13 years ago
For a workaround, I have added STDOUT.flush at the end of each of the three scripts ruby-1.8.7-p357/ext/dl/mk*rb .
This allowed the compile to proceed.
Updated by pwnall (Victor Costan) over 12 years ago
Please consider merging this, so 1.8.7 builds on Fedora without patches.
Updated by naruse (Yui NARUSE) over 12 years ago
- Status changed from Open to Rejected
- Priority changed from 5 to Normal
The normal maintenance of Ruby 1.8.7 is finished in June.
So the patch won't be merged.
specify --without-dl and use libffi gem or something.