'버그'에 해당되는 글 4건

  1. 2012/02/06 프로그래머 3부 (03)
  2. 2009/01/21 나를 바꾼 버그 (4)
  3. 2008/11/04 FindBugs: 코드의 정적 분석을 통한 버그 탐색 (2)
  4. 2008/04/23 Erlang GS 모듈 폰트 관련 예제 (2)
Thoughts2012/02/06 13:17
2011년 1월 21일 11:30

"뭐가 좀 나왔나요?"

호출을 받고 달려온 유식의 첫 물음이었다. 유식은 사태를 그다지 심각하게 생각하지 않고 있었다. 버그 없는 시스템이란 상상할 수 없었고, 모든 버그는 해결 가능한 것이었다. 유식이 보기에, 버그는 '재미있는 것' 이지 '심각한 것'이 아니었다. 하지만 허동수의 표정은 심각했다.

"보이소. 내가 담당한 부분이 아니라서 뭐라고 말을 못하겠네예."

공통 라이브러리에 해당하는 코드 담당자는 유식과 대수였다. 유식은 고개를 끄덕였다.

"제가 맡은 부분이니 제가 봐야겠죠. 그런데 문제가...?"

허동수는 모니터를 가리켰다. 허동수가 가리킨 그곳에는, 소스코드가 변경되었음을 알리는 diff 문자열이 찍혀 있었다. diff는 거짓말을 하지 않았다. 이미 십수년간, 수많은 개발자들이 어루만지고 개선한 프로그램이었다. 그리고 diff는, 유식이 담당한 코드를 누군가 수정했음을 알리고 있었다.

http://dstein.egloos.com/1702045



"어떻게 바뀐 것 같습니꺼?"

어느새 선화와 대수도 유식 뒤에 와 있었다.

"함수 인자 형이 바뀌었고, 코멘트가 한줄 추가되었군요."

"그건 저도 압니더. 내가 알고 싶은거는, 이렇게 바꾸고 나면 시스템에 어떤 영향이 있느냐는 겁니더."

"PolicyAgent는 Agent의 하위 클래스이니까..."

유식은 생각했다. PolicyAgent는 Agent의 하위 클래스이다. 상위 클래스에는, 하위 클래스 구현을 편리하게 해 주는 코드가 들어가 있게 마련이다. 또한, 하위 클래스에서 바꿀 필요가 없는 공통의 프로그램 로직이 들어가 있게 마련이다. 하위 클래스에서 상위 클래스의 동작 방식을 변경하고자 할 때에는, 변경할 메소드만 골라 내어 오버라이딩(overriding)한다. 오버라이딩 된 '같은 이름의' 메소드는, 상위 클래스에 존재하는 '같은 이름의' 메소드를 대체한다.

유식은 생각했다.

'pass_policy라는 메소드가 상위 클래스에 있었나?'

상위 클래스에 없었다면 문제될 것이 없지만, 상위 클래스에 있는 메소드였다면 문제가 심각해지기 때문이었다. 가령 pass_policy라는 메소드가 하위 클래스에만 있는 메소드였다면, 그 인자의 형(type)에서 const가 탈락되더라도 크게 문제될 것은 없었다. 하지만 상위 클래스에도 있는 메소드라면, 상위 클래스의 pass_policy와 하위 클래스 pass_policy는 순간 다른 메소드가 되어 버린다. 그러니 하위 클래스 메소드의 인자형을 바꿔버리는 순간, 하위 클래스 pass_policy 대신 상위 클래스 pass_policy가 호출되도록 프로그램은 바뀌어 버릴 것이다.

"잠깐 키보드 좀 쓸께요."

유식은 동수로부터 키보드를 넘겨받고 소스코드를 확인했다.

"어떻습니꺼?"

몇 글자 쳐 넣지도 않았는데 허동수가 결과를 물었다.

"잠시만요. 급하시긴..."

"급한 일이니까 그렇지예. 유식씨는 별로 안 심각한갑네."

"서두른다고 빨리 해결 될 일이면 저도 서두르죠."

서두른다고 타이핑 속도가 늘어나는 것도 아니고, 서두른다고 생각의 속도가 달라지는 것도 아니지 않나. 유식의 생각은 그랬다. 오히려 중요한 것은 숨고르기였다. 문제가 드러났을 때 서두르면, 코드는 망가지게 되어 있었다. 천천히 생각하고 또 생각해야, 문제를 교정한답시고 더 많은 버그를 만들어 내는 어리석음을 피할 수 있었다. 지금 말썽을 부리고 있는 저 부분이, 필요 없어 보인다는 판단에 아무 생각없이 const를 걷어내서 생긴 버그가 아니라고 누가 장담할 수 있겠는가.

