2013. 1. 4. 09:26ㆍProgramming/윈도우 드라이버
PAGED_CODE는 다음과 같이 생긴 매크로이다.
#define PAGED_CODE(){\
if(KeGetCurrentIrql() > APC_LEVEL) { \
kdPrint(""EX: Pageable code called at IRQL %d\n", KeGetCurrentIrql())); \
PAGED_ASSERT(FALSE); \
} \
}
현재의 IRQL을 체크해보고 IRQL이 APC_LEVEL 보다 높다면 시스템을 종료시킨다.
디바이스 드라이버의 세계에서 중요한 규칙 중 하나는 IRQL이 Dispatch 레벨 이상일 때는 페이지 폴트가 일어나서는 안된다는 것이다.
IRQL >= DISPATCH_LEVEL 일 때 페이지 폴트가 일어나게 되면 시스템은 크래쉬 된다.
위 규칙을 알고나면 #pragma alloc_text를 이용해서 코드를 페이징 가능하게 만들었을 경우에, IRQL이 DISPATCH_LEVEL 이상인 상태에서 해당 함수가 불릴 경우 페이지 폴트가 발생해서 블루스크린이 발생할 수도 있다는 것을 알 수 있다.
따라서 IRQL이 높을 때 불릴 수 있는 함수들은 paged pool에 할당해서는 안된다.
그런데 운이 좋아서 해당 시점에 코드가 램에 잘 존재하고 있어서 페이지 폴트가 일어나지 않는다면 이는 버그를 감추어주게 되고 나중에 더 골치 아픈 문제를 가져다 준다.
페이징 가능한 함수들에 PAGED_CODE 매크로를 사용하면 이런 운에 의해 감추어지는 버그들을 없애 버리고 곧장 시스템을 크래쉬 시켜 버림으로써 문제가 있는 부분을 쉽게 찾아낼 수 있다.
그래서 페이징 가능한 모든 코드에는 함수의 시작부에 PAGED_CODE() 매크로를 사용하는 것이다.