我的问题涉及Python,Qt,PyQt和其他东西,但问题实际上是Linux的ld.so
实际上是如何工作的。
问题
如果一个程序加载了两个不同的共享库,它们都有相同的入口点名称(即它们都定义了一个具有相同名称和签名的函数),它怎么能告诉它调用哪个版本?
我的问题
我有一个第三方专有的Linux应用程序,它是用C ++编写的(虽然原始语言无关紧要),并且它与Qt3.3动态链接。该应用程序嵌入了一个python解释器,可用于为其编写脚本。
您甚至可以使用应用程序的嵌入式python而不是原始的使用如下命令:
/path/to/the/program/python
它显示以下内容:
Python 2.7.1 (r271:86832, Sep 16 2011, 18:16:32)
[GCC 4.1.2 20080704 (Red Hat 4.1.2-46)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>
使用gcc 4.1.2我已经从源代码构建并安装了PyQt4,而不是系统所拥有的Qt4库。我相信构建是成功的,因为我可以使用:
运行一个小的PyQt4应用程序/path/to/the/program/python mypyqtapp.py
但是,如果我使用GUI加载程序并加载相同的脚本,它会在第一次PyQt4
调用时崩溃,这是QApplication
类的实例化。
由于python环境是相同的,我怀疑它可能是Qt3和Qt4之间的某种共享库冲突。但是,命令strace -e trace=file
表明python正在定位并加载正确的Qt4库。
所以,我的问题是,如果一个程序加载两个共享不同的库来定义相同的函数,它如何知道它正在调用正确的函数? linux加载程序ld.so
是否以某种方式限定了带有文件名的入口点?我怀疑我的问题可能就在那里,应用程序最终加载了两个不同的QApplication
实例并且它调用了错误的实例,但ld.so
内部的实际工作方式让我感到厌烦。
也许我的问题是由完全不同的东西引起的。
谢谢。
答案 0 :(得分:1)
仅在链接(ld)阶段检测到冲突符号,加载程序(ld-linux.so)不检查冲突符号。
当多个库提供重复的符号时,使用首先加载的符号。
实际上有人可以利用这个功能。通过提供LD_PRELOAD = overwrite.so,overwrite.so可以覆盖程序所需的任何函数。