"문제가 뭔지 알았습니다."

"뭔가요?"

대수가 물었다.

"그 원인은 즉슨..."

유식이 설명하자 모두 고개를 끄덕였다. 그런데, 뭔가 찜찜한 것이 있었다. 대수가 물었다.

"그런데, 저 코멘트는 뭘까요?"

"12, 라고 적힌 저 주석(comment)?"

"네. // 대신 /// 를 붙여 놓은 것도 웬지 독특해보이는데 말이죠. 대체 무슨 뜻의 주석일까요?"

"글쎄요..."

그것까지는 유식도 추측할 수 없었다. 주석에 적힌 내용을 분석해서 프로그램에서 사용한 클래스에 대한 문서를 만들어주는 시스템 가운데에는, '///'와 같은 특별한 주석 형식을 사용하는 것도 있긴 했다. 하지만 12와 주석 형식과는 특별한 관련성이 없어 보였다. 아니, 어떤 연관성을 찾아내기에 12라는 숫자가 갖는 상징성은 너무 왜소해보였다.

"어쨌든, 저 부분을 원래대로 되돌려 놓고 테스트를 한 번 해 보죠."

허동수는 대수를 데리고 자기 자리로 돌아갔다. 대수는 유식의 말대로 소스코드를 고쳤고, 허동수는 백업 시스템과 빌드(build) 시스템을 점검한 후 다시 회귀 테스트를 시작했다.

- 위이잉

그 순간 하드디스크가 굉음을 내며 돌아가기 시작했다, 고 느낀 것은 아마 허동수의 착각이었을 것이다. 그는 긴장하고 있었다. 또 실패하면 어떻게 하나. 그 때는 정말로 뒤질 백업도 없는데. 그 때는 정말 팀장에게도 할 말이 없는데.

저작자 표시 비영리 변경 금지

'Thoughts' 카테고리의 다른 글

프로그래머 3부 (04)  (6) 2012/02/10
프로그래머 3부 (03)  (0) 2012/02/06
프로그래머 3부 (02)  (4) 2012/02/01
프로그래머 3부 (01)  (2) 2012/01/30
프로그래머 2부  (0) 2012/01/30
개발자, 면접 대비는 어떻게?  (5) 2012/01/17


Posted by 이병준

TRACKBACK http://www.buggymind.com/trackback/403 관련글 쓰기

댓글을 달아 주세요

Extremely Agile/General2009/01/21 23:51
보통 프로그래머들에게는 한가지씩의 무용담이 있습니다. 그 중 가장 흔한 것이 바로 "내가 만났던 가장 개같은 버그" 류의 무용담입니다.

이런 이야기는 왜 하는 것일까요? 뭐 다들 잘 아시겠습니다만, (1) 이런 무용담이 많으면 어디가서 분위기를 띄우기 좋고 (2) 자기가 경력이 꽤 된다는 걸 간단하게 입증해 보여줄 수 있으며 (3) 다른 프로그래머에게 유용한 정보를 전해줄 수 있다는 장점이 있습니다. 물론 이런 이야기는 '군대에서 축구한 이야기'랑 비슷하기 때문에, 프로그래머들이 둘 이상만 모이면 저절로 튀어나오게 되는 경향도 있긴 합니다. ^^;

프로그래밍 심리학이라는 책에도 나옵니다만, 천공 카드를 통해 프로그래밍을 했던 중세시대에도(ㅋㅋ) 소위 '개발자 커뮤니티'라는 것이 있었습니다. 천공 카드를 컴퓨터에 입력하려면 순번을 기다려야 하니까, 기다리면서 노가리들을 깠던 것이죠. 인터넷이 없었으니 당연했겠죠? 그 시대의 개발자들은 아마 지금 개발자들에 비해 백배는 수다스러웠을 겁니다.

