2015-05-19 33 views
2

我正在爲IO篩選器驅動程序編寫內核模式測試。當我運行我的測試時,它們都會通過,但如果我連續運行它們3次,則測試開始失敗。我把問題縮小到ExAllocatePoolWithTag,經過一段時間後開始返回STATUS_INSUFFICIENT_RESOURCES。要重現此問題我寫了一個專用的測試如何正確使用ExAllocatePoolWithTag,以便它不返回STATUS_INSUFFICIENT_RESOURCES?

static void __stdcall TestFoo_StressLoad() 
{  
    int i;  
    for(i = 0; i < 100; i++) 
    { 
     CFIX_ASSERT(QueueInitialize() == 0); // Soon returns STATUS_INSUFFICIENT_RESOURCES 
     CFIX_ASSERT(QueueDestroy() == 0); 
    } 
} 

我使用的模式是:

  1. 分配內存(ExAllocatePoolWithTag
  2. 執行單一測試
  3. 釋放內存(ExFreePoolWithTag

我的問題是:如何正確使用ExAllocatePoolWithTag以便它不返回STATUS_INSUFFICIENT_RESOURCES

下面是QueueInitialize和提取QueueDestroy

int QueueInitialize() 
{ 
    SIZE_T poolSize;  
    poolSize = sizeof(Event) * 1024; 
    Queue = (Event *)ExAllocatePoolWithTag(NonPagedPool, poolSize, '9gaT'); 

    if(Queue == NULL) 
     return STATUS_INSUFFICIENT_RESOURCES; 

    return 0; 
} 

int QueueDestroy() 
{ 
    SIZE_T poolSize; 
    if(Queue != NULL) 
    {  
     poolSize = sizeof(Event) * 1024; 
     ExFreePoolWithTag((void *)Queue, '9gaT'); 
     ProcessQueue = NULL; 
     return 0; 
    } 
} 

我使用CFIX內核測試和運行在Windows 7 X64的測試。

+0

對於非分頁池可能太大了嗎?什麼是'sizeof(Event)'? –

+0

@HarryJohnston'poolSize = 1335296'和'sizeof(Event)= 1,304'。它確實看起來太大了,我從來沒有意識到這一點......如果我減少事件的大小,我認爲我可以做到幾KB,這將允許我多次重複使用'ExAllocatePoolWithTag'進行測試? TNX。 – oleksii

+0

這隻比兆字節多一點。我不會認爲這太過分。 (我的機器上的任務管理器顯示總共非頁面緩衝池大小爲137MB)。但我不知道還有什麼可能會出錯,這可能值得一試。您也可以嘗試在驅動程序初始化時分配一次內存,並在必要時重新使用它。 –

回答

1

我建議使用lookaside列表,因爲你的緩衝區總是相同的大小。這將顯着減少內核堆碎片。

+0

我猜測在正常情況下(即不在測試期間),這是不可取的 - 這意味着驅動程序可能會長時間佔用實際上並不需要的寶貴的非頁面內存。我想可能在測試過程中使用不同的內存分配器,這取決於具體情況。 –

+0

取決於隊列大小,項目大小以及使用頻率。我猜想這個記憶是微不足道的,除非隊列持有巨大的物品。如果它是一個IRP隊列或類似的地方,只使用像指針這樣的小值,那麼優於ExAllocXxx()。我曾在許多司機中使用過它們,並且從未遇到內存問題。 –

相關問題