Microsoft MVP성태의 닷넷 이야기
디버깅 기술: 5.16. ASP.NET 디버깅 환경 구성 [링크 복사], [링크+제목 복사],
조회: 33064
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
부모글 보이기/감추기
(연관된 글이 2개 있습니다.)

14.1 ASP.NET 디버깅 환경 구성


[환경 : Windows 2003 기준]
".NET 예외 처리 정리"에서 다뤘던 ASP.NET의 예외처리 핸들러에 대해서 좀 더 다뤄보겠습니다.

일단, 예외를 발생시키는 예제를 다음과 같이 했다는 가정하에 진행해 보겠습니다.

public partial class temp_Exception2nd : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        ThreadPool.QueueUserWorkItem(_threadCallback);
    }

    private void _threadCallback(object state)
    {
        throw new ApplicationException("TEST");
    }
}

말씀드린 것처럼 Request를 처리하지 않는 그 이외의 스레드에서 발생한 예외는 이벤트 로그에 그다지 도움이 되는 유형으로 남지는 않습니다. 물론 이러한 이벤트도 aspnet.config 파일의 legacyUnhandledExceptionPolicy[@enabled] 값을 false로 했을 때에 받게 되는데요. 기본적으로는 다음과 같은 식의 예외에 대한 이벤트 로그가 "Application" 부분에 남게 됩니다.

이벤트 형식:	오류
이벤트 원본:	.NET Runtime 2.0 Error Reporting
이벤트 범주:	없음
이벤트 ID:	5000
날짜:		2006-09-16
시간:		오후 4:49:14
사용자:		N/A
컴퓨터:	 XXXXXXXXXX
설명:
EventType clr20r3, P1 w3wp.exe, P2 6.0.3790.1830, P3 42435be1, P4 app_web_lyd_mjmn, P5 0.0.0.0, P6 450ba011, P7 4, P8 a, P9 system.applicationexception, P10 NIL.

자세한 정보는 http://go.microsoft.com/fwlink/events.asp에 있는 도움말 및 지원 센터를 참조하십시오.
데이터:
0000: 63 00 6c 00 72 00 32 00   c.l.r.2.
0008: 30 00 72 00 33 00 2c 00   0.r.3.,.
0010: 20 00 77 00 33 00 77 00    .w.3.w.
0018: 70 00 2e 00 65 00 78 00   p...e.x.
0020: 65 00 2c 00 20 00 36 00   e.,. .6.
0028: 2e 00 30 00 2e 00 33 00   ..0...3.
0030: 37 00 39 00 30 00 2e 00   7.9.0...
0038: 31 00 38 00 33 00 30 00   1.8.3.0.
0040: 2c 00 20 00 34 00 32 00   ,. .4.2.
0048: 34 00 33 00 35 00 62 00   4.3.5.b.
0050: 65 00 31 00 2c 00 20 00   e.1.,. .
0058: 61 00 70 00 70 00 5f 00   a.p.p._.
0060: 77 00 65 00 62 00 5f 00   w.e.b._.
0068: 6c 00 79 00 64 00 5f 00   l.y.d._.
0070: 6d 00 6a 00 6d 00 6e 00   m.j.m.n.
0078: 2c 00 20 00 30 00 2e 00   ,. .0...
0080: 30 00 2e 00 30 00 2e 00   0...0...
0088: 30 00 2c 00 20 00 34 00   0.,. .4.
0090: 35 00 30 00 62 00 61 00   5.0.b.a.
0098: 30 00 31 00 31 00 2c 00   0.1.1.,.
00a0: 20 00 34 00 2c 00 20 00    .4.,. .
00a8: 61 00 2c 00 20 00 73 00   a.,. .s.
00b0: 79 00 73 00 74 00 65 00   y.s.t.e.
00b8: 6d 00 2e 00 61 00 70 00   m...a.p.
00c0: 70 00 6c 00 69 00 63 00   p.l.i.c.
00c8: 61 00 74 00 69 00 6f 00   a.t.i.o.
00d0: 6e 00 65 00 78 00 63 00   n.e.x.c.
00d8: 65 00 70 00 74 00 69 00   e.p.t.i.
00e0: 6f 00 6e 00 20 00 4e 00   o.n. .N.
00e8: 49 00 4c 00 0d 00 0a 00   I.L.....


이벤트 형식:	오류
이벤트 원본:	VsJITDebugger
이벤트 범주:	없음
이벤트 ID:	4096
날짜:		2006-09-16
시간:		오후 6:29:22
사용자:		NT AUTHORITY\SYSTEM
컴퓨터:	XXXXXXXXXX
설명:
An unhandled exception ('System.ApplicationException') occurred in w3wp.exe [392]. 
Just-In-Time debugging this exception failed with the following error: 
Debugger could not be started because no user is logged on.

