Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mysql2.so doesn't link to proper libruby #657

Closed
sorah opened this issue Aug 27, 2015 · 4 comments
Closed

mysql2.so doesn't link to proper libruby #657

sorah opened this issue Aug 27, 2015 · 4 comments

Comments

@sorah
Copy link

sorah commented Aug 27, 2015

Assume both libruby and libmysqlclient are in system libdir (e.g. /usr/lib/x86_64-linux-gnu). When using another ruby installation (e.g. ruby with --enable-shared in rbenv), mysql2.so doesn't link to proper libruby:

$ ls -la /usr/lib/x86_64-linux-gnu/libruby.so /usr/lib/x86_64-linux-gnu/libmysqlclient.so
lrwxrwxrwx 1 root root 20 Oct 11  2014 /usr/lib/x86_64-linux-gnu/libmysqlclient.so -> libmysqlclient.so.18
lrwxrwxrwx 1 root root 40 Aug 25 07:35 /usr/lib/x86_64-linux-gnu/libruby.so -> libruby-2.2.so
$ ruby extconf.rb
checking for ruby/thread.h... yes
checking for rb_thread_call_without_gvl() in ruby/thread.h... yes
checking for rb_thread_blocking_region()... no
checking for rb_wait_for_single_fd()... yes
checking for rb_hash_dup()... yes
checking for rb_intern3()... yes
-----
Using mysql_config at /usr/bin/mysql_config
-----
checking for mysql.h... yes
checking for errmsg.h... yes
checking for mysqld_error.h... yes
-----
Setting libpath to /usr/lib/x86_64-linux-gnu
-----
creating Makefile

$ make V=1
gcc -I. -I/usr/share/rbenv/versions/2.2.3/include/ruby-2.2.0/x86_64-linux -I/usr/share/rbenv/versions/2.2.3/include/ruby-2.2.0/ruby/backward -I/usr/share/rbenv/versions/2.2.3/include/ruby-2.2.0 -I. -I/usr/include/mysql -DHAVE_RUBY_THREAD_H -DHAVE_RB_THREAD_CALL_WITHOUT_GVL -DHAVE_RB_WAIT_FOR_SINGLE_FD -DHAVE_RB_HASH_DUP -DHAVE_RB_INTERN3 -DHAVE_MYSQL_H -DHAVE_ERRMSG_H -DHAVE_MYSQLD_ERROR_H -I/usr/share/rbenv/versions/2.2.3/include    -fPIC  -O2 -march=native -mtune=native -ggdb3 -gdwarf-2 -fPIC -Wall -Wextra -Werror -Wno-unused-function -Wno-declaration-after-statement -Wno-missing-field-initializers  -o infile.o -c infile.c
gcc -I. -I/usr/share/rbenv/versions/2.2.3/include/ruby-2.2.0/x86_64-linux -I/usr/share/rbenv/versions/2.2.3/include/ruby-2.2.0/ruby/backward -I/usr/share/rbenv/versions/2.2.3/include/ruby-2.2.0 -I. -I/usr/include/mysql -DHAVE_RUBY_THREAD_H -DHAVE_RB_THREAD_CALL_WITHOUT_GVL -DHAVE_RB_WAIT_FOR_SINGLE_FD -DHAVE_RB_HASH_DUP -DHAVE_RB_INTERN3 -DHAVE_MYSQL_H -DHAVE_ERRMSG_H -DHAVE_MYSQLD_ERROR_H -I/usr/share/rbenv/versions/2.2.3/include    -fPIC  -O2 -march=native -mtune=native -ggdb3 -gdwarf-2 -fPIC -Wall -Wextra -Werror -Wno-unused-function -Wno-declaration-after-statement -Wno-missing-field-initializers  -o client.o -c client.c
gcc -I. -I/usr/share/rbenv/versions/2.2.3/include/ruby-2.2.0/x86_64-linux -I/usr/share/rbenv/versions/2.2.3/include/ruby-2.2.0/ruby/backward -I/usr/share/rbenv/versions/2.2.3/include/ruby-2.2.0 -I. -I/usr/include/mysql -DHAVE_RUBY_THREAD_H -DHAVE_RB_THREAD_CALL_WITHOUT_GVL -DHAVE_RB_WAIT_FOR_SINGLE_FD -DHAVE_RB_HASH_DUP -DHAVE_RB_INTERN3 -DHAVE_MYSQL_H -DHAVE_ERRMSG_H -DHAVE_MYSQLD_ERROR_H -I/usr/share/rbenv/versions/2.2.3/include    -fPIC  -O2 -march=native -mtune=native -ggdb3 -gdwarf-2 -fPIC -Wall -Wextra -Werror -Wno-unused-function -Wno-declaration-after-statement -Wno-missing-field-initializers  -o statement.o -c statement.c
gcc -I. -I/usr/share/rbenv/versions/2.2.3/include/ruby-2.2.0/x86_64-linux -I/usr/share/rbenv/versions/2.2.3/include/ruby-2.2.0/ruby/backward -I/usr/share/rbenv/versions/2.2.3/include/ruby-2.2.0 -I. -I/usr/include/mysql -DHAVE_RUBY_THREAD_H -DHAVE_RB_THREAD_CALL_WITHOUT_GVL -DHAVE_RB_WAIT_FOR_SINGLE_FD -DHAVE_RB_HASH_DUP -DHAVE_RB_INTERN3 -DHAVE_MYSQL_H -DHAVE_ERRMSG_H -DHAVE_MYSQLD_ERROR_H -I/usr/share/rbenv/versions/2.2.3/include    -fPIC  -O2 -march=native -mtune=native -ggdb3 -gdwarf-2 -fPIC -Wall -Wextra -Werror -Wno-unused-function -Wno-declaration-after-statement -Wno-missing-field-initializers  -o result.o -c result.c
gcc -I. -I/usr/share/rbenv/versions/2.2.3/include/ruby-2.2.0/x86_64-linux -I/usr/share/rbenv/versions/2.2.3/include/ruby-2.2.0/ruby/backward -I/usr/share/rbenv/versions/2.2.3/include/ruby-2.2.0 -I. -I/usr/include/mysql -DHAVE_RUBY_THREAD_H -DHAVE_RB_THREAD_CALL_WITHOUT_GVL -DHAVE_RB_WAIT_FOR_SINGLE_FD -DHAVE_RB_HASH_DUP -DHAVE_RB_INTERN3 -DHAVE_MYSQL_H -DHAVE_ERRMSG_H -DHAVE_MYSQLD_ERROR_H -I/usr/share/rbenv/versions/2.2.3/include    -fPIC  -O2 -march=native -mtune=native -ggdb3 -gdwarf-2 -fPIC -Wall -Wextra -Werror -Wno-unused-function -Wno-declaration-after-statement -Wno-missing-field-initializers  -o mysql2_ext.o -c mysql2_ext.c
rm -f mysql2.so
gcc -shared -o mysql2.so infile.o client.o statement.o result.o mysql2_ext.o -L/usr/lib/x86_64-linux-gnu -Wl,-R/usr/lib/x86_64-linux-gnu -L. -L/usr/share/rbenv/versions/2.2.3/lib -Wl,-R/usr/share/rbenv/versions/2.2.3/lib -L. -L/usr/share/rbenv/versions/2.2.3/lib  -fstack-protector -rdynamic -Wl,-export-dynamic    -Wl,-R/usr/share/rbenv/versions/2.2.3/lib -L/usr/share/rbenv/versions/2.2.3/lib -lruby -L/usr/lib/x86_64-linux-gnu -lmysqlclient -lpthread -lz -lm -ldl  -lpthread -lgmp -ldl -lcrypt -lm   -lc

