今天在調試驅動的時候,發現一個開始覺得很奇怪的問題,就是調用RtlStringCbPrintfW函數來格式化WCHAR字符串時,一定藍屏,提示
IRQL_NOT_LESS_OR_EQUAL,并且比較郁悶的是,在虛擬機上有時不會出現,有時會出現,但在真正的主機上一定會出現(Windows xp sp2)。
一般出現IRQL_NOT_LESS_OR_EQUAL,是IRQL在級別高的地方調用了分頁內存,所以,我就想到把當前的IRQL打出來看看,發現在進入函數
的時候,當前的IRQL是0(PASSIVE_LEVEL),而在執行這段代碼的地方,IRQL是2(DISPATCH_LEVEL),是什么原因使得IRQL發生了變化呢?
仔細查看代碼后,發現了原因,因為在執行這段代碼之前,通過NdisAcquireSpinLock獲取旋轉鎖,而在旋轉鎖釋放之前,其中的代碼是跑在
IRQL=2的,另外,RtlStringCbPrintfW需要處理分頁內存(PagedPool),但在IRQL=2的情況下,是只能處理非分頁內存的(NonpagedPool),所以,
就產生了上面的藍屏現象。
這里給出驅動內存的分配細節:
驅動編程時,也有兩種申請內存的方式:
(1).在核心棧中申請,在X86 R0級中,核心棧只有約兩個頁面的大小,所以DDK中提到,不能使用遞歸調用。
(2).在核心堆中申請,比如ExAllocatePoolWithTag函數就可以。不過核心堆分成兩種:分頁的、非分頁的。
另外,獲取當前IRQL級別方法:
KIRQL uIrql = KeGetCurrentIrql();
DEBUG_INFO(("%s is run on level: %x\n", __FUNCTION__, uIrql));
posted on 2009-01-14 17:05
水 閱讀(5031)
評論(0) 編輯 收藏 引用 所屬分類:
windows驅動