Check the documentation index for 'Just-in-time debugging, errors' for more information.

자세한 정보는 http://go.microsoft.com/fwlink/events.asp에 있는 도움말 및 지원 센터를 참조하십시오.
데이터:
0000: 02 00 5c 80               ..\


보시면, 뭐 그다지 아주 쓸모없는 이벤트 로그는 아닙니다. 오류가 발생한 DLL의 이름도 "app_web_lyd_mjmn"라고 나오지요. 이 파일은 "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files" 폴더 하위에서 찾아 볼 수 있습니다.
어쨌든, 이와 같은 오류 발생은 처리되지 않은 예외이기 때문에 w3wp.exe 파일은 예기치 않게 종료가 되어버려서 뒤이어, "System" 부분에서는 다음과 같은 이벤트 로그가 남게 됩니다.

이벤트 형식:	경고
이벤트 원본:	W3SVC
이벤트 범주:	없음
이벤트 ID:	1011
날짜:		2006-09-16
시간:		오후 4:49:21
사용자:		N/A
컴퓨터:	XXXXXXXXXX
설명:
응용 프로그램 풀 'DefaultAppPool'에 사용되는 프로세스에 World Wide Web 게시 서비스와의 심각한 통신 오류가 있습니다. 
프로세스 ID는 '1760'입니다. 데이터 필드에 오류 번호가 있습니다.

자세한 정보는 http://go.microsoft.com/fwlink/events.asp에 있는 도움말 및 지원 센터를 참조하십시오.
데이터:
0000: 6d 00 07 80               m..

여기까지, asp.net에서 별도의 스레드 동작 시에 예외가 발생한 경우의 이벤트 로그에 대한 설명을 마치고.



실제로, 이러한 오류가 발생했을 때 특이한 점은 "DW20.exe"가 작업관리자에 나타나게 되고 이때의 CPU 사용률은 약 100%까지 올라가게 됩니다. 아래의 그림은 위와 같은 오류가 발생했을 때의 CPU 사용률을 보여주고 있습니다.

DW20.exe CPU 사용률

왜냐하면, 이때 시스템은 DW20.exe를 사용해서 예외가 발생한 상황의 w3wp.exe에 대한 덤프 파일을 받아놓기 때문입니다. 실제로, 이런 상황이 발생한 이후에 "C:\WINDOWS\PCHEALTH\ERRORREP" 폴더에 가보면, 그 하위에 덤프 파일을 포함하고 있는 "CAB" 파일이 들어있는 폴더를 발견할 수 있습니다. 예를 들어, 위와 같은 예외 테스트와 함께 제 컴퓨터에는 다음과 같은 경로의 예외 파일이 생성되었습니다.

C:\WINDOWS\PCHEALTH\ERRORREP\QSignoff
				A7233A5.cab
				A7233A5.txt

위의 "A7233A5.cab" 파일의 압축을 풀면 다음과 같이 덤프 파일을 포함하고 있는 것을 확인할 수 있습니다.

mdmpmem.hdmp
version.txt
w3wp.exe.mdmp

여기서 w3wp.exe.mdmp 파일은 .NET 디버깅과 관련된 sos.dll을 사용하는 경우에는 그다지 도움이 되지 않습니다. 따라서 Heap 정보와 함께 덤프가 된 HDMP 확장자의 파일을 가지고 디버깅을 하는 것이 좋습니다.
그런데, VS.NET의 경우 hdmp 확장자를 지원하지 않기 때문에, "mdmpmem.hdmp" 파일을 "mdmpmem.dmp" 파일로 이름을 변경한 다음 더블 클릭을 하면 VS.NET 2005가 로드되면서 덤프 파일을 읽게 됩니다. 물론, 그 이후에 "F5" 버튼을 누르게 되면 정상적으로 디버깅이 가능합니다. 이에 대한 자세한 내용은 다음의 토픽을 참조하십시오.

3.5.1 VS.NET 2005를 이용한 미니덤프 파일 분석 (1)
; https://www.sysnet.pe.kr/2/0/318

3.5.2 VS.NET 2005를 이용한 미니덤프 파일 분석 (2)
; https://www.sysnet.pe.kr/2/0/319


이 덤프 파일 관리에 대해서 주의하셔야 할 것이 있는데요. "C:\WINDOWS\PCHEALTH\ERRORREP\" 폴더에 있는 것들은 영구적으로 남지 않는 다는 것이 문제입니다. 이들은 "Error Reporting Service" NT 서비스에 의해서 처리(전송)가 되고 나면 삭제되어집니다.



