Bug #932
closedincorrect case statement in "ext/dl/test/test_base.rb" causes library problems on openSUSE 11.1 64-bit
Description
=begin
I compiled Ruby 1.9.1 from the SVN repository and tried to reproduce the segfault issue #633 on my openSUSE 11.1 x86_64 system. Instead of segfaulting, it did this:
znmeb@DreamScape:~/Packages/ruby/ext/dl/test> ruby test_all.rb
nil
Loaded suite test_all
Started
EEEEEEEEEEEEEEEEEE
Finished in 0.002599 seconds.
- 
Error: 
 test_empty(DL::TestBase):
 DL::DLError: /lib/libc.so.6: wrong ELF class: ELFCLASS32
 /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:ininitialize' /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:indlopen'
 /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:in `setup'
- 
Error: 
 test_call_double(DL::TestDL):
 DL::DLError: /lib/libc.so.6: wrong ELF class: ELFCLASS32
 /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:ininitialize' /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:indlopen'
 /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:in `setup'
- 
Error: 
 test_call_int(DL::TestDL):
 DL::DLError: /lib/libc.so.6: wrong ELF class: ELFCLASS32
 /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:ininitialize' /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:indlopen'
 /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:in `setup'
- 
Error: 
 test_call_long(DL::TestDL):
 DL::DLError: /lib/libc.so.6: wrong ELF class: ELFCLASS32
 /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:ininitialize' /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:indlopen'
 /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:in `setup'
- 
Error: 
 test_callback(DL::TestDL):
 DL::DLError: /lib/libc.so.6: wrong ELF class: ELFCLASS32
 /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:ininitialize' /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:indlopen'
 /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:in `setup'
- 
Error: 
 test_cptr(DL::TestDL):
 DL::DLError: /lib/libc.so.6: wrong ELF class: ELFCLASS32
 /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:ininitialize' /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:indlopen'
 /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:in `setup'
- 
Error: 
 test_dlwrap(DL::TestDL):
 DL::DLError: /lib/libc.so.6: wrong ELF class: ELFCLASS32
 /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:ininitialize' /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:indlopen'
 /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:in `setup'
- 
Error: 
 test_empty(DL::TestDL):
 DL::DLError: /lib/libc.so.6: wrong ELF class: ELFCLASS32
 /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:ininitialize' /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:indlopen'
 /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:in `setup'
- 
Error: 
 test_sin(DL::TestDL):
 DL::DLError: /lib/libc.so.6: wrong ELF class: ELFCLASS32
 /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:ininitialize' /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:indlopen'
 /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:in `setup'
- 
Error: 
 test_strcpy(DL::TestDL):
 DL::DLError: /lib/libc.so.6: wrong ELF class: ELFCLASS32
 /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:ininitialize' /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:indlopen'
 /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:in `setup'
- 
Error: 
 test_strlen(DL::TestDL):
 DL::DLError: /lib/libc.so.6: wrong ELF class: ELFCLASS32
 /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:ininitialize' /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:indlopen'
 /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:in `setup'
- 
Error: 
 test_atof(DL::TestFunc):
 DL::DLError: /lib/libc.so.6: wrong ELF class: ELFCLASS32
 /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:ininitialize' /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:indlopen'
 /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:in `setup'
- 
Error: 
 test_empty(DL::TestFunc):
 DL::DLError: /lib/libc.so.6: wrong ELF class: ELFCLASS32
 /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:ininitialize' /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:indlopen'
 /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:in `setup'
- 
Error: 
 test_isdigit(DL::TestFunc):
 DL::DLError: /lib/libc.so.6: wrong ELF class: ELFCLASS32
 /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:ininitialize' /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:indlopen'
 /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:in `setup'
- 
Error: 
 test_qsort1(DL::TestFunc):
 DL::DLError: /lib/libc.so.6: wrong ELF class: ELFCLASS32
 /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:ininitialize' /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:indlopen'
 /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:in `setup'
- 
Error: 
 test_qsort2(DL::TestFunc):
 DL::DLError: /lib/libc.so.6: wrong ELF class: ELFCLASS32
 /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:ininitialize' /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:indlopen'
 /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:in `setup'
