Bug #932

incorrect case statement in "ext/dl/test/test_base.rb" causes library problems on openSUSE 11.1 64-bit

Added by znmeb (Ed Borasky) over 3 years ago. Updated about 1 year ago.

[ruby-core:20893]
Status:Closed Start date:12/27/2008
Priority:High Due date:
Assignee:- % Done:

100%

Category:ext
Target version:1.9.1 Release Candidate
ruby -v:

Description

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.

  1) 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:in `initialize'
    /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:in `dlopen'
    /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:in `setup'

  2) 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:in `initialize'
    /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:in `dlopen'
    /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:in `setup'

  3) 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:in `initialize'
    /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:in `dlopen'
    /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:in `setup'

  4) 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:in `initialize'
    /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:in `dlopen'
    /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:in `setup'

  5) 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:in `initialize'
    /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:in `dlopen'
    /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:in `setup'

  6) 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:in `initialize'
    /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:in `dlopen'
    /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:in `setup'

  7) 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:in `initialize'
    /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:in `dlopen'
    /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:in `setup'

  8) 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:in `initialize'
    /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:in `dlopen'
    /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:in `setup'

  9) 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:in `initialize'
    /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:in `dlopen'
    /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:in `setup'

 10) 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:in `initialize'
    /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:in `dlopen'
    /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:in `setup'

 11) 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:in `initialize'
    /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:in `dlopen'
    /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:in `setup'

 12) 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:in `initialize'
    /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:in `dlopen'
    /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:in `setup'

 13) 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:in `initialize'
    /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:in `dlopen'

    /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:in `setup'

 14) 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:in `initialize'
    /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:in `dlopen'
    /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:in `setup'

 15) 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:in `initialize'
    /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:in `dlopen'
    /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:in `setup'

 16) 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:in `initialize'
    /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:in `dlopen'
    /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:in `setup'

 17) 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:in `initialize'
    /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:in `dlopen'
    /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:in `setup'

 18) 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:in `initialize'
    /home/znmeb/Packages/ruby/ext/dl/test/test_base.rb:29:in `dlopen'
    /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 `<main>'
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} <libc> <libm>")
 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
/home/znmeb/test/bin/ruby
znmeb@DreamScape:~/Packages> ruby -e 'puts RUBY_PLATFORM'
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} <libc> <libm>")
 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.

Associated revisions

Revision 21177
Added by yugui (Yuki Sonoda) over 3 years ago

* ext/dl/test/test_base.rb: add x86_64-linux's case again. #932

Revision 21177
Added by yugui (Yuki Sonoda) over 3 years ago

* ext/dl/test/test_base.rb: add x86_64-linux's case again. #932

Revision 21182
Added by ko1 (Koichi Sasada) over 3 years ago

* ext/dl/test/test_base.rb: add libc search logic. this patch is written by Takehiro Kubo. [ruby-core:20963] [Bug #932] * ext/dl/dl.h: Add ",..." as the last argument. this patch is written by Takehiro Kubo. Bug #633 [ruby-core:19289] * ext/dl/lib/dl/stack.rb: add add_padding() to calculate alignment. this patch is written by Takehiro Kubo. Bug #633 [ruby-core:19289] * ext/dl/test/test_func.rb: atof()'s return value is double. this patch is written by Takehiro Kubo. Bug #633 [ruby-core:19289] * ext/dl/test/test_import.rb: - atof()'s return value is double. - The types of qsort's second and third argument are size_t. - fprintf()'s return value is int. this patch is written by Takehiro Kubo. Bug #633 [ruby-core:19289]

Revision 21182
Added by ko1 (Koichi Sasada) over 3 years ago

* ext/dl/test/test_base.rb: add libc search logic. this patch is written by Takehiro Kubo. [ruby-core:20963] [Bug #932] * ext/dl/dl.h: Add ",..." as the last argument. this patch is written by Takehiro Kubo. Bug #633 [ruby-core:19289] * ext/dl/lib/dl/stack.rb: add add_padding() to calculate alignment. this patch is written by Takehiro Kubo. Bug #633 [ruby-core:19289] * ext/dl/test/test_func.rb: atof()'s return value is double. this patch is written by Takehiro Kubo. Bug #633 [ruby-core:19289] * ext/dl/test/test_import.rb: - atof()'s return value is double. - The types of qsort's second and third argument are size_t. - fprintf()'s return value is int. this patch is written by Takehiro Kubo. Bug #633 [ruby-core:19289]

History

Updated by yugui (Yuki Sonoda) over 3 years ago

  • Priority changed from Normal to High

Updated by yugui (Yuki Sonoda) over 3 years ago

  • Status changed from Open to Closed
  • % Done changed from 0 to 100
Applied in changeset r21177.

Updated by kubo (Takehiro Kubo) over 3 years ago

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.

Updated by yugui (Yuki Sonoda) over 3 years ago

  • Status changed from Closed to Open

Updated by znmeb (Ed Borasky) over 3 years ago

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).

Updated by ko1 (Koichi Sasada) over 3 years ago

  • Status changed from Open to Closed
Applied in changeset r21182.

Updated by ko1 (Koichi Sasada) over 3 years ago

Takehiro Kubo wrote::
> How about the following patch which is a piece of one I posted to #633.

Thank you.  I committed it at r21182 with short ChangeLog entry.  If my
ChangeLog entry is wrong, please correct it.

Regards,
-- 
// SASADA Koichi at atdot dot net

Updated by kubo (Takehiro Kubo) over 3 years ago

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

Updated by ko1 (Koichi Sasada) over 3 years ago

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

Also available in: Atom PDF