Link to specific Oracle instant client dynamic library on OS X Link to specific Oracle instant client dynamic library on OS X oracle oracle

Link to specific Oracle instant client dynamic library on OS X


Updated:

I mailed with the questioner and the crash disappeared by adding "require 'oci8'" at the top of his application.

According the log outputted by DYLD_PRINT_LIBRARIES=1 and DYLD_PRINT_BINDINGS=1, this issue was caused by function interposition. The libclntsh.dylib and the OS X LDAP library export _ldap_first_entry whose implementation differs. When the OS X LDAP libary is loaded into the process memory before libclntsh.dylib and a function in libclntsh.dylib tries to use _ldap_first_entry in libclntsh.dylib, it faulty uses _ldap_first_entry in the OS X LDAP library.It may happen on Unix (except OS X) generally and on OS X only when a library is linked with flat_namespace.

IMO, he doesn't use the OS X LDAP library explicitly. He uses a kind of authorization module, which depends on the library internally.

The rest is not changed.


I have an idea. But I haven't tested it.

IMO, ruby doesn't use OS X version library directly. A extension library such ruby-ldap uses it. If so, "require 'oci8'" before the extension library may solve the issue.

require 'oci8' # This must be before any other extension libraries using LDAP.require 'ldap' # for example

But it causes another issue. When the ruby-ldap library try to use OS X version _ldap_first_entry, Oracle version _ldap_first_entry is called and the process crashes. You need to customize oci8 to avoid it.

Change DLOPEN_FLAG in ext/oci8/oci8lib.c as follows,

#define DLOPEN_FLAG (RTLD_NOW|RTLD_LOCAL)

then install as follows

gem build ruby-oci8.gemspecgem install ruby-oci8-2.1.5.gem -- --with-runtime-check

and use it.

require 'oci8' # This must be before any other extension libraries using LDAP.require 'ldap'

RTLD_LOCAL hides symbols in libclntsh.dylib from other extension libraries.RTLD_NOW resolves symbols immediately and prevents libclntsh.dylib from using symbols in succeedingly loaded libraries.--with-runtime-check forces ruby-oci8 to use dlopen().

I hope that OS X dlopen() specification is same with Linux and it works.


You need to use 'otool -L < path to dylib >' to dump the dylibs that your executable or dylibs are dependent on. They should have been built to access the bundle frameworks via a relative path ('@executable_path/../Frameworks/*' (or @loader_path or @rpath)) instead of the system ones.

See the "DYNAMIC LIBRARY LOADING" section of the dyld man page at: https://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man1/dyld.1.html

The install_path of a dylib is used to tell the execs & dylibs that link against it where they should expect to find it at runtime. You can (try to) change the install_path of a dylib via the install_name_tool command line tool. (I say 'try' because it can fail silently so ALWAYS check afterwords to see if it actually worked.)