Microsoft MVP성태의 닷넷 이야기
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
 
부모글 보이기/감추기
(연관된 글이 1개 있습니다.)
3.2 PDB 파일에 따른 Debug 정보 - .NET 2.0 Web Application Project + Library 유형의 프로젝트

C# 라이브러리 유형의 "BaseLibrary" 프로젝트는 이전 토픽에서 설명했던 프로젝트를 그대로 사용합니다. .NET 2.0 Web Application Model Project 유형은 VS.NET 2005에 기본 웹 사이트 프로젝트 모델이 아닌 새로 나온 유형의 프로젝트입니다.
이에 대해서는 다음의 토픽에서 설명해 놓았으므로 참조하시기 바랍니다.

https://www.sysnet.pe.kr/2/0/288

Web Application 프로젝트의 이름은 "WebApplication1"입니다. Default.aspx/Default.aspx.cs 파일을 포함하고 있으며 내용은 다음과 같습니다.

        private void Form1_Load(object sender, EventArgs e)
        {
            BaseLibrary.ThrowClass throwClass = new BaseLibrary.ThrowClass();
            throwClass.TestMethod();
        }

이번에도 역시 환경을 어떻게 구성하는지에 따라서 우리가 얼마나 유용한 오류 정보를 얻을 수 있는지 알아볼 텐데요. 실제 서비스를 하는 경우를 가정하고 예를 들어보겠습니다. 즉, 사용자가 웹 프로젝트를 돌아다니다가 보는 오류가 난 화면이 아닌 이벤트 뷰어에 남겨진 내용을 기준으로 살펴보겠습니다.

첫 번째로 BaseLibrary.pdb / WebApplication1.pdb 파일이 bin 폴더에 함께 있는 경우에 예외가 발생하면 다음과 같은 내용의 이벤트 로그가 남겨집니다. 그중에서 Stack Trace 부분만을 살펴보겠습니다.

Stack trace:    at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share)
   at System.IO.File.Open(String path, FileMode mode)
   at BaseLibrary.ThrowClass.TestMethod() in D:\temp2\PdbSample\BaseLibrary\ThrowClass.cs:line 14
   at WebApplication1._Default.Page_Load(Object sender, EventArgs e) in D:\temp2\PdbSample\AspNet\WebApplicationModel\WebApplication1\Default.aspx.cs:line 19
   at System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e)
   at System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e)
   at System.Web.UI.Control.OnLoad(EventArgs e)
   at System.Web.UI.Control.LoadRecursive()
   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

WinForm Application의 예를 보신 분들이라면 결과를 예측하실 수 있으셨을 텐데요. 그때와 마찬가지로, 해당 오류가 발생한 모듈과 관련해서 PDB 파일이 존재하면 구체적인 소스 파일과 라인 번호를 얻어낼 수 있습니다. 또한 릴리스 빌드에서도 "pdb-only" 유형의 PDB 파일을 생성하는 것도 동일합니다. 일단, 기본적인 사항들은 WinForm에서의 PDB 역할을 살펴보았던 것과 동일합니다.

그런데, ^^ 한 가지 더 고려할 것이 있지요. 바로, web.config에 있는 compilation[@debug] ="true" 또는 "false"는 어떤 영향을 미칠지에 대해서입니다.

아시는 것처럼, Web Application은 첫 번째로 프로젝트 빌드를 하면 Code Behind 파일의 코드 파일들이 컴파일 되어 /bin 폴더에 위치하게 됩니다. 이후에 사용자들이 실제로 aspx 페이지를 방문하게 되면서 웹 사이트의 /bin 파일들은 shadow-copy가 이뤄지게 됩니다. 이번 예제에서처럼 웹 응용 프로그램의 이름이 "WebApplication1"인 경우에는 다음과 같은 폴더에 shadow copy가 이루어집니다.

C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\webapplication1

aspx는 /bin 폴더에 있는 DLL에 포함된 code behind 클래스들로부터 실행 시에 상속을 받아서 동적으로 컴파일 되어집니다. 바로 이때의 컴파일을 "debug" 모드로 할 것인지, "release" 모드로 할 것인지를 결정하는 것이 web.config의 compilation[@debug] 값입니다. 예제 WebApplication1 프로젝트를 빌드해서 네비게이션을 하게 되면, 다음과 같은 파일들이 ASP.NET 임시 폴더에 생성된 것을 확인할 수 있습니다.

App_Web_dquidpq_0.cs
App_Web_dquidpq_1.cs
App_Web_dquidpq_.dll ( release 빌드 시에는 dll만 생성됨 )
App_Web_dquidpq_.pdb

보시는 것처럼, compilation[@debug] ="true"인 경우에는, PDB 파일과 cs 소스 파일까지 생성된 것을 볼 수 있습니다. 하지만, 그 값을 "false"로 지정하게 되면, pdb 및 소스 파일은 생성되지 않고 DLL 파일만 생성되게 됩니다. debug 빌드 시에 cs 소스 파일을 유지하는 이유는 PDB 파일 내부에 소스 파일의 위치 정보까지 포함하고 있기 때문에 가용한 경우 cs 파일까지 있다면 더욱 확실한 디버그를 할 수 있습니다.

