GLIBCXX_USE_CXX11_ABI

代码在centos7环境上编译可以跑.但是其他同事在测试.刚好手头上有一台rehl8的环境是空闲的.

在rehl8上编译是成功的.但是程序运行就会崩溃.

日志里面可以看到

fusionsphere/so/libfc.so: undefined symbol: _ZN16CFusionSphereSDK10InitialSDKEPFviPKczEP23CFusionSphereDebugLevelRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESD_SD_

可是程序明明是通过编译没有出错,甚至没有泛型这样的rtti. 明显也不是访问错误内存的段错误.

使用ldd -r查看so,发现确实有两个undefined symbol.并且都和libFusionSphere_sdk.so相关.

[root@node1 so]# ldd -r libfc.so
-bash: cd: so: No such file or directory
    linux-vdso.so.1 (0x00007ffd6aaea000)
    libFusionSphere_sdk.so => ./libFusionSphere_sdk.so (0x00007f0feb61b000)
    libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007f0feb286000)
    libm.so.6 => /lib64/libm.so.6 (0x00007f0feaf04000)
    libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f0feacec000)
    libc.so.6 => /lib64/libc.so.6 (0x00007f0fea92a000)
    libssl.so.1.0.0 => ./libssl.so.1.0.0 (0x00007f0fea6b8000)
    libcrypto.so.1.0.0 => ./libcrypto.so.1.0.0 (0x00007f0fea281000)
    libsecurec.so => ./libsecurec.so (0x00007f0fea06f000)
    libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f0fe9e4f000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f0feba56000)
    libdl.so.2 => /lib64/libdl.so.2 (0x00007f0fe9c4b000)
undefined symbol: _ZN16CFusionSphereSDK10InitialSDKEPFviPKczEP23CFusionSphereDebugLevelRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESD_SD_ (./libfc.so)
undefined symbol: _ZN16CFusionSphereSDK17verifyLUNAttachedERKNSt7__cxx114listINS0_12basic_stringIcSt11char_traitsIcESaIcEEESaIS6_EEE    (./libfc.so)
[root@node1 sdk]# c++filt _ZN16CFusionSphereSDK10InitialSDKEPFviPKczEP23CFusionSphereDebugLevelRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESD_SD_
CFusionSphereSDK::InitialSDK(void (*)(int, char const*, ...), CFusionSphereDebugLevel*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)

利用`c++filt` (Demangle C++ and Java symbols.) 将C++ ABI标识符(C++ ABI identifier)转换成C++源程序标识符(original C++ source identifier)

[root@node1 sdk]# c++filt _ZN16CFusionSphereSDK17verifyLUNAttachedERKNSt7__cxx114listINS0_12basic_stringIcSt11char_traitsIcESaIcEEESaIS6_EEE
CFusionSphereSDK::verifyLUNAttached(std::__cxx11::list<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&)

可以看出来无法识别的symbols,都是第三方库接口涵数.库是比较老的.会不会因为兼容问题导致的.查一下果然是.
In the GCC 5.1 release libstdc++ introduced a new library ABI that includes new implementations of std::string and std::list.

GCC5.1 提供 -D_GLIBCXX_USE_CXX11_ABI来控制编译器到底链接哪一个libstdc++.so,

-D_GLIBCXX_USE_CXX11_ABI=0 链接旧版库
-D_GLIBCXX_USE_CXX11_ABI=1 链接新版库

果然增加了这个宏定义就能跑了.

Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.