[그림2. 바이너리 없이 초기화된 모듈]
그림2는 메모장 예제의 결과입니다. 이 결과를 통해 2가지 사실을 알 수 있습니다. 첫 째, 별 표 표시를 통해 바이너리의 경로를 알 수 있습니다. 이 경로는 사용자의 컴퓨터 환경에서 연결된 경로로써 여러분의 컴퓨터에서는 찾을 수 없다는 뜻입니다. 둘 째로, Information 필드에 "No matching binary found" 라는 메시지를 확인할 수 있습니다. 매칭이 되는 바이너리를 찾을 수 있는 핵심은 버전 필드와 파일 이름 필드 입니다. 예를 들어 예를 들어 대부분의 시스템 파일의 버전이 2195 인 것을 보고 이 환경이 windows 2000 임을 예측할 수 있습니다. 이 정보만으로 SP(service pack) 혹은 QFE(quality fix enginerring) 을 설치해야 한다고 바로 판단할 수는 없습니다. 좀 더 정보를 얻기 위해서 DLL 관련 데이터 베이스를 참조하는 것이 좋겠군요.
(
http://support.microsoft.com/servicedesks/fileversion/dllinfo.asp)
이 시점에서 여러분은 윈도우 운영체제의 CD 에서 동일한 바이너리를 찾아 보거나 사용자의 컴퓨터에 설치된 같은 버전의 파일을 찾아 여러분의 경로에 복사해야 할 것입니다. 보통은 프로세스가 사용하는 모든 바이너리를 찾을 필요까지는 없습니다. 하지만 call stack 을 살펴보는 데 필요한 바이너리들을 찾는 것은 중요한 일입니다. 대부분은 운영체제의 바이너리(Kernel32.dll 과 같은) 과 여러분의 응용프로그램 바이너리(예제에서는 Notepad.exe 가 되겠죠) 가 필요할 겁니다.
로컬 디렉토리에 복사하고 디버그 메뉴에서 Stop debugging 을 클릭합니다. 솔루션 탐색기에서 프로젝트 아이콘을 오른쪽 클릭하고 단축메뉴의 Properties 를 클릭합니다. 이것이 디버깅 페이지 입니다. MODPATH 에 다음과 같이 커멘드 인자를 채워 넣어 줍니다. ';' 부호를 사용하여 바이너리 경로를 여러개 입력할 수돌 있습니다.
MODPATH=m:\sysbits
경로를 설정한 후 F5 키를 눌러 minidump 를 다시 로드합니다. MODPATH 에 넣은 경로에서 디버거가 필요한 정보를 사용할 겁니다. 다음 버전의 Visual Studio.NET 은 아마도 이 설정 방법이 좀 더 세련되 질 것 같습니다.
비록 발견된 바이너리들이 call stack 에 도움이 되지 않을 것 같다고 하더라도 모듈 윈도우에는 다음과 같이 몇 가지 변화가 생겼습니다.
[그림3. 바이너리를 포함한 모듈]
"No matching binary found" 라는 메시지가 "Cannot find or open a required DBG file" 와 "No symbols loaded" 로 바뀌었습니다. 첫 번째 메시지는 바이너리의 디버깅 정보인 DBGs 를 사용하는 시스템 DLLs 에서 발생합니다. 두 번째 메시지는 PDBs 를 사용하는 DLL 에서 발생합니다. 바이너리를 매칭하는 작업이 여러분의 call stack 을 반듯이 도움이 되는 것은 아닙니다; call stack 을 위해서는 좀 전에 언급한 바이너리의 디버그 정보도 필요할 것입니다.
방법 A: 어려운 방법완변하게 minidump 를 분석하기 위해서 모든 바이너리의 디버그 정보를 찾을 필요가 있습니다. 하지만 시간을 절약하기 위해, 여러분에게 필요한 정보만 찾을 수도 있습니다. 예제 stack list 에는 User32.dll 과 Kernel32.dll 만 있습니다. 따라서 이 두 녀석은 매칭되는 디버그 정보가 필요합니다.
매칭할 수 있는 디버그 정보Windows NT4 DGBs
Windows 2000 DBGs, PDBs
Windows XP PDBs
http://www.microsoft.com/ddk/debugging 에 가시면 필요한 시스템 심볼 들을 찾을 수 있습니다. 가지고 있는 Windows NT 서버 와 Windows 2000 서버 운영체제의 지원 CD 에서도 시스템 심볼을 구할 수 있습니다. 이번 예제에서를 위해 바이너리 경로에 필요한 바이너르를 복사하였습니다. 실제 상황에서는 Microsoft 가 이닌 바이너리 리스트가 보일 겁니다. 따라서 이런 경우 각 바이너리의 PDB 가 필요합니다. 또한 이번 예제에서, 메모장을 위해 DBG 와 PDB 를 복사했습니다. 왜냐하면 예제 응용프로그램이 사용하고 있기 때문입니다.
디버그 메뉴에서 Stop Debugging 을 클릭한 후에 F5 키를 누르면 그림4 와 같이 call stack 이 리스트업 될 것입니다. 여러분이 필요한 바이너리와 디버그 정보를 잘 찾으셨다면 call stack 은 바뀌어 있을 겁니다. call stack 은 정확하게 연결된 디버그 정보가 있어야만 올바르게 동작합니다. 따라서 여러분이 좀 더 많은 정보를 추가할 수록 stack 은 좀 더 정확해 집니다. 보통은 처음에 보았던 stack 보다 더 많은 프레임이 보일 것입니다.
이번 예제에서, crash 는 없습니다만, 실전에서는 사용자의 crash 를 70 퍼센트 가까이 해결할 수 있는 충분한 정보를 얻을 수 있을 겁니다. 추가로, 이 stack 은 Microsoft 의 시스템 컴포넌트의 심볼도 열어주기 때문에 코드 라인 번호에 대한 정보는 없습니다. 여러분이 만든 바이너리의 경우는 완변한 PDBs 를 연결해준 경우 코드단위의 보다 정확한 stack 을 얻을 수 있을 것입니다.
[그림4. 심볼과 바이너리를 포함한 call stack]
심볼 서버만약 여러분이 여러개의 minidumps 를 다루어야 하고 일반적인 디버깅, 저장, 모든 바이너리와 PDB/DBG 를 접근해야 한다면 매우 번거로운 일이 될 것입니다. Windows NT 는 심볼 서버라고 알려진 기술이 도입되어 심볼을 저장할 수 있는 공간이 있습니다만, 지원하는 바이너리를 찾아 계속 확장해 주어야 합니다. Windows NT 디버거는 이 기능을 지원하는 첫 번째 도구이지만, Visual Studio.NET 또한 문서화 되지 않은 기능으로 이 기능을 포함하고 있습니다. 심볼 서버에 대한 자세한 정보를 얻고 싶으시다면 다음 링크를 확인해 보세요.
http://www.microsoft.com/ddk/debugging/symbols.asp방법 B: 쉬운 방법: 심볼 서버 사용하기우선,
http://www.microsoft.com/ddk/debugging 로 가셔서 디버깅 도구를 다운로드 합니다. Symsrv.dll 이 필요하고 이 것은 경로에 추가가 되어야 합니다. Visual Studio.NET 에서 접근할 수 있도록 devenv.exe 혹은 여러분의 System32 디렉토리에 복사합니다. 한번 Symsrv.dll 을 복사했다면 디버깅 도구를 언인스톨 해도 안전합니다. 또한 로컬 디렉토리를 하나 만들어야 합니다. 예를 들어, C:\localstore 라고 만들었다고 가정해 보겠습니다.
프로젝트 프로퍼티 다이얼로그 박스에 Debugging page 의 Symbol Path 를 다음과 같이 설정합니다.
SRV*c:/localstore*http://msdl.microsoft.com/download/symbols
이 문자열은 디버거에게 심볼 서버를 사용하여 심볼을 얻고 심볼이 복사될 때 필요한 로컬 심볼 서버를 생성하겠다고 말하고 있습니다. 이제, F5 를 눌러 minidump 를 실행하면, 심볼이 Microsoft 웹 사이트에서 복사되어 로컬 저장소에 복사가 되며 디버거가 사용할 수 있는 상태가 될 것입니다. 첫 번째로 이 작업을 수행하고 나면 다음부터 속도는 훨씬 빨라질 것입니다. 웹 사이트 보다 로컬 저장소를 먼저 살펴보기 때문이죠.
Microsoft 응용프로그램이 아닌 응용프로그램을 디버깅할 때에는 방법 A 와 B 를 섞어서 사용할 수 있습니다. A 를 사용하여 시스템 컴포넌트를 얻고 경로를 추가하여 여러분이 작성한 부분과 심볼을 추가할 수 있도록 ';' 구분자를 사용합니다.
c:\drop\build\myapp;SRV*c:\localstore*http://msdl.microsoft.com/download/symbols심볼 서버는 Visual Studio.NET 에 문서화 되지 않은 기능으로, 에러 리포팅이 없기 때문에 만약 문법이 틀렸거나 Symsrv.dll 이 경로에 없다면 심볼은 "No symbols loaded" 라는 에러 메시지와 함께 로드에 실패할 것입니다. 여러분은 또한 바이너리를 저장하고 불러오기 위해 심볼 서버를 사용할 수도 있습니다만, MODPATH 문법상 SRV* 대신에 symsrv*symsrc.dll* 을 사용해야 합니다.
일러두기: Microsoft 심볼 서버는 바이너리 파일을 가지고 있지 않지만 어떤 심볼 서버는 생성할 수 있습니다.
심볼 서버는 minidump 에 국한되지 않고 "살아있는" 디버깅을 할 수 있는 기능입니다. 일반 디버깅에 사용하기 위해 디버깅 페이지에 Symbol Path 에 로컬 심볼 서버의 경로를 추가할 수 있습니다.
Microsoft 는 어떻게 Minidumps 를 사용하는가Microsoft 는 응용프로그램의 질을 향상시키기 위해 minidump 를 사용해 왔습니다. Microsoft Internet Explorer 5.5 와 Microsoft Office XP 는 새로운 Dr. Watson(응용 프로그램의 응답이 없는 것을 감지하고 minidump 를 생성, 사용자에게 오류보고를 보낼 것이냐고 묻는 유틸이죠) 을 사용하여 배포된 첫 번째 제품입니다.
만약 사용자가 에러 리포트를 보낸다고 클릭하면 Dr. Watson 은 Microsoft 웹 사이트 서버에 minidump 를 생성하고 전송합니다. 이 도구는 사용자에게 묻는 부분과 minidump 를 저장하는 부분을 분리하고 있어 crash 로부터 안전합니다. 이런 방식은 crash 된 응용프로그램을 보낼 것인지를 적게 강요하고 있어 사용자로부터 의미있는 minidump 를 받을 확율을 높여 줍니다.
개선 방안서버 입장에서, minidump 는 crash 가 발생된 기반 환경 및 컴포넌트에 따라 유사한 crash 끼리 분석할 수 있습니다. 생산 팀의 경우 응용 프로그램이 얼마나 자주 crash 되는지, 얼마나 자주 crash 발생되는지에 대한 통계 정보를 얻을 수 있습니다. 개발 팀의 경우는 보다 연구해 볼 수 있는 crash 상황의 실제 minidump 를 받아 볼 수 있습니다. 어떤 crash 는 이미 완벽하게 분석이 끝났을 수도 있습니다. 이런 경우 사용자는 자동으로 웹 페이지에 접속하여 관련 정보 혹은 문제를 해결한 파일을 다운로드 할 수도 있습니다. Internet Explorer 5.5 와 Office XP 가 출시된 이후, 많은 다른 제품 팀들이 유사한 기술을 사용하여 crash 정보를 수집하고 있습니다. 이 기술은 또한 Windows XP 에 한해서 표준입니다.
이번 아티클에서 다루고 있는 예제는 minidumps 를 이해할 수 있는 토대를 제공합니다. 예제는 사용자로부터 dump 파일을 회수할 것인지 묻지 않고 있습니다. 간단하게, 사용자는 이메일로 minidump 를 보내줄 수 있습니다. 또한 잠재적인 사생활 침해 이슈가 생길 수 있습니다. 왜냐하면 사용자의 데이터에 stack 과 전체 heap 을 포함한 minidump 의 경우 heap 의 모든 데이터를 볼 수 있기 때문입니다. 이런 데이터는 사용자 쪽에서 날려 버릴 수 있도록 만들어 져야 합니다. Microsoft 의 데이터 수집 정책에 의하면, minidump 가 포함하고 있는 정보에 대하여 추가적인 정보를 고객에게 알릴 수 있도록 하고 있습니다.
http://watson.microsoft.com/dw/1033/dcp.asp추가로, 처리되지 않은 예외가 일어난 Windows 서비스의 minidump 는 추가적인 과제가 있습니다. ....