错误检查 0x1AA:EXCEPTION_ON_INVALID_STACK

EXCEPTION_ON_INVALID_STACK 错误检查的值为 0x000001AA。 此 BugCheck 表明异常调度越过了无效的内核堆栈。 这可能表明内核堆栈指针在异常调度或展开期间已损坏(例如,由于帧指针的堆栈损坏),或者驱动程序正在一个不合法的内核堆栈上执行。

重要

本主题是面向程序员的。 如果您是在使用计算机时收到此错误代码的客户,请参阅蓝屏错误疑难解答

EXCEPTION_ON_INVALID_STACK 参数

参数 说明

1

指向当前堆栈的指针。

2

堆栈限制类型,如 NormalStackLimits (3)。 由于堆栈无效,这代表了内核对计算机状态下应激活的内核堆栈类型的最佳估计。

堆栈限制类型:

  • 0x0 - 错误检查堆栈(如果堆栈限制是在错误检查期间计算的,则可以使用任何堆栈)
  • 0x1 - 处理器 DPC 堆栈
  • 0x2 - KeExpandKernelStackAndCallout(Ex) 堆栈
  • 0x3 - 正常内核线程栈
  • 0x4 - 线程上下文交换期间的内核线程栈(哪个线程处于活动状态尚不明确)
  • 0x5 - win32k 内核/用户标注堆栈
  • 0x6 - 处理器 ISR 堆栈
  • 0x7 - 内核调试器堆栈(内核调试器处理 KD I/O 时的任何堆栈)
  • 0x8 - 处理器 NMI 处理堆栈
  • 0x9 - 处理器计算机检查处理堆栈
  • 0xA - 处理器异常堆栈(用于调度某些引发的 IRQL 异常)

3

指向上下文记录的指针,表示在遇到无效堆栈时正在展开(或为异常调度)的上下文。

4

提供一条表示正在调度的活动异常的异常记录。

原因

尝试访问无效堆栈。 由于内核堆栈的大小有限,因此开发人员需要谨慎跟踪其限制,例如在使用它来复制显存块时。 有关 Windows 内核堆栈的信息,请参阅使用内核堆栈

解决方法

使用完整的内核转储或附加的调试器,以下命令可能有助于收集信息并跟踪错误访问内存的代码。

首先使用 !analyze 命令来收集信息,特别是错误检查参数。 如果有,还可检查故障源行和模块名称。

Arguments:
Arg1: 00000018940ffbe8
Arg2: 0000000000000003
Arg3: ffffe301c8db2900
Arg4: ffffdc0e9ee665d8

使用分析输出中提供的 .trap 命令链接,将上下文设置为陷阱帧。

2: kd> .trap 0xffffdc0e9ee66680
NOTE: The trap frame does not contain all registers.
Some register values may be zeroed or incorrect.
rax=003f8b813f20b6e0 rbx=0000000000000000 rcx=ee7defdd9c530000
rdx=ffffcb81660ea078 rsi=0000000000000000 rdi=0000000000000000
rip=fffff8002b7f8933 rsp=ffffdc0e9ee66810 rbp=ffffcb81511c3010
 r8=0000000000000001  r9=0000000000004014 r10=ffffdc0e9ee66910
r11=0000000000000000 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
iopl=0         nv up ei pl zr na po nc
dxgmms2!RemoveHeadList+0xd [inlined in dxgmms2!VidSchiSignalRegisteredSyncObjects+0x3f]:
fffff800`2b7f8933 48395808        cmp     qword ptr [rax+8],rbx ds:003f8b81`3f20b6e8=????????????????

使用 !vm 命令检查内存使用情况,例如查看正在使用的内核堆栈内存量。

0: kd> !vm

Physical Memory:          1541186 (    6164744 Kb)
Available Pages:           470550 (    1882200 Kb)
ResAvail Pages:           1279680 (    5118720 Kb)

...

Kernel Stacks:              13686 (      54744 Kb)

在本例中,所使用的内存量小于可用内存量。

使用 !thread 命令来收集有关正在运行的内容的信息。 在本例中,视频计划程序工作线程似乎正在运行。

