출처: http://www.simpleisbest.net/archive/2005/08/11/202.aspx




버그 없는 프로그램은 없다. 버그를 잡는 행위를 디버깅(debugging)이라 하며 버그를 잡는 도구들이 디버거(debugger)라고 한다. 버그란 말의 유래는 (아는 사람은 다 알겠지만) 초창기 컴퓨터의 거대함에 유래한다. 초창기 컴퓨터는 진공관(필자도 한번 봐봤는데 어케 생겼는지 기억도 안난다)으로 구성되었는데, 지금 필자의 아들이 쓰는 컴퓨터보다 100배는 느린 간단한 계산 능력만을 가진 컴퓨터가 2층집 만한 크기였다고 한다. 컴퓨터가 크다 보니 유선으로 연결된 기판 사이에 벌레(bug)들이 기어 들어가 컴퓨터가 작동하지 않는 현상이 발생했다고 한다. 이 벌레들 때문에 컴퓨터가 작동하지 않는 현장을 없애기 위해 컴퓨터에 기어 들어간 벌레들을 잡는 일이 허다 했는데... 여기서 프로그램의 논리적인 오류를 없애는 디버그(debug)란 말이 유래되었다고 한다. 그래서 버그를 '잡는다'는 표현을 쓰지 않는가?

테스트와 디버깅은 다르다

어찌 되었건 이번엔 디버깅 도구에 대해 구라를 좀 풀어볼까 한다. 대부분의 개발자는 디버깅을 위한 도구로서 비주얼 스튜디오를 사용할 것이다. 코드를 작성하고 컴파일을 하고... 그리고 프로그램을 테스트 하기 위해 F5 키를 누르거나 삼각형을 자빠뜨린 모양의 버튼을 클릭할 것이다. 그러면 비주얼 스튜디오의 디버거(!)가 기동될 것이다.

코드를 작성하고 컴파일을 하면 곧 바로 디버깅을 하나? 버그가 있는지 없는지 알 수도 없는 상황에서? 코드 작성 및 컴파일 이후에는 당연히 테스트를 해야 할 것이다. 테스트 도중에 버그가 발견되면 버그에 따라 곧바로 버그를 수정할 수도 있고, 디버거를 구동 시켜 버그를 잡으면 될 것이다. 그럼에도 불구하고 대부분의 개발자가 컴파일 후엔 의례 F5키를 누르고 있다.

디버거는 말 그대로 버그를 잡을 때만 쓰자. 그리고 단순히 테스트를 할 때는 디버거를 불러오는 불필요한 작업을 하지 말자. 비주얼 스튜디오는 Run without Debugging 이란 명령이 버젓이 있다. 그리고 이 메뉴에 대한 핫키(hot-key)는 CTRL-F5 이다. 테스트할 때 F5 키를 쓰는 것보다 CTRL-F5를 사용하는 것이 좋은 것은 보다 빠르게 테스트를 할 수 있다는 것이다. F5키를 이용하여 디버거를 불러오면 디버거가 로드하는데 시간이 많이 소요되기 때문이며, 프로그램이 더 많은 어셈블리와 더 많은 DLL 들을 참조(로드)하는 경우에는 더욱 더 많은 시간이 소요된다. 반드시 CTRL-F5 키를 눌러야 하는 것은 아니며 개인 기호라고 치면 더욱 할말이 없지만 그래도 테스트와 디버깅은 다른 행위임은 인지할 필요가 있다.

디버거가 만능은 아니다

모든 상황에서 디버거를 사용할 수 있을까? 대부분은 그럴 것이다. 하지만 여러 쓰레드가 동시에 수행되는 상황이거나 중단점(break point)을 잡기 어려운 상황이거나, 디버거 자체를 사용하기 어려운 상황에서는 그 막강한 비주얼 스튜디오의 디버거는 무용지물이 되곤 한다. 이럴 때도 사용하는 디버깅 기법은 있다. 그것은 바로 변수나 기타 다른 코드의 수행 상황을 찍어보는 것(printf 나 Console.WriteLine 으로 찍어 보듯이...)이 다. 자바 스크립트를 디버깅할 때(비주얼 스튜디오가 자바스크립트 디버깅이 되는 사실을 모를 때) 많이 사용했던 alert() 메쏘드로 변수 값을 화면에 나타내던 것을 기억해 보라. 요즘처럼 디버거가 강력하지 않을 예전(공룡이 헤엄치고 익룡이 날아다니던...) 개발 환경에서 우리의 선배 개발자가 많이 사용했던 방법이며, 지금도 디바이스 드라이버와 같이 디버거 사용이 어려운 상황에서도 애용되고 있는 가장 단순/무식하지만 간단하고 편리한 방법이기도 하다.

그래서 제공되는 것이 닷넷의 System.Diagnostics.Debug 클래스와 System.Diagnostics.Trace 클래스이다. 이들 클래스의 Write, WriteLine 메쏘드는 Debug/Trace 클래스가 지정하는 리스너로 메시지를 출력한다(TraceListener 클래스에 의해 제어된다. MSDN 디비보면 다 다온다). 그리고 이 리스너의 디폴트 구현은 Windows 운영체제가 제공하는 표준 디버그 버퍼에 메시지(데이터, 일반적으로 문자열이게찌?)를 기록하도록 되어 있다.

