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