Определение ошибки сегментации подпроцесса python
Я пишу программу, которая оценивает студенческие программы, и, как я уверен, вы можете себе представить, они иногда имеют недостатки сегментации. Проблема, с которой я сталкиваюсь, заключается в том, что когда ошибка сегментации студенческих программ отсутствует, нет никаких указаний на то, что произошло.
proc = subprocess.Popen(student_command,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
self.stdout, self.stderr = proc.communicate()
self.returncode = proc.returncode
Я беру stderr, stdout и код возврата из подпроцесса, но если ошибка сегментации программы, stderr пуст, stdout пуст, а код возврата - -11. Теперь я мог бы найти код выхода -11 и предположить, что если это код возврата, произошла ошибка сегментации, но также нет ничего, что помешало бы коду-ученику иметь код -11 в качестве кода возврата только потому, что ученику хотелось вернуться -11.
Как вы узнаете, что сегментирование сегментации подпроцесса, а не просто ощущение возврата -11? Мне все равно, что в stderr и stdout, и с этой целью видел несколько сообщений, включая this, которые касаются сбора результатов, но мне все равно, о выходе, хотя было бы неплохо получить строку "Сегментационная ошибка" из stderr, но мне действительно нужен способ окончательно рассказать, что произошло с подпроцессом.
Ответы
Ответ 1
Ну, на самом деле, в UNIX процесс, который пытается вернуть -11
, как правило, возвращает положительное целое. Это связано с тем, что статус возврата из серии функций wait
фактически представляет собой набор битполей, с полем для сигнала, который завершил процесс, и отдельным полем для возвращаемого значения. Python декодирует возвращаемое значение wait
из этих битовых полей.
В большинстве систем эти поля не имеют знака и 8 бит, поэтому вы, вероятно, увидите что-то вроде этого:
>>> import subprocess
>>> subprocess.Popen(['python','-c','import os; os.kill(os.getpid(),11)']).wait()
-11
>>> subprocess.Popen(['python','-c','exit(-11)']).wait()
245
В первом случае процесс "segfaults" (убив себя SIGSEGV), и поэтому wait
возвращает -11. В последнем случае процесс завершается с кодом возврата -11, а итоговое значение wait
равно 245 (256-11). Поэтому вы можете быть уверены, что любое отрицательное возвращаемое значение из wait
должно представлять фатальный сигнал, а не нормальный возврат. Обратите внимание, однако, что процессы могут убить себя, чтобы подделать фатальную ошибку.