sinojelly / mockcpp

Two C/C++ testing tools, mockcpp and testngpp.
Apache License 2.0
66 stars 39 forks source link

TestXXX.so.so not found issue #21

Closed sinojelly closed 3 years ago

sinojelly commented 3 years ago

If use TestXXX.so in the command line, should remove .so in the name, ref to:https://github.com/sinojelly/test-ng-pp/commit/c443925394c7f1b0c45ec0cdb93dc1b71d6b6e1e

仅参考上面一句话可能无法解决。此问题背景: Linux上(A)已经编译了testngpp的二进制文件,直接放到另外一个Linux电脑(B)运行。 发现 TestXXX.so.so找不到。这可能有两个原因: 1、不支持 TestXXX.so 直接使用到命令行中,testngpp runner加载so的时候,再次追加一个 .so。(这种可能性小,因为B上直接源码编译testngpp,是可以运行的) 2、TestXXX.so 依赖于别的库,导致它加载失败,从而 testngpp runner 追加.so,再次尝试加载,还是失败。(这种情况就需要定位 TestXXX.so 为何加载失败,看起来它依赖于 libtestngpp.so 库,用的是本地路径,应该也是可以加载成功的)

如果命令行直接改成 TestXXX 名字,则看起来 so 加载成功了,但是 在 so 中找符号会失败: test suite "libadder-ut-TestAdder" can't be loaded : libadder-ut-TestAdder.so: undefined symbol: _ZNK7mockcpp23ChainableMockObjectBase7getNameEv

sinojelly commented 3 years ago

发现编译机器A上编译的 TestAdder.so 里面是:_ZNK7mockcpp23ChainableMockObjectBase7getNameB5cxx11Ev runner 也是 A 上编译的,在 A 上运行正常。 为何同样 runner 在 B 上运行,访问的 getName 函数名字改编方法不同了呢?

sinojelly commented 3 years ago

服务器 A 上 nm 结果: $ nm build/tests/ut/libadder-ut-TestAdder.so | grep ChainableMockObjectBase 0000000000080576 t _GLOBALsub_I_ChainableMockObjectBase.cpp 00000000000801ba T _ZN7mockcpp23ChainableMockObjectBase6verifyEv 0000000000080018 T _ZN7mockcpp23ChainableMockObjectBaseC1ERKNSt7cxx1112basic_stringIcSt11char_traitsIcESaIcEEE 00000000000800aa T ZN7mockcpp23ChainableMockObjectBaseC1ERKS0 0000000000080018 T _ZN7mockcpp23ChainableMockObjectBaseC2ERKNSt7cxx1112basic_stringIcSt11char_traitsIcESaIcEEE 00000000000800aa T ZN7mockcpp23ChainableMockObjectBaseC2ERKS0 0000000000080168 T _ZN7mockcpp23ChainableMockObjectBaseD0Ev 00000000000800f4 T _ZN7mockcpp23ChainableMockObjectBaseD1Ev 00000000000800f4 T _ZN7mockcpp23ChainableMockObjectBaseD2Ev 000000000007ffc0 T _ZN7mockcpp27ChainableMockObjectBaseImplC1ERKNSt7cxx1112basic_stringIcSt11char_traitsIcESaIcEEE 000000000007ffc0 T _ZN7mockcpp27ChainableMockObjectBaseImplC2ERKNSt7cxx1112basic_stringIcSt11char_traitsIcESaIcEEE 000000000008069c W _ZN7mockcpp27ChainableMockObjectBaseImplD1Ev 000000000008069c W _ZN7mockcpp27ChainableMockObjectBaseImplD2Ev 00000000000802d6 T _ZNK7mockcpp23ChainableMockObjectBase18getMethodContainerEv 000000000008018e T _ZNK7mockcpp23ChainableMockObjectBase19getInvocationMockerERKNSt7cxx1112basic_stringIcSt11char_traitsIcESaIcEEE 00000000000802c0 T _ZNK7mockcpp23ChainableMockObjectBase7getNameB5cxx11Ev 00000000002dd8a0 V _ZTIN7mockcpp23ChainableMockObjectBaseE 00000000000b0a80 V _ZTSN7mockcpp23ChainableMockObjectBaseE 00000000002dd810 V _ZTVN7mockcpp23ChainableMockObjectBaseE

