【问题标题】:_end symbol disappears when linking to libcurl链接到 libcurl 时 _end 符号消失
【发布时间】:2012-11-11 02:41:33
【问题描述】:

在 Linux 上,D 运行时库依赖于_end 符号来确定 GC 根范围 (man 3 end),这实际上与 Boehm GC 所做的非常相似。但是,在 libcurl 中链接时,链接器不再找到该符号:

$ cat test.c
#include <stdio.h>

extern char _end[];
int main() {
    printf("%p\n", &_end);
    return 0;
}

$ gcc test.c # works
$ gcc test.c -lcurl
/usr/bin/ld: /tmp/ccOPtbEv.o: undefined reference to symbol '_end'
/usr/bin/ld: note: '_end' is defined in DSO /usr/lib/libssl.so.1.0.0 so try adding it to the linker command line
/usr/lib/libssl.so.1.0.0: could not read symbols: Invalid operation
collect2: error: ld returned 1 exit status

通过在 D 论坛上的快速搜索,libpq、libdw 和其他几个库似乎触发了同样的问题。知道这里会发生什么吗? test.c 甚至不依赖于 libcurl 中的符号。(Arch Linux x86_64、GCC 4.7.2、ld 2.23)

另外,请注意“尝试在 libssl 中链接”不是我正在寻找的答案,我想了解这里发生了什么。我正在尝试在我正在开发的编译器中解决此问题,因此您可以假设您基本熟悉链接过程的工作原理。

编辑:我对告诉用户只链接 libssl 不是特别满意的原因,...,明确地是 pkg-config --libs curlcurl-config --libs 等不包含此信息;因此,要求它会破坏构建系统。如果有人对确定数据(初始化和 BSS)段的边界有更好的想法,我很想知道。

编辑2:使用上面提到的工具链,end(不带下划线)似乎也被定义了,它不会触发问题。但是,仍然对它发生的原因感到困惑。

【问题讨论】:

  • gcc -Wall -g -o test test.c 使用gcc (Debian 4.4.5-8) 4.4.5 编译时不会出现警告或错误,无论是否使用-lcurl
  • @alk:感谢您提供的数据点。它发生在几个不同的 Arch Linux 安装和至少一个其他发行版上(forum.dlang.org/thread/j2424m$23e4$1@digitalmars.com - Arch 没有lib64)...

标签: linux linker gnu


【解决方案1】:

请注意,“尝试在 libssl 中链接”不是我要寻找的答案。

但很可能它实际上您正在寻找的答案。您的命令行全错。试试这个:

gcc test.c -lcurl

库和源的顺序,命令行上的对象很重要。

【讨论】:

  • 其实我建议gcc -Wall -g test.c -lcurl -o mytestprogram;养成使用-Wall 的习惯(以及用于调试目的的-g)并始终命名生成的二进制文件(a.out 是一个历史产物)。避免将程序命名为 test(这是一个内置的 shell,就像 cd 一样)。当您想在运行时访问程序的符号时,-rdynamic 也很有用。
  • 请重新阅读我的问题 - 我在问是否有人知道这里发生了什么因为测试甚至不依赖于 libcurl 中的符号,所以它应该'一点都不重要。现实中的问题发生在我正在处理的编译器上,并且那里的顺序显然是正确的。对于这个简化的测试用例,没关系。无论如何,我颠倒了顺序,以免误导人们仓促回答。
【解决方案2】:

_end 符号由链接器提供。它指向 bss 中的最后一个对象。但是,这只是一个约定,没有标准要求这样做。显然,您的工具链的链接器没有这样做。

【讨论】:

  • 如果未链接 libcurl,则您错过了符号存在的点。
猜你喜欢
  • 2011-05-09
  • 1970-01-01
  • 1970-01-01
  • 2012-07-19
  • 2023-04-08
  • 1970-01-01
  • 2015-04-22
  • 2018-04-17
  • 2021-07-13
相关资源
最近更新 更多