다음을 통해 공유


버그 검사 콜백 데이터 읽기

많은 드라이버가 콜백 루틴을 검사 버그를 제공합니다. Windows에서 버그 검사 발급하면 시스템을 종료하기 전에 이러한 루틴을 호출합니다. 이러한 루틴은 콜백 데이터보조 콜백 데이터라고 하는 메모리 영역을 지정하고 쓸 수 있습니다.

BugCheckCallback 사용 KBUGCHECK_CALLBACK_ROUTINE
이 루틴에서 작성한 데이터는 콜백 데이터의 일부가 됩니다. 데이터는 크래시 덤프 파일에 포함되지 않습니다.

BugCheckSecondaryDumpDataCallback 사용 KBUGCHECK_REASON_CALLBACK_ROUTINE
이 루틴에서 작성한 데이터는 보조 콜백 데이터의 일부가 됩니다. 데이터는 크래시 덤프 파일에 포함됩니다.

BugCheckAddPagesCallback 사용 KBUGCHECK_REASON_CALLBACK_ROUTINE
이 루틴에 지정된 페이지는 콜백 데이터의 일부가 됩니다. 해당 페이지의 데이터는 크래시 덤프 파일에 포함됩니다.

디버거에서 사용할 수 있는 콜백 및 보조 콜백 데이터의 양은 다음과 같은 몇 가지 요인에 따라 달라집니다.

  • 크래시된 시스템의 라이브 디버깅을 수행하는 경우 BugCheckCallback 에서 이미 작성했거나 BugCheckAddPagesCallback 으로 지정된 콜백 데이터를 사용할 수 있습니다. 보조 콜백 데이터는 고정 메모리 위치에 저장되지 않으므로 사용할 수 없습니다.

  • 전체 메모리 덤프 또는 커널 메모리 덤프를 디버깅하는 경우 BugCheckAddPagesCallback 으로 지정된 콜백 데이터와 BugCheckSecondaryDumpDataCallback 에서 작성한 보조 콜백 데이터를 사용할 수 있습니다. BugCheckCallback에서 작성한 콜백 데이터를 사용할 수 없습니다.

  • 작은 메모리 덤프를 디버깅하는 경우 콜백 데이터를 사용할 수 없습니다. 보조 콜백 데이터를 사용할 수 있습니다.

이러한 다양한 덤프 파일 크기에 대한 자세한 내용은 Kernel-Mode 덤프 파일의 종류를 참조하세요.

콜백 데이터 표시

버그 검사 콜백 데이터를 표시하려면 !bugdump 확장을 사용할 수 있습니다.

매개 변수가 없으면 !bugdump 는 모든 콜백에 대한 데이터를 표시합니다.

하나의 특정 콜백 루틴에 대한 데이터를 보려면 !bugdump구성 요소를 사용합니다. 여기서 Component 은 해당 루틴이 등록되었을 때 KeRegisterBugCheckCallback 에 전달된 것과 동일한 매개 변수입니다.

보조 콜백 데이터 표시

보조 콜백 데이터를 표시하는 방법에는 두 가지가 있습니다. .enumtag 명령을 사용하거나 고유한 디버거 확장을 작성할 수 있습니다.

보조 콜백 데이터의 각 블록은 GUID 태그로 식별됩니다. 이 태그는 BugCheckSecondaryDumpDataCallback에 전달된 (KBUGCHECK_SECONDARY_DUMP_DATA)ReasonSpecificData 매개 변수의 Guid 필드에 의해 지정됩니다.

.enumtag(보조 콜백 데이터 열거) 명령은 매우 정확한 계측기가 아닙니다. 모든 보조 데이터 블록을 표시하여 태그를 표시한 다음, 데이터를 16진수 및 ASCII 형식으로 표시합니다. 일반적으로 보조 데이터 블록에 실제로 사용되는 태그를 확인하는 데만 유용합니다.

이 데이터를 보다 실용적인 방식으로 사용하려면 고유한 디버거 확장을 작성하는 것이 좋습니다. 이 확장은 dbgeng.h 헤더 파일에서 메서드를 호출해야 합니다. 자세한 내용은 새 디버거 확장 작성을 참조하세요.

보조 데이터 블록의 GUID 태그를 알고 있는 경우 확장 프로그램에서 IDebugDataSpaces3::ReadTagged 메서드를 사용하여 데이터에 액세스해야 합니다. 프로토타입은 다음과 같습니다.

STDMETHOD(ReadTagged)(
    THIS_
    IN LPGUID Tag,
    IN ULONG Offset,
    OUT OPTIONAL PVOID Buffer,
    IN ULONG BufferSize,
    OUT OPTIONAL PULONG TotalSize
    ) PURE; 

다음은 이 메서드를 사용하는 방법의 예입니다.

UCHAR RawData[MY_DATA_SIZE];
GUID MyGuid = .... ;

Success = DataSpaces->ReadTagged(  &MyGuid,  0,  RawData,
                                   sizeof(RawData),  NULL); 

너무 작은 BufferSize 를 제공하는 경우 ReadTagged 는 성공하지만 요청된 바이트 수만 버퍼에 씁니다. 너무 큰 BufferSize 를 지정하면 ReadTagged 가 성공하지만 실제 블록 크기만 버퍼에 씁니다. TotalSize에 대한 포인터를 제공하는 경우 ReadTagged는 이 포인터를 사용하여 실제 블록의 크기를 반환합니다. 블록에 액세스할 수 없는 경우 ReadTagged는 오류 상태 코드를 반환합니다.

두 블록에 동일한 GUID 태그가 있는 경우 첫 번째 일치 블록이 반환되고 두 번째 블록에 액세스할 수 없습니다.

블록의 GUID 태그를 잘 모르는 경우 IDebugDataSpaces3::StartEnumTagged, IDebugDataSpaces3::GetNextTaggedIDebugDataSpaces3::EndEnumTagged 메서드를 사용하여 태그가 지정된 블록을 열거할 수 있습니다. 프로토타입은 다음과 같습니다.

STDMETHOD(StartEnumTagged)(
    THIS_
    OUT PULONG64 Handle
    ) PURE;

STDMETHOD(GetNextTagged)(
    THIS_
    IN ULONG64 Handle,
    OUT LPGUID Tag,
    OUT PULONG Size
    ) PURE;

STDMETHOD(EndEnumTagged)(
    THIS_
    IN ULONG64 Handle
    ) PURE;

콜백 루틴 디버깅

콜백 루틴 자체를 디버그할 수도 있습니다. 콜백 루틴 내의 중단점은 다른 중단점과 마찬가지로 작동합니다.

콜백 루틴으로 인해 두 번째 버그 검사 발생하는 경우 이 새 버그 검사 먼저 처리됩니다. 그러나 Windows는 중지 프로세스의 특정 부분을 반복하지 않습니다. 예를 들어 두 번째 크래시 덤프 파일을 작성하지 않습니다. 파란색 화면에 표시되는 중지 코드는 두 번째 버그 검사 코드입니다. 커널 디버거가 연결된 경우 두 버그 검사에 대한 메시지가 일반적으로 표시됩니다.