如何检测多重定义的符号

How to detect multiply defined symbols

本文关键字:定义 符号 何检测 检测      更新时间:2023-10-16

我有一个常见的场景:可执行文件的一些源文件依赖于一些标准库和一些用户库。所有的用户库都静态地链接到可执行文件中,而标准库则动态地链接到它

问题:我相信我在我的完整包中已经有了多重定义的符号(可执行文件已经包括用户库代码+共享标准库)。链接器显然对此有深入的了解,但据我所知,除非遇到多个强命名符号,否则链接器不会抱怨。我担心的是,当我将代码从solaris8/sparc平台转移到solaris10/sparc平台时,一些标准的unix函数已经在用户库中实现,这会导致应用程序在运行时崩溃。请注意,该应用程序在solaris 8/sparc平台中运行良好

我一直面临着奇怪的问题,这让我相信这可能是的来源

  1. 修改一个库中的一个变量就是更改另一个库的另一个变量的值
  2. Solaris 8-10:host2ip转换问题

我需要什么:

  1. 有没有一种方法可以轻松列出所有多重定义的符号
  2. 有没有一种方法可以轻松地列出来自用户库的所有多重定义符号
  3. 你们认为问题#1可能是由链接问题引起的,还是觉得这可能是其他问题的征兆

第1版:从那时起,我知道在使用ld生成映射文件时,它有一段多重定义的符号,我正在通过它来查找看起来像标准库调用的名称。对于不知道的人来说,只有当链接器找到多个具有相同名称的符号并且这些名称是强名称时,链接器才会无法链接。

您可以在编译器(实际上是链接器)设置中打开MAP文件生成,并在映射文件中查找与您关心的UNIX系统函数匹配的符号。您可能需要编写一个脚本来实现自动化,但这将是一个很好的起点。命令行开关可能是-map或类似的东西,这将取决于您使用的编译器/链接器。

实际发生的问题是:这个库(我们称之为lib1)有一个类似下面的数组

#define ARRAY_SIZE 1024
SomeStruct* global_array[ARRAY_SIZE];

这个数组由我的另一个库(让我们称之为lib2)使用,而我的应用程序使用它的外部声明来使用它

在编译lib2时(或者应用程序不确定),我们根本没有定义ARRAY_SIZE。这以某种方式导致lib2(或应用程序)的编译器错误计算了global_array的大小,从而导致它在已经分配给global_arrays的位置为其他变量分配内存。

通过在编译我的库和应用程序时再次定义ARRAY_SIZE,一切都开始正常运行。我不完全理解是什么原因导致了这个问题,以及为什么它得到了解决,因为数组的外部声明不包含大小。此外,如果库真的使用了MACRO ARRAY_SIZE,那么为什么编译不会失败呢?此外,还有一种可能性是,用于定义的名称是标准名称(实际字符串为FD_SETSIZE)

我最初对链接器的直觉是错误的。