0

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

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

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

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

我需要的:

  1. 有没有办法轻松列出所有多重定义的符号?
  2. 有没有办法轻松列出源自用户库的所有多重定义符号?
  3. 你们认为问题 #1 可能是由链接问题引起的,还是您认为这可能是其他问题的迹象?

Edit1:从那时起,我知道在使用 ld 生成地图文件时,它有一段多重定义的符号,我将通过它来查找看起来像标准库调用的名称。对于不知道的人,链接器只有在找到多个具有相同名称且名称是强名称的符号时才会链接失败。

4

2 回答 2

0

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

于 2012-09-18T21:47:39.033 回答
0

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

#define ARRAY_SIZE 1024
SomeStruct* global_array[ARRAY_SIZE];

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

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

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

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

于 2012-09-24T15:51:50.560 回答