SimpleIsBest.NET

유경상의 닷넷 블로그

디버깅 메시지 관찰자 :: Debug View

by 블로그쥔장 | 작성일자: 2005-08-11 오후 11:48:00
이 글은 오래된 전에 작성된 글입니다. 따라서 최신 버전의 기술에 알맞지 않거나 오류를 유발할 수 있습니다. 저자는 이 글에 대한 질문을 받지 않을 것입니다. 하지만 이 글이 리뉴얼 되면 이 글에 대한 질문을 하거나 토론을 할 수도 있습니다.
버그 없는 프로그램은 없다. 버그를 잡는 행위를 디버깅(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 이다.



Comments (read-only)
#re: 디버깅 메시지 관찰자 :: Debug View / 희정 / 2007-04-24 오전 10:01:00
저는.. 루비-레일즈로 개발할때 단지 출력창에 메세지-값을 출력해보는 것만으로 모두 해결했습니다.
C#쪽으로 오니 그런게 없나-했었어요.
이렇게 좋으게 있었군요!
감사합니다!
#re: 디버깅 메시지 관찰자 :: Debug View / 조승태 / 2008-03-17 오후 3:55:00
늘,,,, 이런거 없나 했었는데,, ^^;;
역시 있었군요.
좋은 정보 감사합니다.
#re: 디버깅 메시지 관찰자 :: Debug View / 어떤 개발자 / 2008-04-18 오후 4:36:00
개인적인 의견(취향?)으로는 "F5를 두들겨 대는 것이 좋다"라는 사람입니다. :-)
Ctrl-F5로 실행하는 것의 이점이 로딩속도의 차이 한가지라면 그 속도차이라는 것이
생산성에 지장을 줄만큼 크지 않다는 생각입니다.
그리고 제 경험상 새로운 코딩을 하여 실행을 하게되면 거의 90%는 버그가 있더군요.
그런데 이 버그를 잡으려면 디버그모드로 실행하게 되는데,
첨에 Ctrl-F5로 실행하여 어떤 버그가 있다는 것을 알고 다시 디버그 모드로 실행하는 것
보다는 아예 첨부터 디버그 모드로 실행하게 되면 문제 있는 곳에서 expection이 발생하는
경우가 많으므로 디버거로 가서 Call Trace등으로 역추적 할 수도 있고..
결과적으로 시간이 더 적게 걸리는 경우가 많더라는 것이 제 경험으로 얻은 결론입니다.

#re: 디버깅 메시지 관찰자 :: Debug View / nineye / 2008-07-07 오후 1:27:00
글 잘 읽었습니다... 간편하게 사용할 수 있는 유용한 디버깅 툴이네요...
저 같은 경우는 linux나 unix쪽을 좋아하기 때문에 메세지들을 로그로 남기고 vi로 불러서 쓴다는... vi의 기능은 정말 막강하거든요...
windows쪽도 gvim이라는 툴이 있으니 한번 써보세요... 괜찮을 거에요...
근데 죄송하지만 이정도 툴은 공짜가 맞을 것 같네요.. 걍 지정된 공유메모리로부터 데이터 읽어서 뿌려주고 뿌려준 데이터에 대한
약간의 컨트롤만 제공해 준다는... 써보진 않아서 그 이상의 기능이 있는지는 잘 모르겠네요...
저는 일반적으로 공개라는 개념에서는 거리가 먼 M$사 보다는 linux의 gnu license 기반의 open source 프로젝트에 관련된 사람들이
정말 대단한 사람들이라고 생각합니다. 그들이 만들어 내는 툴은 공개를 원칙으로 하기 때문에 빌드된 바이너리든, 소스든 모두 공개가
됩니다. 따라서 전체적인 설계에서부터 사용한 알고리즘이나 세세한 코딩까지 제대로 된 작품이 나오는 것입니다.
저도 어차피 이쪽에서 밥먹고 사는 사람이기 때문에 그런 공짜 툴들이 돌아다니는 것이 좀 위험하게 보이기는 하지만,
적어도 제가 전문으로 하는 분야에서는 그 사람들보다 더 뛰어난 작품을 만드려고 합니다. 그리고 이런 생각으로 매진하다 보면
그 사람들이 만든 것에서 결점이나 단점들을 찾아내고는 하죠.. 그 사람들도 완벽한 사람들이 아니니.. 어쨌든 어떻게 보면 돈안되는
삽질이긴 한데, 이러한 노력이 고급 프로그래머를 만드는 거라고 생각합니다..
#re: 디버깅 메시지 관찰자 :: Debug View / 블로그쥔장 / 2008-07-07 오후 4:08:00
네... vi 의 기능은 막강하지요. 하지만 사람마다 기호가 다르듯이 선호하는 도구도 다르기 마련입니다.
(사실은 길들여지기 나름이라고 생각합니다만...)
저도 대학원 전공이 운영체제이고 linux 커널을 3년가까이 다루었었습니다. 그때는 vi 만 썼었고
Windows (그땐 3.1이였지요) 버전의 vi를 구해다 쓰곤 했었습니다. ㅎㅎ

