Altruistic Programmer's Blog (KR)

이타주의 프로그래머의 블로그

Archive for the ‘pdb’ tag

pdb를 공부해서 LNK4099 LNK4204를 해결하다

with 2 comments

여러가지 서드파티 라이브러리중에 유독 구글의 프로토콜버퍼만 LNK4099 LNK4204 경고를 무수하게 쏟아내고 있어서 pdb에 대해서 공부를 해봤다. 평소에 궁금해하던 vc90.pdb 파일의 정체를 알게 되어서 기쁘다.

2가지 종류의 pdb

pdb파일은 아래의 두 가지 종류가 존재한다.

  • 컴파일러가 생성하는 pdb
    • /Z7, /Zi, /ZI 등의 컴파일 옵션으로 임베딩 여부와 정보의 양을 결정
    • /Fd 컴파일 옵션으로 pdb 파일이 생성될 경로를 지정
    • VC2008이 지정하는 기본패스는 $(IntDir)\vc90.pdb
    • .obj 파일에 pdb 파일의 경로를 보관한다.
  • 링커가 생성하는 pdb
    • /DEBUB 옵션으로 생성여부 결정
    • /PDB 옵션으로 pdb 파일이 생성될 경로를 지정
    • VC2008이 지정하는 기본패스는 $(TargetDir)$(TargetName).pdb
    • .exe나 .dll 파일에 pdb 파일의 경로를 보관한다.

정적 라이브러리의 pdb

정적 라이브러리는 .obj 파일의 모음으로 볼 수 있으므로 vc90.pdb가 정적 라이브러리의 pdb 파일이 된다. 즉, .lib 파일을 배포할 때는 vc90.pdb도 함께 배포해야 한다.

/Z7은 디버깅 심볼 관련 옵션이기는 하지만 pdb랑은 상관없고 CodeView 포멧의 디버깅 심볼을 .obj에 임베딩시키는 옵션이다. 정적 라이브러리라면 .lib에 임베딩되는 것이고 별도의 .pdb 파일은 생성되지 않는다. 

정적 라이브러리에 기록된 pdb 파일의 경로 읽기

LNK4099나 LNK4204 경고가 났을때 정말로 pdb 파일이 없는지 확인하기 위해서 이 방법을 사용할 수 있다. 단계를 요약해보면

  1. .lib 파일로부터 .obj 파일을 추출한다
    • lib /extract:myobj.obj mylib.lib
  2. .obj 파일에 기록된 .pdb 파일의 경로를 확인한다
    • dumpbin /section:.debug$T /rawdata myobj.obj

주의할 것은 myobj.obj는 보통 ./Debug/myobj.obj처럼 된다는 것. lib 파일을 메모장등에서 열어보면 확인할 수 있다.

LNK4099, LNK4204의 원인은?

정말로 vc90.pdb가 없거나 vc90.pdb는 있는데 그 안에 디버그 정보가 없다는 것. 이번 경우에는 프로토콜버퍼의 3가지 프로젝트가 똑같은 곳에다 vc90.pdb를 생성하는 바람에 파일이 덮어써졌다. 그래서 파일은 있지만 디버그 정보가 없는 경우에 해당한다.

구글의 C++ 테스트 프레임웍의 경우처럼 intermidiate directory(기본은 debug, release)에 프로젝트 이름을 다시 추가하는 방식으로 설정을 바꿔주면 깔끔하게 해결할 수 있다.

  • Output Directory : $(ConfigurationName)
  • Intermediate Directory : $(OutDir)\$(ProjectName)  

교훈

이 날 배운 교훈은 역시나 워닝 메시지는 친절하지 않다는 것이다. 유저인터랙션 분야에서 사용자가 어떻게 제품을 사용하는지 비디오로 녹화해서 연구하는 것과 같은 사용성 분석을 VC개발팀이 하고 있는지 궁금하다.

LNK4099의 에러메시지는 아래와 같은 포멧이다.

libprotobufd.lib(common.obj) : warning LNK4099: PDB 'vc90.pdb' was not found with 'c:\xxx\protobuf-2.2.0\vsprojects\Debug\libprotobufd.lib' or 'c:\yyy\bin\vc90.pdb';linking object as if no debug info

우선 실제로 vc90.pdb 파일이 존재하는 경로는 에러메시지에 나오지 않는다. .lib를 분석해보면 vc90.pdb의 파일 경로는 아주 온전하게 저장되어 있지만, 에러메시지에 나오지 않을 뿐이다.

c:\yyy\bin\은 라이브러리를 링크하는 exe 파일이 생성되는 위치다. 거기서 vc90.pdb를 찾고 있다는 얘기다.

그러고는 vc90.pdb 파일을 찾을 수 없다고 한다. -_-;;

링크

http://www.debuginfo.com/articles/gendebuginfo.html 
좀 옛날 것이지만 디버그 심볼에 대해서 자세하고 친절하게 설명해준 훌륭한 글


Written by muscly

April 18th, 2010 at 4:36 pm