6

私はUbuntuでCで一種の「サンドボックス」を実行しています。プログラムを受け取り、ユーザーの下で安全に実行しますnobody(そして信号などを傍受します)。また、メモリと時間制限を割り当て、時間とメモリ使用量を測定します。
(興味がある方のために説明すると、これは一種の「オンライン審査員」がテスト データにプログラムをマークするためのものです)

現在、 mooshak のsafeexecモジュールを採用しています。ほとんどの機能は正常に動作しますが、メモリ使用量に問題があるようです。(かなり不正確です)

ここでアドバイスを試し、VM を から解析/proc/pid/statしたところ、精度の問題は修正されました。ただし、非常に迅速に終了するプログラムの場合は機能せず、0 が返されます。

safeexecプログラムは次のように動作するようです:

  1. それfork()
  2. execv()子プロセスで使用して、目的のプログラムを実行します
  3. 子プロセスが終了するまで、親プロセスからプログラムを監視します ( を使用するwait4と、たまたま CPU 使用率が返されますが、メモリは返されませんか?)そのため、子プロセスを
    解析し/proc/../statます (execv に置き換えられました)

では、なぜ VM in/proc/child_pid/statが 0 になることがあるのでしょうか?
execv() があまりにも早く終了し、/proc/child_pid/stat利用できないためですか?
もしそうなら、子供のメモリ使用量を取得する他の方法はありますか?
(これは制限時間内でプログラムを判断するためのものなので、valgrind のようにパフォーマンスが低下するものは許せません)

前もって感謝します。

4

3 に答える 3

3

子プロセスが独自のバージョンの et al を使用し、HWM メモリ使用量をログに記録するように手配できますかmalloc()(おそらく に登録されたハンドラーを使用しますatexit())。おそらく、メモリ管理ライブラリをロードするために LD_PRELOAD を使用するでしょう。これは、巨大な静的配列や巨大な自動配列では役に立ちません。


うーん、面白そうですね。ただし、静的/自動配列を追跡する方法はありますか?

静的メモリは、'size' コマンドで分析できます (多かれ少なかれ)。

自動配列は問題です。それらをどのように処理できるかわかりません。メモリ割り当てコードは、呼び出されたときに使用中のスタックの量を確認できます (ローカル変数のアドレスを確認します)。ただし、最大量のローカル配列が使用されているときにメモリが割り当てられるという保証はないため、せいぜい大雑把な尺度になります。

もう 1 つの考え: おそらく、デバッガー テクノロジ (ptrace()システム コール) を使用して、子プロセスを制御し、特に、/proc/....

于 2009-04-13T14:07:54.623 に答える
2

execve() の前にハード リソース制限 (RLIMIT_AS リソースの setrlimit) を設定できます。プログラムは、その量を超えるメモリを割り当てることができません。そうしようとすると、メモリ割り当て呼び出し (brk、mmap、mremap) が失敗します。プログラムがメモリ不足の状態を処理しない場合、segfault が発生し、wait4 によって返される終了ステータスに反映されます。

于 2009-04-13T14:09:43.387 に答える