Есть ли способ выяснить, что дочерний процесс был убит ядром с помощью SIGKILL, когда родительский процесс не является корневым - PullRequest
1 голос
/ 07 ноября 2019

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

Может кто-нибудь дать мне совет? Спасибо.

Ответы [ 2 ]

2 голосов
/ 07 ноября 2019

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

int status = 0;

// wait for child to exit
pid_t child_pid = wait(&status);

if (WIFEXITED(status))
{
    fprintf("exited with %d\n", WEXITSTATUS(status));
}
else if (WIFSIGNALED(status))
{
    printf("Signaled with %d\n", WTERMSIG(status));
}

Если у вас есть несколько дочерних процессовВы можете использовать цикл для ожидания их всех.

WTERMSIG(status) вернет номер сигнала. Чтобы выяснить сигнал, вы можете проверить:

if (WTERMSIG(status) == SIGKILL) {
    ...
} else if (WTERMSIG(status) == SIGTERM) {
    ...
}

Невозможно точно определить, кто послал убийство (будь то убийцей OOM или чем-то еще, например, можно сделать kill -9 PID из оболочки). Разумно предположить, что сигналы не отправляются без разбора в системе, и что обычно само ядро ​​(OOM killer) посылает SIGKILL.

0 голосов
/ 07 ноября 2019

Статус, предоставленный waitXXX( ) (см. Справочную страницу) позволяет определить, что ребенок был убит по сигналу: сначала проверьте, позвонив WIFSIGNALED(wstatus), если это произошло, затем вы можетепозвоните WTERMSIG(wstatus), чтобы определить номер сигнала. Однако вы не можете определить, был ли процесс убит ядром или другим процессом, вызывающим kill().

...