각설하고... 그런데 버그에 관한 그런 무용담들을 들어보면, 보통 '버그를 잡았다'에서 스토리가 끝나버려요. 그 뒤의 이야기들은 좀체로 하질 않습니다. 오늘도 커피를 마시러 휴게실로 가다가 같이 일하는 분들하고 잠시 이야기를 할 기회가 있었는데요. 개발자를 한달간 애먹인 버그에 대해서 들려주시더군요. 관련된 모든 사람들의 영혼을 한달동안이나 잠식했던, 정말 가공할만한 버그였습니다. (가장 큰 문제는 그 버그가 그분들이 개발한 시스템에서 나온게 아니라는 점이었죠.) 듣는 제가 다 소름돋을 정도였으니....

보통은 거기까지 듣고 마는데, 오늘은 제가 이런 질문을 한번 해봤습니다.

"그런 버그를 한 번 겪고 나면 본인이 어떻게 달라졌다고 느끼나요?"

질문을 좀 뜨악하게 들으시는 것 같아서 좀 다르게 물어봤습니다.

"그런 버그가 (프로그래머로서의) 자신의 인생을 바꿔 놓았다고 느낄 때가 있나요?"

생뚱맞게 들리실수도 있겠습니다만, 저는 이런 질문을 한번쯤은 던져 보아야 하지 않나 합니다. 제가 이 직장에 처음 들어왔을때 처음 맞닥뜨린 가장 심각했던 'UNDETERMINISTIC' 버그[각주:1]는 시그널 핸들링 관한 것이었습니다. 시스템이 죽긴 죽는데, 진짜 어쩌다 한번 죽는 겁니다. 그리고 그 상황 사이의 일관성을 찾기가 정말 힘들었어요.

이 문제의 해결책을 찾기 위해 정말 많은 삽질을 했습니다. (지금 생각하면 삽질이 아니라 당연하게 해야 하는 일들이지만요.) 첫 번째로 했던 일은 메모리 누수가 시스템의 crash로 이어지는 시점을 정확하게 동기화시키기 위해 MALLOC_CHECK_ 환경 변수의 값을 설정하는 것이었습니다. (Linux라면 man malloc하시면 관련 자료가 나올 겁니다.) 처음에는 시스템이 죽는 이유가 메모리 누수 때문이 아니었을까 하고 추측했거든요. (그당시에는 valgrind에 대해서 몰랐습니다.)

물론 그래도 문제가 해결이 안되었습니다. 한달 뒤에야 겨우 문제의 실마리를 찾을 수 있었죠. (쪽팔립니다ㅎㅎ) 문제인즉슨 이런거였습니다. write를 할 때 리턴 값으로 '파이프가 깨졌다'는 오류 메시지를 받을 수 있을 것으로 기대했었는데 (write를 하는 중에 서버가 죽을 경우를 대비하려던 거였죠) 문제는 그게 SIGPIPE 시그널을 block 하지 않으면 제대로 동작하지 않고 프로세스가 죽는다는 거였습니다. (그것도 꼭 항상 죽는건 아니었죠. ㅋㅋ)

이 문제의 교훈은 이런 거였습니다. 매뉴얼에 의존해서 그대로 몇 줄 코드를 구현했습니다. ('상대 프로세스가 죽을 경우 내 프로세스는 파이프가 깨졌다는 오류 메시지를 받는다'는 것이 매뉴얼 내용이었습니다.) 그런데 그 코드가 정말로 제대로 동작하는지는 확인을 하지 않았던 겁니다. '몇 줄'에 불과하고, '매뉴얼 대로' 구현했기 때문에, 거기 버그가 숨어들어갈 거라고는 생각을 못했던 것이죠.

이 문제를 '기계적'으로 해결하려면, 작은 수정을 가할 때 마다 그 수정이 정말로 올바른지 확인을 하고 넘어가야 했습니다. TDD 수준으로 보폭을 좁게 가져가는 것이 필요하다는 결론을 그 때 얻은 거죠. 이 결론을 실천해 볼 기회는 2년 뒤에 찾아왔습니다. 일단 모든 코드의 구현을 마친 뒤 (테스트 과정에서 설계가 변경될 수 있다는 가정은 일단 배재했기 때문에 그럴 수 있었습니다. 코드에 확신이 있기도 했고, 사실 무식할 때 가장 용감해지는 법이니까요), 시스템의 아주 작은 부분부터 차례로 테스트를 해 나기가 시작했습니다. 테스트를 마친 코드만을 조금씩 시스템에 포함시켜서 빌드를 해 나가기 시작했고, 그 부분이 제대로 시험되었다는 확신이 들 때메만 다음 코드로 넘어갔습니다. 이런 식으로 해서 결국 연동시험 때 발견된 버그 수를 0으로 낮출 수 있었습니다. 테스트에 CppUnit을 도입한 것, TDD를 공부한 것, '한 걸음을 뗄 때 마다 뒤돌아보기'에 대한 확신이 생긴 것 등이 그 시기에 했고 느꼈던 것들입니다. (지금 생각하면 '책 한 권만 잘 읽었어도 더 잘 할 수 있었을텐데' 하긴 합니다만.)

