버그 검사 콜백 데이터 읽기

많은 드라이버가 콜백 루틴을 검사 버그를 제공합니다. 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는 중지 프로세스의 특정 부분을 반복하지 않습니다. 예를 들어 두 번째 크래시 덤프 파일을 작성하지 않습니다. 파란색 화면에 표시되는 중지 코드는 두 번째 버그 검사 코드입니다. 커널 디버거가 연결된 경우 두 버그 검사에 대한 메시지가 일반적으로 표시됩니다.