如何检测多重定义的符号

时间:2012-09-18 21:23:44

标签: c++ unix linker porting

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

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

中运行良好

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

  1. 修改一个库中的一个变量正在更改另一个库中另一个变量的值
  2. Solaris 8-10: host2ip conversion problems
  3. 我需要什么:

    1. 有没有办法轻松列出所有多重定义的符号?
    2. 有没有办法轻松列出源自用户库的所有多重定义符号?
    3. 你们是否认为问题#1可能是由链接问题引起的,或者您认为这可能是其他问题的迹象?
    4. EDIT1: 从那以后我知道在使用ld生成map文件时,它有一个多重定义的符号部分,我将通过它来查找看起来像标准库调用的名称。对于不知道的人,如果链接器找到多个具有相同名称的符号并且名称是强名称,则链接器将无法链接。

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

发生的实际问题是: 库(我们称之为lib1)有一个如下所示的数组

#define ARRAY_SIZE 1024
SomeStruct* global_array[ARRAY_SIZE];

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

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

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

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