2009-02-10 17 views
0

我不太確定如何標記這個問題還是怎麼寫標題,因此,如果任何人有一個更好的主意,請編輯問題與控制的環境下運行的應用程序(Win32的)

這裏的處理:

前一段時間我寫了一個計算奧林匹克管理系統一點點但卻是一個關鍵部分。系統的工作是從參與者(代碼文件)獲取提交內容,編譯它們,根據預定義的測試用例運行它們並返回結果。加上所有其他的東西,你可以想象它應該做的。

我寫的部分叫做限制器。這是一個小程序,其工作是採取另一個程序並在受控環境中運行。在這種情況下的控制意味着對可用內存的限制,計算時間和對系統資源的訪問。此外,如果程序崩潰,我應該能夠確定異常的類型並向用戶報告。另外,當進程終止時,應該注意它執行了多長時間(分辨率至少爲0.01秒,更好)。

當然,理想的解決方案是虛擬化,但我沒那麼有經驗。

我對此的解決方案分爲三部分。

最簡單的部分是對系統資源的訪問。該程序只需使用有限的訪問令牌即可執行。我組合了一些基本(每個人,匿名等)訪問令牌,可用於所有進程,以便爲系統提供實際的只讀訪問權限,但執行文件夾除外。

內存的限制是通過作業對象完成的 - 它們允許指定最大內存限制。

最後,爲了限制執行時間並捕獲所有異常,我的Limiter作爲調試器附加到進程中。因此,我可以監控花費的時間,如果花費的時間太長,可以終止花費的時間。請注意,我無法爲此使用Job對象,因爲它們只報告作業的內核時間和用戶時間。一個進程可能會做一些類似Sleep(99999999)這樣的計數,但它們都不會計算在內,但仍會禁用測試機器。因此,儘管在最終執行時間內我不計算進程空閒時間,但它仍然必須有一個限制。

現在,我不是這種低級別的東西的專家。我花了幾天的時間閱讀MSDN並玩耍,然後盡我所能提出了一個解決方案。不幸的是,它看起來沒有像預期的那樣運行。大多數情況下它似乎工作正常,但奇怪的情況下不斷爬升。剛纔我有一個小小的C++程序,它自己運行在一瞬間,但是我的Limiter報告了用戶模式時間的8秒(從工作計數器中獲取)。這是代碼。它打印輸出大約半秒,然後花費超過7秒的時間來等待:

#include <iostream> 
#include <vector> 
using namespace std; 

int main() 
{ 
    vector< vector<int> > dp(50000, vector<int>(4, -1)); 
    cout << dp.size(); 
} 

限制器的代碼是相當漫長的,所以我不會在這裏包括它。我也覺得我的方法可能有問題 - 也許我不應該做調試器的東西。也許有一些我不知道的常見陷阱。

我想就其他人如何解決這個問題提供一些建議。也許已經有這樣做了,我的限制器已經過時了嗎?


補充:這個問題似乎是在我上面張貼的小程序。我爲它打開了一個 new question,因爲它有點不相關。我仍然喜歡這種限制程序的方法。

+0

您使用的是調試版本嗎?這是否與所連接的調試器一起運行?如果是這樣,它是否看到任何異常? – newgre 2009-02-10 11:55:22

+0

Nop,這也發生在發佈中。我設置了一些輸出,並且這8秒鐘不在Listener中。 – 2009-02-10 11:56:48

回答

0

使用附加的調試器運行可以改變應用程序的特性。性能可能受到影響,代碼路徑甚至可能改變(如果目標進程根據調試器的存在執行操作,即IsDebuggerPresent)。

我們使用的另一種方法是將我們自己的應用程序配置爲作爲JIT調試器運行。通過設置AeDebug註冊表項,您可以控制應用程序崩潰時調用哪個調試器。這種方式只在目標進程崩潰時才跳入,並且在正常運行時不會影響進程。

本網站有關於設置事後調試器的一些細節:Configuring Automatic Debugging

你的方法限制內存,獲得時間等等,都聽起來很完美。

相關問題