【问题标题】:How to find shared library used by a python module?如何找到python模块使用的共享库?
【发布时间】:2018-04-30 08:44:56
【问题描述】:

我正在调试一个基于pygtk 的python 程序,我想确保该程序使用的是正确的共享库。

pygtk 是 python 的 GTK+ 包装器。我已经使用jhbuild 工具编译了GTK+,我想确保我正在调试的python 脚本使用来自jhbuild 的编译库。

可以像这样导入gtkpygtk

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

例如,我可以使用 gtk 显示一个窗口:

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

这将使用 gtk 在屏幕上绘制一个窗口。但是我不知道使用了哪个共享对象。我安装了很多版本,我需要找到罪魁祸首。

【问题讨论】:

  • 你试过使用ldd了吗?
  • 不,我没有。使用ldd 可以找出python 脚本正在使用哪个库吗?实际上python是如何决定使用哪个共享对象的?
  • 它没有。加载器会。
  • 也试试这个:) https://lldb.llvm.org/scripting.html

标签: python gtk shared-libraries pygtk jhbuild


【解决方案1】:

我假设你使用的是 Linux,如果模块是动态加载的,你可以通过lsof(8) 找到它:

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

$ lsof -p 29982 > before

然后回到python,导入模块:

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

产量:

< /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
...

【讨论】:

  • 输出显示了加载的so文件,但是看到依赖关系会很棒,即它导致了其他文件。无论如何,我看到在jhbuild env 中,正在加载我本地编译的共享对象。
  • with strace 我无法看到so文件的列表。
  • 很遗憾,你需要自己过滤 strace 的输出才能得到你想要的结果。
【解决方案2】:

每当我想知道谁使用什么时,strace 是我最好的朋友。 所以strace -ff -olog -eopen python yourscript.py 为您提供了在此进程中打开的所有文件及其子进程的列表。它将文件存储在log.* 文件中,扩展名是进程的pid。然后你只需grep -i gtk log.* | grep py 并查看结果。

但是,我想知道您为什么要使用仅适用于 GTK+ 2 的 pygtk(已过时且已弃用,2011 年的最后一个版本)。仅当您正在调试一个非常旧的时它才有用非常旧 jhbuild 模块集的程序仍然使用 GTK+ 2。

如果可以,您应该努力使用pygobject 和 GTK+ 3。

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

【讨论】:

  • strace 确实很有趣!但是它只显示直接打开的文件。在这种情况下,它不会记录任何共享对象。我已经知道导入gtk 将至少从包文件夹中导入_gtk.so。而且,问题的程序是Zim,我不知道pygtk老了,昨天才知道。我还在gtk+irc 上询问了人们,并意识到正确的方法是将 Zim 升级到 GTK+3。
  • 我赞成你的答案,因为我了解了strace,我接受了另一个答案,因为它显示了加载的共享对象。
  • 进程必须加载共享对象,所以它们确实出现在strace日志中。看看 strace -eopen ls 返回什么,你就会看到。将我在回答中给出的过滤器替换为grep '\.so' log.* | sort -u 以查看共享对象。
  • 我尝试strace -ff -eopen python2 -c "import gtk;print(gtk._gtk)" 并且输出中没有列出共享对象。即使它已加载 (_gtk)。也许我使用了错误的标志?
  • 或者您可能需要眼镜 :)。 strace -ff -eopen python2 -c "import gtk" 2&gt;&amp;1 | grep _gtk.so 在我的系统上返回 2 行:open("/usr/lib/python2.7/dist-packages/gtk-2.0/gtk/_gtk.so", O_RDONLY) = 4open("/usr/lib/python2.7/dist-packages/gtk-2.0/gtk/_gtk.so", O_RDONLY|O_CLOEXEC) = 5必须加载共享对象才能执行代码,所以我看不出它不能在您的系统上运行的原因。那是计算机科学,而不是魔法:你不能执行你没有先加载的东西。
猜你喜欢
  • 2018-09-16
  • 2014-07-31
  • 1970-01-01
  • 2014-11-17
  • 2019-03-03
  • 1970-01-01
  • 1970-01-01
  • 2022-11-02
  • 2022-12-03
相关资源
最近更新 更多