Код возврата, когда ОС убивает ваш процесс - PullRequest
2 голосов
/ 13 апреля 2009

Я хотел проверить, смогу ли я использовать более чем 4 ГБ оперативной памяти на 32-битном O.S (мой: Ubuntu с 1 ГБ оперативной памяти).

Итак, я написал небольшую программу, которая занимает немного меньше 1 ГБ, и выполнил какое-то действие с этим массивом, и запустил 5 экземпляров этой программы.

Дело в том, что я подозреваю, что О. убил 4 из них, и только один выжил и показал, что "ПИД: я закончил").

(я пробовал это с небольшими массивами и получил 5 печатных изображений, также, когда я смотрю на запущенные процессы с TOP, я вижу только один экземпляр ..)

Странная вещь в том, что я получил код возврата 0 (успех?) Во ВСЕХ случаях, включая те, которые предположительно были убиты О.С.

Я не получил никакого массажа, заявляющего, что процессы были убиты.

Является ли этот код возврата нормальным для этой ситуации?

(Если это так, это снижает мое доверие к "кодам возврата" ...)

спасибо.

Редактировать: некоторые ответы предполагали возможные ошибки в небольшой программе, так что вот оно. Чем больше программа, которая разветвляет и сохраняет коды возврата, тем больше, и мне трудно загрузить ее здесь, но я думаю (и надеюсь), что все в порядке.

Также я заметил, что если вместо того, чтобы запускать его с моей программой разветвления, я запускаю его с терминалом, используя './a.out & ./a.out & ./a.out & ./a.out & '(когда ./a.out - бинарный файл небольшой прикрепленной программы) Я вижу некоторые сообщения «Убито».

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#define SMALL_SIZE 10000
#define BIG_SIZE 1000000000
#define SIZE BIG_SIZE
#define REAPETS 1

    int
main()
{
    pid_t my_pid = getpid();

    char * x = malloc(SIZE*sizeof(char));

    if (x == NULL)
    {
            printf("Malloc failed!");
            return(EXIT_FAILURE);
    }

    int x2=0;
    for(x2=0;x2<REAPETS;++x2)
    {
            int y;
            for(y=0;y<SIZE;++y)
                    x[y] = (y+my_pid)%256;
    }
    printf("%d: I'm over.\n",my_pid);
    return(EXIT_SUCCESS);
}

Ответы [ 6 ]

5 голосов
/ 13 апреля 2009

Ну, если ваш процесс не может malloc() 1 ГБ памяти, ОС не будет убивать процесс. Все, что происходит, это то, что malloc() возвращает NULL. Таким образом, в зависимости от того, как вы написали свой код, возможно, что процесс в любом случае вернет 0 - если вы хотите, чтобы он возвращал код ошибки при сбое выделения памяти (что обычно является хорошей практикой), вам придется запрограммировать это поведение на это.

5 голосов
/ 13 апреля 2009

Какой сигнал использовался для уничтожения процессов?

Коды выхода от 0 до 127 включительно могут использоваться свободно, а коды выше 128 указывают, что процесс был прерван сигналом, где код выхода равен

128 + номер используемого сигнала

4 голосов
/ 13 апреля 2009

Состояние возврата процесса (как возвращено wait, waitpid и system) содержит более или менее следующее:

  • Код выхода, применяется только в случае нормального завершения процесса
  • произошло ли нормальное / ненормальное завершение
  • Сигнал завершения, применяется только в том случае, если процесс был прерван сигналом

Код завершения не имеет смысла, если ваш процесс был убит убийцей OOM (который, очевидно, отправит вам сигнал SIGKILL)

для получения дополнительной информации см. Справочную страницу для команды wait .

3 голосов
/ 14 апреля 2009

Этот код показывает, как получить статус завершения ребенка:

#include <stdio.h>
#include <stdlib.h>

#include <unistd.h>
#include <sys/wait.h>

int
main (void)
{ 
  pid_t pid = fork();

  if (pid == -1)
  {
    perror("fork()");
  }
  /* parent */
  else if (pid > 0)
  {
    int status;

    printf("Child has pid %ld\n", (long)pid);

    if (wait(&status) == -1)
    {
      perror("wait()");
    }
    else
    {
      /* did the child terminate normally? */
      if(WIFEXITED(status))
      {
        printf("%ld exited with return code %d\n",
               (long)pid, WEXITSTATUS(status));
      }
      /* was the child terminated by a signal? */
      else if (WIFSIGNALED(status))
      {
        printf("%ld terminated because it didn't catch signal number %d\n",
               (long)pid, WTERMSIG(status));
      }
    }
  }
  /* child */
  else
  {
    sleep(10);
    exit(0);
  }

  return 0;
}
1 голос
/ 13 апреля 2009

Код выхода «действителен», только если макрос WIFEXITED имеет значение true. См. man waitpid (2) .

Вы можете использовать макрос WIFSIGNALED, чтобы узнать, была ли ваша программа подана.

1 голос
/ 13 апреля 2009

Вы проверили возвращаемое значение с fork()? Есть большая вероятность, что если fork() не сможет выделить достаточно памяти для адресного пространства нового процесса, он вернет ошибку (-1). Типичный способ вызова fork():

pid_t pid;
switch(pid = fork())
{
case 0:
    // I'm the child process
    break;
case -1:
    // Error -- check errno
    fprintf(stderr, "fork: %s\n", strerror(errno));
    break;
default:
    // I'm the parent process
}
...