【问题标题】:Python subprocess : in which case a segfault program returns -11 or 139?Python 子进程:在这种情况下,段错误程序返回 -11 还是 139?
【发布时间】:2019-04-05 14:45:20
【问题描述】:

我正在使用 Python 3.7 和 subprocess 库。

我有一个二进制文件my_prog,它因段错误而崩溃:

$> ./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。
好的,没有输出。为什么不呢。

但是,如果我想在标准输入上读取相同的程序,我必须修改我在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 的含义相同,为什么返回码会在这两种不同的情况下发生变化?还有为什么第一种情况没有输出?

谢谢:)

编辑
在输出问题上添加差异。

【问题讨论】:

    标签: python subprocess signals return-code


    【解决方案1】:

    为了提高效率,shell 只是execs 在某些情况下它运行的最后一个(或唯一一个)命令。然后,该命令与 shell 的 相同 进程(Python 脚本的 直接子)并以通常的方式报告信号(完全作为 -11)。

    重定向输入可以防止这种情况,可能是为了避免过早关闭终端上打开的所有文件描述符的问题。然后将来自my_prog 的段错误报告给shell:作为带有-11 的if,但这实际上是Python 约定。 shell打印一条消息(注意/bin/sh出现在其中)和converts that report进入退出状态139。

    可以重新呈现信号,在它没有 exec 的情况下,通过用相同的信号杀死自己(strace 这样做),但它没有打扰那额外的检查。 (这样你就不必怀疑 shell 本身是否崩溃了。)不幸的是,shell 以这种方式进一步限制了可用退出状态的范围,但它早已确立。

    【讨论】:

    • 感谢您的参考 :) 但是我不确定您的假设为什么程序尝试在标准输入上读取时它会以这种方式工作。
    • @curquiza:对不起,我遗漏了一步。正在编辑……
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-31
    • 2011-06-06
    • 1970-01-01
    • 2021-01-31
    相关资源
    最近更新 更多