Получение нулевой ошибки при запуске программы Bash C - PullRequest
0 голосов
/ 05 февраля 2019

Почему я получаю нулевое значение в переменной 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");
    }
  }

}

Ответы [ 2 ]

0 голосов
/ 06 февраля 2019

Несколько вещей:

  • у вас есть следующее тестирование кода для неинициализированной переменной:

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

    в дочернем процессе, поэтому вы получите ошибочное поведениепоскольку shmid получит мусор, а иногда вы получите ребенка exit(), а некоторые нет.

  • Во-вторых, gettimeofday(2) не получает указатель на time_tзначение, но равное struct timeval *, поэтому вы подвергаетесь переполнению буфера (вы записываете метку времени после конца переменной startTime (struct timeval больше time_t), повреждая стек.

  • в-третьих, вы добавляете (предположительно, поскольку данные уже были неверны) метку времени к указателю, делая указатель, указывающий на точку мусора. После этого указатель полностью используется. Вы добавляете яблоки сpears?
  • далее, execvpe() никогда не возвращается при успешном вызове, поэтому вы получите сообщение "successfully created child process\n" только в случае сбоя execvpe(), что несколько противоречиво.
  • наконец, когда вы делаете waitpid(), нет необходимости повторятьn дочерний pid и вызов waitpid() (вы можете просто позвонить wait(2), поскольку вы создаете только один дочерний элемент, и вы можете верить, что wait(2) выдаст ошибку, если дочерний элемент не может быть создан, например,fork() вызов не удался) Кроме того, returnStatus состоит из большего количества информации, чем просто значение exit(2) от дочернего процесса, поэтому сравнение его с 0 не является правильным способом проверить, как он прошелребенок.См. wait(2) для получения дополнительной информации.
0 голосов
/ 05 февраля 2019

Вы неверно манипулировали указателем ptr.При его использовании, пожалуйста, используйте оператор опоздания *

эту строку:

ptr+=startTime;

должно быть

* ptr + = startTime;

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...