성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] Java - How to use the Foreign Funct...
[정성태] 제가 큰 실수를 했군요. ^^; Delegate를 통한 Bein...
[정성태] Working with Rust Libraries from C#...
[정성태] Detecting blocking calls using asyn...
[정성태] 아쉽게도, 커뮤니티는 아니고 개인 블로그입니다. ^^
[정성태] 질문이 잘 이해가 안 됩니다. 우선, 해당 소스코드에서 ILis...
[양승조
] var대신 dinamic으로 선언해서 해결은 했습니다. 맞는 해...
[양승조
] 또 막혔습니다. ㅠㅠ var list = props[i].Ge...
[양승조
] 아. 감사합니다. 어제는 안됐던것 같은데....정신을 차려야겠네...
[정성태] "props[i].GetValue(props[i])" 코드에서 ...
글쓰기
제목
이름
암호
전자우편
HTML
홈페이지
유형
제니퍼 .NET
닷넷
COM 개체 관련
스크립트
VC++
VS.NET IDE
Windows
Team Foundation Server
디버깅 기술
오류 유형
개발 환경 구성
웹
기타
Linux
Java
DDK
Math
Phone
Graphics
사물인터넷
부모글 보이기/감추기
내용
<div style='display: inline'> <h1 style='font-family: Malgun Gothic, Consolas; font-size: 20pt; color: #006699; text-align: center; font-weight: bold'>NT 서비스 시작 단계에서 닷넷 메서드에 BP를 걸어 디버깅하는 방법</h1> <p> NT 서비스에 Visual Studio를 연결하는 방법을 알아 봤는데요.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > NT 서비스가 시작하자마자 디버거를 연결시키는 방법 (1) ; <a target='tab' href='http://www.sysnet.pe.kr/2/0/1586'>http://www.sysnet.pe.kr/2/0/1586</a> NT 서비스가 시작하자마자 디버거를 연결시키는 방법 (2) ; <a target='tab' href='http://www.sysnet.pe.kr/2/0/1587'>http://www.sysnet.pe.kr/2/0/1587</a> </pre> <br /> 그렇게 연결한 서비스의 닷넷 메서드에 BP를 걸어보는 것도 마저 해봐야겠지요. ^^ 참고로, 방식은 예전의 Main 메서드 거는 것과 크게 다르지 않습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > .NET 4.0 응용 프로그램의 Main 함수에 BreakPoint 걸기 ; <a target='tab' href='http://www.sysnet.pe.kr/2/0/1021'>http://www.sysnet.pe.kr/2/0/1021</a> </pre> <br /> 자, 그럼 레지스트리의 "Image File Execution Options"에 windbg로 "SQL Server Reporting Services" 서비스를 디버깅하는 것으로 시작해 볼까요? ^^<br /> <br /> 일단 디버거가 로드되면,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Microsoft (R) Windows Debugger Version 6.12.0002.633 AMD64 Copyright (c) Microsoft Corporation. All rights reserved. CommandLine: "C:\Program Files\Microsoft SQL Server\MSRS11.MSSQLSERVER\Reporting Services\ReportServer\bin\ReportingServicesService.exe" Symbol search path is: SRV*d:\Symbols*http://msdl.microsoft.com/download/symbols Executable search path is: ModLoad: 00000000`00330000 00000000`007ea000 ReportingServicesService.exe ...[생략]... ModLoad: 00000000`50000000 00000000`50007000 C:\Program Files\Microsoft SQL Server\MSRS11.MSSQLSERVER\Reporting Services\ReportServer\bin\SQLRSOS.dll ...[생략]... ModLoad: 00007ff8`2c770000 00007ff8`2c796000 C:\Windows\SYSTEM32\DEVOBJ.dll (1b50.107c): Break instruction exception - code 80000003 (first chance) ntdll!LdrInitShimEngineDynamic+0x330: 00007ff8`305e7710 cc int 3 </pre> <br /> NT 서비스 로드의 제약 시간에 걸리지 않게 mscorlib까지만 빠르게 진행을 시켜줍니다. (아니면, <a target='tab' href='https://docs.microsoft.com/en-us/troubleshoot/windows-client/system-management-components/windows-trace-session-manager-service-not-start-event-id-7000'>ServicesPipeTimeout을 변경해 주어 시간을 늘리는 것</a>도 좋겠고.)<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 0:013> <span style='color: blue; font-weight: bold'>sxe ld mscorlib</span> 0:013> <span style='color: blue; font-weight: bold'>g</span> Profiler Initialize - End! ModLoad: 00000000`068f0000 00000000`06d4e000 mscorlib.dll ntdll!NtMapViewOfSection+0xa: 00007ff8`305b67fa c3 ret </pre> <br /> 이제 sos를 로드하고 BP를 걸어볼까요?<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 0:013> <span style='color: blue; font-weight: bold'>.loadby sos mscorwks</span> 0:013> <span style='color: blue; font-weight: bold'>!bpmd mscorlib System.Runtime.Remoting.Messaging.StackBuilderSink.SyncProcessMessage</span> PDB symbol for mscorwks.dll not loaded Adding pending breakpoints... </pre> <br /> 위와 같이 메시지가 나오면 pending이라고는 되어 있지만 BP가 안 걸린 것입니다. 따라서 BP가 걸릴 수 있을 정도로 좀 더 진행해야 할 필요가 있는데요. System.Data까지 해보았습니다. (어디까지 할지는 몇번 시행 착오를 거쳐야 합니다.)<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 0:013> <span style='color: blue; font-weight: bold'>sxe ld system.data</span> 0:013> <span style='color: blue; font-weight: bold'>g</span> ModLoad: 00000000`1b6d0000 00000000`1b9dc000 System.Data.dll ntdll!NtMapViewOfSection+0xa: 00007ff8`305b67fa c3 ret </pre> <br /> 이제서야 BP가 제대로 걸립니다. ^^<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 0:010> <span style='color: blue; font-weight: bold'>!bpmd mscorlib System.Runtime.Remoting.Messaging.StackBuilderSink.SyncProcessMessage</span> <span style='color: blue; font-weight: bold'>Found 2 methods...</span> MethodDesc = 00007ff7c02e9fa8 MethodDesc = 00007ff7c02e9fb0 Adding pending breakpoints... </pre> <br /> 같은 pending이라도 위와 같이 "Found" 메시지가 나와줘야 BP가 걸린 것입니다. 이렇게 하고 진행을 하면 다음과 같이 해당 메서드의 실행 순간에 멈춥니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 0:010> <span style='color: blue; font-weight: bold'>g</span> (c4c.1408): CLR notification exception - code e0444143 (first chance) JITTED <span style='color: blue; font-weight: bold'>mscorlib!System.Runtime.Remoting.Messaging.StackBuilderSink.SyncProcessMessage</span>(System.Runtime.Remoting.Messaging.IMessage) Setting breakpoint: bp 00007FF7C0C4DA70 [System.Runtime.Remoting.Messaging.StackBuilderSink.SyncProcessMessage(System.Runtime.Remoting.Messaging.IMessage)] Breakpoint 0 hit 00007ff7`c0c4da70 53 push rbx </pre> <br /> BP로 걸린 메서드의 MethodDesc 값을 알아내어,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 0:010> <span style='color: blue; font-weight: bold'>!name2ee mscorlib!System.Runtime.Remoting.Messaging.StackBuilderSink.SyncProcessMessage</span> Module: 00007ff7c0172020 (mscorlib.dll) Token: 0x0000000006004510 MethodDesc: <span style='color: blue; font-weight: bold'>00007ff7c02e9fa8</span> Name: System.Runtime.Remoting.Messaging.StackBuilderSink.SyncProcessMessage(System.Runtime.Remoting.Messaging.IMessage) <span style='color: blue; font-weight: bold'>JITTED Code Address: 00007ff7c0c4da70</span> </pre> <br /> sos.dll의 !U 명령어를 통해 역어셈블할 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 0:010> <span style='color: blue; font-weight: bold'>!U 00007ff7c02e9fa8</span> Normal JIT generated code System.Runtime.Remoting.Messaging.StackBuilderSink.SyncProcessMessage(System.Runtime.Remoting.Messaging.IMessage) Begin 00007ff7c0c4da70, size cf 00007ff7`c0c4da70 53 push rbx 00007ff7`c0c4da71 55 push rbp 00007ff7`c0c4da72 57 push rdi ...[생략]... 00007ff7`c0c4db2a e8a1a9225f call mscorwks!PreBindAssembly+0x5cad0 (00007ff8`1fe784d0) (JitHelp: CORINFO_HELP_RETHROW) 00007ff7`c0c4db2f 488d05a3ffffff lea rax,[00007ff7`c0c4dad9] 00007ff7`c0c4db36 4883c430 add rsp,30h 00007ff7`c0c4db3a 5f pop rdi 00007ff7`c0c4db3b 5d pop rbp 00007ff7`c0c4db3c 5b pop rbx 00007ff7`c0c4db3d f3c3 rep ret </pre> <br /> sos.dll의 !U 명령어말고 windbg 자체의 u(nassemble)도 있는데요. 2개의 출력 결과가 다소 다릅니다. !U로 한 경우에는 내부에 닷넷 메서드 호출들의 표시가 추가되므로 로직 파악이 더 쉽습니다.<br /> <br /> <hr style='width: 50%' /><br /> <br /> 참고로, 실패했지만 한 가지 더 설명해 보겠습니다. <br /> <br /> 위의 방법대로하면 Local SYSTEM 설정 및 데스크톱 보안 문제로 디버깅이 다소 불편한데요. 이것 때문에 아예 VM을 대상으로 커널 디버깅으로 해볼까... 시도를 해봤습니다.<br /> <br /> 아래의 문서대로 환경 구성을 하고,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Windbg - Hyper-V 윈도우 7 원격 디버깅 구성 ; <a target='tab' href='http://www.sysnet.pe.kr/2/0/938'>http://www.sysnet.pe.kr/2/0/938</a> </pre> <br /> Hyper-V 호스트 컴퓨터에 windbg를 설치해,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Debugging Tools for Windows 독립 설치 버전 ; <a target='tab' href='http://www.sysnet.pe.kr/2/0/1447'>http://www.sysnet.pe.kr/2/0/1447</a> </pre> <br /> VM 자체를 커널 디버깅으로 연결을 했습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Microsoft (R) Windows Debugger Version 6.12.0002.633 AMD64 Copyright (c) Microsoft Corporation. All rights reserved. Opened \\.\pipe\windbg_port Waiting to reconnect... Connected to Windows 7 9600 x64 target at (Fri Jan 17 21:04:16.771 2014 (UTC + 9:00)), ptr64 TRUE Kernel Debugger connection established. Symbol search path is: SRV*d:\Symbols*http://msdl.microsoft.com/download/symbols Executable search path is: Windows 7 Kernel Version 9600 MP (6 procs) Free x64 Product: Server, suite: TerminalServer SingleUserTS Built by: 9600.16452.amd64fre.winblue_gdr.131030-1505 Machine Name: Kernel base = 0xfffff803`0e40f000 PsLoadedModuleList = 0xfffff803`0e6d3990 Debug session time: Fri Jan 17 21:04:12.158 2014 (UTC + 9:00) System Uptime: 0 days 0:21:53.376 Break instruction exception - code 80000003 (first chance) nt!DbgBreakPointWithStatus: fffff803`0e563890 cc int 3 </pre> <br /> 프로세스 생성에 대해 BP를 잡고,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > bp nt!PspInsertProcess </pre> <br /> g로 시작해 NT 서비스를 실행하니 services.exe에서 잡혔습니다. 그래서 한번 더 g를 거치고 나서야 정상적으로 ReportingServicesService.exe에 잡혔습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 0: kd> <span style='color: blue; font-weight: bold'>g</span> Breakpoint 1 hit nt!PspInsertProcess: fffff803`0e840a78 48895c2420 mov qword ptr [rsp+20h],rbx 0: kd> <span style='color: blue; font-weight: bold'>kc</span> Call Site nt!PspInsertProcess nt!NtCreateUserProcess 0: kd> <span style='color: blue; font-weight: bold'>!process -1 0 </span> PROCESS ffffe000013d8940 SessionId: 0 Cid: 0298 Peb: 7ff7e527e000 ParentCid: 0238 DirBase: 10b32b000 ObjectTable: ffffc0000270f0c0 HandleCount: <Data Not Accessible> Image: <span style='color: blue; font-weight: bold'>services.exe</span> 0: kd> <span style='color: blue; font-weight: bold'>g</span> Breakpoint 1 hit nt!PspInsertProcess: fffff803`0e840a78 48895c2420 mov qword ptr [rsp+20h],rbx 1: kd> <span style='color: blue; font-weight: bold'>!process -1 0 </span> PROCESS <span style='color: blue; font-weight: bold'>ffffe00003f44940</span> SessionId: 0 Cid: 1100 Peb: 7ff5ff4fa000 ParentCid: 0298 DirBase: 13a79c000 ObjectTable: ffffc000132ace00 HandleCount: <Data Not Accessible> Image: <span style='color: blue; font-weight: bold'>ReportingServicesService.exe</span> ** 이미 실행중인 process라면, 해당 프로세스 정보를 얻어서 유저 모드로 내려갈 수 있습니다. !process 0 0 ReportingServicesService.exe .process /i ffffe00003f44940 </pre> <br /> 이후, LoadLibrary에 BP를 거는 방식을 통해 적절한 닷넷 DLL이 로드되었을때<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > bp /p @$proc kernel32!LoadLibraryW </pre> <br /> SOS를 로드하고 !name2ee와 같은 확장 명령어를 실행해 봤지만 정상적으로 동작하지 않았습니다. 제가 잘못한 건지는 알수 없으나 어쨌든 커널 모드의 windbg에서는 sos.dll을 동작시키는 것에 실패했습니다. (혹시 이에 대해 아시는 분은 덧글 좀 부탁드립니다. ^^)<br /> </p><br /> <br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
9301
(왼쪽의 숫자를 입력해야 합니다.)