Код возврата, когда ОС убивает ваш процесс
Я хотел проверить, могу ли я использовать более чем 4 ГБ оперативной памяти на 32-битной ОС с несколькими процессами (мой: Ubuntu с 1 ГБ оперативной памяти).
Итак, я написал небольшую программу, которая занимает немного меньше 1 ГБ, и выполнил некоторые действия с этим массивом, и запустил 5 экземпляров этой программы.
Дело в том, что я подозреваю, что ОС убила 4 из них, и только одна выжила и показала "PID: я закончил").
(Я пробовал это с маленькими массивами и получил 5 печатных изображений, также, когда я смотрю на запущенные процессы с TOP, я вижу только один экземпляр..)
Странно то, что я получил код возврата 0 (успех?) Во всех случаях, включая те, которые предположительно были убиты ОС
Я не получил никакого массажа, заявляющего, что процессы были убиты.
Является ли этот код возврата нормальным для этой ситуации?
(Если так, это уменьшает мое доверие к "кодам возврата"...)
Благодарю.
Изменить: некоторые ответы предложили возможные ошибки в небольшой программе, так что вот оно. Чем больше программа, которая разветвляет и сохраняет коды возврата, тем больше, и у меня возникают проблемы с ее загрузкой здесь, но я думаю (и надеюсь), что все в порядке.
Также я заметил, что если вместо того, чтобы запускать его с моей программой разветвления, я запускаю его с терминалом, используя './a.out & ./a.out & ./a.out & ./a.out &' (когда./a.out - это бинарный файл небольшой прилагаемой программы) Я вижу некоторые сообщения "Killed".
#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 ответов
Статус возврата процесса (как возвращено wait
, waitpid
а также system
) содержит более или менее следующее:
- Код выхода, применяется только в случае нормального завершения процесса
- произошло ли нормальное / ненормальное завершение
- Сигнал завершения, применяется только в том случае, если процесс был прерван сигналом
Код выхода совершенно бессмыслен, если ваш процесс был убит убийцей OOM (который, очевидно, отправит вам сигнал SIGKILL)
для получения дополнительной информации см. справочную страницу для команды ожидания.
Какой сигнал был использован, чтобы убить процессы?
Коды выхода от 0 до 127 включительно могут использоваться свободно, а коды выше 128 указывают, что процесс был прерван сигналом, где код выхода
128 + номер используемого сигнала
Хорошо, если ваш процесс не может malloc()
1 ГБ памяти ОС не убьет процесс. Все, что происходит, это то, что malloc()
возвращает NULL. Таким образом, в зависимости от того, как вы написали свой код, возможно, что процесс в любом случае вернет 0 - если вы хотите, чтобы он возвращал код ошибки при сбое выделения памяти (что обычно является хорошей практикой), вам придется запрограммировать это поведение на Это.
Этот код показывает, как получить статус завершения ребенка:
#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;
}
Вы проверили возвращаемое значение из 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
}
Код выхода "действителен" только тогда, когда макрос WIFEXITED имеет значение true. Смотри человек waitpid (2).
Вы можете использовать макрос WIFSIGNALED, чтобы увидеть, если ваша программа была сигнализирована.