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