표준 디버그 버퍼란 것에 대해 구라를 좀 풀어보자. 몰라도 되지만 알면 으스대며 아는 척하기에 좋은 아이템이다(정말 뽀대 난다). Windows는 디버깅을 위한 공유 메모리(Shared Memory)를 제공한다. 이것이 바로 Windows 3.x 시절부터 내려오는 DBWIN_BUFFER 란 이름의 공유 메모리 버퍼이다. 이 퍼버는 디버거 프로세스(devenv.exe 와 같은 비주얼 스튜디오 프로세스 등)와 디버그 메시지를 작성하는(즉, System.Diagnostics.Debug.WriteLine 메쏘드를 호출하는 프로세스) 프로세스 간에 메시지 전달을 위해 사용되는 IPC(Inter-Process Communication) 방법이다. 두 프로세스가 서로 다르기 때문에 메시지를 전달할 방법이 필요했던 것이다. 이 버퍼에 메시지를 기록하기 위해서는 WIN32 API인 OutputDebugString 를 호출해야 하며, 이 버퍼를 읽기 위해서는 다양한 WIN32 API들(이거 다 설명할려면 골치아프다. 정 궁금하면 메일 날려라...)을 이용하여 DBWIN_BUFFER 공유 메모리를 읽으면 된다. System.Diagnostics.Debug 클래스의 Write, WriteLine 메쏘드의 구현 역시 OutputDebugString API를 호출하도록 되어 있음은 두말하면 입 아프다.

Debug View Utility

일반적으로 디버거(비주얼 스튜디오 디버거나 기타 디버깅 도구들)이 DBWIN_BUFFER 공유 메모리를 읽지만, 앞서도 언급했듯이 디버거를 구동시킬 수 없는 상황이거나, 단순한 테스트를 위해서 굳이 덩치 큰 디버거를 띄울 필요는 없다. 이 버퍼를 전문적으로 읽는 멋진 유틸리티가 있으니 이것이 바로 Debug View 프로그램이다.

'#1' 이 포함된 라인이 붉은색으로 표시하도록 하이라이트를 설정한 Debug View 화면

Debug View는 매우 간단하며 가벼운 디버깅 도구이다. 사실 디버거라고 하기에는 좀 뭐한 도구이지만 디버그 메시지를 표시하는 데는 정말 뛰어난 능력을 갖고 있다. OutputDebugString API 나 System.Diagnostics 네임스페이스의 Debug 클래스, Trace 클래스의 Write 류의 메쏘드가 출력하는 내용들을 캡처 하며 위 그림과 같이 캡처 한 메시지들을 필터링도 해준다(필터링과 더불어 하이라이트도 된다 !). 게다가 캡처한 메시지를 저장할 수도 있으며 캡처한 내용에 코멘트(주석)를 달 수도 있다. 일반적인 어플리케이션 뿐만 아니라 디바이스 드라이버가 출력하는 디버그 메시지 역시 캡처 할 수 있으며 심지어 부팅 시에 디바이스 드라이버가 출력하는 디버그 메시지까지도 캡처 하는 능력을 갖고 있다. 다양한 능력에 마침표를 찍는 기능은 다른 컴퓨터에서 토해내는 디버그 메시지까지도 캡처할 수 있다. 정말 오로지 한가지 일에 최선을 다하는 모습을 보여주는 진정한 유.틸.리.티 이다.

이런 멋진 도구를 맛탱이 가게도 www.sysinternals.com 에서 공짜로 다운로드 받을 수 있다. 이런 도구를 만들어서 무료로 뿌리는 사람은 정말 능력이 뛰어난 사람이여서 먹고 살면서도 이런 일을 할 만큼 시간이 남는 사람이거나, 먹고 사는데 충분한 여유가 있어서 말 그대로 '재미'로 프로그램을 만들거나, 아니면 먹고 사는데 관심 없이 프로그램을 짜는 사람일 것이다. 존경스럽고 부러울 따름이다.

사용법은 대단히 간단하다. 닷넷을 기준으로 설명하면 다음과 같이 디버그 문자열을 출력하는 프로그램을 작성하고 프로그램을 수행시킨다.

System.Diagnostics.Debug.WriteLine("This is Debug Message #1""MyCategory");
System.Diagnostics.Debug.WriteLine("This is Debug Message #2""MyCategory");

여기서 F5 키를 눌러 비주얼 스튜디오의 디버거를 불러오면 디버그 문자열은 고스란히 비주얼 스튜디오의 Output 창으로 출력되어 버린다. 앞서 언급했듯이 Debug View는 디버거를 사용하지 않을 때 유용한 것이라고 했다. Ctrl-F5 키를 눌러 프로그램을 수행시키면 디버그 메시지 출력이 Debug View에 표시될 것이다.

마지막으로 Debug View는 시스템의 모든 디버그 메시지가 표시된 다. 예를 들어 MSN 메신저 6.2를 띄워 놓으면 MSN 메신저 6.2가 출력하는 디버그 메시지 역시 Debug View에 표시된다(황당하게도 6.2 버전은 메신저로 대화하는 내용을 다 디버그 메시지로 찍는다). 메신저 뿐만 아니라 다양한 프로그램의 디버그 메시지가 Debug View에 표시될 수 있으므로, 원하는 디버그 메시지만을 보기 위해서는 필터링/하이라이트 기능을 적절히 사용하면 된다.

요약

유틸리티 소개하는 글에 거창하게 요약이 뭔 말인가 싶겠지만... 필자가 이 유틸리티를 소개하면서 말하고 싶은 것은 비주얼 스튜디오의 디버거가 능사는 아니다는 점이다. 무조건 F5를 두들겨 대는 것 보다는 정작 디버깅이 필요할 때만 디버거를 사용하는 것이 좋다는 것을 말하고 싶으며, 디버거를 사용하기 어려운 상황에서는 디버그 메시지를 출력하는 방식의 디버깅 기법이 유용하며, 디버그 메시지를 보는 좋은 유틸리티가 Debug View 이다.

+ Recent posts