Archive for April, 2010
플래시 소켓과 보안 샌드박스
문제상황
C++ 서버에 플래시 클라이언트를 연결시켰는데 난데없이 패킷이 날라온다. 내용을 보니 "<policy-file-request/>"라는 문자열이다. 소스코드 건든 적도 없는데 갑자기 이런다. -_-;;
Security Sandbox
플래시처럼 웹에서 돌아가는 녀석들은 보안을 위해서 특정 기능을 막는다. 샌드박스라는 개념을 만들어서, 그 샌드박스안에서 플래시가 돌아가게 만든다. 샌드박스의 종류에 따라서는 파일 시스템에 접근할 수 없고, 소켓을 사용할 수도 없다. 자세한 것은 아래 링크에서.
샌드박스를 확인해보니 잘 돌아갈때는 local-trusted 샌드박스 였는데, 지금은 local-with-networking 샌드박스다. 결국 샌드박스에 변경이 생겨서 동작에 변화가 생긴 것이다.
Cross-domain Policy File
플래시의 버전에 따라서 조금씩 다른데, 플래시에서 로우 소켓을 사용해서 서버에 접속하기 위해서는 동일한 서버에 동일한 방식으로 접속을 해서 시큐러티 폴리시 파일을 받아와야한다. 이 파일에는 플래시가 돌아가는 도메인에서 서버가 돌아가는 도메인으로 소켓 연결을 해도 좋은지 허락하는 내용이 들어있다. 허락을 안할 수도 있고. 자세한 스팩은 아래.
http://www.adobe.com/devnet/articles/crossdomain_policy_file_spec.html
실제 서비스라면 서버에 연결해서 폴리시 파일을 받아서 확인을 거친 후에, 동일한 서버에 다른 포트로 연결하는 패턴이 필요하다. 물론, 나는 로컬에서 테스트만 할 목적이었으므로 폴리시 파일을 받아오는 단계는 생략했었고, local-trusted 샌드박스라면 문제없이 잘 동작한다.
The User Flash Player Trust Directory
문제는 소스코드를 한 줄도 안건드렸는데 왜 샌드박스가 바뀌었을까 하는 것. 결론은 swf 파일이 어떻게 빌드되었는냐의 문제가 아니라 swf 파일이 어디 있느냐가 핵심이다. 컴퓨터의 파일시스템의 어딘가에 믿을만한 swf 파일이 있는 디렉토리가 등록되어 있다. 자세한 것은 아래.
http://livedocs.adobe.com/flex/3/html/help.html?content=05B_Security_03.html#140756
예전에 FlashDevelop을 사용할 때는 FlashDevelop이 자동으로 swf가 생기는 디렉토리를 등록해주었던 것. 이번에 빌드 자동화를 위해서 Flex SDK를 직접 사용하도록 바꾸고 swf가 생기는 디렉토리도 바꿨기 때문에 샌드박스가 변경되었던 것이다.
해결책
swf 파일이 있는 디렉토리를 믿을만한 디렉토리로서 등록한다.
리더의 자세 7 – 책임과 권한
리더는 팀 내부와 외부를 살펴서 책임과 권한이 동시에 부여되고 있는지 확인해야한다.
책임과 권한
책임과 권한은 동시에 부여되어야 한다. 책임은 있는데 권한이 없다거나, 권한은 있지만 책임이 없는 상황은 바람직하지 못하다.
팀 내부에서는 동료에게 책임과 권한이 동시에 부여되었는지 관찰해야한다. 경험에 비춰보면, 직위가 낮은 사람일수록 책임은 많고, 권한은 적다. 무엇인가 좋은 것을 만들 책임은 있는데, 어떻게 만들지 최종결정할 권한은 없다. 열심히 고민해서 만들어가면, 리더가 퇴짜를 놓는 식이다.
'무엇을 만들지' 정하는 게 리더의 책임이고 '어떻게 만들지' 고민하는게 팀 멤버의 책임이라면, 리더는 '어떻게 만들지'에 대해서 전적으로 권한을 넘겨줘야 한다.
팀 외부에서는 팀간의 관계에서 책임과 권한이 동시에 부여되었는지 관찰해야한다. A팀이 B팀을 지원하는 경우라면, B팀의 성공과 실패에 따라서 A팀도 영향을 받을 수 있다. 다시 말해, B팀의 성공과 실패에 A팀이 어느 정도 책임이 있다는 뜻이므로 A팀에는 그에 합당한 권한이 있어야 한다.
하지만, 현실에서는 적절한 권한이 없어서 뒤에서 신세한탄만 하다가 함께 침몰하는 경우가 많은 것 같다. A팀의 리더라면 팀이 갖는 책임의 양만큼 권한을 확보하거나, 권한의 양만큼 책임을 덜어내기 위해서 노력해야 한다. 일단 책임과 권한의 균형을 확보했다면 팀을 위해서 적극적으로 권한을 행사해야 한다.
pdb를 공부해서 LNK4099 LNK4204를 해결하다
여러가지 서드파티 라이브러리중에 유독 구글의 프로토콜버퍼만 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 파일이 없는지 확인하기 위해서 이 방법을 사용할 수 있다. 단계를 요약해보면
- .lib 파일로부터 .obj 파일을 추출한다
- lib /extract:myobj.obj mylib.lib
- .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
좀 옛날 것이지만 디버그 심볼에 대해서 자세하고 친절하게 설명해준 훌륭한 글
리더의 자세 6 – 회사에서 인생의 1/3을 보낸다
리더의 자세 시리즈에서 인간적인 리더를 강조해왔다는 점을 인정해야겠다. 그리고, 인간적인 리더 이외에도 다양한 리더가 필요하다는 점도 인정해야겠다. 하지만, 여전히 인간적인 리더를 가장 으뜸으로 꼽고 싶다.
회사에서 인생의 1/3을 보낸다
회사는 인생의 1/3 정도의 시간을 보내는 곳이다. 어떤 회사 생활을 하느냐가 어떤 인생을 살았는가의 1/3 정도를 말해주게 된다. 회사는 월급의 댓가로 노동을 제공하는 장소라기 보다는 인생의 많은 시간을 살아가고 있는 삶의 무대이다.
그러므로 회사와 사회에서 정의한 인위적인 규칙에 휘둘리기 보다는, 자신이 정한 인생의 목표를 이루고 내면의 욕구를 충족시키기 위해서 시간을 보내야한다. 성장하고, 승진하고, 연봉을 올리기 위해 자신을 혹사시키는 대신에, 하고 싶은 일을 열정적으로 하고, 동료들과 추억을 쌓으면서 즐거운 시간을 보내야 한다. 그리고 리더라면, 자신 뿐만 아니라 동료들이 그런 시간을 보낼 수 있도록 노력해야 한다.
회사가 손해를 본다는 오해가 없길 바란다. 만약 회사에서 요구하는 일과 자신이 즐거움을 느끼는 일이 크게 다르다면 회사를 옮기는 것이 서로에게 좋은 일이다. 반면에 자신이 원하는 일을 즐겁게 하는 개인은 엄청난 집중력과 능력을 발휘해서 회사에 큰 이익을 가져다 준다고 믿는다.
인생의 목표를 제쳐두고 올바른 회사생활을 논하는 것은, 여행의 목적지를 제쳐두고 올바른 교통수단을 논하는 것과 다를 바가 없다.
리더의 자세 5 – 리더는 역할이다
내가 생각하는 리더는 역할 혹은 직군의 이름이다. 프로그래머나 디자이너, 기획자처럼 말이다.
리더는 역할이다
이런 관점에서 보면, 가장 뛰어난 개발자에게 리더의 역할을 주는 것은 그다지 합리적인 일이 아니다. "니가 프로그램을 제일 잘 짜니 윈도우를 인스톨해라"라고 하는 것처럼 왠지 그럴듯하게 들리지만 비합리적인 일이다.
리더는 팀을 올바른 방향으로 이끌고, 동료들에게 용기를 불어넣어주고, 외부 세계와의 관계를 조율하는 전문가다. 프로그램을 개발할 때 필요한 능력과는 또 다른 능력이 필요한 직군이다.
리더가 팀에서 제일 훌륭하고, 높은 사람이라는 기존의 사고방식은 리더의 전문 분야가 아닌 분야에까지 권한을 행사하게 만든다. 마치 디자이너에게 프로그램 설계의 최종 승인 권한을 주는 것과 같다.
삼권분립
검증된 모델은 아니지만 개발팀의 세 가지 권력을 분리한다는 개인적인 아이디어다. 기술적인 전문가로서의 아키텍트, 협업 프로세스의 전문가인 프로세스 마스터(스크럼 마스터를 흉내낸 것), 팀의 목표를 정하고 외부 세계와의 관계를 조율하는 리더.
한 사람이 이 역할을 모두 맡는 대신에 각각의 담당자를 두면 그 만큼의 전문화가 가능하므로 업무의 질이 높아지고 개인의 스트레스도 적어진다. 각각의 권력이 서로를 견제하므로 한 명의 독단적인 권한 남용이나 비합리적인 결정도 줄어든다. 무엇보다도 기존의 수직적인 관계를 무너트리고, 수평적인 관계를 형성하는데 도움이 된다.