성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] Detecting blocking calls using asyn...
[정성태] 아쉽게도, 커뮤니티는 아니고 개인 블로그입니다. ^^
[정성태] 질문이 잘 이해가 안 됩니다. 우선, 해당 소스코드에서 ILis...
[양승조
] var대신 dinamic으로 선언해서 해결은 했습니다. 맞는 해...
[양승조
] 또 막혔습니다. ㅠㅠ var list = props[i].Ge...
[양승조
] 아. 감사합니다. 어제는 안됐던것 같은데....정신을 차려야겠네...
[정성태] "props[i].GetValue(props[i])" 코드에서 ...
[정성태] 저렇게 조각 코드 말고, 실제로 재현이 되는 예제 프로젝트를 압...
[정성태] Modules 창(Ctrl+Shift+U)을 띄워서, 해당 Op...
[정성태] 만드실 수 있습니다. 단지, Unity 엔진 내의 스크립트와 W...
글쓰기
제목
이름
암호
전자우편
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'>windbg + 닷넷 디버깅 (1) - 배열 인덱스 사용 패턴</h1> <p> 모듈명 지정은 대체로 확장자를 빼도 잘 됩니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 0:021> <span style='color: blue; font-weight: bold'>!lmi TestApp</span> Loaded Module Info: [TestApp] Module: TestApp Base Address: 6ded0000 Image Name: C:\Windows\assembly\GAC_MSIL\TestApp\5.0.5.0__cc862a9be44088eb\TestApp.dll Machine Type: 332 (I386) Time Stamp: 54ec24dc Tue Feb 24 16:14:36 2015 Size: 102000 CheckSum: fe709 Characteristics: 2102 Debug Data Dirs: Type Size VA Pointer CODEVIEW 11c, fc290, fb290 RSDS - GUID: {D7414896-35BC-40B9-9897-C786B3457959} Age: 1, Pdb: d:\TestApp\obj\Release\TestApp.pdb Symbol Type: DEFERRED - No error - symbol load deferred Load Report: no symbols loaded </pre> <br /> 실제로 lm 명령을 내려도 모듈 명으로 확장자가 누락되어 있기도 한데요.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 0:021> <span style='color: blue; font-weight: bold'>lm</span> start end module name 6bba0000 6bffa000 mscorlib (pdb symbols) d:\symbols\mscorlib.pdb\F9DA4689335E4020947985CC71F44A541\mscorlib.pdb 6ded0000 6dfd2000 <span style='color: blue; font-weight: bold'>TestApp (no symbols)</span> ... 77020000 770e6000 ADVAPI32 (pdb symbols) d:\symbols\advapi32.pdb\66A66DBC8B0E4D88B54A47510DD8039B2\advapi32.pdb 77280000 773a8000 ntdll (pdb symbols) d:\symbols\ntdll.pdb\78B918DA4A614679A2053B1FB82EEE652\ntdll.pdb </pre> <br /> 그런데 위의 목록에 보면 TestApp 모듈이 pdb 로딩이 안되어 있어서 다음과 같이 명시적인 reload를 모듈명만 전달해 실행했더니 로드를 하지 못합니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 0:021> <span style='color: blue; font-weight: bold'>.reload TestApp</span> "TestApp" was not found in the image list. Debugger will attempt to load "TestApp" at given base 00000000. <span style='color: blue; font-weight: bold'>Please provide the full image name, including the extension (i.e. kernel32.dll)</span> for more reliable results.Base address and size overrides can be given as .reload <image.ext>=<base>,<size>. DBGENG: TestApp - Partial symbol image load missing image info DBGHELP: No header for TestApp. Searching for dbg file DBGHELP: .\TestApp.dbg - file not found DBGHELP: TestApp missing debug info. Searching for pdb anyway DBGHELP: Can't use symbol server for TestApp.pdb - no header information available DBGHELP: TestApp.pdb - file not found DBGHELP: TestApp - no symbols loaded Unable to add module at 00000000' </pre> <br /> 헷갈리게도 /f /v 옵션을 붙이면 'unmatched'라는 결과값을 보여줍니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 0:021> <span style='color: blue; font-weight: bold'>.reload /f /v TestApp</span> "TestApp" was not found in the image list. Debugger will attempt to load "TestApp" at given base 00000000. Please provide the full image name, including the extension (i.e. kernel32.dll) for more reliable results.Base address and size overrides can be given as .reload <image.ext>=<base>,<size>. DBGENG: TestApp - Partial symbol image load missing image info DBGHELP: No header for jennifer5. Searching for dbg file DBGHELP: d:\TestApp\bin\TestApp.dbg - file not found DBGHELP: .\TestApp.dbg - file not found DBGHELP: TestApp missing debug info. Searching for pdb anyway DBGHELP: Can't use symbol server for TestApp.pdb - no header information available DBGHELP: TestApp_0 - private symbols & lines <span style='color: blue; font-weight: bold'>d:\TestApp\bin\TestApp.pdb - unmatched</span> Unable to add module at 00000000' </pre> <br /> 물론, <a target='tab' href='http://www.sysnet.pe.kr/2/0/987'>chkmatch.exe</a>로 확인해 보면 둘다 일치하다고 나옵니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > D:\TestApp\bin><span style='color: blue; font-weight: bold'>ChkMatch.exe -c C:\Windows\assembly\GAC_MSIL\TestApp\5.0.5.0__cc862a9be44088eb\TestApp.dll D:\TestApp\bin\TestApp.pdb</span> ChkMatch - version 1.0 Copyright (C) 2004 Oleg Starodumov http://www.debuginfo.com/ Executable: C:\Windows\assembly\GAC_MSIL\TestApp\5.0.5.0__cc862a9be44088eb\TestApp.dll Debug info file: TestApp.pdb Executable: TimeDateStamp: 54ec24dc Debug info: 2 ( CodeView ) TimeStamp: 54ec24dc Characteristics: 0 MajorVer: 0 MinorVer: 0 Size: 284 RVA: 000fc290 FileOffset: 000fb290 CodeView format: RSDS Signature: {d7414896-35bc-40b9-9897-c786b3457959} Age: 1 PdbFile: d:\TestApp\obj\Release\TestApp.pdb Debug information file: Format: PDB 7.00 Signature: {d7414896-35bc-40b9-9897-c786b3457959} Age: 1 <span style='color: blue; font-weight: bold'>Result: Matched</span> </pre> <br /> .reload 명령으로 pdb를 로드할 때는 (에러메시지에서도 나오지만) "full image name", 즉 확장자를 포함한 이름을 줘야 합니다. 그럼, 이렇게 잘 로드가 됩니다. ^^<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 0:021> <span style='color: blue; font-weight: bold'>.reload /f /v TestApp.dll</span> AddImage: C:\Windows\assembly\GAC_MSIL\jennifer5\5.0.5.0__cc862a9be44088eb\TestApp.dll DllBase = 6ded0000 Size = 00102000 Checksum = 000fe709 TimeDateStamp = 54ec24dc SYMSRV: d:\symbols\TestApp.pdb\D741489635BC40B99897C786B34579591\TestApp.pdb not found SYMSRV: http://msdl.microsoft.com/download/symbols/TestApp.pdb/D741489635BC40B99897C786B34579591/TestApp.pdb not found <span style='color: blue; font-weight: bold'>DBGHELP: TestApp - private symbols & lines d:\TestApp\bin\TestApp.pdb</span> </pre> <br /> <hr style='width: 50%' /><br /> <br /> <a target='tab' href='http://faydoc.tripod.com/cpu/cdq.htm'>어셈블리의 cdq 명령어</a>는,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > ...[생략]... 04ce0844 99 cdq 04ce0845 f7f9 idiv eax,ecx </pre> <br /> 대부분 idiv와 쌍을 이룬다고 보시면 됩니다. 나눗셈 명령어는 나누는 수(divisor)가 32비트인 경우 피젯수(dividend)는 64비트가 되는 식으로 2배의 피젯수가 사용되는데요. cdq는 eax 레지스터의 내용을 부호를 고려해 edx 레지스터로 확장해 주는 역할을 합니다. 즉, 32비트의 값을 64비트로 확장해 주는 것입니다. 이 때문에 자연스럽게 idiv 명령어가 요구하는 64비트 피젯수가 마련됩니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > CDQ - Convert Double to Quad ; <a target='tab' href='http://faydoc.tripod.com/cpu/cdq.htm'>http://faydoc.tripod.com/cpu/cdq.htm</a> </pre> <br /> 위의 매뉴얼에 보면, 코드가 99로 동일한 CWD 명령어도 나오는데요. 아마도 이것은 16비트 시절에 사용된 명령어가 아닌가 생각됩니다.<br /> <br /> 그렇다면 64비트에서는 128비트로 확장해 주는 명령어가 필요하다는 것을 유추할 수 있는데요. 찾아보니 cqo 명령어가 그것입니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > x64 Instructions ; <a target='tab' href='https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/x64-instructions'>https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/x64-instructions</a> </pre> <br /> rax 레지스터의 내용을 부호 비트를 고려해 rdx:rax로 확장해 주는데 명령어 코드도 역시 99입니다.<br /> <br /> 참고로, 1바이트의 내용을 2바이트로 확장해 주는 명령어로 cbw가 있는데... 예외적으로 이것은 명령어 코드가 98입니다.<br /> <br /> <hr style='width: 50%' /><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;' > int [] array = new int [4]; int n = 3; <span style='color: blue; font-weight: bold'>int result = array[n];</span> </pre> <br /> 닷넷은 관리코드로써 n의 값이 array.Length를 벗어나지 않음을 체크하기 때문에 이런 경우 다음과 같이 JIT_RngChkFail 메서드 호출이 JIT 컴파일 이후에 나타나게 됩니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 04ce084a 8b45d8 mov eax,3 // 배열 인덱스로 지정된 값 04ce084d 8b55c0 mov edx,4 // 실제로는 Array타입의 Length값을 구해서 들어감. 04ce0850 3b4204 cmp eax, edx // cmp 명령어는 sub처럼 동작하지만 결과값을 저장하지는 않고 FLAG 레지스터만 변경 // 결국, eax의 값에서 edx값을 빼기 // 만약 이 값이 음수가 되면 CF=1을 설정 // 간단히 말해서, // 배열 인덱스 값(eax)이 edx보다 작으면 CF=1 설정 // 배열 인덱스 값(eax)이 edx보다 같거나 크면 CF=0 설정 04ce0853 7205 jb 04ce085a // jb 명령어는 CF=1인 경우, 지정된 주소를 EIP 레지스터로 로드 // 따라서, 배열 인덱스 값이 Array.Length보다 작으면 점프하게 되고, // 같거나 크면 바로 다음 구문을 실행 04ce0855 e86a1cd863 call mscorwks!JIT_RngChkFail (68a624c4) // 이것이 바로 System.IndexOutOfRangeException 예외를 발생. 04ce085a 8b44820c mov eax,dword ptr [edx+eax*4+0Ch] </pre> <br /> 배열 인덱스가 사용되면 거의 저 패턴으로 기계어 코드가 나타난다고 보면 됩니다.<br /> </p><br /> <br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
6991
(왼쪽의 숫자를 입력해야 합니다.)