检测32位用户模式程序是否在64位内核上运行(即系统是否处于“长模式”)时,最好和最可靠的方法是什么?如果可能的话,我宁愿不调用外部程序(或者必须加载任何内核模块)。
注意:我想检测是否正在使用64位内核(或者实际上,CPU是否处于长模式),而不是仅仅是否存在具有64位功能的处理器(/proc/cpuinfo
告诉我但是没有使用64位功能。)
如果uname
编译为32位或使用setarch i686
,则内核伪造32位处理器。
答案 0 :(得分:6)
调用uname()
函数并检查返回的machine
字符串,对于64位Intel平台,该字符串为x86_64
。
扭转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
的效果。
答案 1 :(得分:1)
假设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);
}
答案 2 :(得分:0)
如果为其配置了内核,则可以从/proc/config.gz
中读取内核配置zcat /proc/config.gz | grep CONFIG_64BIT
# CONFIG_64BIT is not set
我不确定你需要多么便携 - 它似乎不是一个超级常见的配置选项。