简体   繁体   中英

Getting the error of null when running Bash C Program

Why am I getting null in the ptr variable at the end when I compile? I am trying to get the start time after the program terminates. The output says that "The code has successfully terminated" or the child has successfully terminated, but the ptr variable at the end is set to null. Can anyone hypothesis as to why this is?

#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");
    }
  }

}

Your manipulated the wrong way on ptr pointer. When use it please use the deference operator *

this line:

ptr+=startTime;

should be

*ptr += startTime;

Several things:

  • you have the following code testing on an uninitialised variable:

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

    in the child process, so you'll get erratic behaviour as shmid will get rubbish and sometimes you'll get child exit() ing and some not.

  • Second, gettimeofday(2) doesn't get a pointer to a time_t value, but a struct timeval * , so you are incurring in a buffer overrun (you are writing the timestamp data past the end of the startTime variable ( struct timeval is larger than time_t ), corrupting the stack.

  • third, you add (supposedly, as the data was already wrong) a timestamp to a pointer, making the pointer to point to a garbage point. After that the pointer is completely useles. Are you adding apples with pears?
  • next, execvpe() never returns, when called successfully, so you'll get a message of "successfully created child process\\n" only in case execvpe() fails, which is somewhat contradictory.
  • finally, as you do a waitpid() , it is not necessary to retain the child pid and call waitpid() (you can simply call wait(2) , as you only create a single child, and you can trust that wait(2) will give an error, if the child finally could not be created, eg the fork() call didn't succeed) Also, returnStatus is composed of more info than just the exit(2) value from the child process, so comparing it with 0 is not the proper way to check how did it go in the child. See wait(2) for more info.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM