在共享对象中命名不兼容的符号 - 在哪里寻找问题

Posted

技术标签:

【中文标题】在共享对象中命名不兼容的符号 - 在哪里寻找问题【英文标题】:symbols named incompatibly in shared objects - where to look for problems 【发布时间】:2012-02-10 22:29:05 【问题描述】:

我是 Linux 新手。我可以访问两台 Linux 机器,一台 40 核服务器(A)和一个集群(B)。我试图在两台机器上做同样的事情,它在 A 上工作,在 B 上不起作用。我对这两个机器都没有 sudo 权限。 A 在 debian 挤压/sid 上运行。 B 在内核 2.6.18-238.el5 上运行。我在 /etc 下找不到任何发布信息文件。 A 具有 gcc 4.6.2,而 B 具有 gcc 4.1.2。

我在两台机器上本地编译并安装了一个给定的网格划分软件 Pkg1 和一个给定的求解器 Pkg2。两者都需要 Libtool 和 automake。 Pkg2 是一个 .so 文件。一切正常,我可以运行示例。代码是用 mpicxx 构建的。两者都有不同的 mpi 编译器。 A使用openmpi154,B使用qlogicmpi_gnu-0.1.0。

现在我介绍我的代码,比如 Pkg3,一些 .cpp 文件。我用它构建了一个.so。我没有使用 Libtool 和 automake。使用了一个简单的 make 文件,使用 gcc 作为编译器和链接器(也尝试了 mpicxx)。

在 A 上,Pkg3 运行良好。在 B 上,Pkg3 崩溃。当它尝试将 Pkg3 中的某些类型动态地转换为 Pkg2 中定义的类型并带有消息 St8bad_cast 时,它会崩溃。对于另一个数据文件,当 Pkg2 中的函数尝试从 Pkg3 转换类型时,它会崩溃,消息“元素类型为 N5ngfem8FE_Segm2E 预期类型为 N5ngfem19ScalarFiniteElementILi1EEE”

我在哪里寻找问题?抱歉含糊其辞。这里的所有软件都是开源的,但是软件包太大而无法通过少量工作制作一个独立的复制品。我既没有使用过 automake 和 Libtools,也没有使用过 mpi,这使问题更加复杂。我查看了 Pkg1 和 Pkg2 的 makefile 并尝试使用我的简单 makefile 映射 CXX、LDFLAGS 等,但是 automake/libtools 创建的多个间接方式使其变得困难。

我了解 Pkg2 中的符号在符号表中的处理方式与 Pkg3 中的不同。但这应该已经处理了链接器?!我已经尝试过为 Pkg3 使用和不使用“-Wl,-E”选项。 -fPIC 始终存在。链接 Pkg3 的规则指向库 Pkg2 ()。我已经发布了 Pkg3 的 makefile 的正文。

 %.o : %.cpp
     gcc  -O2 -fopenmp -fPIC -DNETGEN_ELTRANS -DUSE_TIMEOFDAY -DLAPACK -I. -I$(NETGENDIR)/../include -c $? -o $@

 libmyngsolve.so : $(objects)
      gcc -shared -Wl,-E -fopenmp -fPIC $(objects) -L/home/lv70227/elan/ng/lib -lngsolve -o $@

 clean:
     rm *.o libmyngsolve.so

注1:

Pkg2 的./configure 命令具有-Wl,--start-group -lmkl_intel_lp64 -lmkl_sequential -lmkl_core -Wl,--end-group -lpthread 即,它没有 -E 标志。但这就是指定给我的方式,作为参考。

注2:

链接规则中定义的路径,-L/home/lv70227/elan/ng/lib, 有 pkg​​2.so.0.0.0,有两个符号链接,还有 pkg​​2.la,而不是 pkg2.sa,因为它是由 libtools 创建的。

感谢任何有关问题所在的提示。我在两台机器上都遵循了相同的程序,使偏差最小以适应安装在 A 和 B 中的不同 mpi、gcc、mkl 库。

谢谢, 伊兰。

【问题讨论】:

您可以考虑在机器 B 上构建最近的 GCC 4.6 编译器(来自其源代码),并可能构建其他软件。你不需要root权限来构建免费软件(也许通过configure --prefix=$HOME 请编辑您的问题以使其格式更合适:您可以更好地显示您的源代码或仅显示您的命令。 GCC 4.1 之间存在很大差异(特别是在修饰和标准库 API 方面)。和 GCC 4.6,尤其是 C++ 代码! 感谢 Basile 的回复。我确实在复制粘贴的格式方面遇到了困难。我也会看看我是否可以指出一些特定的错误消息。 【参考方案1】:

正如我在 cmets 中告诉您的,GCC 4.1 和 GCC 4.6 是如此不同,因此可能的解决方案是在您的旧机器上安装 GCC 4.6(可能通过编译其源代码和所需的依赖项)。

【讨论】:

以上是关于在共享对象中命名不兼容的符号 - 在哪里寻找问题的主要内容,如果未能解决你的问题,请参考以下文章

程序员自我修养阅读笔记——Linux共享库管理

在哪里寻找 Spring XML 命名空间配置的确切效果?

去哪里寻找不可能的分子?

函数范围的静态变量如何导致与共享库中函数代码的未来使用不兼容

NoSuchFieldError Java

导出符号意味着什么?