1 컴퓨터 프로그래밍 과정 중의 디버그
1.1 개요
디버그(Debug)는 프로그래밍 과정중에 발생하는 오류나 비정상적인 연산, 즉 버그를 찾고 수정하는 것이다. 이 과정을 디버깅(Debugging)이라 하기도 한다.
프로그래밍을 하는 모든 사람이 뼈저리게 겪는 격언이 바로 '버그가 없는 프로그램은 없다.' 혹은 '한번에 돌아가는 프로그램은 없다' 라는 것. 이는 일종의 불가항력 같은 것이라서 아무리 능력이 좋거나 경험이 많더라도 버그가 없는 프로그램을 만들 수는 없다. 다만 요령있는 사람은 오류 지향적인 설계보다는 견고한 설계를 지향하고 버그가 나더라도 쉽게 잡아낼 수 있도록 유도하여 짠다.
비전공자나 프로그래밍 경험이 없는 많은 사람들이 "그냥 뚝딱뚝딱 만들고 돌아가게 하면 되는거 아냐?" 라고 오해하는 것과는 반대로 프로그램 제작 과정에서 코딩이 2할이면 디버깅은 8할이라고 보면 된다. 프로그램이라는 것은 사람이 만드는 것이기 때문에 버그가 필연적으로 생기기 마련이고, 이 버그를 잡는 디버그 과정은 프로그래밍 과정에서 필수적으로 행해야 하는 것 중 하나이다.
생기는 이유도 천차 만별인데 굳이 따지자면 아래와 같다.
- 사람의 사소한 오타로 생기는 버그. 이 경우가 가장 흔해서 일단 찾으면 수정이 쉽지만, 찾는 과정이 은근 빡친다.
- 특수한 케이스를 미처 생각 못한 논리적인 버그. 예외를 감안하지 않은 경우가 주로 이런 경우이다.
- 프로그램의 실행을 담당하는 OS, 또는 프로그램이 의존하는 다른 라이브러리의 버그로 인해 발생하는 버그. 특히 소스가 공개되지 않은 것이라면 해당 기능을 우회해야만 하며, 소스가 공개되어 있다 해도 수정의 난이도 및 라이선스 문제를 고려해야 한다.
- 시스템 상의 한계로 인한 오류, 하드웨어가 소프트웨어를 버티지 못하는 경우가 주로 이 경우이다. 음파공격 버그 역시 근본적으로는 이 오류였다. 이 경우는 원인을 찾는 것은 물론, 문제를 해결하는 데에도 상당한 시간이 소요된다.
- 컴퓨터에
벌레(Bug)[1] 먼지(...)가 들어가서 생기는 경우. 굳이 이 경우가 아니더라도 하드웨어의 노후화나 고장으로 인해 생기기도 한다. 버블 시스템이나 별의 커비 슈퍼 디럭스의 버그가 주로 이런 경우. 간혹 하드웨어 설계 자체의 이상으로 버그가 발생하기도 한다. 이 정도 가면 그냥 하드웨어 또는 그 설계를 바꿔야 하는데, 특히 설계 자체가 잘못된 것이라면 더 이상의 자세한 설명은 생략한다.
1.2 과정
디버그를 하는 것 자체는 말로 설명하면 굉장히 쉽다. 오류 혹은 비정상적인 작동을 하는 부분을 찾아 수정하면 된다.
하지만 행동이 말 처럼 쉬웠다면 이 항목은 작성됐을 리 없다.
디버깅은 프로그래머가 만드는 과정에서 미처 고려하지 못한 부분이나 실수를 찾는 것이기 때문에 이 오류가 난 부분을 찾기란 굉장히 어렵다. 프로그램 코드의 길이가 수십줄~수천줄 정도라면 근성으로 코드를 샅샅히 뒤져 찾을 수도 있겠지만 수만줄 이상이 넘어가면 답이 없다. 프로그래머가 예측하는 부분 안에서 나오길 바라는 수 밖에.
그렇다고 이걸 안하면 수십억이 날아가는 건 기본, 심한 경우 소송까지 갈 수도 있다. 버그 하나가 회사 하나를 통째로 날려먹은 사례도 있다. 한 술 더 떠서 프로그램이 영향이 현실에 끼치는 영향이 큰 임베디드 시스템 쪽에서는 버그가 곧 재앙이다.
이런 빡침악명과 사례는 이미 오래전부터 알려져 있어서 지금에 이르러서는 이 디버깅을 도와주는 프로그램 적인 도구들이 많이 등장한 상태이다. 프로그램 내에 존재하는 모든 변수 값을 표시하거나, 프로그램 코드를 한줄 한줄 멈춰가며 구동시키는 것 등이 대표적으로 디버깅에 도움을 주는 것들이다. 하지만 이것들은 말 그대로 도움을 주는 것이지 직접 버그를 찾아주는 것은 절대 아니다. 가령 1+2를 해야할 프로그램에서 프로그래머의 실수로 1-2를 적는다면 의도하지 않은 결과가 나오기 때문에 버그이지만 컴퓨터 입장에선 어쨌든 실행은 멀쩡히 되기 때문에 오류로 인식하지 않는다. 디버깅의 핵심은 바로 이런 부분을 찾아야 하는 것이다.
또한 이 디버깅이 얼마만큼의 시간이 걸리는 지는 아무도 모른다. 일단 버그가 정확히 몇 개다. 라고 단정지을 수 있는 것도 아니고 버그가 발생되는 코드가 프로그래머가 생각하는 부분에 있다는 보장이 전혀 없기 때문이다. 프로그래머가 생각한 부분에서 버그가 발생되는 코드가 발견 되었다면 디버깅 시간은 짧아질 것이고 전혀 엉뚱한 곳에서 나온다면 디버깅에 걸리는 시간은 한없이 길어진다. 그리고 안타깝게도 대부분의 버그는 전혀 예상치 못한 곳에서 뜬금없이 튀어나온다. 그리고 예상치 못한 야근으로 이어진다.
이런 과정들을 줄여주는것이 단위 테스트인데, xUnit등을 이용해서 자동화를 시켜놓으면 그동안의 뻘짓이 허무하게 느껴질정도로 디버깅 시간이 확 줄어든다. 눈도 안아프고 말이다 하지만 선임자가 똥을 싸놓았다면 어떨까? 물론 단위 테스트가 끝났다고 다 끝난 것은 아니고, 상위 테스트를 통해 단위 간의 상호작용 과정에서 발생할 수 있는 버그도 줄여야 한다.