服务器 B 上 nm 结果: 000000000009fb96 t _GLOBALsub_I_ChainableMockObjectBase.cpp 000000000009f7da T _ZN7mockcpp23ChainableMockObjectBase6verifyEv 000000000009f638 T _ZN7mockcpp23ChainableMockObjectBaseC1ERKNSt7cxx1112basic_stringIcSt11char_traitsIcESaIcEEE 000000000009f6ca T ZN7mockcpp23ChainableMockObjectBaseC1ERKS0 000000000009f638 T _ZN7mockcpp23ChainableMockObjectBaseC2ERKNSt7cxx1112basic_stringIcSt11char_traitsIcESaIcEEE 000000000009f6ca T ZN7mockcpp23ChainableMockObjectBaseC2ERKS0 000000000009f788 T _ZN7mockcpp23ChainableMockObjectBaseD0Ev 000000000009f714 T _ZN7mockcpp23ChainableMockObjectBaseD1Ev 000000000009f714 T _ZN7mockcpp23ChainableMockObjectBaseD2Ev 000000000009f5e0 T _ZN7mockcpp27ChainableMockObjectBaseImplC1ERKNSt7cxx1112basic_stringIcSt11char_traitsIcESaIcEEE 000000000009f5e0 T _ZN7mockcpp27ChainableMockObjectBaseImplC2ERKNSt7cxx1112basic_stringIcSt11char_traitsIcESaIcEEE 000000000009fcbc W _ZN7mockcpp27ChainableMockObjectBaseImplD1Ev 000000000009fcbc W _ZN7mockcpp27ChainableMockObjectBaseImplD2Ev 000000000009f8f6 T _ZNK7mockcpp23ChainableMockObjectBase18getMethodContainerEv 000000000009f7ae T _ZNK7mockcpp23ChainableMockObjectBase19getInvocationMockerERKNSt7cxx1112basic_stringIcSt11char_traitsIcESaIcEEE U _ZNK7mockcpp23ChainableMockObjectBase19getInvocationMockerERKSs 000000000009f8e0 T _ZNK7mockcpp23ChainableMockObjectBase7getNameB5cxx11Ev U _ZNK7mockcpp23ChainableMockObjectBase7getNameEv 00000000002d6f08 V _ZTIN7mockcpp23ChainableMockObjectBaseE 00000000000b2120 V _ZTSN7mockcpp23ChainableMockObjectBaseE 00000000002d6e78 V _ZTVN7mockcpp23ChainableMockObjectBaseE

sinojelly commented 3 years ago

用 nm --demangle 发现, 服务器B上多了一个非cxx11的函数依赖: 000000000009f8e0 T mockcpp::ChainableMockObjectBase::getName[abi:cxx11]() const U mockcpp::ChainableMockObjectBase::getName() const

sinojelly commented 3 years ago

服务器 A: gcc 5.4.0 服务器 B: gcc 4.8.5

sinojelly commented 3 years ago

提了一个问题,谁有好的解决办法告诉下: https://stackoverflow.com/questions/66827134/why-c-so-depends-on-a-non-cxx11-method

sinojelly commented 3 years ago

最后发现就是 gcc 版本不同,导致的编译结果无法兼容。

一种规避办法: 把 libmockcpp.a 和 testngpp 的所有 so, 可执行文件, .a 都替换成老的编译器编译的结果。 用一个 gcc 4.8.4 版本编译的结果,可以在 B 上成功运行了。

使用工具的二进制,不同编译环境,会有这样的兼容性问题。好处是工具不用反复重新编译,节省时间。