다음을 통해 공유


기호 확인

기호 문제는 다양한 형태로 나타날 수 있습니다. 스택 추적에 잘못된 정보가 표시되거나 스택에 있는 함수의 이름을 식별하지 못할 수 있습니다. 또는 디버거 명령이 모듈, 함수, 변수, 구조 또는 데이터 형식의 이름을 이해하지 못했을 수 있습니다.

디버거가 기호를 올바르게 로드하지 않는 것으로 의심되는 경우 이 문제를 조사하기 위해 수행할 수 있는 몇 가지 단계가 있습니다.

먼저 lm(로드된 모듈 나열) 명령을 사용하여 기호 정보가 포함된 로드된 모듈 목록을 표시합니다. 이 명령의 가장 유용한 형식은 다음과 같습니다.

0:000> lml 

WinDbg를 사용하는 경우 디버그 | 모듈 메뉴 명령을 사용하면 이 정보도 볼 수 있습니다.

이러한 디스플레이에서 볼 수 있는 노트 또는 약어에 특히 주의하세요. 이에 대한 해석은 기호 상태 약어를 참조하세요.

적절한 기호 파일이 표시되지 않는 경우 가장 먼저 해야 할 일은 기호 경로를 확인하는 것입니다.

0:000> .sympath
Current Symbol Path is: d:\MyInstallation\i386\symbols\retail

기호 경로가 잘못된 경우 수정합니다. 커널 디버거를 사용하는 경우 로컬 %WINDIR%이 당신의 기호 경로에 포함되지 않도록 확인하십시오.

그런 다음 .reload(모듈 다시 로드) 명령을 사용하여 기호를 다시 로드 합니다.

0:000> .reload ModuleName 

기호 경로가 올바른 경우 dbghelp가 로드하는 기호 파일을 볼 수 있도록 노이즈 모드를 활성화해야 합니다. 그런 다음, 모듈을 다시 로드합니다. 노이즈 모드를 활성화하는 방법에 대한 자세한 내용은 기호 옵션 설정을 참조하세요.

다음은 Microsoft Windows 심볼의 불필요한 다시 로드 예입니다.

kd> !sym noisy
kd> .reload nt
 1: Kernel Version 2081 MP Checked
 2: Kernel base = 0x80400000 PsLoadedModuleList = 0x80506fa0
 3: DBGHELP: FindExecutableImageEx-> Looking for D:\MyInstallation\i386\ntkrnlmp.exe...mismatched timestamp
 4: DBGHELP: No image file available for ntkrnlmp.exe
 5: DBGHELP: FindDebugInfoFileEx-> Looking for
 6: d:\MyInstallation\i386\symbols\retail\symbols\exe\ntkrnlmp.dbg... no file
 7: DBGHELP: FindDebugInfoFileEx-> Looking for
 8: d:\MyInstallation\i386\symbols\retail\symbols\exe\ntkrnlmp.pdb... no file
 9: DBGHELP: FindDebugInfoFileEx-> Looking for d:\MyInstallation\i386\symbols\retail\exe\ntkrnlmp.dbg... OK
10: DBGHELP: LocatePDB-> Looking for d:\MyInstallation\i386\symbols\retail\exe\ntkrnlmp.pdb... OK
11: *** WARNING: symbols checksum and timestamp is wrong 0x0036a4ea 0x00361a83 for ntkrnlmp.exe

기호 처리기는 먼저 로드하려는 모듈(줄 3과 4)과 일치하는 이미지를 찾습니다. 이미지 자체가 항상 필요한 것은 아니지만 잘못된 이미지 자체가 있으면 기호 처리기가 실패하는 경우가 많습니다. 이러한 줄은 디버거가 D:\MyInstallation\i386\ntkrnlmp.exe이미지를 찾았지만 시간 날짜 스탬프가 일치하지 않음을 보여줍니다. 시간 날짜 스탬프가 일치하지 않아 검색이 계속됩니다. 다음으로 디버거는 로드된 이미지와 일치하는 .dbg 파일 및 .pdb 파일을 찾습니다. 이는 6~10줄에 있습니다. 줄 11은 기호가 로드되었지만 이미지의 시간 날짜 스탬프가 일치하지 않음을 나타냅니다(즉, 기호가 잘못됨).

