我有一个非常简单的测试程序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版本或编译方式存在一个模糊的错误/问题......