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

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

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


person Rost    schedule 07.11.2019    source источник


Ответы (2)


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

int status = 0;

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

if (WIFEXITED(status))
{
    printf("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 из оболочки). Разумно предположить, что сигналы не отправляются в системе без разбора и что обычно SIGKILL отправляет само ядро ​​(убийца OOM).

person P.P    schedule 07.11.2019

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

person Ingo Leonhardt    schedule 07.11.2019