nineye 님의 생각 중에 "이정도 툴은 공짜가 맞을 것 같네요" 라는 생각은 전혀 동의하지 않습니다.
뭐 이정도가지고 돈을 받냐라는 생각은 저작자에 대한 노력을 간과하는 것 아닐까요?
저작자가 자신의 노력에 대해 비용을 받아야 한다고 생각한다면 그 사람(들)이 적합한 비용을 책정하는 것은 합당하다고 봅니다.
그것을 그 가격에 구매할 것이냐 말 것이냐는 구매자의 선택아닐가요?
다만 자신의 노력을 아무런 댓가 없이 공개하는 이들을 높게 사야 하는 것이지
그(들)의 노력에 대한 결과물에 대해 비용을 요구하는 것을 비난할 것이 아니라고 봅니다.

이런 관점에서 M$라는 표현 역시 그다지 좋지 않다고 봅니다.
그들은 그들이 생각하는 자기 제품에 대한 가치를 고객에게 요구하는 것이고
고객이 그 가치를 인정하지 않는다면 구매 역시 하지 않겠지요.

마지막으로 공개된 소프트웨어라고 해서 제대로 된 작품이 나온다는 것은 논리의 비약이라고 봅니다.
소스가 공개되지 않은 소프트웨어는 발로 코딩한 것 처럼 개판일까요?
고급 프로그래머는 오랜 경험과 다양한 기술적인 바탕하에서 만들어지는 것이라 봅니다.
어떤 소프트웨어를 만들었느냐 그리고 그것이 open 진영이냐 아니냐에 따라서 프로그래머의 질이 나누어진다고
보지는 않습니다.
#re: 디버깅 메시지 관찰자 :: Debug View / greenfrog / 2009-04-21 오후 2:21:00
좋은 글 잘 보고 가요 ~~ ^^
#re: 디버깅 메시지 관찰자 :: Debug View / plasma / 2010-03-30 오전 11:13:00
다른 사람이 만든 프로그램에 대해 "이 정도 툴은 공짜가 맞을 것 같네요" 라고 자신있게 말할 수 있는 분은 개발을 얼마나 잘 하시고, 얼마나 많은 공짜툴은 이 세상에 뿌리셨는지 궁금하군요. (이건 단순히 진짜로 궁금합니다.)
아...근데...이 툴은 예전부터 (저는 약 10년쯤 전부터 써왔습니다만) 공짜입니다...
"이 정도 툴"이 공짜인지 아닌지도 모르셨나보군요? :b

그리고...Trace 메세지에 대해 "지정된 공유메모리" "쯤"으로 생각하시는 모양인데, 그런 말씀 하시려면 윈도우에 대해 더 공부하시고 말씀하세요.
자신이 잘 하는 분야(nineye님의 경우에는 리눅스 쪽이 전문이신듯한데)가 아닌 쪽에 대해 그 내용을 명확히 아는 상태가 아니면, 넘겨짚어 이야기하는 것은 매우 위험한 발상입니다.

그리고, 오픈소스 진영의 개발자들 대부분은 훌륭한 개발자라고 생각합니다.
그리고, 소스 오픈 안하는 MS진영 개발자들도 대부분은 훌륭한 개발자라고 생각합니다.
그냥...개발자들은...대부분...다...훌륭합니다...

마지막으로, vi는 훌륭한 툴입니다.