kubo / ruby-oci8

Ruby-oci8 - Oracle interface for ruby
Other
169 stars 75 forks source link

oci8 initialization error #53

Closed rushirajchavan closed 10 years ago

rushirajchavan commented 10 years ago

Hi,

I am using ruby-oci8 gem in my project. Everything works fine when I require "oci8" before an internal gem but when I change the order, oci8 initialization fails.

The internal gem is a C extension gem which contains some .c files and .so files in addition to .rb files.

I got the following error : OCIError: OCI Library Initialization Error from oci8lib.c:127:in oci8lib.so ..... .....

The snippet from oci8lib.c where the error occurs: 124 /* allocate a temporary errhp to pass Init_oci_number() */ 125 rv = OCIEnvCreate(&envhp, oci8_env_mode, NULL, NULL, NULL, NULL, 0, NULL); 126 if (rv != OCI_SUCCESS) { 127 oci8_raise_init_error(); 128 }

Thanks, Rushi

kubo commented 10 years ago

What OS do you use? If it is Linux, could you post the output of the following command or send it to kubo@jiubao.org?

LD_DEBUG=all ruby -e "require 'your-extension-library'; require 'oci8'"

If it is OS X, use the following command.

DYLD_PRINT_LIBRARIES=1 DYLD_PRINT_BINDINGS=1 ruby -e "require 'your-extension-library'; require 'oci8'"
kubo commented 10 years ago

IMO, your issue will be caused by symbol interposition. If the internal gem has a symbol whose name is accidentally same with a symbol in Oracle libraries, Oracle libraries call the symbol in the internal gem by mistake.

Interposed symbols are found by LD_DEBUG=all if it prints lines such as the following:

binding file /path/to/oracle-libraries/libclntsh.so.12.1 [0] to /path/to/your-extension-library.so [0]: normal symbol `symbol_name'
rushirajchavan commented 10 years ago

Hi, I got about 100 such lines in the debug output.

binding file /usr/lib/oracle/12.1/client64/lib/libclntsh.so.12.1 [0] to /data/OLT/lib/libclntshcore.so.12.1 [0]: normal symbol some symbol

Our internal gem uses oracle's OLT libraries for language identification.

I have mailed you the debug output.

How do we resolve such errors?

Thanks, Rushi

kubo commented 10 years ago

Do you have two Oracle installations under /usr/lib/oracle/12.1/client64 and /data/OLT? If so, could you change the OTL libraries to use Oracle libraries in /usr/lib/oracle/12.1/client64/lib? Otherwise, could you recompile ruby-oci8 to use Oracle libraries in /data/OLT?

rushirajchavan commented 10 years ago

Yes I have two installations but there working is entirely different.

  1. /usr/lib/oracle/12.1/client64 has oracle instant client libraries on which oci8 depends
  2. /data/OLT is used by our internal gem for language indentification

I cannot use one for the other.

Thanks, Rushi

kubo commented 10 years ago

The issue is not related to symbol interposition. As far as I checked, Oracle libraries try to get a nls data file (libociicus.so or libociei.so) in the directory at which libclntshcore.so.12.1 is.

I recommend you to use one Oracle installation. There are no solution to use two installations except the following illegal workaround. If the workaround causes another unexpected behavior, I'll just say that "use one Oracle installation" because nobody knows its side effect.

Download ruby-oci8-2.1.7.tar.gz and ad-hoc.fix and make a new ruby-oci8 gem as follows and install it.

tar xvfz ruby-oci8-2.1.7.tar.gz
cd ruby-oci8-2.1.7
patch -p1 < ../ad-hoc.fix
gem build ruby-oci8.gemspec

It hooks dladdr function calls from libclntshcore.so.12.1 and replace "/data/OLT/libclntshcore.so.12.1" with "/usr/lib/oracle/12.1/client64/lib/libclntshcore.so.12.1" in the dli_fname member. https://gist.github.com/kubo/156953f93cde9737f300#file-ad-hoc-fix-L33

rushirajchavan commented 10 years ago

Hi,

Gem install is failing with the following error,

oci8lib.c:10:21: error: plthook.h: No such file or directory oci8lib.c: In function ‘Init_oci8lib_18’: oci8lib.c:100: error: ‘plthook_t’ undeclared (first use in this function) oci8lib.c:100: error: (Each undeclared identifier is reported only once oci8lib.c:100: error: for each function it appears in.) oci8lib.c:100: error: ‘plthook’ undeclared (first use in this function) oci8lib.c:101: warning: implicit declaration of function ‘plthook_open’ oci8lib.c:102: warning: implicit declaration of function ‘plthook_replace’ oci8lib.c:103: warning: implicit declaration of function ‘plthook_close’ make: *\ [oci8lib.o] Error 1

Thanks, Rushi

kubo commented 10 years ago

Sorry, add ext/oci8/plthook.h and ext/oci8/plthook.c to dist-files before gem build ruby-oci8.gempspec.

rushirajchavan commented 10 years ago

It worked. Thanks a lot.