undefined symbol: isc_attach_database
plainlystated opened this issue · 7 comments
Excited to find this gem, but I'm having trouble getting it to run. I installed version 0.7.4 via 'gem install fb', and it built the native extension without a problem.
When I try to run the README, though, it complains:
$ ruby README
ruby: symbol lookup error: /home/patrick/.rvm/gems/ruby-2.2.1@fb/gems/fb-0.7.4/fb.so: undefined symbol: isc_attach_database
I think I have the required client installed:
$ ls /usr/lib/libfb*
/usr/lib/libfbclient.so /usr/lib/libfbclient.so.1 /usr/lib/libfbclient.so.1.5.6 /usr/lib/libfbembed.so /usr/lib/libfbembed.so.1 /usr/lib/libfbembed.so.1.5.6
... but perhaps not...
I tried building from source and I see this when running extconf.rb:
$ ruby extconf.rb
checking for isc_attach_database() in -lfbclient... no
checking for isc_attach_database() in -lgds... no
creating Makefile
I'm running 2.2.1 in RVM.
Any help would be greatly appreciated. This library will be a huge help to me :)
I should also mention that I'm on ubuntu 14.04 and I installed firebird 1.5.6 from source to /opt/firebird. I tried using --with-opt-dir=/opt/firebird on extconf.rb but that didn't seem to have an effect.
I would try something like
strace ruby -e "require 'fb'" 2>&1 | less
and see which libraries it is trying to load. Search for "libfb" of course. I get
open("/usr/local/rbenv/versions/2.2.3/lib/libfbclient.so.2", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/usr/local/rbenv/versions/2.2.3/lib/libfbclient.so.2", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 7
fstat(7, {st_mode=S_IFREG|0644, st_size=53484, ...}) = 0
mmap(NULL, 53484, PROT_READ, MAP_PRIVATE, 7, 0) = 0x7fcffa5c3000
close(7) = 0
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
open("/usr/lib/libfbclient.so.2", O_RDONLY|O_CLOEXEC) = 7
Since you installed Firebird from source, make sure the libraries are properly registered:
strings /etc/ld.so.cache | grep libfb
I'm also on Ubuntu 14.04, but I use rbenv. Ruby 2.2.1 didn't want to install, but 2.1.8 and 2.2.3 both work for me. I haven't used Firebird < 2.x for several years, but I've heard reports of others still using it.
Yeah, the 1.5.6 requirement is to match a vendor's choice. I tried opening the files with 2.x and firebird said the files were invalid, so I guess when they did a major version bump they said 'screw it' to opening their pre 2.x files :(
It looks like I have the libs installed correctly. At least, I see them here:
$ strings /etc/ld.so.cache | grep libfb
libfbembed.so.1
/usr/lib/libfbembed.so.1
libfbembed.so
/usr/lib/libfbembed.so
libfbclient.so.2
/usr/lib/x86_64-linux-gnu/libfbclient.so.2
libfbclient.so.1
/usr/lib/libfbclient.so.1
libfbclient.so
/usr/lib/libfbclient.so
I don't see libfb mentioned anywhere in strace, though:
$ strace ruby -e "require 'fb'" 2>&1 | grep libfb
(no output)
Here's the libs it does try to load:
$ strace ruby -e "require 'fb'" 2>&1 | grep -oE "[a-z_0-9]+\.so" | sort | uniq
date_core.so
encdb.so
fb.so
ld.so
libcrypt.so
libc.so
libdl.so
libm.so
libpthread.so
libruby.so
operating_system.so
ruby.so
thread.so
transdb.so
FWIW, ldd doesn't mention it either:
$ ldd /home/patrick/.rvm/gems/ruby-2.2.1@fb/gems/fb-0.7.4/fb.so
linux-vdso.so.1 => (0x00007ffe5aad8000)
libruby.so.2.2 => /home/patrick/.rvm/rubies/ruby-2.2.1/lib/libruby.so.2.2 (0x00007fe46190f000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fe46154a000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fe46132c000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fe461128000)
libcrypt.so.1 => /lib/x86_64-linux-gnu/libcrypt.so.1 (0x00007fe460eef000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fe460be9000)
/lib64/ld-linux-x86-64.so.2 (0x00007fe461ffb000)
And, when I run the extconf.rb myself, this line returns nil, which I'm guessing means ruby can't find the library for some reason:
libs.find {|lib| have_library(lib, test_func) }
I'm not very familiar with native extensions in ruby. Is there some flag or somesuch I should be specifying?
Thanks for having a look and trying to help. This will be a huge help to me if I can get it to work.
At one time, extconf.rb would abort when have_library failed, but on some platforms, notably Darwin, the have_library function would fail even though the framework was available. So, now it crosses its fingers and violates the fail-early principle.
I'm not sure how your fb.so managed to build without finding fbclient.
brent@andromeda:~/src$ ldd /usr/local/rbenv/versions/2.1.8/lib/ruby/gems/2.1.0/gems/fb-0.7.4/fb.so
linux-vdso.so.1 => (0x00007ffccdb65000)
libfbclient.so.2 => /usr/lib/libfbclient.so.2 (0x00007fc17b20c000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fc17ae47000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fc17ab41000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fc17a93d000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fc17a71f000)
/lib64/ld-linux-x86-64.so.2 (0x00007fc17b701000)
To open a Firebird 1.5 database in 2.x, one would need to back it up with the -t (transportable) option using Firebird 1.5 and then restore it with 2.x. I don't know if it will work in reverse, though. Maybe if you don't use any 2.x-specific features?
One more explanation comes to mind: The output of your ldd command shows you're using a 64-bit Ruby. Firebird didn't support 64-bit until 2.0. The wire protocol is architecture-agnostic, but your libfbclient has got to be 32-bit, which would explain why it's not getting linked into your 64-bit program.
So, you either need to use a 32-bit Ruby or at least connect to your 32-bit server using a 64-bit, Firebird 2.x client.
As usual, if it breaks, you get to keep the pieces...
Were you able to resolve your 32/64-bit issues?
Unfortunately, not yet.
I've been shaving yaks trying to build a 32 bit ruby. Doesn't seem to work in RVM, even on a 32-bit OS (in a VM). Ugh.
Hoping to get more time this week to put into researching this.
I did kinda end up getting it to work, but I had to completely destroy the 64-bit build environment by one-by-one replacing packages with their 32-bit equivalent. Debian's multiarch stuff is a huge pain :(
I've decided to scrap that strategy, and will be doing what you mentioned above: export it on a 1.5.6 box and then run 2.x on my app boxes. I only need read-only access, so this strategy should work for me.
Thanks for the help!