--- Begin Message ---
- To: pygtk@daa.com.au
- Cc: 38138@bugs.debian.org
- Subject: Themes and python-gtk
- From: Torsten Landschoff <torsten>
- Date: Tue, 25 May 1999 20:24:43 +0200
- Message-id: <19990525202442.A23082@wormhole.galaxy>
Hi *,
I am sorry I did not write to this list earlier. I did some investigation on
the themes-related bug in PyGTK and came to the conclusion that it is not
a bug in pygtk. In fact the theme engines are at fault.
You need some background information to understand the problem. If you are
familar with the scopes of symbols in the dynamic linker you can skip this
section.
Okay - here is how loading an object works:
1. the object requested is mapped into the address space of the program.
(if this wasn't done already)
2. the objects required by this object are mapped
3. the symbols are resolved
We hit the wall at step three - the dynamic linker can not resolve the symbols
of the theme engine (in my case it is libpixmap.so). This is from the debugging
output of the dynamic linker (enabled with export LD_DEBUG=symbols; export
LD_DEBUG_OUTPUT=/tmp/foo):
01507: symbol=gdk_display; lookup in file=python
01507: symbol=gdk_display; lookup in file=/usr/lib/libpython1.5.so.0.0
01507: symbol=gdk_display; lookup in file=/lib/libdl.so.2
01507: symbol=gdk_display; lookup in file=/lib/libpthread.so.0
01507: symbol=gdk_display; lookup in file=/lib/libm.so.6
01507: symbol=gdk_display; lookup in file=/lib/libc.so.6
01507: symbol=gdk_display; lookup in file=/lib/ld-linux.so.2
01507: symbol=gdk_display; lookup in
file=/usr/lib/gtk/themes/engines/libpixmap.so
01507: symbol=gdk_display; lookup in file=/usr/lib/libgdk_imlib.so.1
01507: symbol=gdk_display; lookup in file=/usr/lib/libgmodule-1.2.so.0
01507: symbol=gdk_display; lookup in file=/lib/libdl.so.2
01507: symbol=gdk_display; lookup in file=/usr/X11R6/lib/libXi.so.6
01507: symbol=gdk_display; lookup in file=/usr/X11R6/lib/libXext.so.6
01507: symbol=gdk_display; lookup in file=/usr/X11R6/lib/libX11.so.6
01507: symbol=gdk_display; lookup in file=/lib/libm.so.6
01507: symbol=gdk_display; lookup in file=/lib/libc.so.6
01507: symbol=gdk_display; lookup in file=/usr/lib/libglib-1.2.so.0
01507: symbol=gdk_display; lookup in file=/lib/ld-linux.so.2
As you can see he does not try to load the symbols from libgtk.so. Why?
So where does ld.so seek for symbols?
1. it searches the global scope
2. it searches the object itself
3. it searches the dependencies of the object the symbol is needed in.
What is in the global scope? dl-deps.c from the libc6 source says:
/* Now that all this succeeded put the objects in the global scope if
this is necessary. We put the original object and all the dependencies
in the global scope. If an object is already loaded and not in the
global scope we promote it. */
This is a bit ambiguous. In fact the original object (python) and its
dependencies are put into the global scope. So let's construct the searchlist
for libpixmap.so:
1. the global scope
python - the object itself
torsten@pulsar:~ $ ldd /usr/bin/python - the dependencies
libpython1.5.so.0.0 => /usr/lib/libpython1.5.so.0.0 (0x40005000)
libdl.so.2 => /lib/libdl.so.2 (0x4006f000)
libpthread.so.0 => /lib/libpthread.so.0 (0x40073000)
libm.so.6 => /lib/libm.so.6 (0x40084000)
libc.so.6 => /lib/libc.so.6 (0x400a1000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x00000000)
2. the object itself
libpixmap.so
3. its dependencies
torsten@pulsar:~ $ ldd /usr/lib/gtk/themes/engines/libpixmap.so
libgdk_imlib.so.1 => /usr/lib/libgdk_imlib.so.1 (0x4000e000)
libgmodule-1.2.so.0 => /usr/lib/libgmodule-1.2.so.0 (0x4003c000)
libdl.so.2 => /lib/libdl.so.2 (0x40040000)
libXi.so.6 => /usr/X11R6/lib/libXi.so.6 (0x40043000)
libXext.so.6 => /usr/X11R6/lib/libXext.so.6 (0x4004b000)
libX11.so.6 => /usr/X11R6/lib/libX11.so.6 (0x40057000)
libm.so.6 => /lib/libm.so.6 (0x400fd000)
libc.so.6 => /lib/libc.so.6 (0x40293000)
libglib-1.2.so.0 => /usr/lib/libglib-1.2.so.0 (0x40271000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x00000000)
Now compare these lists - the debug output and this list correspond exactly.
Okay, so what can we do about this? Remember this:
Where does ld.so seek for symbols?
1. it searches the global scope
2. it searches the object itself
3. it searches the dependencies of the object the symbol is needed in.
So we could put the libgtk and libgdk in (1), (2) or (3). Of course (2) will
not work - we do not want to statically link libpixmap against libg[dt]k.
What can we do about (1) - no problem. We can manually put libgdk and libgtk
in there. We only need to do dlopen("libgtk.so", RTLD_LAZY|RTLD_GLOBAL). The
problem is that we have to sync this with the lib linked against _gtkmodule.so
- at least it has to have the same soname as the dynamic linker will catch
this. Of course we need libgdk.so also.
Fine. But the simplest way to get out of this is: simply use the dependency
information of libpixmap.so to put libgtk.so and libgdk.so in (3). This only
requires a simple patch to the Makefile of the theme engines:
torsten@pulsar:~/test/gtk-engines-thinice-1.0.1 $ diff -u Makefile.am
Makefile.am.new
--- Makefile.am Tue May 25 20:12:46 1999
+++ Makefile.am.new Tue May 25 20:12:40 1999
@@ -9,4 +9,5 @@
thinice_theme_main.c \
thinice_theme.h
libthinice_la_LDFLAGS = -export-dynamic
+libthinice_la_LIBADD = $(GTK_LIBS)
EXTRA_DIST = autogen.sh
After this patch the thinice engine works with no problem on my system. Even
perl-gtk starts working. Before it had the same problem.
Conclusion: Let's talk to the engines authors and tell them how to fix their
packages.
Thanks
Torsten
PS: This is Cc'ed to a Debian bugreport. Please keep the Cc when answering to
this mail.
--- End Message ---