1. 컴퓨터 프로그래밍 과정 중의 디버그
1.1. 개요
디버그(Debug)는 프로그래밍 과정중에 발생하는 오류나 비정상적인 연산, 즉 버그를 찾고 수정하는 것이다. 이 과정을 디버깅(Debugging)이라 하기도 한다.1.2. 설명
Debug의 어원의 유래는 초창기 컴퓨터에 나방이 들어가 고장을 일으킨데에 있다. 그뒤로 버그는 조작하는데 발생한 오류의 은유적 표현이 되었다.(세계 최초로 실제 벌레(bug)가 일으킨 버그를 미 해군 제독이자 코볼의 창시자였던 그레이스 호퍼가 제거한 그 나방은 현재 미국 스미스소니언 박물관에 잘 보관되어 있다.)프로그래밍을 하는 모든 사람이 뼈저리게 겪는 격언이 바로 '버그가 없는 프로그램은 없다.' 혹은 '한번에 돌아가는 프로그램은 없다' 라는 것. 이는 일종의 불가항력 같은 것이라서 아무리 능력이 좋거나 경험이 많더라도 버그가 없는 프로그램을 만들 수는 없다. 다만 요령있는 사람은 오류 지향적인 설계보다는 견고한 설계를 지향하고 버그가 나더라도 쉽게 잡아낼 수 있도록 유도하여 짠다.
프로그램 제작 과정에서 코딩이 2할이면 디버깅은 8할이라고 보면 된다.[1] 프로그램이라는 것은 사람이 만드는 것이기 때문에 버그가 필연적으로 생기기 마련이고, 이 버그를 잡는 디버그 과정은 프로그래밍 과정에서 필수적으로 행해야 하는 것 중 하나이다. 프로그래밍 언어를 회화 언어와 동등하게 놓고 보면, 디버그는 화자(개발자)가 생각한 것(알고리즘)이 제대로 글(코드)로 표현됐는지, 또는 회화 언어로 쓰인 요구사항이 프로그래밍 언어로 제대로 번역되었는지를 검증하는, 아주 기초적인 과정이라 보면 된다. 그러니까 "그냥 뚝딱뚝딱 만들고 돌아가게 하면 되는거 아냐?"라고 하는 건 번역으로 치면 초벌 번역에나 해당되는 말이고, 이는 곧 프로그래머와 번역가, 양측에 모두 실례되는 발언이라 할 수 있다. 좋은 번역가 역시 초벌 번역에 2할을 할애하고, 나머지 8할을 번역 검증에 투자한다.
코딩 과정조차 상당히 힘들고 어려운 과정인데, 코딩을 끝나면 디버깅이라는 새로운 시작이 기다리고 있다. 그만큼 디버깅 과정은 초보자들은 물론 전공자들조차 가장 어려워하는 과정 중 하나이다.
IT관련 회사중에서는 디버깅에 특화된 회사도 존재한다. 예를 들면 일본의 디지털 하트라는 회사가 있다.[2] 이 회사는 한국 지사도 있다.
1.3. 버그의 유형
버그가 생기는 이유도 천차 만별인데 굳이 따지자면 아래와 같다.- 사람의 사소한 오타로 생기는 버그.
이 경우가 가장 흔해서(예: 콜론(:)과 세미콜론(;)) 일단 찾으면 수정이 쉽다. 코드 부분의 오타라면 문법 오류나 구문 오류로 인해 컴파일이 불가능한 경우가 많아 컴파일러나 IDE가 친절하게 프로그램이 빌드되어 실행되기 이전에 원천적으로 오류 부분을 지적해 주고 빌드를 막아버리므로 프로그래머가 곧바로 인지할 수 있기에 사실 프로그래머에게는 버그라고 부르기에도 애매한 실수 수준이다. 오히려 이러한 오타라면 천만다행인 수준.
하지만 오타임에도 언어의 문법 상으로는 문제가 없어[3] 컴파일러가 오타임을 인지하지 못하고 그냥 빌드해서 프로그램이 실행되는 경우도 있는데, 이 경우는 코드를 훑어보면서 오타를 찾아야 하므로 굉장히 귀찮게 된다. 컴파일러의 성능 발달로 문법 오류는 매우 잘 잡히게 되었다고는 하지만, 역으로 문법 오류가 아닌 단순한 상수값 오기입은 컴파일러가 잡아내지 못하기 때문이다. 이렇게 컴파일러가 잡아내지 못하는 오타가 오히려 더 심각한 문제가 된다.
- 특수한 케이스를 미처 생각 못한 논리적인 버그
소프트웨어 설계 과정에서 요구사항 또는 예외를 감안하지 않은 경우가 주로 이런 경우이다. 이렇게 되면 요구사항과 실제 구현을 대조해야 하는데, 이 과정에서 언어 불일치가 가장 큰 문제로 작용한다. 법적 또는 윤리적 결함으로 발생한 것도 이 경우에 해당하며, 설계 자체의 결함 또는 요구사항 변경 등으로 버그가 발생하기도 한다. 당산역 마을버스 칼부림 사건에서 드러난 '45자 버그'가 이런 예.
- 프로그램이 의존하는 OS, 또는 다른 라이브러리의 버그로 인해 발생하는 버그
소스가 공개되지 않은 것이라면 해당 기능을 우회해야만 하며, 소스가 공개되어 있다 해도 수정의 난이도 및 라이선스 문제 등을 고려해야 한다. 특히 4GB 문제는 대용량의 데이터를 처리할 때 큰 골칫거리로 작용한다. 염소 시뮬레이터도 이것만은 해결하지 못했으며[4], 이건 아예 스팀 과제로 등록되어 있다.
- 시스템 상의 한계로 인한 오류
하드웨어는 정상적이나, 하드웨어가 소프트웨어를 버티지 못하는 경우가 주로 이 경우이다. 이런 경우는 하드웨어에 최적화되지 않은 코드 작성으로 자주 발생하며, 경우에 따라서는 하드웨어 스펙을 숙지해야 할 수 있다. 음파 크래시 버그가 근본적으로는 이 오류였다. 이 경우는 원인을 찾는 것은 물론, 문제를 해결하는 데에도 상당한 시간이 소요된다.
- 하드웨어 자체의 노후화, 고장으로 인한 오류
대표적으로 컴퓨터에 벌레 또는 먼지가 들어갔을 때 발생하며, 굳이 이 경우가 아니더라도 하드웨어의 노후화나 고장으로 인해 생기기도 한다. 이 정도면 이미 개발자가 할 수 있는 게 없어지고, 사용자가 직접 하드웨어를 점검 또는 교체해야 할 수 있다. 버블 시스템이나 별의 커비 슈퍼 디럭스의 버그가 주로 이런 경우이며, 최초의 버그라 알려져 있는 Mark.II의 버그도 이것이다.[5]
- 하드웨어 설계 문제로 인한 오류
간혹 하드웨어 설계 자체의 이상으로 버그가 발생하기도 한다. 이 경우는 설계 회사에 직접 항의하는 것 밖에는 방법이 없으며, 물리적인 요인까지 다 고려해야 하는지라 문제 해결에 최소 몇 년은 기다려야 할 수도 있다. 심하면 그 오류의 근본적인 원인을 제공한 기술을 포기해야 하는데, 그 비용은 당연히 천문학적으로 들게 된다. 수학적, 과학적으로 불가능한 경우에는 그냥 그 오류를 안고 가는 수 밖에 없다. 같은 하드웨어를 사용하는 모든 시스템에도 악영향이 되는지라 그 파장이 다른 오류보다 심각하며, 때문에 발견 즉시 모든 게 끝났다 봐도 된다. CPU 게이트가 이런 예.사실 도란스를 내리면 된다고 카더라
1.4. 버그의 악영향
버그의 악영향에 따라 단순한 불편부터 형사 처벌, 사망 사고에 이르기까지 매우 다양하다. 개발자들이 디버그에 목매는 이유이기도 하며, 디버그가 전체 프로그램 개발의 80% 이상을 차지하는 이유이기도 하다. 버그의 유형이 반드시 악영향과 비례하는 것은 아닌지라, 단순한 오타에도 신경 써야 하는 이유이기도 하다. 특히 금융이나 의료, 산업, 군사 등의 분야에 사용되는 소프트웨어의 경우 버그의 발생 때문에 큰 피해를 볼 수 있고, 이게 소프트웨어 제작사나 개발자에게 큰 책임이 들어오는 경우가 있기 때문에 이런 소프트웨어의 경우 잘못 개발하면 회사가 망하거나 개인 커리어가 끝장나는 경우가 생길 수도 있다. 그래서 이런 분야들로 갈수록 QA에 큰 돈을 쏟아야 하거나 훨씬 더 보수적으로 이루는 모습을 볼 수 있다.- 단순 불편
응용 프로그램 이용자들이 자주 겪는 불편으로, 데이터가 날아가는 등의 손실은 없다. 다만 사용자에 따라서는 프로그램을 원하는대로 실행할 수 없는 등 큰 불편을 느낄 수 있다. 게임의 밸런스 등이 그런 예로, 이 쪽의 사례가 대부분을 차지한다. 게임의 경우 일부는 창발적 플레이로 인정받아 정식 시스템으로 들어가기도 한다.
- 재화 손실 등
데이터나 재화 등의 손실로 이어질 수 있는 오류로, 프로그램 이용자들이 복구할 수 없는 손실을 입을 수 있는 경우를 모두 포함한다. 여기서부터는 보안상 문제를 깔고 들어가는 경우가 많아, 전문 업체의 컨설팅을 받기도 한다. 재화 손실이 심한 경우에는 소송이 들어가기도 한다. 블레이드앤소울 돈 복사 버그가 대표적인 예.
- 민사 소송, 형사 처벌 등
어떤 버그는 발생 그 자체로 민사 소송이나 형사 처벌의 대상이 되기도 한다. 이 유형의 버그가 발생했다는 것 자체로 프로그램의 신뢰는 이미 끝장난 거나 마찬가지이기에, 개인정보를 다루는 시스템 등에서는 꽤 민감하게 다루고 있다. 회사에 악영향이 되는 건 당연한지라, 관련 시스템 개발자는 법률 및 규제 사항을 반드시 숙지해야 한다. 전문 컨설팅을 받아야 하는 건 말할 것도 없다. 2005형 캠리의 의도치 않는 가속으로 인한 사고가 대표적인 예이며, 회사 하나를 통째로 날려먹은 사례 역시 존재한다. 메이플스토리2의 인챈트 성공확률 오류 사건 등도 이런 오류에 해당한다.
- 인명 사고, 재난 등
임베디드 시스템의 경우에는 프로그램의 동작이 현실에 끼치는 영향이 매우 크기에, 버그 하나가 사람을 죽일 수도 있다. 의료용 로봇 같이 환자 한 명 죽이는 건 기본, 핵무기 통제 시스템 같이 지구를 통째로 멸망시킬 수 있는 버그도 있다. 때문에 이런 시스템과 관련이 있는 자는 엄격한 윤리교육을 받기도 하며, 때문에 단순 코더가 넘보기 어려운 영역이 많다. 테슬라 모델X 사망사고 등이 대표적인 예이며, 록맨 에그제 시리즈 등에서도 경고한 사물인터넷 보안 문제 역시 이 영역에 들어간다. 우발적 핵전쟁을 유발할 수도 있는 핵무기 자동화가 이 악영향을 야기할 수 있는 가장 극단적인 예이며, 스타니슬라프 페트로프가 시스템의 버그를 확인해 핵전쟁을 막은 일화는 매우 유명하다. 1980년대 Therac-25 사고도 있다. 방사선 암 치료기기의 소프트웨어 버그로 인하여 환자가 치사량의 방사선에 노출되었고, 그 중 몇 명은 끝내 사망하였다.
1.5. 과정
디버깅 과정은 말은 굉장히 쉽다. 오류 혹은 비정상적인 작동을 하는 부분을 찾아 수정하면 된다. 문제는 디버깅은 프로그래머가 만드는 과정에서 미처 고려하지 못한 부분이나 실수를 찾는 것이기 때문에 이 오류가 난 부분을 찾기란 굉장히 어렵다. 프로그램 코드의 길이가 수십줄~수천줄 정도라면 근성으로 코드를 샅샅히 뒤져 찾을 수도 있겠지만 수만줄 이상이 넘어가면 답이 없다. 프로그래머가 예측하는 부분 안에서 나오길 바라는 수 밖에. 그렇다고 디버그를 안하면 앞서 언급한 악영향 중에 어떤 악영향이 나올지를 장담할 수 없다.이런 악명과 사례는 이미 오래전부터 알려져 있어서 지금에 이르러서는 이 디버깅을 도와주는 프로그램 적인 도구들이 많이 등장한 상태이다. 프로그램 내에 존재하는 모든 변수 값을 표시하거나, 프로그램 코드를 한줄 한줄 멈춰가며 구동시키는 것 등이 대표적으로 디버깅에 도움을 주는 것들이다. 하지만 이것들은 말 그대로 도움을 주는 것이지 직접 버그를 찾아주는 것은 절대 아니다. 가령 1+2를 해야 할 프로그램에서 프로그래머의 실수로 1-2를 적는다면 의도하지 않은 결과가 나오기 때문에 버그이지만 컴퓨터 입장에선 어쨌든 실행은 멀쩡히 되기 때문에 오류로 인식하지 않는다. 디버깅의 핵심은 바로 이런 부분을 찾아야 하는 것이다.
또한 이 디버깅이 얼마만큼의 시간이 걸리는 지는 아무도 모른다. 일단 버그가 정확히 몇 개다. 라고 단정지을 수 있는 것도 아니고 버그가 발생되는 코드가 프로그래머가 생각하는 부분에 있다는 보장이 전혀 없기 때문이다. 프로그래머가 생각한 부분에서 버그가 발생되는 코드가 발견 되었다면 디버깅 시간은 짧아질 것이고 전혀 엉뚱한 곳에서 나온다면 디버깅에 걸리는 시간은 한없이 길어진다. 그리고 대부분의 버그는 전혀 예상치 못한 곳에서 뜬금없이 튀어나온다.
그래서 이런 부분은 개발 기간과 QA에 쏟아붇는 자원을 늘리는 것이 정답이고, 그렇지 못하면 빌 게이츠의 굴욕처럼 제품 출시 후 어마어마한 버그를 내뱉으며 망신을 당한다는 것을 임원들이 깨달아 크런치처럼 개발자를 혹사시키는 경영학적인 리스크로 돌아온다는 것을 인지해야 한다. 하지만 사이버펑크 2077같은 예시를 볼때 실제로 기간을 늘리거나 투자금을 어마어마하게 받아도 소프트웨어 품질 향상에 기여를 못하는 것을 보면 사람들이 부정부패를 의심하기도 한다.
이런 과정들을 줄여주는것이 단위 테스트인데, xUnit 등을 이용해서 자동화를 시켜놓으면 디버깅 시간이 확 줄어든다. 물론 단위 테스트가 끝났다고 다 끝난 것은 아니고, 상위 테스트를 통해 단위 간의 상호작용 과정에서 발생할 수 있는 버그도 줄여야 한다. 게다가 코드 상으로는 버그가 아니더라도 윤리적으로는 치명적인 결함, 그리고 앞서 언급했듯 발생 자체가 불법인 결함이 얼마든지 발생할 수 있으므로, 이러한 결함 역시 줄여야 하는 게 디버그의 몫이다. 실제로 패션쥬디의 경우 가져왔던 광고 라이브러리가 멀웨어임이 드러나면서 모든 앱이 구글 직권으로 내려갔고, 이에 따라 개발사였던 ENI 스튜디오는 더 이상 구글 플레이에 앱을 등록할 수 없게 되면서 사업 영역 역시 대폭 축소해야만 했다.
1.6. 관련 문서
2. iOS/Mac 개발자 인터뷰 팟캐스트
Debug는 애플 관련 온라인 미디어인 iMore의 편집장 Rene Ritchie와 Guy English가 공동진행하는 인터뷰 형식의 팟캐스트로, 매 회마다 iOS/Mac 개발자를 초대하여 앱 개발에 관련된 에피소드나 개발자로 일해온 경력 등을 소재로 얘기한다. 특히, 참여한 게스트 중에서는 애플에서 일한 경력이 있는 사람들도 있어 애플이 기업문화나 개발자들의 면면을 살짝이나마 알아볼 수 있다. 애플의 미국계정 팟캐스트의 테크놀로지 챠트에서는 늘 10위권에 들 정도로 인기가 있다. 공동 호스트인 Guy English는 탭 탭 리벤지 개발에 참여한 것으로 유명하다.[1] 컴퓨터가 마냥 똑똑한 기계라고 생각하는 사람들에게 전공자들이 똑똑하긴 커녕 아주 멍청한 기계라고 말하는 이유도 프로그램 하나 구동되는데 필요한 코드의 양이 상상을 초월하기 때문이다. 그래서 비전공자가 가벼운 취미로 디버깅 등을 배워보려다 상상을 초월하는 엄청난 양의 코드를 보고는 정색하고 때려치우는 경우가 많다.(…) 애당초 전공자라도 정말 천부적인 재능을 가진 경우가 아니라면 미칠듯한 노가다에 시달린다고 하니 뭐... 그래도 수많은 사람들의 노력으로 컴퓨터가 점점 똑똑해지고 있긴 하다[2] B2B 이외의 영역에서는 이 회사의 자회사 아에타스(Aetas)가 게임웹진 4Gamer를 운영하는것으로 유명하다.[3] 이를테면 =와 ==은 C언어에서 전혀 다른 문법이지만 하나를 잘못 적는다고 논리적으로 문제가 발생하지 않는 경우도 많다. 때문에 이런 문제를 원천적으로 회피하고자 변수와 상수의 순서를 바꾸는 요다 조건문이라는 코딩 방식도 있을 정도. 보통 if문에서 bool 타입 변수를 체크할 때는 if(변수 == 상수)같은 방식을 사용하는데, 요다 조건문은 이를 뒤집어서 if(상수 == 변수)로 기입한다. 변수 = 상수는 문법 오류가 아니므로 컴파일러가 잡지 못하지만, 상수 = 변수는 컴파일러가 잡아내는 오류이므로 이를 이용한 것. 다만 버그를 잡아낼 수 있지만 역으로 프로그래머 입장에서 가독성이 떨어지게 만든다는 결점이 존재한다. 조건문 내에서 변수 할당 자체가 원천적으로 불가능한 언어에서는 전혀 쓸 필요가 없는 코딩 스타일이고, C언어 등의 고전 언어 계통이더라도 가독성 이슈 때문에 사용이 기피되곤 한다.[4] 염소 시뮬레이터 자체가 32비트 기반으로 작동하기에, 64비트로 새로 빌드하지 않는 이상 해결은 불가능하다.[5] 그레이스 호퍼 항목에서 그 유명한 나방을 확인할 수 있다.