2: kd> !thread
THREAD ffffcb816348b040  Cid 0c58.4a1c  Teb: 0000000000000000 Win32Thread: 0000000000000000 RUNNING on processor 2
Not impersonating
DeviceMap                 ffff840f38c04170
Owning Process            ffffcb81648980c0       Image:         YourPhone.exe
Attached Process          N/A            Image:         N/A
Wait Start TickCount      34501403       Ticks: 0
Context Switch Count      43             IdealProcessor: 3             
UserTime                  00:00:00.000
KernelTime                00:00:00.015
Win32 Start Address 0x00007fff34656d00
Stack Init ffffdc0e9ee675b0 Current ffffdc0e9ee66610
Base ffffdc0e9ee68000 Limit ffffdc0e9ee61000 Call 0000000000000000
Priority 8 BasePriority 8 PriorityDecrement 0 IoPriority 2 PagePriority 5
...

然后使用 kb (Display Stack Backtrace) 和 f 选项来显示堆栈和内存使用情况,以查看是否存在大内存用户。

2: kd> kf
...
02        40 ffffdc0e`9ee66850 fffff800`2b7f8801     dxgmms2!VidSchiMarkDeviceAsError+0x4d  
...

如果代码的某一部分看起来可疑,请使用 u, ub, uu (Unassemble) 命令来检查相关的汇编语言代码。

2: kd> u ffffdc0e`9ee66850 l10
ffffdc0e`9ee66850 1030            adc     byte ptr [rax],dh
ffffdc0e`9ee66852 1c51            sbb     al,51h
ffffdc0e`9ee66854 81cbffffc068    or      ebx,68C0FFFFh
ffffdc0e`9ee6685a e69e            out     9Eh,al
ffffdc0e`9ee6685c 0e              ???
ffffdc0e`9ee6685d dcff            fdiv    st(7),st
ffffdc0e`9ee6685f ff00            inc     dword ptr [rax]
ffffdc0e`9ee66861 0000            add     byte ptr [rax],al
ffffdc0e`9ee66863 0000            add     byte ptr [rax],al
ffffdc0e`9ee66865 0000            add     byte ptr [rax],al
ffffdc0e`9ee66867 000e            add     byte ptr [rsi],cl
ffffdc0e`9ee66869 0000            add     byte ptr [rax],al
ffffdc0e`9ee6686b 0000            add     byte ptr [rax],al
ffffdc0e`9ee6686d 0000            add     byte ptr [rax],al
ffffdc0e`9ee6686f 0010            add     byte ptr [rax],dl
ffffdc0e`9ee66871 301c51          xor     byte ptr [rcx+rdx*2],bl

使用 .cxr (Display Context Record) 命令,利用 !analyze 提供的参数 3 值来显示上下文记录。

2: kd> .cxr ffffe301c8db2900
rax=003f8b813f20b6e0 rbx=ffffcb813f607650 rcx=ee7defdd9c530000
rdx=ffffcb81660ea078 rsi=0000000000000000 rdi=ffffcb81511c30a8
rip=fffff8002b7f8933 rsp=ffffdc0e9ee66810 rbp=ffffcb81511c3010
 r8=0000000000000001  r9=0000000000004014 r10=ffffdc0e9ee66910
r11=0000000000000000 r12=ffffdc0e9ee66910 r13=ffffcb814019c000
r14=0000000000000000 r15=ffffdc0e9ee66910
iopl=0         nv up ei pl zr na po nc
cs=0010  ss=0018  ds=002b  es=002b  fs=0053  gs=002b             efl=00050246
dxgmms2!RemoveHeadList+0xd [inlined in dxgmms2!VidSchiSignalRegisteredSyncObjects+0x3f]:
fffff800`2b7f8933 48395808        cmp     qword ptr [rax+8],rbx ds:002b:003f8b81`3f20b6e8=????????????????

使用 .exr (Display Exception Record 命令,利用 !analyze 提供的参数 4 值来显示例外记录。

2: kd> .exr ffffdc0e9ee665d8
ExceptionAddress: fffff8002b7f8933 (dxgmms2!RemoveHeadList+0x000000000000000d)
   ExceptionCode: c0000005 (Access violation)
  ExceptionFlags: 00000000
NumberParameters: 2
   Parameter[0]: 0000000000000000
   Parameter[1]: ffffffffffffffff
Attempt to read from address ffffffffffffffff

异常记录显示试图从 ffffffffffffffff 的地址读取数据,这将是一个需要进一步调查的方面。

另请参阅

错误检查代码参考