Unix程序使用共享库中的错误函数

时间:2010-03-05 21:09:56

标签: gcc shared-libraries unix

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

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

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

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

我的服务器makefile有以下标志用于编译主程序:

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

每个共享库旁边都没有使用共享库的标志,并且没有使用-fPIC。

1 个答案:

答案 0 :(得分:7)

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

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

但是,在您的位置,我会蓬勃发展一些基于sed的脚本,以使用唯一名称重命名违规函数。对原始过度复制贴纸的一些报复行动也可能是有序的。

您应该使用-fPIC。在某些体系结构上不使用-fPIC共享库是一个致命的错误。由于您的代码没有崩溃,我想您可以在x86硬件上运行。