I have a drive that uses a worker thread (based on src\input\vserial sample). The driver runs fine on an XP 32bit computer, but bug check on a AMD64 dual in EvtDeviceContextCleanup. I just load then unload the driver so the execution path just went through the functions below.
NTSTATUS MyTestEvtDeviceAdd(IN WDFDRIVER Driver, PWDFDEVICE_INIT DeviceInit)
{
…
// Initialize the work queue semaphore
KeInitializeSemaphore(&pDevContext->IrpQueueSem, 0, MAXLONG);
// Reset the termination flag
pDevContext->bTerminateThread = FALSE;
InitializeObjectAttributes(&objAttrs, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
status = PsCreateSystemThread(&hThread, THREAD_ALL_ACCESS, &objAttrs, (HANDLE)0, NULL, WorkerThreadMain, pDevContext);
// Obtain pointer and close thread
ObReferenceObjectByHandle(hThread, THREAD_ALL_ACCESS, NULL, KernelMode, (PVOID*)&pDevContext->pThreadObj, NULL);
ZwClose(hThread);
…
}
VOID WorkerThreadMain(IN PVOID pContext)
{
…
while(TRUE)
{
…
KeWaitForSingleObject(&pDevContext->IrpQueueSem, Executive, KernelMode, FALSE, NULL);
// Exit when termination flag is set
if(pDevContext->bTerminateThread)
{
PsTerminateSystemThread(STATUS_SUCCESS);
return;
}
// Do its things here
…
}
}
VOID MyTestEvtDeviceContextCleanup(IN WDFDEVICE Device)
{
…
if(pDevContext->pThreadObj)
{
// Set the termination flag
pDevContext->bTerminateThread = TRUE;
// Wake worker thread up so it can handle the termination
KeReleaseSemaphore(&(pDevContext->IrpQueueSem), 0, 1, TRUE);
// Wait for the thread to terminate
status = KeWaitForSingleObject(&(pDevContext->pThreadObj), Executive, KernelMode, FALSE, NULL);
ObDereferenceObject(&(pDevContext->pThreadObj));
}
…
}
I compared the value of pDevContext->pThreadObj at creation time and crash time, and they are the same. Below is output from !analyze -v
*******************************************************************************
* *
* Bugcheck Analysis *
* *
*******************************************************************************
IRQL_NOT_LESS_OR_EQUAL (a)
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 a kernel debugger is available get the stack backtrace.
Arguments:
Arg1: 0000000100060000, memory referenced
Arg2: 000000000000000c, IRQL
Arg3: 0000000000000001, value 0 = read operation, 1 = write operation
Arg4: fffff8000105b554, address which referenced memory
Debugging Details:
*** No owner thread found for resource fffff800013e6ae0
*** No owner thread found for resource fffff800013e6ae0
WRITE_ADDRESS: 0000000100060000
CURRENT_IRQL: c
FAULTING_IP:
nt!KeWaitForSingleObject+404
fffff800`0105b554 4c8928 mov qword ptr [rax],r13
DEFAULT_BUCKET_ID: DRIVER_FAULT
BUGCHECK_STR: 0xA
PROCESS_NAME: System
TRAP_FRAME: fffffadfc8e8ca60 – (.trap fffffadfc8e8ca60)
NOTE: The trap frame does not contain all registers.
Some register values may be zeroed.
rax=0000000100060000 rbx=0000000000000000 rcx=fffffadfcda95fb8
rdx=fffff78000000014 rsi=0000000000000008 rdi=fffffadfcd5144f0
rip=fffff8000105b554 rsp=fffffadfc8e8cbf0 rbp=fffffadfcdd52bd0
r8=0000000000000000 r9=0000000000000000 r10=fffff78000000008
r11=0000000000000000 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
iopl=0 nv up ei pl zr na po nc
nt!KeWaitForSingleObject+0x404:
fffff800`0105b554 4c8928 mov qword ptr [rax],r13 ds:0004:0000=???
Resetting default scope
LOCK_ADDRESS: fffff800013e6be0 – (!locks fffff800013e6be0)
Resource @ nt!IopDeviceTreeLock (0xfffff800013e6be0) Shared 1 owning threads
Threads: fffffadfcdd52bd0-01<*>
1 total locks, 1 locks currently held
PNP_TRIAGE:
Lock address : 0xfffff800013e6be0
Thread Count : 1
Thread address: 0xfffffadfcdd52bd0
Thread wait : 0x10611d8a
LAST_CONTROL_TRANSFER: from fffff8000105c0c7 to fffff8000119c2c0
STACK_TEXT:
fffffadfc8e8c1e8 fffff800
0105c0c7 : 000000000000000a fffffadf
cdd52bd0 0000000100060000 00000000
00000001 : nt!DbgBreakPointWithStatus
fffffadfc8e8c1f0 fffff800
0105d3d0 : fffff80000000003 00000000
0000000a 0000000100060000 00000000
0000000c : nt!KiBugCheckDebugBreak+0x17
fffffadfc8e8c260 fffff800
01193144 : 000000000000000a 00000001
00060000 000000000000000c 00000000
00000001 : nt!KeBugCheck2+0x6a0
fffffadfc8e8c8a0 fffff800
011a21b4 : 000000000000000a 00000001
00060000 000000000000000c 00000000
00000001 : nt!KeBugCheckEx+0x104
fffffadfc8e8c8e0 fffff800
011a1147 : 0000000000000001 00000001
00060000 0000000000000000 fffffadf
c8e8ca60 : nt!KiBugCheckDispatch+0x74
fffffadfc8e8ca60 fffff800
0105b554 : 0000e5fb00000000 00000000
00000008 0000000000000004 fffffadf
cda95f00 : nt!KiPageFault+0x207
fffffadfc8e8cbf0 fffffadf
c8b459c9 : fffffadfcda95fb0 fffffadf
00000000 0000000000000000 00000000
00000000 : nt!KeWaitForSingleObject+0x404
fffffadfc8e8cc80 fffffadf
c5f12f6d : 000005203256a438 00000000
a079654b 0000000000000001 00000000
00000000 : MyTestDev!MyTestEvtDeviceContextCleanup+0x179 [c:\projects\kwdftest\mytestdev.c @ 915]
fffffadfc8e8ccd0 fffffadf
c5f15d2f : fffffadfcda95bc0 fffffadf
cda95bc0 fffffadfcda95be0 fffffadf
cd514530 : Wdf01000!FxObject::CallCleanup+0x75
fffffadfc8e8cd00 fffffadf
c5f14f9b : fffffadfcda95bc0 fffffadf
00000005 fffffadf45457000 00000000
00000101 : Wdf01000!FxObject::DisposeChildrenWorker+0x457
fffffadfc8e8ce80 fffffadf
c5f153be : fffffadfcda95bc0 fffffadf
c5f13700 fffffadfcd6e9001 00000000
00000002 : Wdf01000!FxObject::PerformDisposingDisposeChildrenLocked+0x1d3
fffffadfc8e8cf90 fffffadf
c5f1450e : fffffadfcda95bc0 fffffadf
cda95b00 fffffadfcda95b01 00000000
00000000 : Wdf01000!FxObject::PerformEarlyDisposeWorkerAndUnlock+0x23e
fffffadfc8e8d060 fffffadf
c5f54a56 : fffffadfcda95bc0 fffffadf
cd5dcb80 0000000000000124 00000000
00000000 : Wdf01000!FxObject::EarlyDispose+0x226
fffffadfc8e8d130 fffffadf
c5f5243f : fffffadfcd5dcb80 fffffadf
cd5dcb80 0000000000000124 fffffadf
cd5dcb80 : Wdf01000!FxPkgPnp::PnpEventRemovedCommonCode+0x2d2
fffffadfc8e8d1b0 fffffadf
c5f53855 : fffffadfcd5dcb80 00000520
00000004 fffffadf00000015 fffffadf
c5f816d0 : Wdf01000!FxPkgFdo::PnpEventFdoRemovedOverload+0x17
fffffadfc8e8d1e0 fffffadf
c5f53058 : fffffadfcd5dcb80 fffffadf
00000117 fffffadfcd5dcb80 00000520
3256a400 : Wdf01000!FxPkgPnp::PnpEnterNewState+0x385
fffffadfc8e8d2b0 fffffadf
c5f52d90 : fffffadfcd5dcb80 fffffadf
c8e8d430 0000000000000000 fffffadf
00000000 : Wdf01000!FxPkgPnp::PnpProcessEventInner+0x154
fffffadfc8e8d3a0 fffffadf
c5f45b2f : fffffadfcd5dcb80 fffffadf
00000200 0000000000000000 fffffadf
c5f8c1a8 : Wdf01000!FxPkgPnp::PnpProcessEvent+0x4fc
fffffadfc8e8d480 fffffadf
c5f433a3 : fffffadfcd5dcb80 fffffadf
c8e8d5b0 0000000000000000 00000520
3256a438 : Wdf01000!FxPkgPnp::_PnpRemoveDevice+0xe7
fffffadfc8e8d530 fffffadf
c5f1ad8f : fffffadfcd5dcb80 fffffadf
cd684cf0 fffffadfcd684cf0 fffffadf
cdbf2630 : Wdf01000!FxPkgPnp::Dispatch+0x79b
fffffadfc8e8d600 fffffadf
c5f1acc2 : fffffadfcd5db070 fffffadf
cd684cf0 fffffadfcd5db070 fffff800
01000000 : Wdf01000!FxDevice::Dispatch+0xb7
fffffadfc8e8d630 fffff800
014e6442 : fffffadfcd5db070 fffffadf
cd684cf0 fffffadfc8e8d758 00000000
ffffffff : Wdf01000!FxDevice::DispatchWithLock+0x82
fffffadfc8e8d670 fffff800
014e6a1f : fffffadfcdbf2870 fffffadf
c8e8d758 0000000000000000 00000000
00000000 : nt!IopSynchronousCall+0x2b2
fffffadfc8e8d710 fffff800
0104fe47 : fffffadfcdbf2870 fffff800
00000002 fffffadfcdbf2870 00000000
00000000 : nt!IopRemoveDevice+0x1cf
fffffadfc8e8d7f0 fffff800
014e9b4e : fffffadfcdbf2630 fffff800
00000015 fffffa8000357930 00000000
00000002 : nt!IopRemoveLockedDeviceNode+0x667
fffffadfc8e8d890 fffff800
014f37bf : fffffadfcdbf2870 fffffa80
00357930 0000000000000002 fffff800
01007201 : nt!IopDeleteLockedDeviceNodes+0x29e
fffffadfc8e8d910 fffff800
014f0a10 : fffffadfc8e8da70 fffff800
01632210 fffffadfc8e8da90 81010101
01010100 : nt!PiProcessQueryRemoveAndEject+0x188f
fffffadfc8e8da40 fffff800
01185cb4 : fffffadfcd9d5d40 fffffadf
00000001 0000000000000000 00000000
00000000 : nt!PiWalkDeviceList+0x790
fffffadfc8e8dce0 fffff800
0157059e : 0000000000000001 00000000
00000000 0000000000000000 00000000
00000000 : nt!ExpWorkerThread+0x194
fffffadfc8e8dd70 fffff800
0119be76 : fffff80001185b20 00000000
00000001 fffff80001570560 00000000
00000000 : nt!PspSystemThreadStartup+0x3e
fffffadfc8e8ddd0 00000000
00000000 : 0000000000000000 00000000
00000000 0000000000000000 00000000
00000000 : nt!KiStartSystemThread+0x16
STACK_COMMAND: kb
FOLLOWUP_IP:
MyTestDev!MyTestEvtDeviceContextCleanup+179 [c:\projects\kwdftest\mytestdev.c @ 915]
fffffadf`c8b459c9 89442438 mov dword ptr [rsp+38h],eax
FAULTING_SOURCE_CODE:
911: TRUE); // Must call WaitForXxx right after this
912:
913: // Wait for the thread to terminate
914: status = KeWaitForSingleObject(&(pDevContext->pThreadObj), // Ptr to thread
915: Executive, // Reason for wait
916: KernelMode, // wait mode
917: FALSE, // Alertable?
918: NULL); // ptr to timeout value. Null = indefinetely
919:
920: ObDereferenceObject(&(pDevContext->pThreadObj));
SYMBOL_STACK_INDEX: 7
FOLLOWUP_NAME: MachineOwner
MODULE_NAME: MyTestDev
IMAGE_NAME: MyTestDev.sys
DEBUG_FLR_IMAGE_TIMESTAMP: 498b4647
SYMBOL_NAME: MyTestDev!MyTestEvtDeviceContextCleanup+179
FAILURE_BUCKET_ID: X64_0xA_W_MyTestDev!MyTestEvtDeviceContextCleanup+179
BUCKET_ID: X64_0xA_W_MyTestDev!MyTestEvtDeviceContextCleanup+179