ASP.NET에서의 예외 처리에 대한 문제 해결을 위해서 위와 같이 시스템이 자동적으로 남겨주는 덤프 파일을 사용하는 것도 좋은 방법이지만, 만약 그 예외가 빈번하게 발생하는 상황이라면 CPU 100% 사용률과 함께 덤프 파일이 남겨지는 것은 여간 부담스러운 일이 아닐 수 없습니다. 가능하다면 이런 상황을 피하는 것이 좋겠는데요. 바로 이런 경우를 위해 ".NET 예외 처리 정리"에서 소개시켜 드렸던 다음의 URL에서 제공하는 방법이 권장되어집니다.

Unhandled exceptions cause ASP.NET-based applications to unexpectedly quit in the .NET Framework 2.0
; https://docs.microsoft.com/en-us/troubleshoot/aspnet/exceptions-cause-apps-quit

여러분들이 위의 토픽을 보시고 직접 HttpModule을 작성하셔도 되겠지만, 제가 이 토픽에 첨부한 WebLib.Snippet에 이미 코딩을 해놓았으니 그것을 이용하셔도 좋겠습니다. 방법은 간단합니다.

1. WebLib.Snippet.dll 파일을 GAC에 등록.

2. 다음과 같은 내용을 web.config에 등록.

===== IIS 6 또는 IIS 7/7.5에서의 Classic Mode =====
<configuration>
	<system.web>
		; [중간 생략]
		<httpModules>
			<add name="UnhandledExceptionModule" 
			type="WebLib.Snippet.UnhandledExceptionModule, WebLib.Snippet, Version=1.0.0.2, Culture=neutral, PublicKeyToken=f9e203bf2db94124" />
		</httpModules>
	</system.web>
</configuration>

===== IIS 7/7.5에서의 Integrated Mode =====
<configuration>
  <system.webServer>
    <modules>
      <add name="UnhandledExceptionModule" type="WebLib.Snippet.UnhandledExceptionModule, WebLib.Snippet, Version=1.0.0.2, Culture=neutral, PublicKeyToken=f9e203bf2db94124"/>
    </modules>
  </system.webServer>
</configuration>

3. "%WINDIR%\Microsoft.NET\Framework\v2.0.50727\Aspnet.config" 파일의 legacyUnhandledExceptionPolicy 값을 다음과 같이 true로 변경.

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
    <runtime>
        <legacyUnhandledExceptionPolicy enabled="true" />
        <legacyImpersonationPolicy enabled="true"/>
        <alwaysFlowImpersonationPolicy enabled="false"/>
        <SymbolReadingPolicy enabled="1" />
    </runtime>
</configuration>

4. "iisreset" 실행



위와 같이 설정하고 나서, 이제 다시 예외를 발생시키는 웹폼 페이지를 방문하게 되면 이벤트 로그에는 "Application" 영역에 다음과 같이 하나의 로그만 남게 되고, w3wp.exe는 종료를 하지 않게 됩니다. 물론 덤프 파일 처리도 하지 않게 되어 CPU 사용률이 올라가는 일도 없습니다.

이벤트 형식:	오류
이벤트 원본:	ASP.NET 2.0.50727.0
이벤트 범주:	없음
이벤트 ID:	0
날짜:		2006-09-16
시간:		오후 6:47:48
사용자:		N/A
컴퓨터:	XXXXXXXXXX
설명:
이벤트 ID( 0 )(원본 ( ASP.NET 2.0.50727.0 )에 있음)에 대한 설명을 찾을 수 없습니다. 
로컬 컴퓨터에 원격 컴퓨터에서 보낸 메시지를 표시하기 위해 필요한 레지스트리 정보 또는 메시지 DLL 파일이 없을 수 있습니다. 
이 설명을 검색하는 데 /AUXSOURCE= 플래그를 사용할 수 있습니다. 자세한 정보는 도움말 및 지원을 참조하십시오. 
다음 정보는 이벤트의 일부입니다. 

UnhandledException logged by UnhandledExceptionModule.dll:

appId=/LM/W3SVC/1/ROOT

type=System.ApplicationException

message=TEST

stack=
   위치: temp_Exception2nd._threadCallback(Object state) 파일 d:\...\Exception2nd.aspx.cs:줄 22
   위치: System.Threading._ThreadPoolWaitCallback.WaitCallback_Context(Object state)
   위치: System.Threading.ExecutionContext.runTryCode(Object userData)
   위치: System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
   위치: System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
   위치: System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   위치: System.Threading._ThreadPoolWaitCallback.PerformWaitCallback(Object state)