- 
Error: 
 test_strcpy(DL::TestFunc):
 DL::DLError: /lib/libc.so.6: wrong ELF class: ELFCLASS32
 /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:ininitialize' /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:indlopen'
 /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:in `setup'
- 
Error: 
 test_strtod(DL::TestFunc):
 DL::DLError: /lib/libc.so.6: wrong ELF class: ELFCLASS32
 /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:ininitialize' /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:indlopen'
 /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:in `setup'
18 tests, 0 assertions, 0 failures, 18 errors, 0 skips
/home/znmeb/test/lib/ruby/1.9.1/dl/import.rb:52:in rescue in block in dlload': can't load /lib/libc.so.6 (DL::DLError) from /home/znmeb/test/lib/ruby/1.9.1/dl/import.rb:49:in block in dlload'
from /home/znmeb/test/lib/ruby/1.9.1/dl/import.rb:40:in collect' from /home/znmeb/test/lib/ruby/1.9.1/dl/import.rb:40:in dlload'
from /home/znmeb/Packages/ruby/ext/dl/test/test_import.rb:7:in <module:LIBC>' from /home/znmeb/Packages/ruby/ext/dl/test/test_import.rb:5:in module:DL'
from /home/znmeb/Packages/ruby/ext/dl/test/test_import.rb:4:in <top (required)>' from test_all.rb:6:in require'
from test_all.rb:6:in `'
znmeb@DreamScape:~/Packages/ruby/ext/dl/test>
After a little poking around with "locate", "ldd" and "grep" I discovered this "case" statement in "test_base.rb":
require 'test/unit'
2 require 'dl'
3
4 case RUBY_PLATFORM
5 when /cygwin/
6   LIBC_SO = "cygwin1.dll"
7   LIBM_SO = "cygwin1.dll"
8 when /linux/
9   LIBC_SO = "/lib/libc.so.6"
10   LIBM_SO = "/lib/libm.so.6"
11 when /mingw/, /mswin32/
12   LIBC_SO = "msvcrt.dll"
13   LIBM_SO = "msvcrt.dll"
14 else
15   LIBC_SO = ARGV[0]
16   LIBM_SO = ARGV[1]
17   if( !(LIBC_SO && LIBM_SO) )
18     $stderr.puts("#{$0}  ")
19     exit
20   end
21 end
22
On an openSUSE 11.1 64-bit system, "/lib/libc.so.6" is the 32-bit one, and the 64-bit one is "/lib64/libc.so.6". On my system, "RUBY_PLATFORM" is
znmeb@DreamScape:/Packages> which ruby/Packages> ruby -e 'puts RUBY_PLATFORM'
/home/znmeb/test/bin/ruby
znmeb@DreamScape:
x86_64-linux
So I added a branch to the "case":
3
4 case RUBY_PLATFORM
5 when /cygwin/
6   LIBC_SO = "cygwin1.dll"
7   LIBM_SO = "cygwin1.dll"
8 when /x86_64-linux/
9   LIBC_SO = "/lib64/libc.so.6"
10   LIBM_SO = "/lib64/libm.so.6"
11 when /linux/
12   LIBC_SO = "/lib/libc.so.6"
13   LIBM_SO = "/lib/libm.so.6"
14 when /mingw/, /mswin32/
15   LIBC_SO = "msvcrt.dll"
16   LIBM_SO = "msvcrt.dll"
17 else
18   LIBC_SO = ARGV[0]
19   LIBM_SO = ARGV[1]
20   if( !(LIBC_SO && LIBM_SO) )
21     $stderr.puts("#{$0}  ")
22     exit
23   end
24 end
25
and the library problem goes away. As far as I know, the "libc.so.6" problem shows up only on openSUSE 11.1, but there should probably be a more portable / robust way of setting that constant. I looked at a few other uses of "RUBY_PLATFORM" in the source tree, and there are quite a few places where it's comparing against "just" /linux/. Some of those may also need to differentiate between 32-bit and 64-bit Linux platforms.
=end
        
           Updated by yugui (Yuki Sonoda) almost 17 years ago
          Updated by yugui (Yuki Sonoda) almost 17 years ago
          
          
        
        
      
      - Priority changed from Normal to 5
=begin
=end
        
           Updated by yugui (Yuki Sonoda) almost 17 years ago
          Updated by yugui (Yuki Sonoda) almost 17 years ago
          
          
        
        
      
      - Status changed from Open to Closed
- % Done changed from 0 to 100
=begin
Applied in changeset r21177.
=end
        
           Updated by kubo (Takehiro Kubo) almost 17 years ago
          Updated by kubo (Takehiro Kubo) almost 17 years ago
          
          
        
        
      
      =begin
How about the following patch which is a piece of one I posted to #633.
Index: ext/dl/test/test_base.rb¶
--- ext/dl/test/test_base.rb	(revision 21112)
+++ ext/dl/test/test_base.rb	(working copy)
@@ -6,8 +6,17 @@
LIBC_SO = "cygwin1.dll"
LIBM_SO = "cygwin1.dll"
when /linux/
- LIBC_SO = "/lib/libc.so.6"
- LIBM_SO = "/lib/libm.so.6"
- libdir = '/lib'
- case [0].pack('L!').size
- when 4
- 
32-bit ruby¶
- libdir = '/lib32' if File.directory? '/lib32'
- when 8
- 
64-bit ruby¶
- libdir = '/lib64' if File.directory? '/lib64'
- end
- LIBC_SO = File.join(libdir, "libc.so.6")
- LIBM_SO = File.join(libdir, "libm.so.6")
 when /mingw/, /mswin32/
 LIBC_SO = "msvcrt.dll"
 LIBM_SO = "msvcrt.dll"
I got similar problems When I ran i386 ruby on ubuntu x86_64.
32-bit libraries are in /lib32 on the platform.
redhat-based x86_64 linux distributions:
/lib    - 32-bit libraries
/lib64  - 64-bit libraries
debian-based x86_64 linux distributions:
/lib    - 64-bit libraries
/lib32  - 32-bit libraries
/lib64  - symbolic link to /lib
This patch will fix all cases.
=end
        
           Updated by yugui (Yuki Sonoda) almost 17 years ago
          Updated by yugui (Yuki Sonoda) almost 17 years ago
          
          
        
        
      
      - Status changed from Closed to Open
=begin
=end
        
           Updated by znmeb (Ed Borasky) almost 17 years ago
          Updated by znmeb (Ed Borasky) almost 17 years ago
          
          
        
        
      
      =begin
Yeah ... that should work. I'll try it as soon as it makes it into the trunk. By the way, Gentoo is like Debian -- /lib is a link to /lib64 (and /usr/lib links to /usr/lib64).
=end
        
           Updated by ko1 (Koichi Sasada) almost 17 years ago
          Updated by ko1 (Koichi Sasada) almost 17 years ago
          
          
        
        
      
      - Status changed from Open to Closed
=begin
Applied in changeset r21182.
=end
        
           Updated by ko1 (Koichi Sasada) almost 17 years ago
          Updated by ko1 (Koichi Sasada) almost 17 years ago
          
          
        
        
      
      
    
        
           Updated by kubo (Takehiro Kubo) almost 17 years ago
          Updated by kubo (Takehiro Kubo) almost 17 years ago
          
          
        
        
      
      =begin
Did you apply the patch dl-test.dif?
It is a bit old than the last I posted. It lacks the following change.
--- ext/dl/test/test_import.rb	(revision 21182)
+++ ext/dl/test/test_import.rb	(working copy)
@@ -13,7 +13,7 @@
extern "int isdigit(int)"
extern "double atof(string)"
extern "unsigned long strtoul(char*, char **, int)"
- extern "int qsort(void*, int, int, void*)"
- extern "int qsort(void*, unsigned long, unsigned long, void*)"
 extern "int fprintf(FILE*, char*)"
 extern "int gettimeofday(timeval*, timezone*)" rescue nil
=end
        
           Updated by ko1 (Koichi Sasada) almost 17 years ago
          Updated by ko1 (Koichi Sasada) almost 17 years ago
          
          
        
        
      
      =begin
Takehiro Kubo wrote::
Issue #932 has been updated by Takehiro Kubo.
Did you apply the patch dl-test.dif?
It is a bit old than the last I posted. It lacks the following change.
Thank you. I committed it.
--
// SASADA Koichi at atdot dot net
=end