Fiddle::TestHandle#test_NEXT fails on AIX due to unexported symbols of extension libraries
Fiddle::TestHandle#test_NEXT fails on AIX.
[ 4/21] Fiddle::TestHandle#test_NEXT = 0.00 s 1) Error: Fiddle::TestHandle#test_NEXT: Fiddle::DLError: unknown symbol "Init_objspace" /ss/home/rayod/Dev/Contribution/ruby-trunk-blue1/test/fiddle/test_handle.rb:171:in `' /ss/home/rayod/Dev/Contribution/ruby-trunk-blue1/test/fiddle/test_handle.rb:171:in `rescue in test_NEXT' /ss/home/rayod/Dev/Contribution/ruby-trunk-blue1/test/fiddle/test_handle.rb:144:in `test_NEXT'
The reason for this is a little bit complicated.
Fiddle::TestHandle#test_NEXT tests the behavior of
dlsym(3). According to the manual,
RTLD_NEXT of AIX should behave like that of BSD, so the following part in
Fiddle::TestHandle#test_NEXT should succeed, but in fact it fails.
# BSD # <snip> require 'objspace' handle = Handle::NEXT refute_nil handle['Init_objspace']
The problem is that on AIX, Ruby's extension libraries do not export their symbols, because they are loaded not by dlopen(3)/dlsym(3) but by load(3). The build process on AIX only specifies
Init_* functions as the entry points of the extension shared libraries. This means
Init_objspace cannot be the search target of
RTLD_NEXT, and the test above results in nil. (FYI, the symbols in the modules loaded by load(3) can be found by
RTLD_NEXT if they are exported.)
One way to solve this is to somehow export the
Init_objspace function. However, specifying -Wl,-bexpall does not export the entry points, so we need to specify -Wl,-bexpfull, which looks like overkill for just passing this test.
Fortunately, on AIX, test/fiddle/helper.rb creates and loads a dummy shared library, libaixdltest.so, which contains and exports
strcpy and some other functions, so we can take advantage of it for testing
RTLD_NEXT. That is, we can simply query
strcpy to check whether or not
RTLD_NEXT works correctly, as follows. The patch is attached.
handle = Handle::NEXT refute_nil handle['strcpy']