在Linux下检测32位进程是否在64位环境中运行

3
我正在分发一个32位软件版本。我想在运行时检测用户空间是否为64位,并能够运行64位可执行文件(ELF 64位x86-64)。这不同于在编译时检测体系结构是否为32位或64位的问题。
我希望以最便携的方式解决此问题,因此希望避免像file $(which init) | grep x86-64这样依赖的方法。
我认为读取cpuid也不是解决方案——在64位CPU上运行32位操作系统是可能的。
检测处于长模式下运行的64位CPU似乎也不是解决方案,检测内核本身是否为64位也不是解决方案,因为操作系统是32位用户空间和64位内核的可能性存在(如某些Debian配置)。
我主要关心的不是除32位和64位之外的位数检测。
我能想到的一个可能的健壮解决方案是实际包含并尝试调用64位ELF二进制文件,看它是否运行,但这不像是一种非常有效的方法。是否有Linux函数或STL或Boost中的内容可以帮助我可靠地找出呢?
具有讽刺意味的是,对于Windows来说,相应的问题非常容易解决

为什么?“file $(which init) | grep x86-64”这个想法可能并不那么疯狂。当然,在ARM64上会有问题,但现在谁在使用ARM64呢? - MSalters
@MSalters 在我的系统中,init 位于 /sbin/init,而且 /sbin 不在 $PATH 中,除非你是 root。 - ZyX
@MSalters的想法file $(which init)取决于路径中是否存在init,并且这是系统能力的代表。对于一个非特权用户来说,情况可能并非如此。 @mafso:是的,uname解决方案可以告诉你内核是什么,但在32位用户空间与64位内核的情况下可能会有问题,正如问题中提到的那样。 - Riot
你可以使用 uname... - Gophyr
@Gophyr 那不正确。uname系统调用仅返回有关内核的信息。请参阅此问题,以了解从uname报告x86_64并实际运行32位用户空间的设置示例:http://unix.stackexchange.com/q/134391 - Riot
显示剩余8条评论
1个回答

3
你可以测试是否存在/lib64/ld-linux-x86-64.so.2。理论上这并不总是有效,因为Linux系统可能会将动态链接器放在其他位置,但这个特定路径是最常见的,并且动态链接器的路径已经硬编码到ELF二进制文件中,所以这种方法至少和实际将64位库与软件捆绑在一起一样好(只要有匹配的libc)。

没错!/lib64/ld-linux-x86-64.so.2确实是硬编码到64位ELF中的,我之前没有意识到这一点。我认为将其与从内核获取uname信息相结合,以避免任何误报风险,将是最稳健的解决方案。 - Riot

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接