그럼, 이제 compilation[@debug] = "false" 값으로 놓고 default.aspx를 방문해 볼까요? 그럼, 이제 다음과 같은 이벤트 로그 오류 정보를 얻을 수 있습니다.

Stack trace:    at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, 
      FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share)
   at System.IO.File.Open(String path, FileMode mode)
   at BaseLibrary.ThrowClass.TestMethod() in D:\temp2\PdbSample\BaseLibrary\ThrowClass.cs:line 14
   at WebApplication1._Default.Page_Load(Object sender, EventArgs e) in D:\temp2\PdbSample\AspNet\WebApplicationModel\WebApplication1\Default.aspx.cs:line 19
   at System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e)
   at System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e)
   at System.Web.UI.Control.OnLoad(EventArgs e)
   at System.Web.UI.Control.LoadRecursive()
   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

보시는 것처럼, 달라진 것은 없습니다. 그렇습니다. default.aspx/cs 파일과 같은 응용 프로그램 구성이라면 굳이 compilation[@debug] 값을 "true"로 설정해 놓으실 필요는 없습니다. 그럼, 과연 이 옵션은 언제 필요할까요? ^^

asp.net의 코드는 code behind 파일에만 있는 것은 아니죠. 바로 aspx 파일 자체에 코드가 포함되어 있는 경우에는 compilation[@debug] 값을 "true"로 해놓는 것이 의미가 있어집니다.
차이를 확인하기 위해서, default.aspx의 html에 다음과 같이 코드를 추가해 보겠습니다.

----- default.aspx.cs -------
    public partial class _Default : System.Web.UI.Page
    {
        public BaseLibrary.ThrowClass throwClass = new BaseLibrary.ThrowClass();
    }

----- default.aspx -------
<head runat="server">
    <title>Untitled Page : <% throwClass.TestMethod(); %></title>
</head>

아래의 이벤트 로그는 compilation[@debug] = "true"인 경우입니다.

Stack trace:    at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, 
        FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share)
   at System.IO.File.Open(String path, FileMode mode)
   at BaseLibrary.ThrowClass.TestMethod() in D:\temp2\PdbSample\BaseLibrary\ThrowClass.cs:line 14
   at ASP.default_aspx.__Render__control3(HtmlTextWriter __w, Control parameterContainer) in d:\temp2\PdbSample\AspNet\WebApplicationModel\WebApplication1\Default.aspx:line 7
   at System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children)
   at System.Web.UI.Control.RenderChildren(HtmlTextWriter writer)
   at System.Web.UI.HtmlControls.HtmlTitle.Render(HtmlTextWriter writer)
   [이하 생략....]

아래의 이벤트 로그는 compilation[@debug] = "false"인 경우입니다.

Stack trace:    at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, 
         FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share)
   at System.IO.File.Open(String path, FileMode mode)
   at BaseLibrary.ThrowClass.TestMethod() in D:\temp2\PdbSample\BaseLibrary\ThrowClass.cs:line 14
   at ASP.default_aspx.__Render__control3(HtmlTextWriter __w, Control parameterContainer)
   at System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children)
   at System.Web.UI.Control.RenderChildren(HtmlTextWriter writer)
   at System.Web.UI.HtmlControls.HtmlTitle.Render(HtmlTextWriter writer)
   [이하 생략....]

