检测 32 位用户模式程序是否在 64 位内核上运行(即系统是否处于“长模式”)的最佳和最可靠的方法是什么?如果可能的话,我宁愿不调用外部程序(或者必须加载任何内核模块)。
注意:我想检测是否正在使用 64 位内核(或者实际上,CPU 是否处于长模式),而不仅仅是是否存在支持 64 位的处理器(/proc/cpuinfo
告诉我,但不是 64 位正在使用能力)。
uname
如果编译为 32 位或使用了,内核会伪造 32 位处理器setarch i686
。
调用该uname()
函数并检查返回的machine
字符串,该字符串x86_64
适用于 64 位 Intel 平台。
扭转使用效果的一种方法setarch
是重置个性:
#include <stdio.h>
#include <sys/utsname.h>
#include <sys/personality.h>
int main()
{
struct utsname u;
personality(PER_LINUX);
uname(&u);
puts(u.machine);
return 0;
}
这显示了在 32 位模式下编译并在 64 位系统上运行时的正确结果:
$ gcc -m32 -o u u.c
$ ./u
x86_64
$ setarch i686 ./u
x86_64
编辑:修复代码以反转setarch
.
参考。
假设 uname() 是作弊,仍然有几种机制。一种方法是检查任何内核符号的地址宽度。
#include <stdio.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc, char **argv) {
char *inputline = malloc(1024);
char *oinputline = inputline;
int fd = open("/proc/kallsyms", O_RDONLY);
int numnibbles = 0;
if (fd == -1) {
perror("open");
free(inputline);
exit(1);
}
read(fd, inputline, 1024);
close(fd);
while(!isspace(*inputline)) {
numnibbles++;
inputline++;
}
printf("%dbit\n", numnibbles*4);
free(oinputline);
exit (0);
}
如果为它配置了内核,您可以从 /proc/config.gz 读取内核配置
zcat /proc/config.gz | grep CONFIG_64BIT
# CONFIG_64BIT is not set
我不确定您需要它的便携性 - 它似乎不是一个超级常见的配置选项。