기호 검색에 치명적인 오류가 발생하면 양식의 메시지가 표시됩니다.

ImgHlpFindDebugInfo(00000000, module.dll, c:\MyDir;c:\SomeDir, 0823345, 0) failed

파일 시스템 오류, 네트워크 오류 및 손상된 .dbg 파일과 같은 항목으로 인해 발생할 수 있습니다.

기호 로드 오류 진단

시끄러운 모드에서 디버거는 기호 파일을 로드할 수 없는 경우 오류 코드를 출력할 수 있습니다. .dbg 파일에 대한 오류 코드는 winerror.h에 나열됩니다. .pdb 오류 코드는 다른 소스에서 제공되며 가장 일반적인 오류는 일반 영어 텍스트로 인쇄됩니다.

winerror.h의 .dbg 파일에 대한 몇 가지 일반적인 오류 코드는 다음과 같습니다.

0xB
ERROR_BAD_FORMAT (형식 오류)

0x3
경로를 찾을 수 없습니다 (ERROR_PATH_NOT_FOUND)

0x35
ERROR_BAD_NETPATH

네트워킹 오류로 인해 기호 파일을 로드할 수 없습니다. ERROR_BAD_FORMAT 또는 ERROR_BAD_NETPATH 오류가 표시되고 네트워크의 다른 컴퓨터에서 심볼을 로드하는 경우, 심볼 파일을 호스트 컴퓨터에 복사한 다음 그 경로를 심볼 경로 설정에 추가합니다. 그런 다음 기호를 다시 로드합니다.

검색 경로 및 기호 확인

Let "c:\MyDir; c:\SomeDir"은 기호 경로를 나타냅니다. 디버그 정보는 어디에서 찾아야 하나요?

디버그 정보가 제거된 Windows의 무료 빌드와 같은 경우에는, 먼저 다음 위치에서 .dbg 파일을 찾아보세요.

c:\MyDir\symbols\exe\ntoskrnl.dbg
c:\SomeDir\symbols\exe\ntoskrnl.dbg
c:\MyDir\exe\ntoskrnl.dbg
c:\SomeDir\exe\ntoskrnl.dbg
c:\MyDir\ntoskrnl.dbg
c:\SomeDir\ntoskrnl.dbg
current-working-directory\ntoskrnl.dbg

다음으로, 다음 위치에서 .pdb 파일을 찾습니다.

c:\MyDir\symbols\exe\ntoskrnl.pdb
c:\MyDir\exe\ntoskrnl.pdb
c:\MyDir\ntoskrnl.pdb
c:\SomeDir\symbols\exe\ntoskrnl.pdb
c:\SomeDir\exe\ntoskrnl.pdb
c:\SomeDir\ntoskrnl.pdb
current-working-directory\ntoskrnl.pdb

.dbg 파일을 검색할 때 디버거는 MyDir 및 SomeDir 디렉터리를 번갈아 검색하지만, .pdb 파일을 검색할 때는 번갈아 검색하지 않습니다.

Windows XP 이상 버전의 Windows는 .dbg 기호 파일을 사용하지 않습니다. 자세한 내용은 기호 및 기호 파일을 참조하세요.

일치하지 않는 빌드

종종 업데이트되는 컴퓨터의 디버깅 실패에서 가장 일반적인 문제 중 하나는 다른 빌드에서 일치하지 않는 기호입니다. 이 문제의 일반적인 원인은 잘못된 빌드의 기호를 가리키고, 해당 기호 없이 비공개로 빌드된 이진 파일을 사용하고, 다중 프로세서 컴퓨터에서 HAL(유니프로세서 하드웨어 추상화 수준) 및 커널 기호를 사용하는 것입니다. 처음 두 항목은 단순히 이진 파일과 기호를 일치시키는 문제입니다. 세 번째는 hal*.dbg 및 ntkrnlmp.dbg의 이름을 hal.dbg 및 ntoskrnl.dbg로 변경하여 수정할 수 있습니다.

