사용자 도구

사이트 도구


kb:symbolserver

Symbol Server

윈도우즈에서 디버깅을 할 때, 깨끗한 콜스택을 얻기 위해서는 심볼 관리가 필수다. 이 심볼 관리에 들어가는 노력을 덜어주는 심볼 서버의 기능에 대해서 정리해 보고자 한다.

Debugging Applications for Microsoft .NET and Microsoft Windows에 나온 내용을 나름대로 정리한 것이다.

왜 심볼 서버가 필요한가?

MiniDump를 이용해서, 덤프 파일을 생성하는 기능을 애플리케이션에다 추가했다고 하자.

OS 심볼을 다운로드받아 설치해 두었다면, 한 컴퓨터에서 개발하고, 테스트하는 동안은 큰 문제가 없을 것이다. 각종 바이너리들의 버전이 같기 때문이다. (같은 컴퓨터니까!) 하지만 개발은 2000에서 하고, 실행은 XP에서 하게 되는 경우를 생각해 보자. 이 경우 커널 DLL 등이 전혀 틀리기 때문에, 덤프 파일을 받아와서 봐도 콜스택이 제대로 나오지 않는다. 그렇다고 일일이 해당하는 바이너리와 심볼 파일들을 찾아서 세팅해 주는 것도 거의 불가능하다.

그렇다면 도대체 어떻게 해야하나? 마이크로소프트는 이 문제를 해결하기 위해서 심볼 서버라는 기능을 도입했다. 심볼 서버의 기능을 요약하자면, “덤프 파일이 생길 때의 환경을 재현하기 위해서 필요한 심볼들을 자동으로 다운로드” 정도가 되겠다.

즉 위에서 말한 “2000에서 개발, XP에서 테스트”의 경우, XP에서 생긴 덤프 파일을 받아와서 2000 디버거에서 띄우면 XP 쪽의 심볼을 다운로드받아서 로드한다는 말이다. 너무 좋은 기능 같아 보인다! 그러나 이것저것 해줘야할 일들이 꽤 많다.

OS 심볼 자동으로 다운받기

일단 심볼 서버로 사용할 컴퓨터를 하나 마련한다. 하드만 넉넉하면 된다. 각각의 컴퓨터에다가 심볼 서버를 구성하는 것도 가능하지만, 하드 낭비, 대역폭 낭비다. 하지만 어쩔 수 없다면 자기 컴퓨터에 해도 상관없다. 어쨌든 이 컴퓨터의 이름을 SSERVER라고 하자.

SSERVER 컴퓨터에다가 공유 디렉토리를 두 개 생성한다. 하나는 OS 심볼, 하나는 개발 중인 애플리케이션의 심볼을 저장할 곳이다. 전자는 SYMBOLS_OS, 후자는 SYMBOLS_PRODUCT라고 하자. 모든 프로그래머들이 접근 가능하도록 권한을 설정해 준다.

프로그래머가 작업하는 각각의 컴퓨터에 Debugging Tools for Windows를 설치한다. 그 다음 디버깅 툴을 설치한 디렉토리를 패스에다 추가해준다. symsrv.dll 파일을 어디서든지 액세스할 수 있도록 만들기 위해서이다. 그리고 환경 변수 설정하는 부분에 가서 _NT_SYMBOL_PATH 변수의 값을 아래와 같이 설정한다. (없다면 만든다.)

SRV*\\SSERVER\SYMBOLS_OS*http://msdl.microsoft.com/download/symbols;SRV*\\SSERVER\SYMBOLS_PRODUCT

여기까지만 해도 OS 심볼 파일들을 디버거가 다운로드받는 것을 볼 수 있을 것이다. 그러나 아직 완벽하지 않다.

바이너리와 심볼

덤프 파일을 가지고 디버깅을 하기 위해서는, 필요한 것들은 다음과 같다.

  • OS 바이너리들 - 대부분 DLL?
  • OS 심볼 파일
  • 애플리케이션 바이너리
  • 애플리케이션 심볼 파일

