Insufficient kernel pool memory, spiking thread and data contents locality: pattern cooperation
Saturday, September 18th, 2010A complete memory dump was generated from a totally unresponsive frozen system. Looking at its virtual memory stats we see the shortage of nonpaged pool (insufficient kernel pool memory pattern):
0: kd> !vm
*** Virtual Memory Usage ***
Physical Memory: 1047977 ( 4191908 Kb)
Page File: \??\C:\pagefile.sys
Current: 4195328 Kb Free Space: 4167696 Kb
Minimum: 4195328 Kb Maximum: 4195328 Kb
Page File: \??\E:\pagefile.sys
Current: 8372224 Kb Free Space: 8348916 Kb
Minimum: 8372224 Kb Maximum: 8388608 Kb
Available Pages: 855939 ( 3423756 Kb)
ResAvail Pages: 958559 ( 3834236 Kb)
Locked IO Pages: 100 ( 400 Kb)
Free System PTEs: 200627 ( 802508 Kb)
Free NP PTEs: 0 ( 0 Kb)
Free Special NP: 120925 ( 483700 Kb)
Modified Pages: 52 ( 208 Kb)
Modified PF Pages: 52 ( 208 Kb)
NonPagedPool Usage: 65199 ( 260796 Kb)
NonPagedPool Max: 65536 ( 262144 Kb)
********** Excessive NonPaged Pool Usage *****
PagedPool 0 Usage: 7731 ( 30924 Kb)
PagedPool 1 Usage: 6334 ( 25336 Kb)
PagedPool 2 Usage: 6316 ( 25264 Kb)
PagedPool 3 Usage: 6333 ( 25332 Kb)
PagedPool 4 Usage: 6318 ( 25272 Kb)
PagedPool Usage: 33032 ( 132128 Kb)
PagedPool Maximum: 66560 ( 266240 Kb)
********** 7041316 pool allocations have failed **********
Session Commit: 2860 ( 11440 Kb)
Shared Commit: 3904 ( 15616 Kb)
Special Pool: 255 ( 1020 Kb)
Shared Process: 9336 ( 37344 Kb)
PagedPool Commit: 33032 ( 132128 Kb)
Driver Commit: 2147 ( 8588 Kb)
Committed pages: 174724 ( 698896 Kb)
Commit limit: 4148057 ( 16592228 Kb)
Dumping sorted pool consumers we see the most used were DRV* pool tags:
0: kd> !poolused 3
Sorting by NonPaged Pool Consumed
Pool Used:
NonPaged
Tag Allocs Frees Diff Used
DRV2 21683882 21280457 403425 80685000 UNKNOWN pooltag ‘DRV2′, please update pooltag.txt
DRV4 46621052 46217627 403425 54156728 UNKNOWN pooltag ‘DRV4′, please update pooltag.txt
DRV5 37848660 37065132 783528 31341120 UNKNOWN pooltag ‘DRV5′, please update pooltag.txt
MmCm 15754 14607 1147 24917536 Calls made to MmAllocateContiguousMemory , Binary: nt!mm
DRV3 16189418 15785993 403425 19364400 UNKNOWN pooltag ‘DRV3′, please update pooltag.txt
[…]
We also check CPU consumption and see two spiking threads:
0: kd> !running
System Processors f (affinity mask)
Idle Processors 9
Prcbs Current Next
1 f7727120 87c5ca48 …………….
2 f772f120 881ccae0 …………….
We see the first thread spent much more kernel time and stack trace involved DriverA module:
0: kd> !thread 87c5ca48 1f
THREAD 87c5ca48 Cid 0ba0.0bc8 Teb: 7ffd7000 Win32Thread: 00000000 RUNNING on processor 1
Not impersonating
DeviceMap e10028f0
Owning Process 87c3a978 Image: ApplicationB.exe
Attached Process N/A Image: N/A
Wait Start TickCount 4516745 Ticks: 2 (0:00:00:00.031)
Context Switch Count 2234544
UserTime 00:00:58.500
KernelTime 00:55:09.218
Win32 Start Address ApplicationB (0×402016bd)
Start Address kernel32!BaseThreadStartThunk (0×77e617ec)
Stack Init b8771000 Current b87708b4 Base b8771000 Limit b876e000 Call 0
Priority 13 BasePriority 8 PriorityDecrement 1
ChildEBP RetAddr
b8770bd0 80892b6f nt!ExFreePoolWithTag+0xb7
b8770be0 80933bcd nt!ExFreePool+0xf
b8770c0c 808bb471 nt!ObOpenObjectByName+0×163
b8770cf8 b951f08e nt!NtOpenKey+0×1ad
WARNING: Stack unwind information not available. Following frames may be wrong.
b8770d50 808897cc DriverA+0×1608e
b8770d50 7c82860c nt!KiFastCallEntry+0xfc (TrapFrame @ b8770d64)
00c0f0b4 7c827369 ntdll!KiFastSystemCallRet
00c0f0b8 7d206cb1 ntdll!ZwOpenKey+0xc
00c0f118 7d1fe187 ADVAPI32!LocalBaseRegOpenKey+0xd0
00c0f14c 40202284 ADVAPI32!RegOpenKeyExA+0×11c
[…]
00c0ffb8 77e6482f ApplicationB+0×1891
00c0ffec 00000000 kernel32!BaseThreadStart+0×34
0: kd> !thread 881ccae0 1f
THREAD 881ccae0 Cid 05b8.05c4 Teb: 7ffde000 Win32Thread: 00000000 RUNNING on processor 2
Not impersonating
DeviceMap e10028f0
Owning Process 881cf020 Image: ApplicationC.exe
Attached Process N/A Image: N/A
Wait Start TickCount 4516747 Ticks: 0
Context Switch Count 115916
UserTime 00:00:03.468
KernelTime 00:00:53.156
Win32 Start Address ADVAPI32!ScSvcctrlThreadA (0×7d1f5e70)
Start Address kernel32!BaseThreadStartThunk (0×77e617ec)
Stack Init b900d000 Current b900cc50 Base b900d000 Limit b900a000 Call 0
Priority 13 BasePriority 8 PriorityDecrement 0
ChildEBP RetAddr
005bf9c4 7d1eef7e ADVAPI32!LocalBaseRegEnumKey+0×2
005bfc24 010091c9 ADVAPI32!RegEnumKeyExA+0×12f
WARNING: Stack unwind information not available. Following frames may be wrong.
005bfc74 0100a28c ApplicationC+0×91c9
[…]
005bffb8 77e6482f ApplicationC+0×8b13
005bffec 00000000 kernel32!BaseThreadStart+0×34
We check the pool entry it was freeing:
0: kd> .thread /r /p 87c5ca48
Implicit thread is now 87c5ca48
Implicit process is now 87c3a978
Loading User Symbols
0: kd> kv L1
ChildEBP RetAddr Args to Child
b8770bd0 80892b6f 8ab6b3c8 00000000 b8770c0c nt!ExFreePoolWithTag+0xb7
0: kd> !pool 8ab6b3c8
Pool page 8ab6b3c8 region is Nonpaged pool
8ab6b000 size: c8 previous size: 0 (Allocated) DRV2
8ab6b0c8 size: 70 previous size: c8 (Allocated) MmCa
8ab6b138 size: 10 previous size: 70 (Free) DRV2
8ab6b148 size: 30 previous size: 10 (Allocated) DRV3
8ab6b178 size: 30 previous size: 30 (Allocated) DRV3
8ab6b1a8 size: 28 previous size: 30 (Allocated) NtFs
8ab6b1d0 size: 30 previous size: 28 (Allocated) DRV3
8ab6b200 size: 18 previous size: 30 (Free) IrpC
8ab6b218 size: a8 previous size: 18 (Allocated) File (Protected)
8ab6b2c0 size: 100 previous size: a8 (Allocated) MmCi
*8ab6b3c0 size: 38 previous size: 100 (Allocated) *ObCi
Pooltag ObCi : captured information for ObCreateObject, Binary : nt!ob
8ab6b3f8 size: 48 previous size: 38 (Allocated) DRV2
8ab6b440 size: 8 previous size: 48 (Free) DRV4
8ab6b448 size: 28 previous size: 8 (Allocated) NtFs
8ab6b470 size: 8 previous size: 28 (Free) Mdl
8ab6b478 size: 60 previous size: 8 (Allocated) DRV4
8ab6b4d8 size: c8 previous size: 60 (Allocated) DRV2
8ab6b5a0 size: a8 previous size: c8 (Allocated) File (Protected)
8ab6b648 size: c8 previous size: a8 (Allocated) DRV2
8ab6b710 size: c8 previous size: c8 (Allocated) DRV2
8ab6b7d8 size: 10 previous size: c8 (Free) File
8ab6b7e8 size: 98 previous size: 10 (Allocated) DRV4
8ab6b880 size: 30 previous size: 98 (Allocated) DRV3
8ab6b8b0 size: 28 previous size: 30 (Allocated) NtFs
8ab6b8d8 size: 28 previous size: 28 (Allocated) DRV5
8ab6b900 size: 30 previous size: 28 (Allocated) DRV3
8ab6b930 size: a8 previous size: 30 (Allocated) File (Protected)
8ab6b9d8 size: 100 previous size: a8 (Allocated) MmCi
8ab6bad8 size: 10 previous size: 100 (Free) ObCi
[…]
In the output above we see all clustering of DRV* pool tags and check their contents:
0: kd> dps 8ab6b000
8ab6b000 0a190000
[…]
8ab6b06c b95349a0 DriverA+0×2b9a0
8ab6b070 87cb85c8
8ab6b074 002d0000
8ab6b078 8ab6b078
8ab6b07c 8ab6b078
0: kd> dps 8ab6b8d8
8ab6b8d8 0a050005
[…]
8ab6b8f8 b95349a0 DriverA+0×2b9a0
8ab6b8fc 00000074
[…]
It looks like all DRV* pool entries have symbolic references in the range of DriverA (data contents locality):
0: kd> lm m DriverA
start end module name
b9509000 b9537f00 DriverA (no symbols)
So the conclusion was to refer to DriverA vendor for any updates.
- Dmitry Vostokov @ DumpAnalysis.org + TraceAnalysis.org -