Crash Dump Analysis Patterns (Part 7)

http://www.dumpanalysis.org/blog/index.php/2007/01/24/crash-dump-analysis-patterns-part-7/

번역: 김희준(2007-08-04, drost@naver.com, http://insidekernel.net)

 

불완전한(inconsistent) 덤프를 만들어내는 툴들이 많이 있습니다. 예를 들자면, sysinternals.com에서 나온 LiveKd.exe는 서버를 재시작 하지 않고도 전체 메모리 덤프를 받을 수 있어서 Microsoft나 Citrix 기술지원 팀에서 자주 사용됩니다. Citrix 고객들을 위해서 다음과 같은 글을 쓴 적도 있습니다:

 

시스템 hang 시에 LiveKd를 이용해서 전체 메모리 덤프를 받는 법

여러분들께서 저 글을 읽어보시면, 다음과 같은 중요한 사항을 발견하실 수 있습니다:

LiveKd.exe가 만들어내는 덤프 파일은 항상 일정하지 않기 때문에 리소스 경쟁과 같은 특정 상황에서는 덤프 파일을 신뢰해서는 안 된다. 이것은 live 시스템에서 덤프를 만들어낼 때에는 굉장히 많은 시간이 걸리기 때문이며 그 작업 동안에 시스템이 계속 변경되기 때문이다. 전통적인 Ctrl+Scroll 버튼으로 바로 만들어내는 방법이나 SystemDump 툴을 사용하는 방법은 우선 시스템을 멈춰버리기 때문(모든 프로세스와 커널 동작이 정지된다)에 신뢰할 수 있는 덤프를 페이지 파일로 만들어낸다.

만약 이러한 불완전한 덤프를 살펴본다면, ERESOURCE 리스트 같은(!locks) 많은 커널 구조체들이 깨져있거나 잘못된 참조를 하고 있기 때문에 WinDbg가 이상한 출력 결과를 보여줄 것입니다.

 

이렇게 (고객 수준에서) 쉽고 간단하게 “Live” 툴을 이용해서 덤프를 만든다는 것은, 그 방법이 아주 많이 사용되기 때문에 우리가 이들 툴들로 만들어진 덤프를 많이 분석해야만 한다는 것을 뜻하기도 합니다. 그래서 이와 관련된 “불완전한 덤프(Inconsistent Dump)”라 불리는 크래쉬 덤프 패턴이 만들어지게 되었습니다.

만약 여러분들이 이러한 덤프를 살펴봐야 한다면 가장 근본적인 원인을 밝혀내고 이후에 어떻게 진행할지 알아낼 수 있도록 최대한 많이 유용한 정보를 뽑아내야 합니다. 이러한 덤프 파일에서 모든 정보들이 다 깨져있는 것은 아닙니다. 예를 들어서 드라이버, 프로세스, 스레드 스택과 IRP 리스트는 어떠한 동작들을 하고 있는지에 대한 힌트를 줄 것입니다. 심지어 제대로 된 완전한 덤프에서는 볼 수 없는 어떤 정보들이 불완전한 덤프에서 보이기도 합니다.

자, 제가 이전에 만들어둔 스크립트를 사용해서 LivdKd 덤프의 프로세스 스택을 살펴본 예입니다:

Yet another WinDbg script

 

여기에서 프로세스에서 자신들이 가지고 있는 기존 스레드 외에 스크립트가 완전히 다른 프로세스에 속한 이미 종료된 스레드들도 추가적으로 보여주었습니다(완전한 덤프에선 절대 볼 수 없었죠)

 

프로세스 89d87d88은 active 프로세스 리스트에선 보이진 않습니다(!process 0 0 명령). 그러나 우리가 이 메모리 주소를 !process 명령에 직접 전해주면(또는 dt 명령어를 이용하여 _EPROCESS 구조체를 직접 살펴본다면) 다음과 같은 내용을 볼 수 있습니다.

 

다음과 같은 상황이 발생한 것으로 추측됩니다: 종료된 프로세스 89d97d88이 active 프로세스 리스트에선 제거되었지만 메모리에는 데이터가 아직 남아있고 스레드 리스트가 마찬가지로 깨지면서 종료된 스레드가 다른 프로세스들의 스레드가 리스팅될 때 함께 보여진 것입니다.

Session 2에서 winlogon.exe가 죽었고 텅빈 데스크탑 윈도우를 보고 고객이 항의하였습니다. Session 2에서 남겨진 유일한 프로세스는 csrss.exe 였는데, 결론을 내리자면 기본 포스트모텀 디버거로 NTSD를 설정한 다음에 winlogon.exe가 크래쉬 되는 순간을 잡아서 그 다음에 무엇이 발생하는지 봐야겠지요.

- Dmitry Vostokov –