0

为什么我在编译时最后的 ptr 变量为空?我试图在程序终止后获取开始时间。输出显示“代码已成功终止”或子进程已成功终止,但末尾的 ptr 变量设置为 null。谁能假设这是为什么?

#include<stdio.h>
#include<sys/types.h>
#include<sys/shm.h>
#include<sys/ipc.h>
#include<unistd.h>
#include<time.h>
#include<sys/mman.h>
#include <stdio.h>
#include<stdlib.h>
#include<string.h>
#include<fcntl.h>
#include<sys/stat.h>

int main(){
  const char *name = "OS";
  long *ptr;
  pid_t childPid;
  childPid = fork();
  int  shm;
  if(childPid == 0){
    char *args[] ={"ls","-l",NULL};
    int shmid;
    int shsize = 5000000;
    key_t key;

    char *s;
    key = 9876;
    if(shmid < 0){
      printf("error getting shmid");
      exit(1);
    }
    shm = shm_open(name,O_CREAT| O_RDWR,0666);
    if(shm == (char *) -1){
      printf("error getting shared memory");
      exit(1);}
    time_t startTime;
    gettimeofday(&startTime,0);
    ptr = (long *) mmap(0,sizeof(startTime),PROT_READ | PROT_WRITE,MAP_SHARED,shm,0);
    ptr+=startTime;
    time_t endTime;
    execvp(args[0],args);
    printf("successfuly created child proceess");
    exit(0);
  }

  else if (childPid <0){
    printf("unsuccessfuly created child proccess");
  }
  else{
    int returnStatus;
    waitpid(childPid,&returnStatus,0);
    if(returnStatus == 0){
      printf("The chiild terminated normally");
      printf("%s",ptr);
      shm_unlink(name);
    }

    if(returnStatus == 1){

      printf("The child terminated with error");
    }
  }

}
4

2 回答 2

0

几件事:

  • 您对未初始化的变量进行了以下代码测试:

    if(shmid < 0){
        printf("error getting shmid");
        exit(1);
    }
    

    在 child 进程中,因此您会得到不稳定的行为,并且shmid会变得垃圾,有时您会得到 child exit()ing,而有些则不会。

  • 其次,gettimeofday(2)没有获得指向time_t值的指针,而是 a struct timeval *,因此您将导致缓冲区溢出(您正在将时间戳数据写入startTime变量末尾(struct timeval大于time_t),从而破坏了堆栈。

  • 第三,您向指针添加(假设是数据已经错误)时间戳,使指针指向垃圾点。之后指针完全没用。你要加苹果和梨吗?
  • 接下来,execvpe()当调用成功时,永远不会返回,所以你会得到一个消息,"successfully created child process\n" 只有execvpe()失败时,这有点矛盾。
  • 最后,当您执行 awaitpid()时,不必保留子 pid 并调用waitpid()(您可以简单地调用wait(2),因为您只创建一个子,并且您可以相信wait(2),如果最终无法创建子,这将给出错误,例如fork()调用没有成功)此外,returnStatus它包含的信息不仅仅是exit(2)来自子进程的值,因此将其与子进程进行比较0不是检查子进程如何进行的正确方法。有关wait(2)更多信息,请参阅。
于 2019-02-06T05:35:19.133 回答
0

您在 ptr 指针上的操作方式错误。使用时请使用尊重运算符 *

这一行:

ptr+=startTime;

应该

*ptr += 开始时间;

于 2019-02-05T17:59:22.070 回答