결국, '그 자그마한 버그 하나'가 저를 바꿔놓은 것이죠. 이 블로그도 그 덕에 생겼습니다. ^^;

많은 개발자들이 Continuous Integration이나 Issue Tracking의 필요성에 대해 공감은 하면서도 실제 도입을 망설이는 이면에는 '버그는 부끄러운 것'이라는 개발자적 자존심이 어느 정도 깔려 있다고 저는 생각합니다. 그런 부분을 해소할 수 있으려면, 버그 자체도 지식으로 대우하는 자세가 필요합니다. Bug Tracking이라는 말 대신 Issue Tracking이라는 다소 점잖은 용어가 널리 쓰이는 것도, 어쩌면 그래서일지도 모르겠어요.

버그가 나를 더 좋은 곳으로 데려갈 수 있다는 확신을 가지는 것은, 그런 의미에서 중요하다고 생각합니다. 여러분도 저처럼, '나를 바꾼 버그'를 하나씩 가지고 계신가요?

  1. reproduce하기 굉장히 난감한, 발현 시점을 도무지 정확히 알 수 없는 버그. [본문으로]

'Extremely Agile > General' 카테고리의 다른 글

CI 과정에서 조심해야 할 나쁜 냄새들  (8) 2009/02/18
전쟁의 기술  (3) 2009/01/28
나를 바꾼 버그  (4) 2009/01/21
요구사항과 리스크  (2) 2009/01/16
짝 프로그래밍 (Pair Programming)  (2) 2009/01/15
Microsoft Groove  (4) 2008/12/19


Posted by 이병준

TRACKBACK http://www.buggymind.com/trackback/193 관련글 쓰기

댓글을 달아 주세요

  1. 공감하고 갑니다. ^^

    2009/01/29 02:40 [ ADDR : EDIT/ DEL : REPLY ]
    • 아. 안녕하세요? 제가 블로그 첨 열었을 때 A2님 블로그에서 X-note에 리눅스 설치하는 방법을 참고했던 기억이 나네요. 새해 복은 많이 받으셨는지? 올해도 건승하시길~

      2009/01/29 09:11 [ ADDR : EDIT/ DEL ]
  2. 정말 공감가는 글입니다. 저는 아직 인생까지 걸어보진 못했지만 잡아내는 버그 한두개로 소프트웨어 자체를 fail 시켜야 한다는 점에서는 거의 매일 누구에겐가는 운명적인(?) 버그를 잡아낸다고 해야하나요. 하지만 더 열심히 한다면 언젠가는 저도 제 인생을 바꿀만한 버그를 잡아내는 날이 오겠죠? ^^; 어쨌든 이젠 돌다리를 두들겨만보고 건너는 버릇은 아예 없앴습니다. 뛰어보고 엎어보고 발로 차보고 긁어보고 맛도 본 후에나 건너게 되더군요.

    2009/03/26 13:00 [ ADDR : EDIT/ DEL : REPLY ]

Extremely Agile/TDD2008/11/04 15:34
FindBugs라는 프로젝트가 있습니다. 코드의 정적 분석을 통해 코드에 내재된 버그를 찾는 솔루션을 만드는 프로젝트입니다.

많은 개발자들이 정적 분석을 통한 버그 탐색 방법을 도외시하는 경향이 있습니다만, 개발자들도 사람이니 '바보같은' 실수를 저지르게 되어 있기 마련이라는 점을 감안한다면, 짝 프로그래밍이나 코드 리뷰가 버그를 많이 줄여준다고 하더라도 그런 미련한 버그들이 코드에 뒤섞이는 것을 100% 방지할 수는 없습니다.

정적 분석 (static analysis) 방법이 그런 버그를 찾을 수 있게 도와준다면, 사용하지 않을 이유는 없어 보이는데요. 다행히 FindBugs 프로젝트는 Eclipse나 Netbeans 같은 IDE상에서도 사용할 수 있을 정도로 성숙되었고, 많은 분들이 쓰고 계십니다.



