单个静态对象库中的多个重复符号

Posted

技术标签:

【中文标题】单个静态对象库中的多个重复符号【英文标题】:Multiple duplicate symbols in a single static object library 【发布时间】:2017-02-20 06:59:33 【问题描述】:

为什么在同一个静态对象文件中有重复的符号?在实践中是什么意思?

在运行nm /lib64/libc.so.6 | cut -d' ' -f 3 | uniq -c | sort -rn 之后,它会查看文件中的符号并打印符号出现的次数。我得到以下输出。

 59 lock
 38 buffer
 15 free_mem
 15 __elf_set___libc_subfreeres_element_free_mem__
  2 __strftime_internal
  2 startp_initialized.9864
  2 startp_initialized.11643
  2 null
  2 nbits.11331

更新

00000000003c1b98 b lock
00000000003c1bb0 b lock
...
00000000003c2690 b lock
00000000003c1710 b buffer
00000000003c1718 b buffer
...
00000000003c1720 b buffer
00000000003bc768 d __elf_set___libc_subfreeres_element_free_mem__
...
00000000003bc770 d __elf_set___libc_subfreeres_element_free_mem__
00000000003bc778 d __elf_set___libc_subfreeres_element_free_mem__
...
00000000001899de r null
0000000000191e70 r null

更新 2(可能有帮助):

readelf -Ws /lib64/libc.so.6 | grep .*\ buffer$
Num:    Value           Size Type    Bind   Vis      Ndx Name
1277: 00000000003c1710     8 OBJECT  LOCAL  DEFAULT   35 buffer
1289: 00000000003c1718     8 OBJECT  LOCAL  DEFAULT   35 buffer
1293: 00000000003c1720     8 OBJECT  LOCAL  DEFAULT   35 buffer
1298: 00000000003c1728     8 OBJECT  LOCAL  DEFAULT   35 buffer
1319: 00000000003c1730     8 OBJECT  LOCAL  DEFAULT   35 buffer
...

【问题讨论】:

一些“重复”可能是一个定义(通常只有一个),另一个可能是对该单个定义的引用。您不知道这一点,因为您从 nm 输出中删除了该信息。 特别忘了过滤所有出现的外部引用 (U) 和周对象 (w, W, v, V)。这些是交叉引用而不是重复。 或者您看到的符号可能是static 全局符号?因此,即使存在重复,它们也不会发生冲突,因为它们是单个翻译单元的本地。但是,这些变量的 存储 必须放在某个地方,通常是在全局数据或 bss 段中。 “静态对象库”是一种奇怪的调用动态库的方式。 谢谢。我一直无法找到帮助辨别差异的文档。你有什么有用的资源可以涵盖这个主题吗? 【参考方案1】:

为什么同一个静态对象文件中会有重复的符号?

    你所谓的“静态对象文件”,别人称之为动态共享对象,简称共享库。 大多数共享库都链接自多个可重定位的目标文件。 在此类对象文件中包含static 数据并不罕见(此类数据具有内部链接,即可以从给定的对象文件中访问)。当您将多个此类文件链接到一个共享库中时,您最终会得到此类数据的多个实例。这些数据项的名称无关紧要——它们不会因内部链接而相互冲突,而且在不同的源文件中名称相同的情况并不少见。

例子:

// main.c
extern int foo();

static buffer[10];

int main()

  buffer[0] = 'a';
  foo();
  return buffer[0];


// foo.c
static buffer[5];
int foo()  buffer[0] = 'b'; return 0; 

当您将上面的两个文件链接在一起时,您将拥有两个完全独立的buffer 变量,程序的返回码将是0x61(ASCII 表示'a'),而不是 0x62,尽管 foo0x62 分配给 buffer[0]

【讨论】:

以上是关于单个静态对象库中的多个重复符号的主要内容,如果未能解决你的问题,请参考以下文章

隐藏在使用 Xcode 构建的静态库中的符号

Linux的nm命令查看动态库和静态库中的符号

与静态库中的 std::string 相关的 C++ 未定义符号

如何使静态库中的 gcc 链接强符号覆盖弱符号?

静态库中的未定义符号链接到动态库

静态库中的符号有时会链接到可执行文件,有时不会