【问题标题】:Unix program using the wrong function from shared librariesUnix 程序使用了共享库中的错误函数
【发布时间】:2010-03-05 21:09:56
【问题描述】:

我正在重构一套旧实用程序并创建一个新服务器,该服务器将使用所有这些实用程序的通用代码来统一它们的功能并允许远程客户端进行外部访问。对于每个实用程序,我将获取服务器所需的代码并将其重构到共享库中,以便实用程序和服务器现在都链接到共享库。由于这些实用程序的前实现者做事的方式,他们几乎只是在需要创建新实用程序时复制和粘贴所有内容,因此有大量具有相同签名的函数(即 XML 解析器的回调)但是在里面做不同的事情。

当我运行经过重构以链接到共享代码的独立实用程序时,它们运行良好。当我尝试使用与给定实用程序具有相同功能的服务器时,服务器使用的是第一个链接的库中的代码,而不是它应该从中获取功能的库。

例如,我有设备 A、B、C 的 xml,这些设备由公共 xml 库解析,但每个设备都有自己的共享库 libA、libB、libC,供服务器使用。当我调用服务器为设备 C 发送 xml 时,它使用的是 libA 中的函数“HandleStartElement”,而不是 libC 中同名和签名的函数,即使共享库只在内部声明这些函数并且不要t 共享任何提及这些用于解析 xml 的内部回调的标头。

有人可以向我解释为什么它没有读取正确的功能,以及将来如何避免这种情况?

我的服务器生成文件具有以下用于编译主程序的标志:

-I../include -L../lib -lA -lB -lC

每个共享库几乎没有使用共享库的标志,并且没有使用 -fPIC。

【问题讨论】:

    标签: gcc shared-libraries unix


    【解决方案1】:

    当与-l 标志一起使用时,共享库应该像非共享库一样工作,特别是不支持存在多个具有相同名称的函数。你已经有点幸运了,服务器运行起来了。

    如果我正确理解您的问题,那么具有相同名称的函数不打算在共享库之外“看到”。共享库有一个“动态符号表”,其中列出了共享库导出和导入的符号。使用 GNU 工具,您可以使用 nm -D libfoo.so 查看其内容。传统的 Unix 链接器通过使用对象文件中的所有公共实体(即非static 函数和全局变量)来填充该符号表。您在这里想要的是对该符号表的更受控制的构造。如果您的代码使用 GNU 工具(例如,您在 Linux 上运行),那么您需要阅读 this article,尤其是第 2.2 节。小故事:ELF 格式支持您所追求的,并且有多种工具/方法可以实现它。

    但是,在您的位置上,我会使用一些基于 sed 的脚本来使用唯一名称重命名有问题的函数。对原始过度复制粘贴的一些报复行动也可能是有序的。

    您应该使用-fPIC。在某些架构上不对共享库使用-fPIC 是一个致命的错误。由于您的代码不会崩溃,我想您是在 x86 硬件上运行的。

    【讨论】:

    • 您确实正确地理解了这个问题,并且我确实希望对符号表进行更可控的构造。我实际上是从运行带有 2.6 内核的 Gentoo 的 x86 机器交叉编译到运行 2.4 内核的 PPC 405 嵌入式机器。我会阅读这篇文章,看看我是否可以操纵符号表的构造,否则我只需要重命名一堆废话。非常感谢。
    • 浏览文章。只需将我的内部模块函数重新声明为静态(我一开始就应该知道这样做)就足以防止它们在符号表中被公开访问。再次感谢您。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-25
    • 2010-11-13
    相关资源
    最近更新 更多