본문 바로가기

IT 살이/04. 기술 - 프로그래밍

스마트클라이언트 디버깅 툴 소개

스마트클라이언트 애플리케이션은 디버깅하기가 상당히 까다로운 면이 있다. 특히 IE 브라우저 임베딩 타입의 스마트클라이언트 애플리케이션의 경우는 디버깅에 상당한 어려움을 느끼는 경우가 많다. 이제 기본적인 디버깅 툴들을 소개한다. 이런 툴들을 언제 사용해야 할지를 알고 적절한 시기에 적절한 툴을 사용할 수 있도록 해야 할 것이다.

■ 어셈블리 다운로드 캐시 뷰어

외부의 배포 서버에서 다운된 어셈블리는 어셈블리 다운로드 캐시(assembly download cache)에 저장이 된다. 그 저장 결과를 그림처럼 윈도우 탐색기를 이용해서 볼 수 있다. 다음 명령을 실행하면 뷰어가 구동된다.

시작->실행->”assembly”

어셈블리 다운 여부에 대한 결과만을 확인하고 싶다면 윈도우 탐색기를 이용해서 어셈블리 다운로드 캐시(assembly download cache)를 확인해봐서도 알 수 있다.

1121090377

어셈블리 다운로드 캐시 확인

그런데 어셈블리 다운로드와 관련해서 어셈블리 다운로드 캐시 뷰어만으로는 해결할 수 없는 문제들이 많이 있다.

■ HTTP요청/응답 캡쳐 툴들

어셈블리 다운로드와 관련해서 구체적인 에러 내용을 알고 싶은 경우 사용할 수 있는 툴들이 있다. 다음 툴들은 클라이언트 PC에서 나가고 들어오는 모든 HTTP 트래픽을 캡쳐해서 분석해준다. 이런 툴들을 사용하면 스마트클라이언트 애플리케이션 특히 NTD기반의 애플리케이션을 제작할 때 아주 편리하다.