PDB 파일 구성만 제대로 해주시면 위와 같이 실제 예외가 발생한 소스 파일명과 라인 번호까지 얻을 수 있습니다.



[이 토픽에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]

[연관 글]






[최초 등록일: ]
[최종 수정일: 12/2/2022]

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

비밀번호

댓글 작성자
 



2008-10-09 09시58분
Watson Bucket 정보를 이용한 CLR 응용 프로그램 예외 분석
; http://www.sysnet.pe.kr/2/0/595
kevin25

... 16  17  18  19  20  21  22  23  [24]  25  26  27  28  29  30  ...
NoWriterDateCnt.TitleFile(s)
13053정성태5/10/20226914.NET Framework: 2006. C# - GC.KeepAlive 메서드의 역할
13052정성태5/9/20226902.NET Framework: 2005. C# - 생성한 참조 개체가 언제 GC의 정리 대상이 될까요?
13051정성태5/8/20226824.NET Framework: 2004. C# XingAPI - ACF 검색 결과로 구한 CSV 파일을 통해 퀀트 종목 찾기파일 다운로드1
13050정성태5/6/20226847.NET Framework: 2003. C# - COM 개체의 이벤트 핸들러에서 발생하는 예외에 대한 CLR의 특별 대우파일 다운로드1
13049정성태5/6/20225747오류 유형: 811. GoLand - Error: Cannot find package
13048정성태5/6/20226963오류 유형: 810. "ASUS TUF GAMING B550M-PLUS (WI-FI)" 모델에서 블루투스 장치가 인식이 안 되는 문제
13047정성태5/6/20226973오류 유형: 809. Speech Recognition could not start
13046정성태5/5/20227285.NET Framework: 2002. C# XingAPI - ACF 파일을 이용한 퀀트 종목 찾기(t1857)
13045정성태5/5/20227282.NET Framework: 2001. C# XingAPI - 주식 종목에 따른 PBR, PER, ROE 구하는 방법(t3341 예제)
13044정성태5/4/20226687오류 유형: 808. error : clang++ exited with code 127
13043정성태5/3/20226377오류 유형: 807. C# - 닷넷 응용 프로그램에서 Informix DB 사용 시 오류 메시지 정리
13042정성태5/3/20226802.NET Framework: 2000. C# - 닷넷 응용 프로그램에서 Informix DB 사용 방법파일 다운로드1
13041정성태4/28/20227132개발 환경 구성: 642. Informix 데이터베이스 docker 환경 구성
13040정성태4/27/20227545VC++: 156. 비주얼 스튜디오 - Linux C/C++ 프로젝트에서 openssl 링크하는 방법
13039정성태4/27/20228389.NET Framework: 1999. C# - Playwright를 이용한 간단한 브라우저 제어 실습
13038정성태4/26/20226122오류 유형: 806. twine 실행 시 ConfigParser.ParsingError: File contains parsing errors: /root/.pypirc
13037정성태4/25/20226571.NET Framework: 1998. Azure Functions를 사용한 간단한 실습
13036정성태4/24/20227423.NET Framework: 1997. C# - nano 시간을 가져오는 방법 [2]
13035정성태4/22/20227956Windows: 204. Windows 10부터 바뀐 QueryPerformanceFrequency, QueryPerformanceCounter
13034정성태4/21/20227289.NET Framework: 1996. C# XingAPI - 주식 종목에 따른 PBR, PER, ROE, ROA 구하는 방법(t3320, t8430 예제)파일 다운로드1
13033정성태4/18/20227837.NET Framework: 1195. C# - Thread.Yield와 Thread.Sleep(0)의 차이점(?)
13032정성태4/17/20227550오류 유형: 805. Github의 50MB 파일 크기 제한 - warning: GH001: Large files detected. You may want to try Git Large File Storage
13031정성태4/15/20227183.NET Framework: 1194. C# - IdealProcessor와 ProcessorAffinity의 차이점
13030정성태4/15/20226813오류 유형: 804. 정규 표현식 오류 - Quantifier {x,y} following nothing.
13029정성태4/14/20227205Windows: 203. iisreset 후에도 이전에 설정한 전역 환경 변수가 w3wp.exe에 적용되는 문제
13028정성태4/13/20227172.NET Framework: 1193. (appsettings.json처럼) web.config의 Debug/Release에 따른 설정 적용
... 16  17  18  19  20  21  22  23  [24]  25  26  27  28  29  30  ...