Share via


Example 4: Valid Error Reported in the Wrong Place

PREfast for Drivers can report a valid error in one location that is actually caused by code in another location.

For example, when PREfast for Drivers analyzes a code path that raises the IRQL at which the driver is executing, it assumes that the programmer intended to raise the IRQL and it does not issue a warning. However, if the code then calls a function for which the raised IRQL is invalid, PREfast for Drivers then warns about the invalid IRQL.

In the following example, PREfast for Drivers reports Warning 28123 while analyzing function Y. Function Y begins by calling KeAcquireSpinLockAtDpcLevel, which can be called only when then the caller is executing at DISPATCH_LEVEL. Based on this call, PREfast for Drivers assumes that the caller is executing at DISPATCH_LEVEL. Therefore, when Y calls KeDelayExecutionThread, which must be called at IRQL <=APC_LEVEL, PREfast for Drivers warns that KeDelayExecutionThread is being called at an IRQL that is too high. However, based on the call to KeDelayExecutionThread, PREfast for Drivers now assumes that the code should be executing at APC_LEVEL. Therefore, when it encounters a call to KeReleaseSpinLockFromDpcLevel, which must be called at DISPATCH_LEVEL, PREfast for Drivers warns that the function is being called at an IRQL that is too low.

17    void Y(void)
18    //This routine will be always called at DISPATCH_LEVEL
19    {

PREfast analysis path begins

20    LARGE_INTEGER SleepTime;
21    KeAcquireSpinLockAtDpcLevel(&spinLock);
22    
23    if(some_condition) {
24    //Driver performs I/O to the hardware and decides
25    //to get a response or check the state.
26    
 27    KeDelayExecutionThread(KernelMode, FALSE, &SleepTime);

xy.c(27) : warning 28123: The function KeDelayExecutionThread is not permitted to be called at a high IRQ level. Prior function calls are inconsistent with this constraint: It may be that the error is actually in some prior call that limited the range.problem occurs in function 'Y'Path includes 4 statements on the following lines:20 21 23 27

28    }
 29    KeReleaseSpinLockFromDpcLevel(&spinLock);
30    }

xy.c(29) : warning 28122: The function KefReleaseSpinLockFromDpcLevel is not permitted to be called at a low IRQ level. Prior function calls are inconsistent with this constraint: It may be that the error is actually in some prior call that limited the rangeproblem occurs in function 'Y'Path includes 5 statements on the following lines:20 21 23 27 29

There is clearly an IRQL-related error in the function, but it's not clear whether the error is in the initial call to KeAcquireSpinLockAtDpcLevel or occurs at some later point.

To correct this situation, consider one of the following solutions:

  • If the wait time is short (less than a clock tick, but more than for a few instructions), call KeStallExecutionProcessor, which can be called at any IRQL, instead of KeDelayExecutionThread.

  • Use CustomTimerDpc to queue a timer object with a callback function that checks the hardware state.

 

 

Send comments about this topic to Microsoft

Build date: 5/3/2011