-
삽질을 통한 성장, 아픈만큼 성숙해진다.IT topics 2008. 6. 12. 17:05반응형어떤 사람이던 성장을 한다. 어려서부터 많이 먹고 자라서 키도 크고 몸무게도 커지면서 육체적인 성장을 하고 학교 등에서 배움으로 지식도 성장한다. 그리고 다양한 경험을 통해서도 성장하곤 한다. 특히 어려운 일을 당해서 곤욕을 치룬 뒤에 얻는 경험을 통한 성장은 매우 소중하다는 생각이 든다.
최근에 회사에서 일이 많이 몰려서 꽤나 바쁘다. 그것도 대형껀수로 2~3개가 한꺼번에 몰리니 정신이 없다. 그리고 그것 모두 회사 입장에서는 놓칠 수 없는 큰 금액이 걸려있기에 담당자인 나를 계속 쪼아대고 있는 상황이다. 쪼아대는 것이 적절치 못한 표현이라면 그렇겠지만 꼭 해야한다고 계속 압박하고 있는 중이다.
회사에서 내가 맡은 일이 여러가지가 있고 모두가 다 중요한 일이지만 그 중에서 서버 컨퍼넌트 모듈을 만드는 일이 있다. DRM 서버도 내가 맡았지만 지금은 밑에 직원이 와서 그 친구에게 넘겨줬고 DRM 적용 툴도 넘겨줬지만 DRM 서버 컨퍼넌트 모듈은 아직 못넘겨줬다. 솔직히 서버와 적용 툴은 어느정도 최적화가 되고 안정화가 된 상태여서 넘겨줄 수 있었지만 서버 컨퍼넌트 모듈은 어떤 환경에서 어떻게 적용될지 모르기 때문에 쉽게 넘겨줄 수 없었다. 게다가 서버와 적용 툴은 윈도 기반 응용 프로그램이지만 서버 컨퍼넌트 모듈은 윈도 기반, 리눅스 기반, 유닉스 기반 등 어떤 OS에서 돌아갈지 모르는 상황이고 또 웹서버 위에서 올라가는 모듈인지라 ASP가 될지 PHP가 될지 JSP가 될지 모르는 정말 다양한 변수가 존재하는 모듈인지라 못넘겨주고 그냥 내가 갖고 있는 상태였다.
이번에 E사에 DRM 서버를 업그레이드하면서 서버 컨퍼넌트 역시 업그레이드를 하는 작업을 했다. 그런데 예전까지는 서버 컨퍼넌트 모듈을 CGI로 만들어서 작업했는데 그것이 문제가 되어 이번에 JSP용 모듈로 교체하기로 한 것이다. 그래서 들어가서 서버 컨퍼넌트 모듈을 교체하는 작업을 하는데 문제가 생겼다. 제대로 올라가지 않는 것이다.
일단 E사의 환경부터 살펴보면 서버는 HP 서버 머신이고 OS는 HP-UX며 웹서버는 WebToB, WAS는 제우스를 돌린다. 이미 여러번 WebToB에 제우스 환경에서 JSP용 서버 컨퍼넌트 모듈을 만들어본 경험이 있었기 때문에 큰 문제가 없겠다 싶었다. 하지만 문제는 HP 머신 위에 HP-UX 위에서 올라가는 것은 처음해본 일이기 때문에(IBM 머신 위에서 AIX에서는 해봤다) 걱정이 앞섰다. 첫날에는 어떤 문제인지 제대로 파악도 못한 상태로 사무실로 들어와야 했다.
다음날에 다시 E사에 가서 그 서버에 붙어서 작업을 계속했다. 일단 JSP 모듈로 만들기 전의 라이브러리부터 검증하기 시작했다. 원래 윈도 기반의 모듈을 리눅스용으로 만들었고 그걸 다시 유닉스용으로 만들었기 때문에 플랫폼에 따른 설정의 차이로 문제가 생길 수 있겠다는 생각이 들었기 때문이다. 역시나 라이브러리부터 문제가 보였다. 그래서 하나하나 디버깅하면서 잡아내기 시작했다. 역시나 제일 큰 문제는 메모리 배열문제. 흔히들 Endian 문제라 말하는 int형 메모리 배치문제가 컸다. 윈도나 리눅스의 경우 Little-Endian을 사용하기 때문에 윈도 소스를 그대로 리눅스에서 사용할 수 있었지만 유닉스에서는 대부분 Big-Endian을 사용하기 때문에 메모리 배치를 바꿔줄 필요가 있었다. 솔직히 여기까지 알아내는데 이틀이 걸렸다. 그 전에는 왜 엉뚱한 값을 가져와서 에러를 내는지 알 수 없었으나 한참의 고민끝에 예전에 비슷한 경험을 한 것이 생각나서 혹시나 싶어서 알아본 것이 정답이었던 것이다. 결국 둘째날도 Endian 문제임을 확인하고 다시 사무실로 돌아왔다.
사무실로 돌아와서는 회사에 HP 머신과 HP-UX를 지원해달라고 요청했고 그 다음날 테스트를 할 수 있는 HP-UX가 설치된 HP 머신을 받아서 맹렬히 디버깅을 했다. Endian 문제를 해결하고 32/64비트 문제도 해결해서 라이브러리 단계에서의 디버깅을 끝낸 뒤에 JSP용 모듈로 만들어서 테스트를 했다. 그런데 라이브러리 테스트는 무리없이 끝났는데 JSP 모듈 테스트에서 계속 죽는 현상이 발견되었다. JSP용 모듈을 만드는데는 자바의 JNI 기술을 사용해서 만든다. 라이브러리는 C로 만들어졌기 때문에 자바 기반의 JSP 모듈은 결국 자바로 만들어야 했고 다른 언어를 자바로 적용시키는 JNI 기술을 이용해서 만들게 된다. 그래서 혹시 JNI를 사용하는 것에 문제가 있을까 싶어서 걱정을 했다. 나는 그 부분에 대해서는 모르기 때문이다. 자바에 대해서도 거의 모른다(기본적인 문법은 알지만). 그렇기 때문에 덜컥 겁이 났다. 회사 안에서도 이 부분에 대해서 아는 사람이 아무도 없기 때문이다. 주변에 이 부분에 대해서 물어볼 사람도 없다. 결국 내가 막히면 끝이라는 얘기다. 어쩔 수 없이 구글을 붙들면서 JNI에 대한 정보를 찾으면서 JNI 문제가 아닌 혹시 다른 문제가 아닐까 하는 생각으로 문제를 계속 찾아봤다.
그런데 재미난 것은 3개의 모듈이 올라가는데 1개는 올라가고 2개는 안올라갔다. 즉, JNI쪽 문제는 아니라는 얘기다. JNI쪽 문제라면 3개 모두 안올라가야 정상인데 1개가 올라갔다는 것은 JNI를 사용한 모듈이 제대로 동작하고 있다는 증거다. 그래서 내린 결론은 라이브러리를 만들때 사용하는 GCC(리눅스, 유닉스에서 사용하는 C 컴파일러)에서 버퍼 오버플로(할당된 메모리 영역을 넘어가는 것)를 제대로 못잡아주는데 JSP에서 사용하는 JVM(자바 가상 머신)에서는 그것을 귀신같이 잡아내주고 있다는 결론을 내렸다. JVM이 민감해서 GCC에서 못잡은 문제를 끄집어냈다는 의미다. 그렇다면 어디서 오버플로가 나는지 확인하는 일을 해야 했다.
그런데 문제가 생겼다. 어디서 오버플로가 나는지 어떻게 찾아내야 하나? GCC에서는 못찾았고 GDB를 이용해서 시도했지만 제대로 못잡아냈다. 결국 무식한 방법으로 라이브러리의 각 단계마다 주석처리를 하고 하나씩 풀어가면서 오버플로가 나는 부분을 찾아내기 시작했다. 컴파일하고 모듈 만들고 올리고 실행해서 에러가 안나면 다음의 주석을 제거하고.. 이런 방식으로 4시간을 돌려서 오버플로가 나는 부분을 찾을 수 있었다. 또 전날에 수정했던 Endian 문제도 다시 수정했다. 2개의 모듈에 문제가 있었는데 하나는 4시간이 걸렸고 나머지 하나는 3시간이 걸렸다. 여하튼간에 겨우 문제를 해결했다.
그리고 오늘. 다시 E사에 와서 작업을 하는데 첫날처럼 또 안되는 것이다. 왜 안되나 싶어서 계속 살펴봤는데 문제가 없어야 하는데 계속 문제가 있는 것이다. 게다가 에러가 나지 말아야 할 부분까지 에러가 나는 것을 보고는 황당했다. 하지만 흥분을 가라앉히고 찬찬히 살펴보니 라이브러리를 읽어들이는 경로에 변화가 생긴 것을 확인했다. 예전에 작업했던 경로가 아닌 그 한단계 앞으로 다 변경이 된 것이다. 계속 예전 경로로 라이브러리를 복사해두고 테스트를 했으니 에러가 나오는 수 밖에. 결국 제자리로 돌린 다음에 테스트를 하니 제대로 되는 것을 볼 수 있었다. 다행이라 생각해서 맘을 돌릴 수 있었다.
물론 현재 제대로 돌아가고 있는 것이 아니다. JSP용 서버 컨퍼넌트 모듈이 그 HP머신의 HP-UX에 맞는 모듈임을 확인은 했으나 WAS인 제우스의 환경설정에 제대로 안물려서 잘 돌아가지 않는 상황이다. 하지만 이 부분은 내가 해결해야 할 부분이 아니라 여기 서버 담당자가 해결해야 할 문제이기에 지금 담당자를 기다리면서 이렇게 블로그에 그동안에 있었던 일들을 쭉 풀어내고 있다.
DRM 서버 컨퍼넌트 모듈은 위에서도 얘기했듯 윈도나 리눅스, 유닉스 모두에서 돌아가도록 만들어야 한다. 그리고 어떤 웹 스크립트 언어를 사용했느냐에 따라서도 또 다 적용을 해야한다. ASP, PHP, JSP에 모두 적용이 가능해야 하니 그 가지수도 꽤 된다. ASP야 윈도의 IIS에서만 돌아가니 큰 문제는 없고(얘는 DLL로 만들어주면 된다) 문제는 역시나 PHP와 JSP. 윈도용으로 PHP와 JSP에 맞도록 DLL을 만들어주고 테스트를 해야 한다. 또 IIS용과 윈도 아파치용은 조금 다르다. 여하튼 변수가 좀 많다. 더 골때리는 것은 리눅스와 유닉스용이다. 리눅스용은 좀 괜찮은 편이다. 윈도와 비슷하기 때문에 큰 무리없이 적용을 시킬 수 있었다. 리눅스가 유닉스보다 덜 민감해서 어지간한 에러나 오버플로에도 잘 버틸 수 있다는 것도 리눅스용 서버 컨퍼넌트 모듈이 한결 쉬울 수 있는 이유다. 하지만 유닉스로 넘어가면 얘기가 달라진다. 솔라리스, HP-UX, AIX 등 유닉스 종류도 각기 다를 뿐만 아니라 메모리 배치도 다르고 JSP는 더 까다롭다. 이번에 겪었던 일로 확실히 유닉스가 왜 안전한지 알 수 있었던 계기가 되었다. 이렇게 까다로우니 어지간한 버그는 사전에 다 차단되지 않겠는가.
이번 일을 겪으면서 기존에 있었던 서버 컨퍼넌트 모듈 소스에 있었던 잠재적인 버그들을 다 잡을 수 있었다. 그것은 매우 큰 소득이었다. 언제 터질지 모르는 잠재적은 버그들이 수없이 많이 존재하고 있었는데 이번 디버깅을 통해 그런 버그들을 잡았으니 윈도와 리눅스용 모듈에 안정성을 더해줄 수 있을 것이다. 또 다른 유닉스(솔라리스, AIX 등)에서도 잘 적용할 수 있는 소스로 강화되었다는 것도 큰 소득이라 할 수 있을 것이다. 일주일동안의 고생이 단지 삽질로 끝난게 아니라는 것이다.
이번 일로 나 자신이 내부적으로 성장했음을 많이 느꼈다. 어떻게 디버깅을 해야 하는지, 어떻게 오버플로를 막아야 하는지, 어떤 OS에서든 어떻게 적용을 해야할지 등 수많은 경험을 몸소 느끼면서 내 자신의 기술적인 향상을 어느정도 이룰 수 있었던 계기가 되었다.
역시 엔지니어는 삽질을 통해서 성장하는거 같다.반응형댓글