이 프로젝트 URL은 http://findbugs.sourceforge.net/ 입니다. 논문도 꽤 나온 것 같은데, 재미있어 보이네요. (아직 읽어보진 않았습니다.) Lesser GPL로 배포되고 있으니, 상업적 프로젝트에도 무리없이 적용 가능할 것 같습니다.

참고할만한 다른 링크들 :

http://benelog.egloos.com/2079841 - FindBugs + Maven 2 + Hudson
http://findbugs.blogspot.com/ - FindBugs 공식 블로그
http://findbugs.sourceforge.net/bugDescriptions.html - 버그 패턴 설명
http://www.ibm.com/developerworks/kr/library/tutorial/j-cq11207/index.html - 지속적 통합과 결함 발견


Posted by 이병준

TRACKBACK http://www.buggymind.com/trackback/177 관련글 쓰기

  1. FindBugs + Eclipse + Maven2 + Hudson  삭제

    2009/01/24 07:08TRACKBACK FROM 개발을 통한 자기수양 - benelog

      FindBugs를 이용한 코드검사를 Maven2을 통해 실행하고, Hudson을 통해 확인하는 설정을 정리해 봅니다. Hudson을 설치하는데 필요한 정보를 추가로 얻고 싶으신 분들은 http://benelog.springnote.com/pages/1822522 페이지에 모아진 링크를 참조하시면 어렵지 않게 진행하실 수 있으실 것입니다.     FindBugs에 대해 보다 자세히 알고 싶으신 분은 아래링크를 참조하...

댓글을 달아 주세요

  1. 동영상 내용 많이 도움이 될 것 같네요. 제 블로그의 포스트에서도 이 포스트에 링크를 걸었습니다~ 잘 봤습니다.

    2009/01/24 07:09 [ ADDR : EDIT/ DEL : REPLY ]

Languages/Erlang2008/04/23 14:06

Erlang 웹사이트에 가서 GS 사용자 가이드를 다운받아 GUI 관련 프로그래밍을 Erlang으로 해 보고 있었는데요. 이거 조금 문제가 있군요. ㅋㅋ Linux에서는 잘 되는 예제가 Windows에서는 좀 이상하게 실행됩니다. 이렇게 되면 Windows 환경에서 GS를 사용해서 프로그래밍하는 것이 좀 어려워 질 수도 있겠군요.

GS 사용자 가이드 chapter 1의 예제 15번입니다. 다음과 같은 GUI를 화면에 그리는 것이 목적입니다.

사용자 삽입 이미지


그런데 이 예제를 Windows에서 실행하면 제대로 되질 않습니다. 왜 그런가 봤더니, 텍스트의 Width와 Height가 전부 똑같이 계산되더군요. 다음과 같이 출력됩니다. Rectangle 크기가 전부 동일하게 계산되는 바람에, 글자 주변에 사각형을 제대로 그릴 수가 없네요. Windows 환경에서 실행되는 gs:read(name, {font_wh, {Font, Text}}) 함수에 버그가 있는 것 같습니다.

사용자 삽입 이미지

화면 캡처도 이상하게 되는군요. ㅋㅋ

'Languages > Erlang' 카테고리의 다른 글

Erlang for C programmers (1) : 타입과 변수  (0) 2008/09/01
Erlyweb 개발 입문시 발생하는 문제 해결법  (0) 2008/07/04
Ubuntu에서의 yaws 설치 오류  (0) 2008/06/14
Programming Erlang  (2) 2008/06/12
Erlang GS 모듈 폰트 관련 예제  (2) 2008/04/23
Programming Erlang  (0) 2008/04/17


Posted by 이병준
TAG Erlang, gs, 버그

TRACKBACK http://www.buggymind.com/trackback/129 관련글 쓰기

댓글을 달아 주세요

  1. 오.. 네트워크에 강한 erlang 공부하시는군요. 행복해 보입니다. 자기가 하고 싶은 것을 한다는 것 말이에요.

    2008/04/28 10:23 [ ADDR : EDIT/ DEL : REPLY ]
    • 그렇게 봐 주시니 감사합니다. 그런데 제가 요령이 없어서 그런지 공부하기가 쉽지 않네요. ^^;

      2008/04/28 13:23 [ ADDR : EDIT/ DEL ]