Не получает SIGCHLD для процессов, выполняемых с помощью sudo

В настоящее время я нахожусь в процессе написания оболочки. Я запускаю процессы и использую обработчик сигналов SIGCHLD для их очистки (ожидания) по завершении.

Все работает, за исключением случаев, когда я запускаю процессы, повышающие привилегии с помощью sudo. В этих случаях я никогда не получаю сигнал SIGCHLD, поэтому я никогда не узнаю, завершилось ли выполнение процесса.

Когда я получаю такую ​​команду, как sudo ls, я запускаю программу sudo и затем указываю ls в качестве параметра. Я выполняю это выполнение с помощью execvp.

Если я взгляну на ps -aux после того, как моя оболочка выполнила sudo ls, я увижу следующее:

root      4795  0.0  0.0   4496  1160 pts/29   S+   16:51   0:00 sudo ls
root      4796  0.0  0.0      0     0 pts/29   Z+   16:51   0:00 [ls] <defunct>

Итак, sudo запустился и получил pid = 4795, а ребенку (ls) был назначен 4796. Ребенок выполнил свою задачу и теперь сидит в состоянии зомби. sudo, похоже, не хочет пожинать плоды зомби-процесса и просто сидит там.

Я хотел бы знать, что вызывает такое поведение - я пробовал разные методы очистки этих зомби-процессов, такие как запуск моей оболочки под sudo и ожидание непосредственно sudo и PID, которые выполняет sudo (4796 в приведенном выше примере). Ни одна из этих техник не сработала.

Как всегда, любые советы приветствуются.


person BSchlinker    schedule 22.11.2011    source источник
comment
Я бы предложил проверить strace(1) вывод sudo(8) при запуске вашей оболочкой и при запуске стандартной системной оболочкой. Поскольку трассировка возится с разрешениями setuid для исполняемых файлов, вам нужно будет прикрепить strace после запуска sudo, но до того, как он проделает большую работу; sudo -k сначала заставит sudo повторно запрашивать пароль, а пока он ждет, вы можете найти его pid и запустить strace -o /tmp/out -f -p <pid>.   -  person sarnold    schedule 22.11.2011
comment
Это происходит и под другими оболочками?   -  person bdonlan    schedule 22.11.2011
comment
@bdonlan, под другими оболочками вы имеете в виду, запускаю ли я sudo vi через bash? Там этого не происходит.   -  person BSchlinker    schedule 22.11.2011
comment
Вы можете попробовать прочитать исходный код bash (или другой оболочки) и увидеть, что для sudo существует что-то другое/какое-то особое поведение. Кроме того, если sudo меняет идентификатор пользователя, может ли это помешать вашему процессу работать с sudo?   -  person Paolo    schedule 22.11.2011
comment
Запрос: Покажите нам наименьший компилируемый код, который воспроизводит проблему, и сообщите нам версию sudo, так как существует ошибка в точке. Вопрос: Вы блокируете SIGCHLD при выполнении? sudo не полагается исключительно на CHLD, IIRC, но это определенно не поможет.   -  person pilcrow    schedule 26.11.2011


Ответы (1)


person    schedule
comment
Да, вы можете придраться ко мне за поведение устаревшей обработки сигналов, но я использовал множество сред на протяжении десятилетий и до сих пор пишу код для защиты от них всех, когда мне должно использоваться устаревшие сигналы. - person Gilbert; 25.11.2011
comment
Не уместно. Основная проблема заключается в том, что sudo не замечает, что ls вышел, и поэтому, в свою очередь, не выходит, чтобы сигнализировать код OP. Будет ли код OP правильно обнаруживать и обрабатывать завершение sudo, это отдельная проблема. - person pilcrow; 26.11.2011
comment
Я все еще хотел бы увидеть обработку сигнала ... если sudo завершится, не подняв SIGCHILD ls, его пользовательская оболочка получит как SIGCHLDS, так и за один вызов обработчика сигнала. Если обработчик не пожинает оба процесса при одном вызове обработчика сигнала, вы получаете зомби. Я видел это МНОГО раз. Не с sudo, а со многими другими. - person Gilbert; 26.11.2011
comment
Я прочитал ваш комментарий, в котором говорилось, что процесс может получить SIGCHLD для внука (…его пользовательская оболочка получит оба SIGCHLDS…) и что процесс может получить (a-wait(2)) внука (< i>Если раздающий не пожинает оба…). Ни то, ни другое не является правильным — процесс получает SIGCHLD и может пожинать плоды только для своих непосредственных потомков. Может показаться, что пожинание умершего ребенка также увольняет внуков-зомби, но на самом деле именно init(1) автоматически усыновляет и пожинает недавно осиротевших внуков. - person pilcrow; 26.11.2011