Hi,
I am developing a serial driver in which i have a couple of DPC functions (one for processing read requests and another one for write requests).
In case of read, DPC function copies the data from hardware to the driver buffer, if necessary copies the data to the application
buffer, unmarks the read request to be cancellable and completes the request.
In case of Write the DPC function writes the data to hardware (buffer if required) and if all the data requested by the WRite command has been written, then it completes the write request.
When testing the driver for higher baud rates, i am consistently getting crashes in this DPC function. I am getting crashes at different locations , not in a single location. Below is the output of “analyze -v” command for one such crash.
The analysis output says that i am accessing paged memory at DPC level. However i didn’t allocate any pageable memory anywhere in my code.
BugCheck D1, {c5c4c466, 2, 0, 8bc44261}
Probably caused by : PortDriver.sys ( PortDriver!WdfRequestUnmarkCancelable+20 )
Followup: MachineOwner
nt!RtlpBreakWithStatusInstruction:
832b7840 cc int 3
0: kd> !analyze -v
*******************************************************************************
* *
* Bugcheck Analysis *
* *
*******************************************************************************
DRIVER_IRQL_NOT_LESS_OR_EQUAL (d1)
An attempt was made to access a pageable (or completely invalid) address at an
interrupt request level (IRQL) that is too high. This is usually
caused by drivers using improper addresses.
If kernel debugger is available get stack backtrace.
Arguments:
Arg1: c5c4c466, memory referenced
Arg2: 00000002, IRQL
Arg3: 00000000, value 0 = read operation, 1 = write operation
Arg4: 8bc44261, address which referenced memory
Debugging Details:
READ_ADDRESS: c5c4c466
CURRENT_IRQL: 2
FAULTING_IP:
Wdf01000!FxIoQueue::RequestCancelable+e
8bc44261 80b9a400000000 cmp byte ptr [ecx+0A4h],0
DEFAULT_BUCKET_ID: VISTA_DRIVER_FAULT
BUGCHECK_STR: 0xD1
PROCESS_NAME: SerialValidati
TRAP_FRAME: 8078ae3c – (.trap 0xffffffff8078ae3c)
ErrCode = 00000000
eax=87e46290 ebx=8719f010 ecx=c5c4c3c2 edx=00000400 esi=87e46290 edi=781b9d68
eip=8bc44261 esp=8078aeb0 ebp=8078aebc iopl=0 nv up ei ng nz na po nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00010282
Wdf01000!FxIoQueue::RequestCancelable+0xe:
8bc44261 80b9a400000000 cmp byte ptr [ecx+0A4h],0 ds:0023:c5c4c466=??
Resetting default scope
LAST_CONTROL_TRANSFER: from 8331bffb to 832b7840
STACK_TEXT:
8078aa04 8331bffb 00000003 a2f9e648 00000065 nt!RtlpBreakWithStatusInstruction
8078aa54 8331caf9 00000003 c5c4c466 8bc44261 nt!KiBugCheckDebugBreak+0x1c
8078ae1c 8327dcdb 0000000a c5c4c466 00000002 nt!KeBugCheck2+0x68b
8078ae1c 8bc44261 0000000a c5c4c466 00000002 nt!KiTrap0E+0x2cf
8078aebc 8bc4cc29 8719f010 00000000 00000000 Wdf01000!FxIoQueue::RequestCancelable+0xe
8078aee8 917c4d60 87180ea0 87e46290 8078af24 Wdf01000!imp_WdfRequestUnmarkCancelable+0xab
8078aef8 917c8c28 781b9d68 00000000 c0000001 PortDriver!WdfRequestUnmarkCancelable+0x20 [c:\program files\windows kits\8.0\include\wdf\kmdf\1.11\wdfrequest.h @ 780]
8078af24 8bc81c40 78e608e8 8336a600 8719f748 PortDriver!PortWriteCompleteDPC+0x368 [d:\08-09-2014\08-09-2014\08-09-2014\dpc.c @ 339]
8078af40 8bc81c57 8078afa4 832b4935 8719f748 Wdf01000!FxDpc::DpcHandler+0x9b
8078af48 832b4935 8719f748 8719f710 00000000 Wdf01000!FxDpc::FxDpcThunk+0xd
8078afa4 832b4798 83368d20 8818ed48 00000000 nt!KiExecuteAllDpcs+0xf9
8078aff4 832b3f5c ad01fbe4 00000000 00000000 nt!KiRetireDpcList+0xd5
8078aff8 ad01fbe4 00000000 00000000 00000000 nt!KiDispatchInterrupt+0x2c
WARNING: Frame IP not in any known module. Following frames may be wrong.
832b3f5c 00000000 0000001a 00d6850f bb830000 0xad01fbe4
STACK_COMMAND: kb
FOLLOWUP_IP:
PortDriver!WdfRequestUnmarkCancelable+20 [c:\program files\windows kits\8.0\include\wdf\kmdf\1.11\wdfrequest.h @ 780]
917c4d60 5d pop ebp
FAULTING_SOURCE_CODE:
776: WDFREQUEST Request
777: )
778: {
779: return ((PFN_WDFREQUESTUNMARKCANCELABLE) WdfFunctions[WdfRequestUnmarkCancelableTableIndex])(WdfDriverGlobals, Request);
780: }
781:
782: //
783: // WDF Function: WdfRequestIsCanceled
784: //
785: typedef
SYMBOL_STACK_INDEX: 6
SYMBOL_NAME: PortDriver!WdfRequestUnmarkCancelable+20
FOLLOWUP_NAME: MachineOwner
MODULE_NAME: PortDriver
IMAGE_NAME: PortDriver.sys
DEBUG_FLR_IMAGE_TIMESTAMP: 542a97e1
FAILURE_BUCKET_ID: 0xD1_PortDriver!WdfRequestUnmarkCancelable+20
BUCKET_ID: 0xD1_PortDriver!WdfRequestUnmarkCancelable+20
Followup: MachineOwner
0: kd> .trap 0xffffffff8078ae3c
ErrCode = 00000000
eax=87e46290 ebx=8719f010 ecx=c5c4c3c2 edx=00000400 esi=87e46290 edi=781b9d68
eip=8bc44261 esp=8078aeb0 ebp=8078aebc iopl=0 nv up ei ng nz na po nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00010282
Wdf01000!FxIoQueue::RequestCancelable+0xe:
8bc44261 80b9a400000000 cmp byte ptr [ecx+0A4h],0 ds:0023:c5c4c466=??
Below is the some of code in my write DPC.
// WdfSpinLockAcquire(pstDeviceContext->hPortSpinLock);
hRequest = pstDeviceContext->hCurrentWriteRequest;
…// Some code to write the data to hardware buffer if necessary
pstRequestContext->ulBytesNeedtoTransmit -= ulBytesTransmitting;
//Completing the Write Request
if(!pstRequestContext->ulBytesNeedtoTransmit)
{
lStatus = WdfRequestUnmarkCancelable(hRequest);
if(lStatus != STATUS_CANCELLED)
{
pstDeviceContext->hCurrentWriteRequest = NULL;
bIsSpinLockReleased = TRUE;
WdfSpinLockRelease(pstDeviceContext->hPortSpinLock);
WdfRequestCompleteWithInformation(hRequest, STATUS_SUCCESS,(ULONG_PTR)pstRequestContext->ulLength);
}
else
{
bIsSpinLockReleased = TRUE;
WdfSpinLockRelease(pstDeviceContext->hPortSpinLock);
}
}
I have used PAGED_CODE() macro for the functions in my code that creates DPC objects. The DPC objects themselves are present in non paged pool though. I am using the macro WdfObjectGet_DEVICE_CONTEXT for retrieving the device context space.
WHen i am not creating any paged memory at all why do i still see these errors related to page faults at higher IRQL levels?