GCC 编译 - __stack_chk_fail@GLIBC_2.4 符号来自哪里?

GCC 编译 - __stack_chk_fail@GLIBC_2.4 符号来自哪里?

我使用的是 GCC 4.7.2开发工具集CentOS 5 上的软件包(CentOS 5 是因为我们需要与旧版 Linux 兼容,GCC 4.7 是因为它比 4.4 优化得更好)。

有一个符号阻止我的二进制文件在 RHEL4 上运行:__stack_chk_fail@GLIBC_2.4。它仅包含在某些 C++ 程序中,并且该-fno-stack-protector标志没有帮助。

这是重现问题的最小程序(但使用相同的stdio.h方法):

#include <iostream>
int main(int argc, char *argv[]) {
    for(int i=0; i < argc; i++)
        std::cout << " " << argv[i];
    return 0;
}

当使用优化 ( -O/ -O2) 编译时,它会引用__stack_chk_fail

$ g++ -fno-stack-protector -O2 foo.cc
$ readelf -s a.out | grep chk
    15: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __stack_chk_fail@GLIBC_2.4 (5)
   105: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __stack_chk_fail@@GLIBC_2

知道为什么这个符号出现在这里以及如何摆脱它吗?

以防万一,完整readelf输出并且gcc -v这里

编辑:此问题可能特定于 Red Hat Developer Toolset 1.1。默认 CentOS 编译器__stack_chk_fail不被引用。

答案1

这个符号来自libstdc++_nonshared.a.

与发行版中的 GCC 不同,devtoolset 中的 GCC 具有 libstdc++ 的非共享部分。 GCC 4.7 中的 libstdc++.so 是一个链接器脚本,它使用 GCC 4.1 中的 libstdc++ 和静态链接的额外函数:

$ cat /opt/centos/devtoolset-1.1/root/usr/lib/gcc/i386-CentOS-linux/4.7.2/libstdc++.so
/* GNU ld script
   Use the shared library, but some functions are only in
   the static library, so try that secondarily.  */
OUTPUT_FORMAT(elf32-i386)
INPUT ( /usr/lib/libstdc++.so.6 -lstdc++_nonshared )

使用禁用的堆栈保护器重新编译后,libstdc++_nonshared.a最终程序可以在 RHEL4 上运行。

答案2

它与 GLibC 一起提供。针对较旧的 GLibC 进行构建。

您可以告诉 GCC 4.7 发出优化的汇编代码,然后在旧系统上汇编和链接它

相关内容