디버깅 이야기
한빛미디어
|
2004-04-30
|
by HANBIT
19
12,847
저자: 임백준 / 루슨트 테크놀로지스 네트워크
80년대 SF 영화를 대표하는 작품을 두 개 고르라고 하면(사람에 따라 논쟁의 여지는 있지만) 대개 리들리 스콧 감독의 ‘블레이드 러너(Blade Runner)’와 테디 길리엄 감독의 ‘브라질(Brazil)’을 꼽을 수 있다. 미래 사회의 모습을 충격적일 정도로 우울하게 묘사한 ‘블레이드 러너’는 보지 않은 사람이 드물 정도로 잘 알려진 영화이지만, 그에 비해서 ‘브라질’은 본 사람이 드물 정도로 덜 알려진 영화이다.
‘브라질’은 타자기에 벌레가 끼어서 ‘터틀(Tuttle)’이라는 죄수의 이름이 ‘버틀(Buttle)’로 바뀌는 데에서 시작된다. 유명한 배우인 로버트 드니로가 분한 터틀은 전체주의 사회에 저항하는 테러리스트였지만 버틀은 그저 평범한 시민일 뿐이었다. 그렇지만 기계적으로 작동하는 숨 막히는 ‘정보사회’에서 일단 죄수로 낙인찍힌 버틀은 변명을 할 기회조차 갖지 못하고 자신의 거실에서 가죽 포대에 얼굴을 씌운 채 체포당한다.
미래 사회에 대한 진지한 통찰을 넘치는 상징과 절제된 미장센(mise-en-scene)을 통해서 우스꽝스러우면서도 긴장감 있게 묘사한 ‘브라질’은 SF를 좋아하는 사람이라면 한 번쯤 볼만한 영화임에 틀림없다. 그런데 ‘프로그래머’의 입장에서 보았을 때 특히 흥미로운 부분은 영화의 도입부에서 사용된 ‘타자기’ 사건과 비슷한 일이 프로그래밍의 역사에서 실제로 등장했었다는 사실이다.
프로그래밍과 버그
코볼(COBOL) 언어의 탄생에 기여한 것으로 잘 알려진 여성 컴퓨터학자 그레이스 머레이 호퍼(Grace Murray Hopper)는 1945년 여름에 ‘마크 II’ 컴퓨터를 이용해서 특정 계산을 수행하고 있었다. 그런데 아무리 계산을 해보아도 자신이 생각하는 답과 다른 결과가 산출되어 원인을 찾기 위해서 고심했다. 그리하여 그녀가 최종적으로 발견한 것은 컴퓨터 내부의 부품 사이에 낀 채 죽어 있는 큼직한 나방 한 마리였다(요즘 컴퓨터라면 나방과 같은 벌레가 들어갈 구멍이 없겠지만, 옛날 컴퓨터는 덩치가 컸기 때문에 나방이 아니라 ‘쥐’조차 들어갈 수 있었을 것이다).
컴퓨터 내부에서 ‘버그(벌레)’를 발견한 그레이스 호퍼는 죽은 나방을 조심스럽게 꺼내서 자신의 연구 노트에 올려놓고 스카치테이프를 이용해서 고정시켰다. 그 다음 그 밑에 “버그가 발견된 첫 번째 사례(First actual case of bug being found)”라는 글을 남겼다. 컴퓨터 프로그램에서 프로그래머의 실수나 논리적 결함 때문에 발생하는 ‘예상 외의 결과’는 보통 ‘버그(bug)’라는 말로 표현한다. 그것이 단순히 ‘실수’나 ‘잘못’ 같은 따분한 말이 아니라 ‘버그’처럼 생동감 넘치는 말로 표현된 데에는 이와 같은 이유가 있었던 것이다.
버그라는 표현이 절묘한 이유는 단지 재미있거나 귀여워서가 아니다. 그것은 컴퓨터 프로그래밍에서 수시로 등장하는 버그의 주요한 특징을 ‘버그’라는 표현이 매우 정확하게 포착하고 있기 때문이다. 징그러운 비유지만 바퀴벌레를 생각해 보자. 방 한구석에 나타난 바퀴벌레를 잡기 위해서 (맨손은 좀 너무하고) 휴지를 감은 손을 내려친다고 하자. 이때 가만히 앉아서 손에 맞는 바퀴벌레는 없다. 가만있기는 커녕 깜짝 놀랄 만큼 빠른 속도로 달아나기 시작할 것이다.
컴퓨터 프로그램에 존재하는 버그도 마찬가지다. 소프트웨어가 아무 일도 하지 않고 가만히 있을 때 모습을 드러내는 멍청한(?) 버그는 세상에 없다. 소프트웨어 내부에서 쓰레드(thread)가 동작하거나 외부에서 사용자가 사건(event)을 발생시킬 때 버그는 잠깐 모습을 드러내고 사라진다. 지독한 버그라면 소프트웨어 전체의 동작을 중단시킬 정도로 파괴적이기도 하지만 그런 경우는 드물다.
사용자나 테스터(tester)들은 잠깐 모습을 드러냈다가 사라진 버그를 보고 “벌레를 봤다”고 외친다. 때론 정말 그런 벌레가 있는지조차 의심스러울 때도 있지만 프로그래머의 운명은 가혹해서 자기 눈에는 보이지 않는 벌레와 사투를 벌어야 할 때가 있다. 설령 벌레의 모습이 한 번쯤 보였다고 해도 한 자리에 계속 머물러 있지 않기 때문에 휴지를 감은 손을 한번 내려쳐서 잡을 수 있는 버그는 없다.
내공의 잣대 ‘디버깅’
흔히 말하는 프로그래머의 ‘내공’은 누가 큼직한 소프트웨어를 잘 ‘설계’하는지, 누가 복잡한 알고리즘을 정교하게 ‘구현’하는지 만으로 결정되지 않는다. 설계와 구현에 못지않게 중요한 비중으로 내공을 구성하는 요소가 벌레를 잡는 능력, 즉 디버깅 능력이기 때문이다.
바둑을 좋아하는 필자는 소프트웨어의 전체 윤곽을 그리는 설계를 종종 바둑의 ‘포석’에, 자세하고 복잡한 알고리즘을 작성하는 구현을 바둑의 ‘사활문제’에 비교하곤 한다. 그렇다고 했을 때 벌레를 잡는 디버깅은 어떤 특정한 부분에 국한된 이야기가 아니라 바둑의 전반적인 ‘수읽기’ 능력이 비교될 수 있다. 말하자면 디버깅은 설계나 구현과 따로 떨어진 존재가 아니라 소프트웨어 제작의 모든 과정에 스며들어 있기 때문에 내공을 가늠 하는 가장 결정적인 잣대가 되는 것이다.
썬 마이크로시스템즈의 한갤(Sudheen Hangal)과 스탠포드 대학의 모니카 램(Monica S. Lam)은 유명한 저널인 ACM(Association for Computing Machinery)의 2002년 5월호에 “예외적 상황을 자동으로 감지하여 소프트웨어의 버그를 추적하기(Tracking Down Software Bugs Using Automatic Anomaly Detection)”라는 글을 통해서 디버깅의 ‘자동화’를 추구했다. 디버깅을 ‘직관’의 문제로 해석하고 있었던 필자에게 신선한 자극이 되었던 글인데 글의 서문에 다음과 같은 내용이 포함되어 있다.
“안정적인 소프트웨어를 만드는 일은 프로그래머들이 세부사항에 대한 문서를 자세하게 기술하지 않는다는 사실 때문에 어려움에 자주 봉착하게 된다. 따라서 소프트웨어에 대한 문서는 대개 불완전하거나 낡은 것이기 쉽다. 게다가 복잡한 소프트웨어는 덩치가 너무나 커서 한 사람이 시스템의 모든 부분을 파악하는 것이 실질적으로 불가능하다.”
그리고 계속해서 다음과 같이 말하고 있다.
“소프트웨어 시스템은 흔히 여러 개의 컴포넌트로 구성되어 있다. 이러한 컴포넌트들은 또 서로 독립적인 별개의 조직에 속해 있는 사람들이 서로 다른 개발과 테스팅 방법론을 이용해서 개발한 경우가 많다. 이러한 시스템의 모퉁이에서(in rare corner cases) 발생하는 버그를 잡는 일은 며칠 혹은 몇 주의 시간을 요구할 수 있다.”
한갤과 램은 DIDUCE(Dynamic Invariant Detection U Checking Engine)라는 도구의 개념과 구현 방식에 대해서 소개한 다음, 구체적인 실험을 통해서 JSSE(Java Secure Socket Extension) 패키지 안에서 ‘타이밍’과 관련된 버그를 실제로 잡아낸 과정 등을 소개했다. 그들이 ‘디버깅’이라는 좀처럼 정형화시키기 어려운 주제를 ‘자동화’하려고 시도한 점 자체만으로도 흥미가 만만치 않지만, 특히 사람의 직관으로는 발견하기 어려운 ‘타이밍’과 관련된 버그를 ‘자동으로’ 검출했다는 점이 놀라왔다.
이와 같이 디버깅을 자동화하려는 시도는 물론 새로운 것이 아니다. 그러한 주제는 그 전에도 많이 다루어졌고, 최근에도 많은 연구 논문과 함께 실제 소프트웨어 도구가 새롭게 발표되고 있다. 그렇지만 이렇게 디버깅을 자동으로 수행하는 소프트웨어를 만들려고 하는 시도는 한 가지 근본적인 질문을 낳는다. 디버깅을 수행하는 소프트웨어 내부에 존재하는 버그는 누가 검출할 것인가?
실제적인 질문이라기보다는 다소 철학적인 질문에 해당하지만 생각해 보면 간단한 문제는 아니다. 컴퓨터 게임이 없었던 70~80년대에 (유닉스를 만든 켄 톰슨과 같은) 날고 기는 해커들이 ‘P’를 출력하는 프로그램 ‘P’, 즉 자신의 소스코드를 군더더기 하나 없이 토씨하나 틀리지 않고 고스란히 출력하는 프로그램을 작성하면서 시간을 보냈다는 이야기는 잘 알려져 있다.
말하자면 디버깅 프로그램은 그런 프로그램과 마찬가지로 비슷한 종류의 재귀(recursion)의 패러독스에 빠진 셈이다. 똑같은 손이 서로를 그리고 있거나, 안팎이 구별되지 않는 뫼비우스의 띠 위를 기어가는 개미의 모습을 즐겨 그린 에셔(M. C. Escher)의 그림은 재귀의 역설을 시각적으로 표현한 대표적인 작품으로 손꼽힌다.
디버깅을 검출하는 프로그램을 D라고 하자. D를 D에 대해서 실행시켰는데 아무런 버그가 보고되지 않았다고 해보자. 이 결과를 놓고 D가 완벽하다고 말할 수 있을까. 이 경우에 D가 아무런 버그가 없이 완벽하기 때문에 그런 결과가 나온 것인지 아니면 D가 불완전한 나머지 몇몇 버그를 인식하지 못해서 그런 결과가 나온 것인지 판별할 수 있을까. 왼손이 오른손을 그리는지 아니면, 오른손이 왼손을 그리는지, 개미가 기어가고 있는 쪽이 띠의 바깥쪽인지 아니면 안쪽인지 판별할 수 있는 것일까. 찰스 배비지가 컴퓨터를 일컬어 자기 꼬리를 잡아먹는 괴물 ‘우로보로스’를 닮았다고 말한 것은 이와 같은 ‘재귀의 역설’을 진작부터 간파하고 있었기 때문일 것이다.
직관이 필요하다
이번에도 결론을 내려 보자. 한 마디로 말해서 이 세상에는 ‘완벽한’ 소프트웨어가 존재할 수 없다. 따라서 D를 D에 대해서 실행시켰을 때 아무런 버그가 보고되지 않았다면, 그것은 D가 불완전하기 때문이지 그 반대의 경우가 아니다. (착각하지 말자.) 소프트웨어가 불완전한 이유는 여러 가지가 있겠지만 그것은 방법론적인 문제라기보다는 그저 인간이라는 존재 자체가 불완전하기 때문이다. 다시 말해서 소프트웨어가 불완전한 것은 인간이 불완전한 만큼이며 그 이상도 이하도 아닌 것이다.
그래서 결국 소프트웨어에 숨어 있는 벌레를 잡는 일은 적어도 아직까지는 사람의 몫이다. 사람의 ‘직관’으로 풀어야 하는 영역이 아직 남아 있는 것이다. 그렇지만 자신의 ‘직관’을 과학적 방법론과 결합시키려는 노력을 기울이는 사람과, 그렇지 않은 사람은 디버깅 능력에서 현격한 차이를 갖는다. 말하자면 그것이 바로 ‘내공’의 차이인 셈이다.
- 출처 : 마이크로소프트웨어 2004년 4월호 -
TAG :