17

私は学生のプログラムを採点するプログラムを書いていますが、ご想像のとおり、時々セグメンテーション違反が発生します。私が抱えている問題は、学生がセグメンテーション違反をプログラムしたときに、何が起こったのかを示す兆候がないことです。

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

stderrstdoutおよび からのリターン コードを取得しますsubprocessが、プログラム セグメンテーション フォールトの場合、stderrstdoutであり、空であり、リターン コードは -11 です。ここで、-11 終了コードを探して、それが戻りコードである場合、セグメンテーション違反があったと想定できますが、生徒が戻りたいと感じたという理由だけで、生徒のコードが戻りコードとして -11 を持つことを妨げるものは何もありません。 -11.

-11 を返すように感じるのではなく、サブプロセスのセグメンテーションが失敗したかどうかをどのように判断しますか? 私は stderr と stdout にあるものについてはあまり気にしません。そのために、これを含む出力の取得を扱う多くの投稿を見てきましたが、出力についてはそれほど気にしません。 stderr から "Segmentation Fault" 文字列を取得できればいいのですが、本当に必要なのは、サブプロセスに何が起こったのかを明確に伝える方法です。

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

前者の場合、プロセスは (SIGSEGV で自分自身を強制終了することによって) 「segfault」するため、wait-11 を返します。後者の場合、プロセスはリターン コード -11 で終了し、結果のwait値は 245 (256-11) になります。したがって、 からの負の戻り値はwait、通常の戻り値とは対照的に、致命的なシグナルを表している必要があります。ただし、致命的なエラーを偽装するために、プロセスが自分自身を強制終了する可能性があることに注意してください。

于 2013-09-11T02:55:47.383 に答える