Hi,
I am having some problems with queuing a DPC from a NMI callback. The result is a KERNEL_MODE_EXCEPTION_NOT_HANDLED (8e) bug check.
I am writing a driver that listens to NMIs generated by the processors performance counters. I register the NMI callback using KeRegisterNmiCallback. In the callback routine all I do is reset the performance counter in order to receive further interrupts (this involves writing to a MSR and unmaksing a bit in the APIC memory space), this works fine. At least that’s how it appears, I have encountered no problem and no bug checks.
However, when I try to queue a DPC the system bug checks:
KeInsertQueueDpc(&cpu_dpc_int[KeGetCurrentProcessorNumber()],NULL,NULL);
Each processor core has it’s own KDPC object that is allocated in non-pagable memory. I have confirmed that the entire structure is readable from the NMI callback routine. I have also tried calling the DPC handler directly which works. The DPC routine is empty except for a single call to DbgPrint.
It should be noted that this problem does not occur on 64-bit (AMD64) versions of Windows, I have confirmed that it works on both Vista and Windows 7. It should also be noted that if generating NMIs with a very long time period, for example once every second everything works on 32-bit versions as well (perhaps by luck?).
I have stripped my driver clean trying to make sure that nothing else interferes. The driver passes through the driver verifier without any problems (with and without the call to KeInsertQueueDpc).
I am probably misunderstanding something fundamental, hopefully some of you can shed some light on the issue.
Regards,
Christian
Below follows the output from WinDbg, the process name (lsass.exe in this case) seems to be random:
Microsoft (R) Windows Debugger Version 6.11.0001.404 X86
Copyright (c) Microsoft Corporation. All rights reserved.
Loading Dump File [C:\Windows\MEMORY.DMP]
Kernel Summary Dump File: Only kernel address space is available
Symbol search path is: C:\Users\developer\Desktop\nmi_test;C:\Symbols
Executable search path is:
Windows 7 Kernel Version 7600 MP (2 procs) Free x86 compatible
Product: WinNt, suite: TerminalServer SingleUserTS
Built by: 7600.16385.x86fre.win7_rtm.090713-1255
Machine Name:
Kernel base = 0x8281b000 PsLoadedModuleList = 0x82963810
Debug session time: Wed May 19 08:31:52.295 2010 (GMT+2)
System Uptime: 0 days 16:55:00.355
Loading Kernel Symbols
…
…
…
Loading User Symbols
PEB is paged out (Peb.Ldr = 7ffdb00c). Type “.hh dbgerr001” for details
Loading unloaded module list
…
0: kd> !analyze -v
*******************************************************************************
* *
* Bugcheck Analysis *
* *
*******************************************************************************
KERNEL_MODE_EXCEPTION_NOT_HANDLED (8e)
This is a very common bugcheck. Usually the exception address pinpoints
the driver/function that caused the problem. Always note this address
as well as the link date of the driver/image that contains this address.
Some common problems are exception code 0x80000003. This means a hard
coded breakpoint or assertion was hit, but this system was booted
/NODEBUG. This is not supposed to happen as developers should never have
hardcoded breakpoints in retail code, but …
If this happens, make sure a debugger gets connected, and the
system is booted /DEBUG. This will let us see why this breakpoint is
happening.
Arguments:
Arg1: c0000005, The exception code that was not handled
Arg2: 828d8441, The address that the exception occurred at
Arg3: 8293e7a0, Trap Frame
Arg4: 00000000
Debugging Details:
PEB is paged out (Peb.Ldr = 7ffdb00c). Type “.hh dbgerr001” for details
PEB is paged out (Peb.Ldr = 7ffdb00c). Type “.hh dbgerr001” for details
EXCEPTION_CODE: (NTSTATUS) 0xc0000005 - The instruction at 0x%08lx referenced memory at 0x%08lx. The memory could not be %s.
FAULTING_IP:
nt!KiDispatchException+27a
828d8441 8b87c4000000 mov eax,dword ptr [edi+0C4h]
TRAP_FRAME: 8293e7a0 – (.trap 0xffffffff8293e7a0)
ESP EDITED! New esp=8293eb00
ErrCode = 00000000
eax=8293edfc ebx=8293ef20 ecx=8a3012c0 edx=00000000 esi=00000000 edi=8293eb00
eip=828d8441 esp=8293e814 ebp=8293ef04 iopl=0 nv up ei pl nz na pe nc
cs=0000 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00000206
nt!KiDispatchException+0x27a:
828d8441 8b87c4000000 mov eax,dword ptr [edi+0C4h] ds:0023:8293ebc4=00000000
Resetting default scope
DEFAULT_BUCKET_ID: VISTA_DRIVER_FAULT
BUGCHECK_STR: 0x8E
PROCESS_NAME: lsass.exe
CURRENT_IRQL: 0
EXCEPTION_RECORD: 8293ef20 – (.exr 0xffffffff8293ef20)
ExceptionAddress: 00000000
ExceptionCode: c000001d (Illegal instruction)
ExceptionFlags: 00000000
NumberParameters: 0
LAST_CONTROL_TRANSFER: from 828d8372 to 828f7d10
STACK_TEXT:
8293e294 828d8372 0000008e c0000005 828d8441 nt!KeBugCheckEx+0x1e
8293e6bc 8284db08 8293edfc 00000000 8293e7a0 nt!KiDispatchException+0x1ac
8293e770 82861fa7 8293edfc 8293e824 00000000 nt!KiRaiseException+0x185
8293e78c 8285e42a 8293edfc 8293e824 00000000 nt!NtRaiseException+0x33
8293e78c 828d8441 8293edfc 8293e824 00000000 nt!KiFastCallEntry+0x12a
8293ef04 8285f016 8293ef20 00000000 8293ef74 nt!KiDispatchException+0x27a
8293ef6c 8285efb2 00000000 00000000 00000023 nt!CommonDispatchException+0x4a
8293ef74 00000000 00000023 00000023 0102f6c0 nt!Kei386EoiHelper+0x17a
STACK_COMMAND: kb
FOLLOWUP_IP:
nt!KiDispatchException+27a
828d8441 8b87c4000000 mov eax,dword ptr [edi+0C4h]
SYMBOL_STACK_INDEX: 0
SYMBOL_NAME: nt!KiDispatchException+27a
FOLLOWUP_NAME: MachineOwner
MODULE_NAME: nt
IMAGE_NAME: ntkrpamp.exe
DEBUG_FLR_IMAGE_TIMESTAMP: 4a5bc007
FAILURE_BUCKET_ID: 0x8E_VRF_nt!KiDispatchException+27a
BUCKET_ID: 0x8E_VRF_nt!KiDispatchException+27a