使用gcc的外部版本编译时可执行文件损坏

时间:2014-04-03 03:18:46

标签: linux gcc g++ cross-compiling

我有一个非常简单的测试程序foo.cpp

#include <string>
int main(int argc, const char** argv)
{
    std::string A = "blah";
    std::string B = "bluh";
    return A==B;
}

我可以在我的Centos机器上构建并运行它:

> g++ --version
g++ (GCC) 4.4.7 20120313 (Red Hat 4.4.7-4)
Copyright (C) 2010 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

> g++ foo.cpp -o foo
> ./foo

现在,由于我不会涉及的原因,我正在尝试使用驻留在网络文件夹上的单独的gcc 4.4.0副本来构建代码。那个gcc是在很久以前由其他人建造的,目的是在Centos机器上使用它,并且在很多情况下它总体上运行良好。不幸的是,在这种情况下,它会产生损坏的代码:

> export PATH=/a/network/drive/gcc44/bin:$PATH
> g++ --version
g++ (GCC) 4.4.0
Copyright (C) 2009 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

> g++ foo.cpp -o foo
> ./foo
Segmentation fault (core dumped)

gdb提供以下跟踪:

Program terminated with signal 11, Segmentation fault.
#0  0x0000000000600f30 in memcmp@@GLIBC_2.2.5 ()
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.132.el6.x86_64 libgcc-4.4.7-4.el6.x86_64 libstdc++-4.4.7-4.el6.x86_64
(gdb) bt
#0  0x0000000000600f30 in memcmp@@GLIBC_2.2.5 ()
#1  0x00000000004009d0 in std::char_traits<char>::compare(char const*, char const*, unsigned long) ()
#2  0x0000000000400a3d in __gnu_cxx::__enable_if<std::__is_char<char>::__value, bool>::__type std::operator==<char>(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) ()
#3  0x000000000040092c in main ()

我尝试修改我的LD_LIBRARY_PATH以添加/a/network/drive/gcc44/lib,然后从那里加载libgcc_s.so.1和libstdc ++。so.6 - 但结果是相同的。在编译时添加这些库路径也没有区别。

如果我用return A.compare(B);替换最后一行代码,则没有分段错误。

我期待大多数答案都是“停止尝试做一些如此愚蠢的事情”,但这种情况在很大程度上超出了我的控制范围。我需要至少尝试使这项工作,如果它永远不会工作,那么我真的想了解这里到底出了什么问题。我想gcc的远程副本正在拾取一些对我主机上的libc副本无效的头文件,或类似的东西,但我很难将其固定下来。任何人都可以帮我解决这个问题吗?

修改

让我澄清在编译时和运行时发现的libstdc ++库。

为了弄清楚找到的编译时库,我使用g++ -v然后按顺序搜索所有-L路径libstdc++.so(让我知道这听起来是否错误)。

编译时:本地g ++

  • 找到/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../lib64/libstdc++.so.6
  • ...这是/usr/lib64/libstdc++.so -> libstdc++.so.6.0.13

编译时:远程g ++

  • 找到/a/network/drive/gcc44/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.4.0/../../../../lib64/libstdc++.so
  • ...这是/a/network/drive/gcc44/lib64/libstdc++.so -> libstdc++.so.6.0.11

运行时

/a/network/drive/gcc44/lib64上的LD_LIBRARY_PATH

> ldd foo
    linux-vdso.so.1 =>  (0x00007fff725ff000)
    libstdc++.so.6 => /a/network/drive/gcc44/lib64/libstdc++.so.6 (0x00007f9a0f3f3000)
    libm.so.6 => /lib64/libm.so.6 (0x0000003955200000)
    libgcc_s.so.1 => /a/network/drive/gcc44/lib64/libgcc_s.so.1 (0x00007f9a0f1dc000)
    libc.so.6 => /lib64/libc.so.6 (0x0000003954600000)
    /lib64/ld-linux-x86-64.so.2 (0x0000003953e00000)

/a/network/drive/gcc44/lib64上没有 LD_LIBRARY_PATH

> ldd foo
    linux-vdso.so.1 =>  (0x00007fff2ddff000)
    libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00000032c1e00000)
    libm.so.6 => /lib64/libm.so.6 (0x0000003955200000)
    libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00000032c3600000)
    libc.so.6 => /lib64/libc.so.6 (0x0000003954600000)
    /lib64/ld-linux-x86-64.so.2 (0x0000003953e00000)

在运行时,没有区别我使用的libstdc++:使用本地g ++构建的程序在两种情况下都有效,并且使用remove g ++ seg构建的程序出错在这两种情况下。

编辑2

进一步挖掘......添加-O3消除了问题,-B /usr/bin也是如此(即使用我主机的链接器)。使用远程4.4.0链接器,memcmp的地址完全映射到错误的偏移量 - 它位于可执行文件的数据部分。也许这个gcc版本或编译方式存在一个模糊的错误/问题......

0 个答案:

没有答案