Подпроцесс Python: в каком случае программа segfault возвращает -11 или 139? - PullRequest
0 голосов
/ 01 ноября 2018

Я использую библиотеку Python 3.7 и subprocess.

У меня есть двоичный файл my_prog, который падает с segfault:

$> ./my_prog
[1]    9328 segmentation fault  ./my_prog

В моем скрипте main.py у меня есть следующие строки кода:

try:
    output = subprocess.check_output(['./my_prog'], shell=True, stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as exc:
    print(exc.returncode)
    print(exc.output)

В этом случае я получаю

$> python3 main.py
-11
b''

Хорошо, подпроцесс обрабатывает сигнал SIGSEGV.
Хорошо, нет выхода. Почему нет.

Но, если я хочу, чтобы та же программа читала на stdin, я должен изменить мою строку в main.py (файл "text.txt" существует):

output = subprocess.check_output(['./my_prog < text.txt'], shell=True, stderr=subprocess.STDOUT)

И в этом случае я получаю:

$> python3 main.py
139
b'/bin/sh: line 1: 17235 Segmentation fault: 11  ./my_prog < text.txt\n'

Я знаю, что это 11 + 128, это также означает SIGSEGV.
И теперь у меня есть выход!

Даже если 139 и -11 означают одно и то же, почему код возврата изменяется в этих двух разных ситуациях? И почему нет выхода в первом случае?

Спасибо:)

РЕДАКТИРОВАТЬ :
Добавьте разницу в выпуске.

1 Ответ

0 голосов
/ 01 ноября 2018

Для эффективности оболочка просто exec является последней (или единственной) командой, которую она запускает в определенных случаях. Тогда команда - это такой же процесс, как и оболочка - прямой потомок вашего скрипта Python - и сообщает о сигналах обычным способом (полностью как -11).

Перенаправление ввода предотвращает это, возможно, чтобы избежать проблем с преждевременным закрытием всех файловых дескрипторов, открытых на терминале. Затем segfault из my_prog сообщается оболочке: как , если с -11, но на самом деле это соглашение Python. Оболочка печатает сообщение (обратите внимание, что в нем появляется /bin/sh), а преобразует этот отчет в состояние выхода 139.

Он может повторно представить сигнал в тех случаях, когда он не exec, убивая себя тем же сигналом (strace делает это), но это не мешает с этой дополнительной проверкой. (И таким образом, вам не нужно удивляться, не сломалась ли сама оболочка.) К сожалению, оболочки еще больше ограничивают диапазон используемых состояний выхода таким образом, но это давно установлено.

...