대상 컴퓨터에 설치된 Windows 빌드를 확인하려면 꼭짓점(대상 컴퓨터 버전 표시) 명령을 사용합니다.

kd> vertarget 
Windows XP Kernel Version 2505 UP Free x86 compatible
Built by: 2505.main.010626-1514
Kernel base = 0x804d0000 PsLoadedModuleList = 0x80548748
Debug session time: Mon Jul 02 14:41:11 2001
System Uptime: 0 days 0:04:53 

기호 테스트

기호 테스트가 더 어렵습니다. 디버거에서 스택 추적을 확인하고 디버그 출력이 올바른지 확인하는 작업이 포함됩니다. 다음은 시도할 한 가지 예입니다.

kd> u videoprt!videoportfindadapter2
Loading symbols for 0xf2860000     videoprt.sys ->   videoprt.sys

VIDEOPRT!VideoPortFindAdapter2:
f2856f42 55               push    ebp
f2856f43 8bec             mov     ebp,esp
f2856f45 81ecb8010000     sub     esp,0x1b8
f2856f4b 8b4518           mov     eax,[ebp+0x18]
f2856f4e 53               push    ebx
f2856f4f 8365f400         and     dword ptr [ebp-0xc],0x
f2856f53 8065ff00         and     byte ptr [ebp-0x1],0x0
f2856f57 56               push    esi

u 명령은 videoprt.sysvideoportfindadapter 문자열을 언어셈블합니다. 밀어넣기 및 mov와 같은 일반적인 스택 명령이 스택에 표시되므로 디버거에서 기호가 올바르습니다. 대부분의 함수는 기본 포인터(ebp) 또는 스택 포인터(esp)를 사용하여 추가, 하위 또는 푸시 작업으로 시작합니다.

기호가 제대로 작동하지 않을 때는 보통 명확합니다. Glintmp.sys 함수가 Glintmp 옆에 나열되지 않으므로 이 예제에 기호가 없습니다.

kd> kb
Loading symbols for 0xf28d0000     videoprt.sys ->   videoprt.sys
Loading symbols for 0xf9cdd000      glintmp.sys ->   glintmp.sys
*** ERROR: Symbols could not be loaded for glintmp.sys
ChildEBP RetAddr  Args to Child
f29bf1b0 8045b5fa 00000001 0000a100 00000030 ntoskrnl!RtlpBreakWithStatusInstruction
f29bf1b0 8044904e 00000001 0000a100 00000030 ntoskrnl!KeUpdateSystemTime+0x13e
f29bf234 f28d1955 f9b7d000 ffafb2dc f9b7d000 ntoskrnl!READ_REGISTER_ULONG+0x6
f29bf248 f9cde411 f9b7d000 f29bf2b0 f9ba0060 VIDEOPRT!VideoPortReadRegisterUlong+0x27
00000002 00000000 00000000 00000000 00000000 glintMP+0x1411 [No function listed.] 

이 스택 추적에 대해 잘못된 빌드 기호가 로드되었습니다. 처음 두 호출에 대해 나열된 함수가 없는 방법을 확인합니다. 이 스택 추적은 win32k.sys 사각형 그리기 문제처럼 보입니다.

1: kd> 
1: kd> kb                      [Local        9:50 AM]
Loading symbols for 0xf22b0000       agpcpq.sys ->   agpcpq.sys
*** WARNING: symbols checksum is wrong 0x0000735a 0x00000000 for agpcpq.sys
*** ERROR: Symbols could not be loaded for agpcpq.sys
Loading symbols for 0xa0000000       win32k.sys ->   win32k.sys
*** WARNING: symbols checksum is wrong 0x00191a41 0x001995a9 for win32k.sys
ChildEBP RetAddr  Args to Child
be682b18 f22b372b 82707128 f21c1ffc 826a70f8 agpCPQ+0x125b [No function listed.]
be682b4c a0140dd4 826a72f0 e11410a8 a0139605 agpCPQ+0x372b [No function listed.]
be682b80 a00f5646 e1145100 e1cee560 e1cee560 win32k!vPatCpyRect1_6x6+0x20b
00000001 00000000 00000000 00000000 00000000 win32k!RemoteRedrawRectangle+0x32 

