Vadim Konovalov wrote:
On Thursday 29 May 2008 22:40:11 Brian Bevins wrote:
> Hi Jeff,
>
> I'm pretty sure stubs aren't the problem since neither BLT nor the
> perl Tcl module are compiled against the stub libraries. They are
> compiled against exactly the same version of libtcl8.4.so.
>
> When I examine the perl Tcl module library, I see a dependence on
> libtcl8.4.so:
>
> ldd
>
<blah>/perl/5.8.2/lib/site_perl/5.8.2/i686-linux-thread-multi/auto/Tcl/Tcl.
> so libtcl8.4.so => <blah>/tcl/8.4/lib/libtcl8.4.so (0x00b62000)
> libc.so.6 => /lib/tls/libc.so.6 (0x00577000) libdl.so.2 =>
> /lib/libdl.so.2 (0x00e83000) libpthread.so.0 =>
> /lib/tls/libpthread.so.0 (0x00708000) libm.so.6 =>
> /lib/tls/libm.so.6 (0x00144000) /lib/ld-linux.so.2 (0x00785000)
>
> So as I understand it, when perl loads Tcl.so, that should force
> the dynamic loader to also load libtcl8.4.so. When I look at our
> BLT library:
>
> ldd <blah>/tcl/8.4/lib/libBLT24.so libc.so.6 => /lib/tls/libc.so.6
> (0x0050d000) /lib/ld-linux.so.2 (0x00785000)
>
> It does not show any dependence on libtcl8.4.so (but I am certain
> that this is the version of Tcl against which it was compiled).
>
> However, when perl tries to load BLT inside the Tcl module, there
> are unresolved symbols. This script:
>
> #!<blah>/perl/5.8.2/bin/perl use Tcl::Tk; my $m =
> Tcl::Tk::MainWindow->new(); my $i = $m->interp(); $i->Eval('package
> require BLT');
>
> gives this error:
>
> ERROR: couldn't load file "<blah>/tcl/8.4/lib/libBLT24.so":
> <blah>/tcl/8.4/lib/libBLT24.so: undefined symbol: TclpRealloc
>
> If I use just Tcl rather than Tcl::Tk I get the same error. The
> missing symbol TclpRealloc is found in libtcl8.4.so:
>
> nm <blah>/tcl/8.4/lib/libtcl8.4.so | grep TclpRealloc 0007ade8 T
> TclpRealloc
>
> So my conclusion is that libBLT24.so needs to have libtcl8.4.so
> loaded even though it doesn't ask for it explicitly. Perl should be
> loading libtcl8.4.so since it is asked for by perl's Tcl.so.
> However, for some reason when I "use Tcl" from perl, libtcl8.4.so
> does not get loaded, and hence it is not there when libBLT24.so
> needs it.
>
> I think this confirmed by the fact that everything works if I force
> the loading of libtcl8.4.so like so:
>
> #!<blah>/perl/5.8.2/bin/perl use Tcl::Tk; my $m =
> Tcl::Tk::MainWindow->new();
IMO at the moment of this line both libtcl84.so and libtk84.so
already loaded, otherwise you'll get an error.
I agree. libtcl8.4.so and libtk8.4.so should be loaded at this point.
Otherwise I shouldn't be able to open create a toplevel MainWindow.
But I think that it is different than
/usr/csite/pubtools/tcl/8.4/lib/libtcl8.4.so
I'm trying to understand how that can be so, since
"/usr/csite/pubtools/tcl/8.4/lib/libtcl8.4.so" is the only copy of
libtcl8.4.so that exists on the system. Really.
> my $i = $m->interp(); $i->Eval('load
> /usr/csite/pubtools/tcl/8.4/lib/libtcl8.4.so Tcl');
> $i->Eval('package require BLT');
>
> Then I get no error. What I don't understand is why I have to do
> that. Perl should be loading libtcl8.4.so automatically, but for
> some reason it doesn't.
I think perl do load libtcl84..., but then you load different
libtcl84 library which have another missing symbol, i.e resolving
goes okay, but you do get a mess of some kind.
You should try isolate your libtcl-s and try to work with only
/usr/csite/pubtools/tcl/8.4/lib/libtcl8.4.so one.
As far as I can tell, using every method I can think of, that is the
only library I am using. I created the perl Tcl package with:
perl Makefile.PL --tclsh=/usr/csite/pubtools/tcl/8.4/bin/tclsh8.4
--library=/usr/csite/pubtools/tcl/8.4/lib/libtcl8.4.so --nousestubs
And when I look at the resulting Tcl.so object in the perl library, I
see that it is finding /usr/csite/pubtools/tcl/8.4:
ldd
<blah>/perl/5.8.2/lib/site_perl/5.8.2/i686-linux-thread-multi/auto/Tcl/Tcl.so
libtcl8.4.so => <blah>/tcl/8.4/lib/libtcl8.4.so (0x00b62000) libc.so.6 =>
/lib/tls/libc.so.6 (0x00577000)
libdl.so.2 => /lib/libdl.so.2 (0x00e83000)
libpthread.so.0 => /lib/tls/libpthread.so.0 (0x00708000)
libm.so.6 => /lib/tls/libm.so.6 (0x00144000)
/lib/ld-linux.so.2 (0x00785000)
I know that that is the Tcl.so that perl is loading because when I
rename it, perl cannot load Tcl. And I know that that Tcl.so is using
/usr/csite/pubtools/tcl/8.4/lib/libtcl8.4.so from the output of ldd
above. (I have replaced /usr/csite/pubtools with <blah> for brevity.)
So when I try to include BLT, perl behaves as though
/usr/csite/pubtools/tcl/8.4/lib/libtcl8.4.so is not loaded, but it must
be. It's the only version available, and without it everything should
fail, not just BLT.
> Is there any way to get perl to tell me exactly what libraries have
> been loaded? In Tcl I would use "info loaded" for this purpose.
dynaloader tracks loaded libraries internally, it do not track any
shared libraries that were loaded by library that it loaded
perl -MTcl::Tk -lwe 'print join " ",keys %{DynaLoader::},";;
",qq/@DynaLoader::dl_shared_objects/'
dl_require_symbols dl_error dl_install_xsub dl_modules dl_find_symbol
boot_DynaLoader bootstrap dl_undef_symbols isa dl_load_file
dl_librefs dl_shared_objects dl_unload_file ;;
/opt/perl-5.8.8/lib/site_perl/5.8.8/i686-linux/auto/Tcl/Tcl.so
Alas, our perl is so old (5.8.2) that DynaLoader doesn't have a
dl_shared_objects member. The closest info I can get is:
perl -MTcl::Tk -lwe 'print join " ",keys %{DynaLoader::},";;
",qq/@DynaLoader::dl_modules/'
dl_require_symbols dl_error bootstrap_inherit dl_install_xsub dl_modules
dl_find_symbol boot_DynaLoader dl_undef_symbols dl_load_file dl_librefs
dl_unload_file ;; Tcl
And:
perl -MTcl::Tk -lwe 'print join " ",keys %{DynaLoader::},";;
",qq/@DynaLoader::dl_librefs/'
dl_require_symbols dl_error bootstrap_inherit dl_install_xsub dl_modules
dl_find_symbol boot_DynaLoader dl_undef_symbols dl_load_file dl_librefs
dl_unload_file ;; 140285888
So I cannot seem to get perl to absolutely verify where it is finding
Tcl.so, but as I said above I know which one it is using because if I
rename it, the Tcl package stops being able to load altogether.
I am very confused.
Thanks,
--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.