我必须在CentOS 7上构建程序并在其他Linux机器上进行部署。该程序需要较新的版本glibc
,并且某些库尚未(也不会)安装在目标计算机上。因此,我决定将可执行文件与动态库一起提供。我用patchelf
修补了interpreter
和rpath
。
我在计算机上测试了可执行文件,并且可执行(也与ldd
进行了检查,以确保使用了新的rpath)。但是,当我使用libs复制到其他计算机时,该程序无法运行。仅打印此行:
非法指示
更新:
二元
因此,SIGILL是由shlx
函数中的__tls_init()
指令引起的。我不知道哪个库提供此功能,我不确定它来自glibc。
我删除了从另一台计算机复制的glibc,并使用目标计算机上已安装的glibc,但问题并未得到解决。
答案 0 :(得分:1)
我用patchelf修补了解释器和rpath
您的问题非常不清楚:您将解释器和rpath更改为什么?
我认为您所做的是:
patchelf
将二进制文件更改为指向非标准路径SIGILL
。最可能的原因:您为目标处理器配置的不是您构建的非标准GLIBC,这与构建计算机上使用的处理器不同。
默认情况下,GCC将使用-march=native
,这意味着如果您基于在Haswell计算机上,那么二进制文件将使用目标计算机不支持的AVX2
指令。
要解决此问题,您需要将-march=generic
或-march=$target_architecture
添加到CFLAGS
(和CXXFLAGS
)中,并重新构建GLIBC和主程序。
另一方面,您的GDB回溯显示了
/lib64/ld-linux-x86-64.so.2
和/lib64/libc.so.6
,所以也许我不理解您执行的步骤 。
更新:
我没有构建新的glibc,而是将其从我的计算机复制到目标计算机。我的机器使用E5-2690v4,但目标机器使用E5-2470。
E5-2690v4是Broadwell。 E5-2470是Ivy Bridge。
前者支持AVX2,但后者不支持。完全按照您所描述的症状将使用AVX2构建的GLIBC复制到Ivy Bridge可能会失败(并且实际上应该使Ivy Bridge完全无法工作;我很惊讶 任何事情都可以解决。)
使用GDB x/i $pc
命令,您可以查看哪个指令生成了SIGILL
。如果这是AVX2指令,则可能是答案。