#4674 load: loaded shared libraries don't export symbols (OS X)

obsolete: 8.6b1
closed-fixed
Jan Nijtmans
5
2013-01-02
2010-07-22
Georgios Petasis
No

I have observed that under OS X 10.6 (at least), libraries loaded with Tcl's load are not visible from other libraries, also loaded with load.
Thus if you load a library A, and then load a library B that depends on A, library B is not loaded if A does not resides on a directory the dynamic linker searches for libraries. It is not recognised that library A is already loaded in the process.
This seems OS X specific, as I cannot reproduce at least under windows & linux.

I know that load calls dlopen(..., RTLD_GLOBAL); which does not seem to do as advertised.
I had to call NSAddImage(NSADDIMAGE_OPTION_RETURN_ON_ERROR |
NSADDIMAGE_OPTION_WITH_SEARCHING |
NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME ), after I loaded lib A, to be able to load lib B.
However, NSAddImage is already deprecated in 10.6.

The relevant thread is here:

http://groups.google.gr/group/comp.lang.tcl/browse_thread/thread/87266afd63143a11/f9b735ee56100d57

Discussion

    • assigned_to: kennykb --> das
     
  • On second thought, I realize that the error message is not at the symbol level, but at the dependency level, so indeed RTLD_GLOBAL is not really concerned. Now, there are two ways of loading a library: either implicitly through dependency, or programmatically with dlopen(). A is loaded through dlopen(), then B too, and B implicitly needs A, but at this point in time, A is *not* "implicitly loaded".

    So, *if* OSX maintains two separate lists of dylds, one implicitly loaded, the other dlopened(), that could explain the behavior. Daniel, is this possible ?

    And if it is the case, then the solution is to refactor A so that it contains only the Tcl API entry points needed for an extension, and shove all the useful shareable code into a 3rd library C, on which A depends. Hence, [load A] also loads C but on the implicit list. Then do the same for B, and C should be reused as is.

     
  • Can you clarify the versions of Tcl and OS X involved?

    tcl/unix/tclLoadDyld.c was switched to use RTLD_GLOBAL on 2009-04-10, anything built from sources earlier than that is using RTLD_LOCAL.

     
  • I have observed this behaviour under OS X 10.6, and ActiveTcl 8.6.0.0b3.
    I don't remember the date ActiveTcl 8.6.0.0b3 was released. And it is true that I looked at the latest CVS head for the sources, when concluding that RTLD_GLOBAL is used by load.

    Looking at the dates of files, i.e. wish8.6 in /usr/local/bin, I see a date of May 20. But I don't know if they include the change or not.

     
  • Jan Nijtmans
    Jan Nijtmans
    2012-11-08

    See: <http://www.tcl.tk/cgi-bin/tct/tip/416>

     
  • Jan Nijtmans
    Jan Nijtmans
    2012-11-08

    • assigned_to: das --> nijtmans
     
  • Jan Nijtmans
    Jan Nijtmans
    2013-01-02

    Since Tcl 8.6, [load -global] can be used to remedy this.

     
  • Jan Nijtmans
    Jan Nijtmans
    2013-01-02

    • status: open --> closed-fixed