차이가 분명하지요. ^^ "true"인 경우에는 default.aspx 페이지의 어느 라인인지까지도 표시가 되어지는 반면, "false"인 경우에는 알 수 없습니다. (그런데, 어째서 여기서의 파일이 shadow-copy 임시 폴더에 있는 cs 파일이 아닌, 원래의 web site 폴더에 있는 aspx를 가리키고 있을까요? 이는 #line 지시자를 임시 폴더의 cs 파일에서 사용하고 있기 때문입니다. 이에 대해서는 나중에 기회되면 설명 드리겠습니다.)

그럼, 이것을 보고 어떻게 결론을 내리는 것이 좋을까요?

웹 애플리케이션인 경우에는 가능한 aspx 페이지에는 직접 코드를 사용하지 않는 것이 좋습니다. 만약, 사용해야 한다면 오류가 거의 발생하지 않을 코드에 대해서 해야 하거나, 부득이한 경우 처리 속도 저하를 감수하고 compilation[@debug] = "true"로 설정해서 배포를 해야 합니다. compilation[@debug] = "false"로 하는 경우라면, 위의 오류 스택에서 보는 것처럼, "ASP.className"과 같이 "ASP"로 시작한다면 aspx 페이지에서 오류가 났음을 이젠 알 수 있을 것입니다.

이러한 문제를 해결하기 위해 MS에 건의하고 싶은 것이 있다면 compilation 옵션에 "build" 속성과 "pdb" 속성을 분리해서 넣어 달라는 정도입니다. 즉, aspx에 코드를 사용하더라도 dll은 release로 빌드하지만 (C++의 경우와 비교해 보면, /Zi 옵션만으로 빌드) pdb 파일이 생성될 수 있도록 하는 조정을 할 수 있게 하면 좋겠지요. ^^ ([2006-08-10] 다시 읽어보니 ^^ 이 부분은 수정이 되어야 할 것 같습니다. "3.3 PDB 파일에 따른 Debug 정보 - .NET 2.0 Web Site Model Project"에 보면 제가 system.codedom에서 이것을 해결하는 방법을 제시했지요.)
[연관 글]






[최초 등록일: ]
[최종 수정일: 7/5/2021]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 




... 151  152  153  154  155  156  157  158  159  160  161  162  [163]  164  165  ...
NoWriterDateCnt.TitleFile(s)
972정성태1/7/201124126개발 환경 구성: 95. SQL Server 2008 R2 이하 버전 정보 확인
971정성태1/5/201133708.NET Framework: 199. .NET 코드 - Named Pipe 닷넷 서버와 VC++ 클라이언트 제작 [2]파일 다운로드1
970정성태1/4/201134238.NET Framework: 198. 윈도우 응용 프로그램에 Facebook 로그인 연동 [1]파일 다운로드1
969정성태12/31/201040348VC++: 45. Winsock 2 Layered Service Provider - Visual Studio 2010용 프로젝트 [1]파일 다운로드1
968정성태12/30/201026595개발 환경 구성: 94. 개발자가 선택할 수 있는 윈도우에서의 네트워크 프로그래밍 기술 [2]
967정성태12/27/201028381.NET Framework: 197. .NET 코드 - 단일 Process 실행파일 다운로드1
966정성태12/26/201026348.NET Framework: 196. .NET 코드 - 창 흔드는 효과파일 다운로드1
965정성태12/25/201027835개발 환경 구성: 93. MSBuild를 이용한 닷넷 응용프로그램의 다중 어셈블리 출력 빌드파일 다운로드1
964정성태12/21/2010142993개발 환경 구성: 92. 윈도우 서버 환경에서, 최대 생성 가능한 소켓(socket) 연결 수는 얼마일까? [14]
963정성태12/13/201027870개발 환경 구성: 91. MSBuild를 이용한 닷넷 응용프로그램의 플랫폼(x86/x64)별 빌드 [2]파일 다운로드1
962정성태12/10/201022756오류 유형: 110. GAC 등록 - Failure adding assembly to the cache: Invalid file or assembly name.
961정성태12/10/201099789개발 환경 구성: 90. 닷넷에서 접근해보는 PostgreSQL DB [5]
960정성태12/8/201045072.NET Framework: 195. .NET에서 코어(Core) 관련 CPU 정보 알아내는 방법파일 다운로드1
959정성태12/8/201031906.NET Framework: 194. Facebook 연동 - API Error Description: Invalid OAuth 2.0 Access Token
958정성태12/7/201028890개발 환경 구성: 89. 배치(batch) 파일에서 또 다른 배치 파일을 동기 방식으로 실행 및 반환값 얻기 [2]
957정성태12/6/201031634디버깅 기술: 31. Windbg - Visual Studio 디버그 상태에서 종료해 버리는 응용 프로그램 [3]
953정성태11/28/201036862.NET Framework: 193. 페이스북(Facebook) 계정으로 로그인하는 C# 웹 사이트 제작 [5]
952정성태11/25/201025312.NET Framework: 192. GC의 부하는 상대적인 것! [4]
950정성태11/18/201076666.NET Framework: 191. ClickOnce - 관리자 권한 상승하는 방법 [17]파일 다운로드2
954정성태11/29/201048669    답변글 .NET Framework: 191.1. [답변] 클릭원스 - 요청한 작업을 수행하려면 권한 상승이 필요합니다. (Exception from HRESULT: 0x800702E4) [2]
949정성태11/16/201027216오류 유형: 109. System.ServiceModel.Security.SecurityNegotiationException
948정성태11/16/201035998.NET Framework: 190. 트위터 계정으로 로그인하는 C# 웹 사이트 제작 [7]파일 다운로드1
947정성태11/14/201041661.NET Framework: 189. Mono Cecil로 만들어 보는 .NET Decompiler [1]파일 다운로드1
946정성태11/11/201041496.NET Framework: 188. .NET 64비트 응용 프로그램에서 왜 (2GB) OutOfMemoryException 예외가 발생할까? [1]파일 다운로드1
945정성태11/11/201025029VC++: 44. C++/CLI 컴파일 오류 - error C4368: mixed types are not supported
944정성태11/11/201031508VC++: 43. C++/CLI 컴파일 오류 - error C2872: 'IServiceProvider' : ambiguous symbol could be ...
... 151  152  153  154  155  156  157  158  159  160  161  162  [163]  164  165  ...