$ ldd mysql2.so
        linux-vdso.so.1 =>  (0x00007fff4b5fe000)
        libruby-2.2.so.2.2 => /usr/lib/x86_64-linux-gnu/libruby-2.2.so.2.2 (0x00007fb0aafb5000)
        libmysqlclient.so.18 => /usr/lib/x86_64-linux-gnu/libmysqlclient.so.18 (0x00007fb0aaa7e000)
        libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fb0aa854000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fb0aa48f000)
        libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fb0aa28b000)
        libcrypt.so.1 => /lib/x86_64-linux-gnu/libcrypt.so.1 (0x00007fb0aa051000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fb0a9d4b000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fb0ab641000)
        libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007fb0a9b32000)

Before 2.2.3 this kind of error isn't detected. But 2.2.3 introduced simple routine to make sure wrong libruby is being linked bugs.ruby-lang.org #11111:

$ ruby -v -r./mysql2.so -e0
ruby 2.2.3p173 (2015-08-18 revision 51636) [x86_64-linux]
/usr/share/rbenv/versions/2.2.3/lib/ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:in `require': incompatible library version - /home/.../mysql2/ext/mysql2/mysql2.so (LoadError)
        from /usr/share/rbenv/versions/2.2.3/lib/ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:in `require'

The cause is specifying libdir into $LIBPATH explicitly:

# extconf.rb
$LIBPATH << libdir unless $LIBPATH.include?(libdir)

(I'm figuring out the smart fix...)

@sorah
Copy link
Author

sorah commented Aug 27, 2015

Hm, Ruby 2.1.7 put libruby's directory more earlier on command line. Maybe ruby's bug?

@sorah
Copy link
Author

sorah commented Aug 27, 2015

@sorah
Copy link
Author

sorah commented Aug 27, 2015

I think this is mkmf's bug. Close for a while...

@defulmere
Copy link

I bumped into this problem a day or two ago while setting up an old Rails app with rvm.

I was able to work around it by temporarily denying access to the system ruby lib to the user who was using rvm, eg:

# as root
setfacl -m u:foo:--- /usr/lib64/libruby.so.2.6

# the user installs mysql2 in rvm, then as root again:

setfacl -x u:foo /usr/lib64/libruby.so.2.6

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants