SimpleIsBest.NET

유경상의 닷넷 블로그

디버깅 : 호출 스택을 보여다오...

by 블로그쥔장 | 작성일자: 2006-01-17 오후 6:31:00
이 글은 오래된 전에 작성된 글입니다. 따라서 최신 버전의 기술에 알맞지 않거나 오류를 유발할 수 있습니다. 저자는 이 글에 대한 질문을 받지 않을 것입니다. 하지만 이 글이 리뉴얼 되면 이 글에 대한 질문을 하거나 토론을 할 수도 있습니다.
닷넷 프레임워크 2.0을 설치한 이후로, 닷넷 프로그램에서 예외(exception)이 발생하면, 오류 보고 다이얼로그가 나타나기 시작했습니다. 예전에는 곧바로 닷넷의 예외 핸들러에 의해 발생한 예외 종류, 메시지, 호출 스택(call stack)이 표시되었는데 말이지요. 지금까지 대략 귀차니즘으로 그냥 그러거니 하고 말았다가 오늘 칼을 빼고 원인 파악을 했습니다. 오늘의 팁이 개발자들은 유용하리라 생각됩니다.

Disable Error Reporting for Displaying Call Stack

닷넷 프로그램을 개발하다 보면 하루에도 수십 번씩 예외(exception)이 발생하곤 한다. 예외 메시지는 문제를 해결하는데 가장 중요한 단초(오옷! 이렇게 어려운 단어를?)를 제공하기 때문에 아무리 강조해도 지나치지 않다. 게시판 등에서 단순히 "에라 나요", "예외 나요" 하는 등의 찌질한 질문을 보면, 도와주고 싶어도 짜증만 이빠이 밀려오는 이유는 어떤 오류, 즉 예외의 종류와 오류 메시지에 대한 정보 없이 문제를 해결하는 것은 정말 찍기 밖에 안되기 때문이다. 예외 메시지와 더불어 중요한 것은 예외가 발생한 위치를 알려주는 호출 스택(call stack)이다. 어디서 어떤 예외가 발생했는가를 알아야 보다 빠르게 문제를 해결할 수 있기 때문이다. 호출 스택이 뭔지 모른다면... 대략 난감일 뿐이다. 찌질하게 여기서 호출 스택이 뭔가를 설명하고 싶지 않다. 요즘 필자가 마법에 걸렸는지 영 글쓰는 것에 귀차니즘을 느껴서... 쯔읍...

Engaging...

닷넷 프로그램이 예외를 발생하면, 예외 처리 핸들러가 수행되게 된다. 예외 처리 핸들러는 try-catch 에 의해 catch 문이 수행되는 것을 말하는데, 사용자 코드가 catch 하지 않은 예외, 즉 처리되지 않은 예외가 발생하면 닷넷 프레임워크의 기본 예외 처리 핸들러가 수행된다. 뭐 예외 처리라고 해 봤자 예외 종류(Exception 클래스 종류), 예외 메시지, 호출 스택을 표시해 주는 것이지만 디버깅의 시작점이 되므로 중요하다고 할 수 있겠다.

Console 어플리케이션의 경우 콘솔에 예외 정보를 표시하고, Windows 어플리케이션의 경우, 화면1과 같은 예외 다이얼로그가 나타난다. 예외 다이얼로그는 Console 어플리케이션의 경우보다 조금 더 친절해서, 단순히 예외 정보 뿐만 아니라 현재 로드 된 어셈블리가 무엇인가를 나타내주기도 한다.


화면1. Windows 응용 프로그램의 예외 표시 다이얼로그

그런데 언제부터인가 Console 어플리케이션 이건 Windows 어플리케이션 이건 예외가 발생하면 쌩뚱 맞게 화면2와 같은 오류 보고 대화 상자가 나타나는 것이었다. 이 대화 상자는 응용 프로그램의 오류가 발생하면 응용 프로그램의 다양한 정보(레지스터 값들, 메모리 정보, 로드된 DLL 들 등등)를 수집하는 Dr. Watson (DW20.EXE; Dr. Watson의 후예쯤으로 생각할 수 있는 Error Reporting 어플리케이션 이다. 편의상 Dr. Watson과 동일하게 취급하겠다)이 표시하는 다이얼로그이다.


화면2. DW20.EXE 에 의해 나타난 오류 보고 대화 상자

왓슨 선생(Dr. Watson)의 이 다이얼로그는 일반 사용자에게는 좀더 친근하고 부드러운 사용자 인터페이스임에 분명하지만, 발생한 오류(예외) 때문에 분노게이지가 상승하고 있는 개발자에게는 어떤 유용한 정보도 제공하지 않는다. 디버그 버튼을 누르면 디버거를 선택하여 디버깅을 할 수 있지만, 디버거가 설치되지 않은 사용자 PC나 운영 서버에서는 아주 중요한 예외 정보와 호출 스택 정보를 전혀 가르쳐 주지 않는다. 가장 짜증 나는 것은 '닫기' 버튼을 눌렀을 때 이다. 닫기 버튼을 누르면 Console 어플리케이션의 경우 콘솔 창에 예외 정보와 호출 스택이 표시되지만 디스크와 CPU가 한 참 조뺑이 친 후에라야 메시지가 표시되며, Windows 어플리케이션의 경우 그냥 생까고 화면1과 같은 예외 정보를 표시해 주지 않는다. 디스크와 CPU가 조뺑이 치는 이유는 오류 보고를 위해 예외가 발생한 프로세스의 현재 정보를 수집하고 미니 메모리 덤프파일로 기록하기 때문이다(상당히 느리다... -_-). 쓰바...

