一位教授Linux的教授给他的学生发了一个奇怪的问题...
奇怪的是,这个程序将给出一个输出,其中父进程和子进程在普通用户模式下运行时将获得相同的物理地址,但当我在根用户模式下运行此程序时,输出显示父进程和子进程具有不同的物理地址,如下所示.
当处于普通用户模式时:
pid:5269, ppid:3152
pid:5270, ppid:5269
Child process : �
virtual addr of str=0x7ffd7023bfd0 and &count=0x7ffd7023bfcc, physical addr of str=0xfd0,&count=0xfcc
Father process : �
count: 1 (0x7ffd7023bfcc), pid: 5269
virtual addr of str=0x7ffd7023bfd0 and count=0x7ffd7023bfcc, physical addr of str=0xfd0,&count=0xfcc
count: 2 (0x7ffd7023bfcc), pid: 5270
当处于root用户模式时:
pid:5294, ppid:3414
pid:5295, ppid:5294
Child process : �
virtual addr of str=0x7ffe501a1530 and &count=0x7ffe501a152c, physical addr of str=0x1298db530,&count=0x1298db52c
Father process : �
count: 1 (0x7ffe501a152c), pid: 5294
virtual addr of str=0x7ffe501a1530 and count=0x7ffe501a152c, physical addr of str=0x12282b530,&count=0x12282b52c
count: 2 (0x7ffe501a152c), pid: 5295
我就是想不通,有谁能帮忙吗?
// file name proc-1.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdint.h>
#include <sys/stat.h>
//#include <linux/capability.h>
//#include <linux/sched.h>
intptr_t mem_addr(unsigned long vaddr, unsigned long *paddr)
{
int pagesize = getpagesize();
unsigned long v_pageindex = vaddr / pagesize;
unsigned long v_offset = v_pageindex * sizeof(uint64_t);
unsigned long page_offset = vaddr % pagesize;
uint64_t item = 0;
int fd = open("/proc/self/pagemap", O_RDONLY);
lseek(fd, v_offset, SEEK_SET);
read(fd, &item, sizeof(uint64_t));
if((((uint64_t)1 << 63) & item) == 0)
{
printf("page present is 0\n");
return 0 ;
}
uint64_t phy_pageindex = (((uint64_t)1 << 55)- 1) & item;
*paddr = (phy_pageindex * pagesize) + page_offset;
return *paddr;
}
int main(void)
{
char str[10];
int count = 1;
unsigned long pa[2]={0,0};
int fd = open("test.txt", O_RDWR);
if(fork() == 0)
{
printf("pid:%d, ppid:%d\n",getpid(), getppid());
read(fd, str, 10);
count += 5;
printf("Child process : %s\n", (char *)str);
mem_addr((unsigned long)str, &pa[0]);
mem_addr((unsigned long)&count, &pa[1]);
printf("virtual addr of str=%p and count=%p, physical addr of str=%p,&count=%p\n",str,&count, pa[0], pa[1]);
printf("count: %d (%p), pid: %d\n", count, &count, getpid());
}
else
{
printf("pid:%d, ppid:%d\n",getpid(), getppid());
read(fd, str, 10);
//count ++;
printf("virtual addr of str=%p and &count=%p, physical addr of str=%p,&count=%p\n",str,&count, mem_addr((intptr_t)str, &pa[0]), mem_addr((intptr_t)&count,&pa[1]));
printf("Father process : %s\n", (char *)str);
printf("count: %d (%p), pid: %d\n", count, &count, getpid());
}
sleep(10);
return 0;
}
我确定这个奇怪的问题应该与文件/proc/pid/pagemap
有关,但我就是解决不了它.