17

我正在编写一个对学生程序进行评分的程序,我相信您可以想象,它们有时会出现分段错误。我遇到的问题是,当学生编程分段错误时,没有迹象表明发生了什么。

proc = subprocess.Popen(student_command, 
                        stdout=subprocess.PIPE, 
                        stderr=subprocess.PIPE)
self.stdout, self.stderr = proc.communicate()
self.returncode = proc.returncode

我从 中提取stderrstdout和返回码subprocess,但如果程序分段错误,stderr则为空,stdout为空,返回码为 -11。现在我可以查找 -11 退出代码并假设如果这是返回代码,则存在分段错误,但也没有什么可以阻止学生的代码将 -11 作为返回代码仅仅因为学生感觉想要返回-11。

您如何判断子进程分段是否出错,而不是仅仅感觉返回 -11?我真的不太关心 stderr 和 stdout 中的内容,为此我看到了很多帖子,包括这个处理获取输出的帖子,但我不太关心输出,虽然从标准错误中获取“分段错误”字符串会很好,但我真正需要的是一种明确告诉子进程发生了什么的方法。

4

1 回答 1

10

好吧,事实上,在 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必须代表致命信号,而不是正常返回。但是请注意,这些进程可能会杀死自己以伪造致命错误。

于 2013-09-11T02:55:47.383 回答