問題描述
我正在編寫一個(gè)對學(xué)生程序進(jìn)行評分的程序,我相信您可以想象,它們有時(shí)會出現(xiàn)分段錯(cuò)誤.我遇到的問題是,當(dāng)學(xué)生編程分段錯(cuò)誤時(shí),沒有跡象表明發(fā)生了什么.
I am writing a program that grades student programs, and as I am sure you can imagine, they sometimes segmentation fault. The problem I am having is that when the student programs segmentation fault, there is no indication that is what happened.
proc = subprocess.Popen(student_command,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
self.stdout, self.stderr = proc.communicate()
self.returncode = proc.returncode
我從 subprocess
中提取 stderr
、stdout
和返回碼,但如果程序分段出錯(cuò),stderr
為空,stdout
為空,返回碼為-11.現(xiàn)在我可以查找 -11 退出代碼并假設(shè)如果這是返回代碼,則存在分段錯(cuò)誤,但也沒有什么可以阻止學(xué)生的代碼將 -11 作為返回代碼僅僅因?yàn)閷W(xué)生感覺想要返回-11.
I pick up the stderr
, stdout
, and the return code from the subprocess
, but if the program segmentation faults, stderr
is empty, stdout
is empty, and the return code is -11. Now I could look for the -11 exit code and assume that if that is the return code there was a segmentation fault, but there is also nothing to prevent a student's code from having -11 as a return code just because the student felt like returning -11.
您如何判斷子進(jìn)程分段是否出錯(cuò),而不是僅僅感覺返回 -11?我不太關(guān)心 stderr 和 stdout 中的內(nèi)容,為此我看到了許多帖子,包括 this 處理拾取輸出,但我不太在意輸出,盡管獲得 "分段錯(cuò)誤"從 stderr 中取出字符串,但我真正需要的是一種明確說明子進(jìn)程發(fā)生了什么的方法.
How do you tell if a subprocess segmentation faults, as opposed to just feeling like returning -11? I don't really care all that much about what is in stderr and stdout, and to that end have seen a number of posts including this that deal with picking up the output, but I don't care all that much about the output, although it would be nice to get the "Segmentation Fault" string out of stderr, but what I really need is a way to definitively tell what happened to the subprocess.
推薦答案
事實(shí)上,在 UNIX 上,嘗試返回 -11
的進(jìn)程通常最終會返回一個(gè)正整數(shù).這是因?yàn)?wait
系列函數(shù)的返回狀態(tài)實(shí)際上是一組位域,其中一個(gè)域用于結(jié)束進(jìn)程的信號,另一個(gè)域用于返回值.Python 從這些位域解碼 wait
返回值.
Well, in fact, on UNIX, a process that attempts to return -11
will usually end up returning a positive integer instead. This is because the return status from the wait
series of functions is actually a set of bitfields, with a field for the signal that ended the process and a separate field for the return value. Python decodes the wait
return value from these bitfields.
在大多數(shù)系統(tǒng)上,這些字段是無符號的,大小為 8 位,因此您可能會看到如下內(nèi)容:
On most systems, these fields are unsigned and 8 bits in size, so you will probably see something like this:
>>> import subprocess
>>> subprocess.Popen(['python','-c','import os; os.kill(os.getpid(),11)']).wait()
-11
>>> subprocess.Popen(['python','-c','exit(-11)']).wait()
245
在前一種情況下,進(jìn)程segfaults"(通過使用 SIGSEGV 殺死自己),因此 wait
返回 -11.在后一種情況下,進(jìn)程以 -11 的返回碼退出,結(jié)果 wait
值為 245 (256-11).因此,您可以放心,來自 wait
的任何負(fù)返回值都必須代表致命信號,而不是正常返回.但請注意,這些進(jìn)程可能會殺死自己以偽造致命錯(cuò)誤.
In the former case, the process "segfaults" (by killing itself with SIGSEGV), and so wait
returns -11. In the latter case, the process exits with a return code of -11, and the resulting wait
value is 245 (256-11). You can therefore rest assured that any negative return value from wait
must represent a fatal signal, as opposed to a normal return. Note, though, that processes may kill themselves to fake a fatal error.
這篇關(guān)于確定 python 子進(jìn)程分段是否錯(cuò)誤的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網(wǎng)!