올바른 스택 추적은 다음과 같습니다. 문제는 정말 AGP440.sys에 있습니다. 스택 추적에 표시되는 첫 번째 항목은 일반적으로 오류가 발생합니다. win32k.sys 사각형 오류가 사라졌습니다.

1: kd> kb                      [Local        9:49 AM]
ChildEBP RetAddr  Args to Child
be682b18 f22b372b 82707128 f21c1ffc 826a70f8 agpCPQ!AgpReleaseMemory+0x88
be682b30 f20a385c 82703638 e183ec68 00000000 agpCPQ!AgpInterfaceReleaseMemory+0x8b
be682b4c a0140dd4 826a72f0 e11410a8 a0139605 VIDEOPRT!AgpReleasePhysical+0x44
be682b58 a0139605 e1cee560 e11410a8 a00e5f0a win32k!OsAGPFree+0x14
be682b64 a00e5f0a e1cee560 e11410a8 e1cee560 win32k!AGPFree+0xd
be682b80 a00f5646 e1145100 e1cee560 e1cee560 win32k!HeapVidMemFini+0x49
be682b9c a00f5c20 e1cee008 e1cee008 be682c0c win32k!vDdDisableDriver+0x3a
be682bac a00da510 e1cee008 00000000 be682c0c win32k!vDdDisableDirectDraw+0x2d
be682bc4 a00da787 00000000 e1843df8 e1843de8 win32k!PDEVOBJ__vDisableSurface+0x27
be682bec a00d59fb 00000000 e1843de8 00000000 win32k!PDEVOBJ__vUnreferencePdev+0x204
be682c04 a00d7421 e1cee008 82566a98 00000001 win32k!DrvDestroyMDEV+0x30
be682ce0 a00a9e7f e1843e10 e184a008 00000000 win32k!DrvChangeDisplaySettings+0x8b3
be682d20 a008b543 00000000 00000000 00000000 win32k!xxxUserChangeDisplaySettings+0x106
be682d48 8045d119 00000000 00000000 00000000 win32k!NtUserChangeDisplaySettings+0x48
be682d48 77e63660 00000000 00000000 00000000 ntkrnlmp!KiSystemService+0xc9 

유용한 명령 및 확장

다음 명령 및 확장은 기호 문제를 추적하는 데 유용할 수 있습니다.

lm(로드된 모듈 나열)
모든 모듈을 나열하고 이러한 모듈에 있는 모든 기호의 로드 상태를 제공합니다.

!dh image-header-base
image-header-base에서 시작하는 로드된 이미지에 대한 헤더 정보를 표시합니다.

.reload /n
모든 커널 기호를 다시 로드합니다.

.reload [이미지 이름]
(CDB 또는 WinDbg만 해당) 이미지 이미지 이름에 대한 기호를 다시 로드합니다. 이미지 이름을 지정하지 않으면 모든 이미지에 대한 기호를 다시 로드합니다. (기호 경로가 변경된 후 기호를 다시 로드해야 합니다.)

!sym noisy
기호 로드에 대한 자세한 정보 표시 모드를 켭니다. 모듈 로드에 대한 정보를 가져오는 데 사용할 수 있습니다. 자세한 내용은 기호 옵션 설정을 참조하세요.

.sympath [new-symbol-path]
새 기호 경로를 설정하거나 현재 기호 경로를 표시합니다. 자세한 내용은 기호 경로를 참조하세요.

커널 기호가 올바르지만 전체 스택을 가져오지 않는 경우 다음 명령도 유용할 수 있습니다.

X *!
현재 기호가 로드된 모듈이 나열됩니다. 커널 기호가 올바른 경우 유용합니다.

.reload /user
그러면 모든 사용자 모드 기호가 다시 로드됩니다. 이 작업은 한 프로세스가 실행되는 동안 기호가 로드되고 나중에 다른 프로세스에서 중단이 발생한 경우 커널 디버깅을 수행하는 동안 필요합니다. 이 경우 이 명령을 실행하지 않으면 새 프로세스의 사용자 모드 기호가 로드되지 않습니다.

