プロセスが無制限の環境で実行されているとします。
(
ulimit ... -v ... -t ... -x 0 ...
./program
)
プログラムが終了します。
理由はさまざまです。単純なセグメントエラーが原因でメモリ/時間/ファイル制限が超過したか、戻りコード0で正常に終了することがあります。
プログラムを変更せずにプログラムが終了した理由をどのように確認できますか?
PS私は「バイナリが与えられたとき」を意味しました。たぶん、いくつかのラッパー(ptrace-ingなど)が役に立ちますか?
答え1
一般的に残念ながら、私はあなたができないと思います。 (一部のオペレーティングシステムではこの機能を提供できますが、どのオペレーティングシステムがサポートしているかわかりません。)
リソース制限リファレンスドキュメント:getrlimit
POSIX 2008から。
CPU制限を例にしてみましょうRLIMIT_CPU
。
- プロセスがソフト制限を超えると送信されます。
SIGXCPU
- プロセスがハード制限を超えると、単純なメッセージが表示されます。
SIGKILL
wait()
プログラムでできる場合は、プログラムが終了したかどうかを確認できますSIGXCPU
。ただし、SIGKILL
厳格な制限違反の派遣と外部からの通常の殺人との違いは区別できません。しかも、プログラムが処理するとXCPU
外部からは見えません。
についても同様ですRLIMIT_FSIZE
。プログラムが処理できない場合は、ステータスSIGXFSZ
で確認できます。wait()
ただし、ファイルサイズの制限を超えると、制限を再テストしたい追加のI / Oが受信されますが、EFBIG
これはプログラムによって内部的に処理されます(残念ながら処理されません)。プログラムがSIGXFSZ
上記と同じようにそれを処理する場合 - ユーザーはそれを知りません。
RLIMIT_NOFILE
?まあ、信号も受けられないね。open
友達と一緒にショーに戻ってくださいEMFILE
。他の何も妨げられないので、この場合、エンコードがどのように失敗しても失敗(または失敗)します。
RLIMIT_STACK
?長すぎるSIGSEGV
ため、他の原因と区別できません。 (これがプロセスを殺した原因であることを状態を通して知ることができますwait
。)
RLIMIT_AS
RLIMIT_DATA
makeだけでmalloc()
他のものは失敗し始めます(またはSIGSEGV
Linuxでスタックを拡張しようとするとAS制限に達すると受信します)。プログラムがうまく書かれていないと、ランダムに失敗する可能性があります。
簡単に言えば、通常、失敗はプロセスの終了の他の理由とは大きく異なるため、確信が持てないか、プログラムで完全に処理される可能性があります。この場合、進行状況/いつ/方法を決定します。一方、あなたは外から来たものではありません。
私が知っている限り、あなたができる最善は、プログラムを分岐して待ってから、次のコードを書くことです。
- 検出する終了ステータスを確認します
SIGXCPU
(SIGXFSZ
AFAIK、これらのシグナルはリソース制限の問題に対してオペレーティングシステムによってのみ生成されます)。特定の要件に応じてリソース制約に関連していると仮定することもできますが、SIGKILL
これはSIGSEGV
やや無理です。 getrusage(RUSAGE_CHILDREN,...)
他の実装に関するヒントを入手するには、実装から何が得られるかを確認してください。
ptrace
ここでは、OS固有のツール(LinuxまたはSolarisのツール)やデバッガタイプの技術が役に立つかもしれませんが、dtrace
これは特定の実装に関連しています。
(私は全く知らない魔法のような質問に他の誰かが答えてくれることを願っています。)
答え2
私は現在同じ問題に対していくつかのことをしています。部分的に解決しました。使った審査サブシステム[1]でタスクを追跡できます。