서버를 관리하다 보면 non paged pool이 부족하다는 메시지(event log 2019, 2020)과 함께
서비스가 다운되는 경우를 볼 수 있다.
이런 경우 대부분 app 관련한 프로그램이 과다하게 non paged pool을 사용하여(memory leak, virus...)
해당 서버에 non paged pool 메모리가 부족하여 메시지를 발생시키는 경우이며
현상으로는 서비스가 메모리를 할당받지 못하고 비정상적으로 종료가 되어진다.
이런 경우 다음과 같이 메모리 덤프 디버깅이 필요하다.
1. 메모리 사용량 확인
!vm 명령어를 사용하여 다음과 같이 메모리 사용량을 확인한다.
7: kd> !vm
*** Virtual Memory Usage ***
Physical Memory: 1572623 ( 6290492 Kb)
Page File: \??\C:\pagefile.sys
Current: 4190208 Kb Free Space: 4000620 Kb
Minimum: 4190208 Kb Maximum: 4190208 Kb
Available Pages: 1039552 ( 4158208 Kb)
ResAvail Pages: 1478483 ( 5913932 Kb)
Locked IO Pages: 154 ( 616 Kb)
Free System PTEs: 199304 ( 797216 Kb)
Free NP PTEs: 331 ( 1324 Kb)
Free Special NP: 0 ( 0 Kb)
Modified Pages: 264 ( 1056 Kb)
Modified PF Pages: 264 ( 1056 Kb)
NonPagedPool Usage: 65128 ( 260512 Kb)
NonPagedPool Max: 65536 ( 262144 Kb)
********** Excessive NonPaged Pool Usage *****
PagedPool 0 Usage: 24475 ( 97900 Kb)
PagedPool 1 Usage: 862 ( 3448 Kb)
PagedPool 2 Usage: 857 ( 3428 Kb)
PagedPool 3 Usage: 866 ( 3464 Kb)
PagedPool 4 Usage: 862 ( 3448 Kb)
PagedPool Usage: 27922 ( 111688 Kb)
PagedPool Maximum: 66048 ( 264192 Kb)
********** 21 pool allocations have failed **********
Shared Commit: 8706 ( 34824 Kb)
Special Pool: 0 ( 0 Kb)
Shared Process: 12244 ( 48976 Kb)
PagedPool Commit: 27986 ( 111944 Kb)
Driver Commit: 2123 ( 8492 Kb)
Committed pages: 930670 ( 3722680 Kb)
Commit limit: 2574783 ( 10299132 Kb)
괄호 앞의 숫자는 page 횟수이고 뒤에 kb는 실제 사용량이다.
bold 체 부분을 살펴보면 Usage 와 Max값이 동일한 것을 알 수 있다.
즉 non paged memory를 전량 사용하고 있다는 것을 알 수 있다.
2. non paged pool memory 과다 사용 process 추출
!poolused -t 10 4
메시지는 다음 의미를 내포한다.
non paged memory 사용 순으로 위에서 10개의 프로세스를 출력하라.
결과는 다음과 같다.
0: kd> !poolused /t 10 2
Sorting by NonPaged Pool Consumed
Pool Used:
NonPaged Paged
Tag Allocs Used Allocs Used
Irp 617714 183309064 0 0 Io, IRP packets
MmCm 41 12374152 0 0 Calls made to MmAllocateContiguousMemory , Binary: nt!mm
tdLL 11552 6372816 0 0 UNKNOWN pooltag 'tdLL', please update pooltag.txt
LSwi 1 2576384 0 0 initial work context
File 13225 2015160 0 0 File objects
PTrk 5831 1749336 0 0 UNKNOWN pooltag 'PTrk', please update pooltag.txt
Thre 2189 1400960 0 0 Thread objects , Binary: nt!ps
TCPA 2660 936320 0 0 TCP/IP network protocol , Binary: TCP
AfdE 2690 753200 0 0 Afd endpoint structure , Binary: afd.sys
IAM 14 721080 2 48 UNKNOWN pooltag 'IAM ', please update pooltag.txt
AfdC 3716 594560 0 0 Afd connection structure , Binary: afd.sys
Devi 303 590384 0 0 Device objects
TCPT 1433 584984 0 0 TCB pool , Binary: TCP
TCPt 38 510208 0 0 TCP/IP network protocol , Binary: TCP
LSwr 128 406528 0 0 raw work context
TCPC 4488 378232 0 0 TCP connection pool , Binary: TCP
TOTAL 734879 223183024 72343 104498008
여기서 보면 IRP packet이 메모리를 과점하고 있는 것을 확인 할 수 있다.
3. 해당 프로세스 분석
과다 사용하는 프로세스가 무엇인지를 살펴보아 원인을 분석해야한다.
IRP는 system.exe와 관련있다는 것을 검색을 통해 확인하였다.
해당 프로세스가 바이러스에 감염된것으로 보여 해당 검색 이력 확인 결과
system.exe가 Worm에 걸렸음을 확인하였다.
메모리 덤프는 위와 같이 가설을 세운 후 시나리오대로 확인해 나가는 것이 필요하며
처음 단추가 가장 중요하다는 것을 이번 기회에 느끼게 되었다.