6

I am debugging a python program based on pygtk and I want to make sure that the program is using the right shared library.

pygtk is a GTK+ wrapper for python. I have already compiled GTK+ using jhbuild tool and I want to make sure that the python script which I am debugging uses the compiled library from jhbuild.

One would import gtk and pygtk like this:

import gtk
import pygtk
print(gtk.__file__)
# /usr/lib/python2.7/site-packages/gtk-2.0/gtk/__init__.pyc
print(pygtk.__file__)
# /usr/lib/python2.7/site-packages/pygtk.pyc

For example I can show a window using gtk:

w = gtk.Window()
w.show()

This will draw a window on the screen using gtk. However I don't know which shared object is be used. I have many versions installed and I need to find the culprit.

mehdix
  • 4,984
  • 1
  • 28
  • 36

2 Answers2

13

I assuming you are using Linux, if the module is dynamically loaded, you could find it out with lsof(8):

$ python
>>> import os
>>> os.getpid()
29982

$ lsof -p 29982 > before

then back to python, import the module:

>>> import gtk
$ lsof -p 29982 > after
$ diff <(awk '{print $NF}' after) <(awk '{print $NF}' before)

yields:

< /usr/lib/x86_64-linux-gnu/libgdk_pixbuf-2.0.so.0.3200.2
< /usr/lib/x86_64-linux-gnu/libcairo.so.2.11400.6
< /usr/lib/x86_64-linux-gnu/libgdk-x11-2.0.so.0.2400.30
< /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0.2400.30
< /usr/lib/python2.7/dist-packages/gtk-2.0/gtk/_gtk.so
...
georgexsh
  • 15,984
  • 2
  • 37
  • 62
  • The output shows the loaded so files, it would be great however to see the dependencies, i.e. which so has lead to other ones. Anyway, I see that in `jhbuild` env, my local compiled shared objects are being loaded. – mehdix Nov 17 '17 at 13:05
  • with `strace` I was unable to see the list of so files. – mehdix Nov 17 '17 at 13:07
  • unfortunately, you need filter the output of strace by yourself to get the result you want. – georgexsh Nov 17 '17 at 13:08
5

Whenever I want to know who uses what, strace is my best friend. So strace -ff -olog -eopen python yourscript.py gives you the list of all the files opened in this process and its children. It stores the files in log.* files, the extension being the pid of the process. Then you just grep -i gtk log.* | grep py and look at the results.

However, I wonder why you're using pygtk (outdated and deprecated, last release in 2011) that only works with GTK+ 2. That's useful only if you're debugging a very old program with a very old jhbuild moduleset that still uses GTK+ 2.

If you can, you should strive to use pygobject and GTK+ 3.

https://python-gtk-3-tutorial.readthedocs.org/en/latest/index.html

liberforce
  • 11,189
  • 37
  • 48
  • `strace` is very interesting indeed! However it only shows directly open files. In this case it does not log any shared objects. I already know that importing `gtk` will import at least `_gtk.so` from the package folder. Moreover, the program in question is Zim, and I had no idea about `pygtk` being old, just learned about it yesterday. I also asked people on `gtk+` irc and realized the correct approach is upgrading Zim to GTK+3. – mehdix Nov 17 '17 at 12:44
  • 1
    I upvoted your answer because I learned about `strace` and I'm accepting the other answer because it shows me the loaded shared objects. – mehdix Nov 17 '17 at 13:06
  • 1
    The process has to load the shared objects, so they appear indeed in `strace` logs. See what a `strace -eopen ls` returns and you'll see. Replace the filter I gave in my answer by `grep '\.so' log.* | sort -u` to see the shared objects. – liberforce Nov 17 '17 at 13:44
  • I try `strace -ff -eopen python2 -c "import gtk;print(gtk._gtk)"` and there is no shared object listed in the output. Even though it is loaded (`_gtk`). Perhaps I'm using wrong flags? – mehdix Nov 17 '17 at 14:00
  • Or perhaps you needs glasses :). `strace -ff -eopen python2 -c "import gtk" 2>&1 | grep _gtk.so` returns 2 lines on my system: `open("/usr/lib/python2.7/dist-packages/gtk-2.0/gtk/_gtk.so", O_RDONLY) = 4` and `open("/usr/lib/python2.7/dist-packages/gtk-2.0/gtk/_gtk.so", O_RDONLY|O_CLOEXEC) = 5`. The shared objects **must** be loaded for the code to be executed, so I can't see a reason why it wouldn't work on your system. That's computer science, not magic: you can't execute something you didn't load first. – liberforce Nov 20 '17 at 09:47
  • It returns nothing on my system. – mehdix Nov 20 '17 at 15:06
  • There a zillion things that are different on your system and mine. FYI, here is the output on my computer: https://pastebin.com/7CCqbSXU – mehdix Nov 20 '17 at 15:13
  • Indeed, you have a problem. Such a command should flood you with messages. The same command throws one thousand lines for me, while yours only is looking for translation files. Try `strace` with simple commands like `ls`. What operating system are you using? How did you install `python`/`strace`? – liberforce Nov 21 '17 at 09:39
  • I know this is an ancient thread, but my current Linux box uses `openat` (not `open`) to open the shared libraries. (I simply traced everything and then looked through it all.) So you want `-eopenat` instead of `-eopen`. – AnthonyFoiani Jun 04 '23 at 07:25