確認方法、どの制限を超えましたか?(ulimitのためにプロセスが終了しました。)


11

プロセスが無制限の環境で実行されると仮定しましょう:

(
ulimit  ... -v ... -t ... -x 0 ...
./program
)

プログラムは終了します。

多くの理由が考えられます。メモリ/時間/ファイルの制限を超えています。単純なセグメンテーションフォルト。または戻りコード0での正常終了。

プログラムを変更せずに、プログラムが終了した理由を確認するにはどうすればよいですか?

PS私は「バイナリが与えられたとき」を意味します。多分いくつかのラッパー(ptrace-ingなど)が役立つでしょう。

回答:


6

一般的に言えば、残念ながらそうはならないでしょう。(一部のオペレーティングシステムはそれを提供する場合がありますが、これをサポートしていることがわかっているオペレーティングシステムについては知りません。)

リソース制限のリファレンスドキュメント:getrlimitPOSIX 2008以降。

CPU制限を例にとりますRLIMIT_CPU

  • プロセスがソフト制限を超えると、プロセスが送信されます SIGXCPU
  • プロセスがハード制限を超えると、明白になります SIGKILL

あなたができる場合はwait()、あなたのプログラムにそれが殺された場合、あなたは言うことができますSIGXCPU。しかしSIGKILL、ハードリミットの違反で派遣された派遣を、外部からの単純な古い殺害と区別することはできません。さらに、プログラムがを処理する場合、XCPU外部からそれを見ることもできません。

同じことRLIMIT_FSIZE。プログラムが処理しない場合はSIGXFSZwait()ステータスから確認できます。ただし、ファイルサイズの制限を超えると、唯一発生するのは、その制限を再度テストしようとするI / Oが単に受信するだけです。EFBIGこれは、プログラムによって内部的に処理されます(または、残念ながら処理されません)。プログラムがを処理する場合、SIGXFSZ上記と同じ-それについてはわかりません。

RLIMIT_NOFILE?まあ、あなたは信号を得ることすらありません。open友達EMFILEはプログラムに戻るだけです。それ以外の場合は問題ありません。そのため、その状況で失敗するようにコーディングされた方法で失敗します(または失敗しません)。

RLIMIT_STACK?古き良きSIGSEGV、配信される他の理由のスコアと区別できません。(それがwaitステータスから、それがプロセスを殺したものだったことがわかるでしょう。)

RLIMIT_ASそして、RLIMIT_DATAばかりになりますmalloc()と、いくつか他の人が失敗を開始(または受信SIGSEGVLinux上でスタックを拡張しようとしたときに、ASの制限がヒットした場合)。プログラムが非常によく書かれていない限り、おそらくその時点でかなりランダムに失敗するでしょう。

つまり、簡単に言えば、一般的に、失敗は他のプロセスの死の理由と視覚的に異なるわけではないため、確信が持てないか、プログラムから完全に処理することができます。外部から。

私が知る限り、あなたができる最善のことは、プログラムを分岐して待機する少しのコードを書くことです。

  • 検出する終了ステータスをチェックSIGXCPUし、SIGXFSZ(私の知る限り、これらの信号のみがリソース制限の問題のためにOSによって生成されます)。正確なニーズによっては、リソースの制限に関連しているSIGKILLと想定することSIGSEGVもできますが、それは少しストレッチです。
  • getrusage(RUSAGE_CHILDREN,...)他の実装についてのヒントを得るために、実装から何を得ることができるかを見てください。

ここで役立つOS固有の機能(おそらくptraceLinuxやSolarisのようなものdtrace)、またはおそらくデバッガータイプの手法が存在する可能性がありますが、それは特定の実装にさらに結びつくことになります。


(私が完全に気付いていない魔法のことで他の誰かが答えてくれることを願っています。)


OK。(Mem)メモリ制限を超えている、(Time)時間制限、(Err)その他のエラーの3つだけはどうですか?私はラッパーを作成することについて知っていますmallocが、残念ながらそれは一般的にメモリの問題を解決しません、それは一般的にシステムコールに関するものですbrk(私は正しいですか?)。
Grzegorz Wierzowiecki '26 / 10/26

1
プログラムを制御しない場合、mallocのラッピングは役に立ちません。あなたは次のようにハックの話をしている場合はLD_PRELOAD、あなたの「プロセスを変更しない」の制約のためにそれの境界線をINGの、そして、それは少し助けではなく、本当にだろう- 、、malloc 及びで失敗します、あなたが本当にメモリ不足の状況にあった正確にいるかのように、 (ただし、メモリ制限をはるかに下回ります)。制限時間はで、壁掛け時計の制限時間はわかりません。brksbrkmmapENOMEMRLIMIT_CPU
マット

について私を確保していただきありがとうございbrkます。私が見るように、「プログラムがシグナルX、Y、Z ...を処理していない」という要件は、waitpidのおかげで、SIGXCPU、SIGXFSZ、SIGSEGVの問題を解決します(私が間違っている場合は修正してください)。
Grzegorz Wierzowiecki 2011年

1
SIGSEGVは、リソース制限違反ではない状況で発生する可能性があります(ヌルポインター逆参照が発生する最も一般的なものです)。それが原因であるulimitヒットを確認することはできません。
マット

について私を確保していただきありがとうございbrkます。私が見るように、「プログラムがシグナルX、Y、Z ...を処理していない」という要件は、waitpidのおかげで、SIGXCPU、SIGXFSZ、SIGSEGVの問題を解決します。私は正しいですか?
Grzegorz Wierzowiecki

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.