Jeff Hobbs wrote:
Jeff Hobbs wrote:
Brian Bevins wrote:
Thanks very much for your help with our little problem. I am out of ideas on this. I can do a "package require BLT" in both wish and tclsh just fine with no problems. And when I try to load BLT into Perl, the error is not that it cannot find the BLT package library. The problem is that when it tries to load that library there is a missing symbol. That symbol is found only in libtcl8.4.so. If I manually load that library before loading BLT then everything works. The odd thing is that I shouldn't have to do that. The Tcl.so used by perl should already be loading libtcl8.4.so.

Is it possible that the implicit loader (or any pre-loading occuring through whatever means) for libtcl is using RTLD_LOCAL instead of RTLD_GLOBAL, which would very possible cause this issue?

OK, I poked my nose in because it may well be my own code on this in the Tcl.xs file. When this builds, it should build against -ltclstub only, and load libtcl dynamically (you should not see -Ltcl or -Rtcl on the compile line). Tcl.xs does use RTLD_NOW | RTLD_GLOBAL as the flags, so that is maybe not the issue (unless libtcl is magically getting loaded implicitly ahead of this).

Hi Jeff,

Thanks again for looking at this. Prompted by your questions, I think I have figured out the problem.

BLT wants a symbol called TclpRealloc and our libtcl8.4.so does not export that symbol globally. It is present, but local to the shared object. However the symbol is exposed by the stubs mechanism. It appears that Tcl.so was built by default without Tcl stubs enabled. It only tries to use stubs if I explicitly add --usestubs, and then it only passes "make test" if I also define where libtcl8.4.so can be found:

perl Makefile.PL --usestubs --define=-DLIB_RUNTIME_DIR=\\\"/usr/csite/pubtools/tcl/8.4/lib\\\"

I was fooled by the fact that if I do just:

perl Makefile.PL

it finds our Tcl 8.4 just fine and builds without errors. It even passes "make test" with flying colors. Only trying to load BLT showed the problem.

When built without --usestubs our Tcl.so does build against libtcl8.4.so (not libtclstub8.4.a). When I ldd it, I get:

> ldd blib/arch/auto/Tcl/Tcl.so
libtcl8.4.so => /usr/csite/pubtools/tcl/8.4/lib/libtcl8.4.so (0x00be5000)
       libc.so.6 => /lib/tls/libc.so.6 (0x00a17000)
       libdl.so.2 => /lib/libdl.so.2 (0x004e6000)
       libpthread.so.0 => /lib/tls/libpthread.so.0 (0x00866000)
       libm.so.6 => /lib/tls/libm.so.6 (0x00ca6000)
       /lib/ld-linux.so.2 (0x00785000)

This is true even if I don't specify --nousestubs to Makefile.PL. Here is what shows up in Makefile:

# --- MakeMaker const_loadlibs section:

# Tcl might depend on some other libraries:
# See ExtUtils::Liblist for details
#
EXTRALIBS = -L/usr/csite/pubtools/tcl/8.4/lib -ltcl8.4
LDLOADLIBS = -L/usr/csite/pubtools/tcl/8.4/lib -ltcl8.4
BSLOADLIBS =
LD_RUN_PATH = /usr/csite/pubtools/tcl/8.4/lib

I think this happens by default because our Tcl 8.4.15 was built without stubs. The stub libraries are present, but not used by tclsh itself. (I didn't build it.) When I ldd tclsh, I get:

> ldd tclsh
libtcl8.4.so => /usr/csite/pubtools/tcl/8.4/lib/libtcl8.4.so (0x007fd000)
       libdl.so.2 => /lib/libdl.so.2 (0x008f7000)
       libpthread.so.0 => /lib/tls/libpthread.so.0 (0x00a00000)
       libm.so.6 => /lib/tls/libm.so.6 (0x008d2000)
       libc.so.6 => /lib/tls/libc.so.6 (0x00111000)
       /lib/ld-linux.so.2 (0x00785000)

So Tcl.so wants to implicitly load the same libtcl8.4.so as our tclsh. Somehow tclsh is making TclpRealloc available to BLT, but Tcl.so doesn't unless I explicitly load libtcl8.4.so after it.

--Brian

--
Brian S. Bevins, PE
Computer Scientist / Mechanical Engineer
Thomas Jefferson National Accelerator Facility

    "Nothing in all the world is more dangerous than
     sincere ignorance and conscientious stupidity."
                                    --Martin Luther King Jr.







Reply via email to