뭐 비주얼 스튜디오에서 F5키를 통해 디버거를 사용하면 되지 않냐고 반박할 독자가 있을지 모르겠지만, 필자 같이 간단한 코드는 비주얼 스튜디오 없이 커맨드 라인에서 작업하거나, 테스트에는 디버거를 사용하지 않고 "Start Without Debugging" 을 사용하는 사람에겐, 예외의 원인을 찾는데 상당히 번거롭게 된다(디버거를 구동해야 하니깐...). 예전에 안 그랬는데 갑자기 왜 화면2와 같이 왓슨 선생이 구동될까 고민하던 필자는 비주얼 스튜디오 2005를 설치한 이후부터라는 것을 깨달았다. 그리고 비주얼 스튜디오를 설치하면서 오류 보고를 하겠냐는 질문에 Yes를 선택했던 것 같기도 했다. 이제 남은 것은 오류 보고를 하지 않도록 설정만 하면 예전의 상태로 돌아갈 수 있을 것이다.

설정은 내 컴퓨터의 등록정보 혹은 제어판의 "시스템" 애플릿에서 고급 탭을 선택하면 하단에 보이는 오류 보고 버튼을 선택하면 된다. 화면3과 같은 다이얼로그(운영체제 혹은 어떤 서비스팩이 설치되었는가에 따라서 다이얼로그의 모양새가 다를 수도 있다. 알아서 찾아내길...)가 나타나면 눈 딱 감고 오류보고 사용 안 함을 선택하고 덤으로 "심각한 오류가 발생하면 알림" 역시 선택하지 않아버리면 된다. 이렇게 하면 더 이상  왓슨 씨를 만날 일이 없을 것이다. 웬지 기분이 구리다고 생각되면 오류 보고 사용을 하되 "프로그램 선택"을 클릭하여 모든 프로그램이 아닌 Microsoft 프로그램과 Windows 구성요소에 대해서만 오류 보고를 하는 것도 좋은 방법이다(필자가 사용하는 선택이다). 오류 보고를 사용하게 되면 오류(예외)가 발생할 때마다 상당한 크기의 오류 보고 파일이 남게 됨 역시 알아두면 좋다.


화면3. 오류 보고 설정

Disengaging

별로 팁 같지도 않은 팁을 무쟈게 길게 쓴 느낌이 똥꼬 깊숙한 곳에서 요동을 치지만... 필자에겐 1달여 동안 상당히 눈살을 찌푸리게 하는 왓슨 씨를 제거한 기쁨에 몇자 남겨 보았다. 혹시나 이런 상황에 있는 독자라면 유용한 팁이 될 것이다.

마지막으로 찌질한 잔소리 하나 더 하자면, 오류 보고 설정을 하는 것은 개발자가 보다 편리하게 개발 및 디버깅을 하기 위한 설정일 뿐이다. 일반 사용자의 PC에 이러한 설정은 당연히 그다지 좋은 설정이 아닌 듯 하다. 사용자에게 예외 메시지나 호출 스택 정보는 쓸데 없는 찌라시 정보일 뿐이기 때문이다. 필자가 권장하는 방법은 응용 프로그램 수준의 예외 핸들러를 만들고 이 핸들러는 사용자에게 최대한 친화적인 메시지(미안하다는 내용으로 사용자가 화나지 않도록 살살 꽁고를 간질러 줘야 한다)를 표시하고, 내부적으로 HTTP, Socket 등등의 방법을 사용하여 예외 메시지, 호출 스택을 서버에 기록하는 것이다. 이런 예외 처리는 귀찮지만 만들어 놓으면 나중에 시스템 유지 보수를 편하게 하는 방법이니, 처음에 조금 고생하고 나중에 오랬동안 배 뚜드리며 시스템을 관리할 수 있다.



Comments (read-only)
#re: 디버깅 : 호출 스택을 보여다오... / 찌유니아빠 / 2006-01-18 오전 11:19:00
호~~~!!!!
안그래도 계속 저거 나와서 짱나던 판인데 ..^^;;
#오~~~ / 조조 / 2006-05-17 오후 3:57:00
우왕. 이거 무지하게 돔 되었습니다 고생한거 넘 쉽게 얻는데 이거 ㅎㅎㅎ
#호! / 희정 / 2007-04-17 오후 4:19:00
이런게 다 있었군요! 오~ 감사합니다!