X wdmaud!*start\*
이름에 "start" 문자열이 포함된 wdmaud 모듈의 기호만 나열됩니다. 이것은 wdmaud의 모든 기호를 강제로 다시 로드하지만 "시작"을 가진 기호만 표시한다는 장점이 있습니다. (즉, 목록이 더 짧게 나타나지만, 항상 "start"가 포함된 기호가 있으므로 로딩이 완료되었는지를 확인하는 몇 가지 검증 단계가 있을 것입니다.)

기호를 확인하는 다른 유용한 기술 중 하나는 코드의 언셈블입니다. 대부분의 함수는 기본 포인터(ebp) 또는 스택 포인터(esp 또는 sp)를 사용하여 추가, 하위 또는 푸시 작업으로 시작합니다. 스택의 일부 함수(오프셋 0부터)를 언셈블 해제(U 함수)하여 기호를 확인합니다.

네트워크 및 포트 문제

기호 파일 및 디버거에 연결하는 동안 문제가 발생합니다. 문제가 발생할 경우 유의해야 할 몇 가지 사항은 다음과 같습니다.

  • 테스트 시스템에서 디버그 케이블이 연결된 COM 포트를 확인합니다.

  • 테스트 시스템의 boot.ini 설정을 확인합니다. /debug 스위치를 찾고 전송 속도 및 COM 포트 설정을 확인합니다.

  • 네트워크를 통해 기호 파일에 액세스하는 경우 네트워크 문제가 디버깅을 방해할 수 있습니다.

  • 이름이 같은 .dll 및 .sys 파일(예: mga64.sys 및 mga64.dll)은 기호 트리의 적절한 디렉터리로 분리되지 않은 경우 디버거를 혼동합니다.

  • 커널 디버거는 항상 빌드 기호 파일을 프라이빗 기호 파일로 바꾸는 것을 좋아하지 않습니다. 기호 경로를 다시 확인하고 잘못된 동작 기호에서 .reloadFileName 을 수행합니다. !dlls 명령은 경우에 따라 유용합니다.

질문 및 오해

Q: 기호를 로드했지만 스택이 잘못된 것 같습니다. 디버거가 고장 났나요?

A: 꼭 그런 건 아니에요. 문제의 가장 가능성이 큰 원인은 잘못된 기호가 있다는 것입니다. 이 섹션에 설명된 단계를 진행하여 유효한 기호를 로드했는지 여부를 확인합니다. 일부 항목이 작동하기 때문에 유효한 기호가 있다고 가정하지 마십시오. 예를 들어 dd nt!ntbuildnumber 또는 잘못된 기호가 있는 u nt!KeInitializeProcess를 실행할 수 있을지도 모릅니다. 위에서 설명한 절차를 사용하여 올바른지 확인합니다.

Q: 디버거가 여전히 잘못된 기호로 작동합니까?

A: 그렇기도 하고 그렇지 않기도 하고. 종종 엄격하게 일치하지 않는 기호를 무사히 사용할 수 있습니다. 예를 들어 이전 Windows 빌드의 기호는 종종 특정 경우에 작동하지만, 언제 작동하는지와 그렇지 않을 때에 대한 규칙은 없습니다.

Q: 커널 디버거에서 중지되었으며 사용자 모드 프로세스에 대한 기호를 보려고 합니다. 나는 그것을 할 수 있습니까?

A: 주로. 커널 디버거가 각 프로세스에 대한 모듈 로드를 추적하기에 충분한 정보를 유지하지 못하지만 합리적인 해결 방법이 있기 때문에 이 시나리오에 대한 지원이 부족합니다. 사용자 모드 모듈에 대한 기호를 로드하려면 .reload -user 명령을 실행합니다. 그러면 현재 컨텍스트에 대한 사용자 모드 모듈이 로드됩니다.

Q: 다음 메시지는 무엇을 의미하나요?

*** WARNING: symbols checksum and timestamp is wrong 0x0036d6bf 0x0036ab55 for ntkrnlmp.exe

A: 이는 ntkrnlmp.exe 대한 기호가 잘못됨을 의미합니다.