당연히 네가지 모두 덤프 파일이 생긴 컴퓨터(애플리케이션이 다운된 컴퓨터!)의 것들을 말한다. 위에서도 언급했듯이 _NT_SYMBOL_PATH와 디버거를 이용하면 OS 심볼 파일은 해결할 수 있다. 그러나 OS 바이너리 자체는 다운로드받을 수 없다. 즉 뭔가 다른 방법이 필요하다는 말이다.

이 문제를 위해서 Debugging Tools for Windows에 딸려오는 심볼 체커(Symbol Checker, symchk.exe)와 심볼 스토어(Symbol Store, symstore.exe)를 이용할 수 있다.

심볼 체커는 커맨드 라인 프로그램으로서, 마이크로소프트로부터 OS 심볼을 다운로드하는 역할을 담당한다. 기본적인 사용법은 대강 다음과 같다.

symchk /r C:\WINNT\SYSTEM32 /s SRV*\\SSERVER\SYMBOLS_OS*http://msdl.microsoft.com/download/symbols

SYSTEM32 디렉토리 하위에 있는 모든 바이너리들에 대한 심볼 파일을 다운로드받는다.

심볼 스토어는 임의의 심볼 또는 바이너리를 사용자의 심볼 저장소에다 집어넣는 역할을 담당한다. 기본적인 사용법은 대강 다음과 같다.

symstore add /r /f D:\build\*.* /s \\SSERVER\SYMBOLS_PRODUCT /t "MyApp" /v "Build 632" /c "2004/05/28 Daily Build"

D:\build 디렉토리 및 하위 디렉토리에 존재하는 모든 심볼 파일과 바이너리 파일을 심볼 저장소에다 저장한다.

위의 예에서도 나와있듯이 심볼 스토어를 이용하면, 사용자의 바이너리와 심볼 파일 또한 저장해둘 수 있다. 버전 별로 바이너리와 심볼을 저장해 두면, 막상 덤프 파일이 생겼을 때, 일치하는 바이너리와 심볼 파일을 찾아 헤메지 않아도 된다.

그렇다면 심볼 체커와 심볼 스토어로 무엇을 해야하겠는가? 가만히 생각해 보면 알 수 있을 것이다. 말로 표현하기가 좀 그러니 슈도 코드로 표현해 보겠다.

// 지원해야할 각각의 OS마다, 
// 서비스팩과 핫픽스를 점진적으로 설치해가면서, 
// 심볼 체커를 이용해 심볼 파일을 저장소에다 받고, 
// 심볼 스토어를 이용해 OS 바이너리를 저장소에다 저장해야한다.

for each OS in 지원해야할 OS
{
    for each 서비스팩, 핫픽스 in OS
    {
        심볼 체커를 이용해 심볼 파일을 저장소에다 저장;
        심볼 스토어를 이용해 OS 바이너리를 저장소에다 저장;
    }
}

딱 봐도 상당히 고통스러운 일이다. 누가 대신 좀 안 해주나… 서버라면 그나마 나은데, 클라이언트의 경우에는 98, Me, 2000, XP 다 설치해가며 심볼 받아둬야 할 테니…

    • 시스템에 설치된 핫픽스 정보 알아내기
    • from Debugging Applications for Microsoft .NET and Microsoft Windows
    • 심볼 다운로드와 설치를 간단하게 해주기 위한 스크립트
    • from Debugging Applications for Microsoft .NET and Microsoft Windows

소스와 심볼

험한 여정을 거쳐, 모든 바이너리와 심볼을 다 설치했다고 하더라도, 일치하는 소스 파일이 없으면 말짱 도루묵이다. 심볼 파일에다가 소스 파일을 집어넣을 수 있는 기능이 있다면 좋겠다만 그런 방법은 없다. 차선책으로 스크립트를 이용해 작업에 들어가는 수고를 약간이라도 덜어야 생명 연장에 도움이 된다.

그랬었는데, SourceServer라는 기능이 생겼다.

kb/symbolserver.txt · 마지막으로 수정됨: 2014/11/12 12:41 저자 excel96