Fiddler(http://www.fiddlertool.com/fiddler/)- 무료판
HTTP Analyzer(http://www.ieinspector.com/) – 시험판

이런 툴들을 사용하면 원하는 어셈블리가 다운되었는지를 확인할 수 있음은 물론 다운이 안되는 구체적인 에러 원인이 무엇인지를 알려줄 수 있다. 특정 HTTP 요청을 더블클릭하면 상세 내용을 출력해주는데, 특히 HTTP 요청 및 응답의 헤더 부분의 내용은 아주 유용하게 사용되는 경우가 많다. 정상적으로 끝나지 않은 HTTP 요청을 클릭하면 그 원인 또는 추적의 단서를 제공해준다. 무료 또는 시험판은 앞의 URL에서 다운로드할 수 있다.

다음은 Fiddler.exe의 실행모습니다. Fiddler는 구동을 시키면 바로 HTTP 트래픽 캡션를 시작한다.
1213950792

Fiddler 실행모습

다음은 HTTP Analyzer 실행모습이다. 이것은 구동 후 캡쳐 시작 버튼 또는 중지 버튼을 클릭해서 트래픽 캡쳐를 제어할 수 있다.
1089419117

HTTP Analyzer 실행 모습

달봉이는 이 도구들의 도움을 톡톡히 본 경험이 있다. NTD 배포의 애플리케이션을 제작할 때 이 툴들은 클라이언트 PC로의 다운은 정상적으로 이뤄졌다는 내용을 출력해주는데도, 어셈블리 다운로드 캐시에서는 다운된 어셈블리가 보이지 않았다. 결국에 가서는 클라이언트로의 다운로드는 이뤄졌으나 캐시에는 저장되지 않은 것이 정상적인 거동이었고, 이것은 IIS 서버의 만료 정책을 “즉시 만료(Expire immediately)”로 선택해놔서 이런 결과가 나왔다는 것을 발견할 수 있었다. 만약 이런 툴들이 없었다면 IIS서버로부터 다운조차도 되지 않았다고 추측하고 그쪽으로만 디버깅을 고수하였을 것이다.
하여튼 이런 툴들을 사용해서 클라이언트 PC로의 다운은 되었으나 캐싱이 되지 않는다는 것을 인식하고는 바로 바인딩시에 로그를 남겼을지도 모른다는 추측을 했다. 그래서 다음에 소개하는 어셈블리 바인딩 로그 뷰어를 사용해서 그 원인이 IIS의 만료 정책 때문이라는 것을 알게 되었던 것이다.

■ 어셈블리 바인딩 로그 뷰어(Fuslogvw.exe)- 바인딩 로그 뷰어

이 툴을 사용하면 어셈블리가 다운된 후 바인딩하는 단계 즉 참조되는 어셈블리를 찾아서 어셈블리 파일을 확보하고 바인딩하는 과정에서 단계별로 남겨지는 모든 로그를 볼 수 있다. 바인딩 과정에서 발생하는 에러 또한 남겨진 로그를 통해서 그 원인을 파악할 수 있다. 어셈블리 바인딩은 모든 .NET 애플리케이션의 실행에서 일어나는 과정으로 따라서 이 툴은 스마트클라이언트 애플리케이션의 디버깅에 국한되는 툴은 아니다. 바인딩 과정에 대해서는 다른 포스트를 참조하기 바란다.

.NET과 함께 제공되는 프롬프트 명령창에서 다음 명령어를 실행시키면 바인딩로그뷰어가구동된다.
1206731669

바인딩 로그 뷰어 실행 명령

1245459083

바인딩 로그 뷰어 구동 모습

이 창에는 바인딩이 실패한 모든 건들이 출력된다. 바인딩 실패에 대해 자세한 내용을 보고 싶다면 원하는 레코드를 더블클릭하거나 선택하고 오른쪽의 View Log 버튼을 클릭하면 상세 내용을 출력하는 창이 뜬다.

“항목 삭제” 버튼은 특정 레코드를 삭제할 때 사용하고, “모두 삭제” 버튼은 기존의 모든 로그를 삭제한다. 삭제 후 .NET 애플리케이션을 실행시키고 나서 “새로 고침” 버튼을 클릭하면 현재 로깅된 내용을 새로 불러와서 출력하는 버튼이다. “설정” 버튼을 클릭하면 로깅과 관련해서 설정할 수 있는 옵션들을 보여주는 창이 뜬다.  
1099874183

로그 설정 창

바인딩시의 모든 로그를 남기고 싶다면 “모든 바인딩을 디스크에”라는 옵션을 선택하면 된다. 또한 바인딩시 실패한 경우만 로그를 남기고 싶다면 “바인딩 실패를 디스크에” 옵션을 선택하면 된다. 또한 바인딩 로그 뷰어가 사용하는 기본적인 로깅 경로대신에 사용자가 정의한 경로에 로그 파일을 남기고 싶은 경우 “사용자 지정 로그 경로 사용”체크 박스를 선택하고 경로를 지정하고 그리고 로그 뷰어에서 로그 위치를 선택하는 부분에서 “기본값” 대신에 “사용자 지정”을 선택하면 된다. 다음은 바인딩 로그의 상세 내용의 예이다.

*** 어셈블리 바인더 로그 엔트리  (2006-05-31 @ 오후 5:43:01) ***
작업을 수행하지 못했습니다.
바인딩 결과: hr = 0x80070002. 지정된 파일을 찾을 수 없습니다.
다음 위치에서 어셈블리 관리자 로드:  C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\mscorwks.dll
다음 실행 파일에서 실행:  C:\Documents and Settings\dalbong70\Local Settings\Apps\2.0\YW9HQRK5.98C\MPV5Z7KK.ZQY\lemc..tion_e57baca1538944b1_07d6.0005_ef2b483355832712\LemContainer.exe
--- 자세한 오류 로그가 아래에 표시됩니다.
=== Pre-bind state information ===
LOG: User = VM-COMPUTER\dalbong70
LOG: Where-ref bind. Location = http://***/SmartControls/Lem.Win.Cons.Construction.LabEquMgmt.dll
LOG: Appbase = file:///C:/Documents and Settings/dalbong70/Local Settings/Apps/2.0/YW9HQRK5.98C/MPV5Z7KK.ZQY
/lemc..tion_e57baca1538944b1_07d6.0005_ef2b483355832712/
LOG: Initial PrivatePath = NULL
LOG: Dynamic Base = NULL
LOG: Cache Base = NULL
LOG: AppName = LemContainer.exe
Calling assembly : (Unknown).
===
LOG: This bind starts in LoadFrom load context.
WRN: Native image will not be probed in LoadFrom context. Native image will only be probed in default load context, like with Assembly.Load().
LOG: Using application configuration file: C:\Documents and Settings\dalbong70\Local Settings\Apps\2.0\YW9HQRK5.98C\MPV5Z7KK.ZQY\lemc..tion_e57baca1538944b1_07d6.0005_ef2b483355832712\LemContainer.exe.config
LOG: Using machine configuration file from C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\config\machine.config.
LOG: Attempting download of new URL http://***/SmartControls/Lem.Win.Cons.Construction.LabEquMgmt.dll.
오류: 다운로드된 파일이 catch되지 않았습니다. 웹 서버가 콘텐츠를 즉시 만료하도록 구성된 것 같습니다.
로그: 모든 URL을 검색하려고 했지만 실패했습니다.

이 로그들을 제대로 해석하기 위해서는 APPBASE, 버전 정책, 설정 파일 등 .NET의 많은 개념들에 대한 이해가 필요하다. 하여튼 이 바인딩 로그는 원하는 어셈블리가 http://***/SmartControls/Lem.Win.Cons.Construction.LabEquMgmt.dll이지만 결국에 가서는 기술된 내용과 오류로 인해서 바인딩이 성공하지 못했다는 내용을 알려주고 있다.

다음 블로그를 보면 로딩시 발생할 수 있는 예외에 대해서 자세히 설명되어 있다.
Debugging Assembly Loading Failures - Suzanne Cook's blog
http://blogs.msdn.com/suzcook/archive/2003/05/29/57120.aspx


다음 블로그도 좋은 내용을 가지고 있다.
Fusion Log Viewer
http://detritus.blogs.com/lycangeek/2005/03/in_previous_pos.html

■ IEHost 로그

바인딩 과정을 무사히 통과하고 로딩단계에서 에러가 발생할 수 있다. 만약 클라이언트측 호스트 프로그램으로 IE 브라우저를 사용하면, 내부적으로 IEHost.dll이라는 관리형 코드(managed code)가 스마트클라이언트 컨트롤을 호스팅하게 된다. 이 어셈블리가 스마트클라이언트 컨트롤을 로딩할 때 로그를 남기도록 설정할 수 있는데, 이 로그를 통해서 로딩시의 에러에 대한 단서를 찾을 수 있다. 로딩시의 에러에 대한 예를 들면, 어셈블리의 권한이 부족하여 로딩이 되지 않는다든가 또는 객체의 초기화 단계에서 에러가 발생할 수도 있다. 로딩시의 에러를 로깅하기 위해 다음과 같은 순의 설정이 필요하다.

1) 시작->실행->regedit.exe
2) HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework
3)오른쪽 클릭->새로만들기->DWORD값->"DebugIEHost" 입력
4) "DebugIEHost" 오른쪽클릭->수정-> 값데이터 : 1 입력
5)오른쪽 클릭->새로만들기-문자열 값->"IEHostLogFile"입력
6) "IEHostLogFile"오른쪽클릭->수정-> 값데이터 : "c:\IEDebug.log" 입력
1081700950

IEHost 로그 설정

이렇게 설정하고 브라우저를 실행시키고 나면 다음과 설정한 경로에 다음처럼 로그 파일이 남는다. 노트 패드같은 텍스트 편집기로 볼 수 있다.
1266656773

IEHost 로그 파일 설정

앞에서 소개한 툴들의 사용법을 익히는 것도 중요하지만 및 이 툴들을 어느 순간 사용해야 할지에 대한 판단을 내리는 것이 더 중요하다. 즉 서버측에서 발생하는 에러인지 어셈블리가 클라이언트로 다운이 되지 않아서 생기는 에러인지 아니면 클라이언트로 다운은 되었으나 어셈블리가 바인딩되는 도중에 발생한것인지, 아니면 로딩하다가 발생한 판단이 정확히 서야 한다는 것이다. 이런 에러에 대한 상황 판단은 많은 부분이 .NET의 어셈블리 버전 정책(versioning policy)과 관련한 이론을 정확히 이해하는 것에 달려있다.