KBUGCHECK_REASON_CALLBACK_ROUTINE callback function

Driver-implemented callback functions that the system executes when it issues a bug check.

The BugCheckAddPagesCallback routine adds one or more pages of data to the crash dump file when the operating system issues a bug check.

The BugCheckDumpIoCallback routine is executed each time the system writes data to a crash dump file.

The BugCheckSecondaryDumpDataCallback routine provides data to the system to append to the crash dump file when the system issues a bug check.

Syntax

KBUGCHECK_REASON_CALLBACK_ROUTINE KbugcheckReasonCallbackRoutine;

void KbugcheckReasonCallbackRoutine(
  KBUGCHECK_CALLBACK_REASON Reason,
  _KBUGCHECK_REASON_CALLBACK_RECORD *Record,
  PVOID ReasonSpecificData,
  ULONG ReasonSpecificDataLength
)
{...}

Parameters

Reason

Specifies the reason for the call to the callback routine. This value can be one of the following as defined in KBUGCHECK_CALLBACK_REASON

  • KbCallbackAddPages: The purpose of the callback function is to enable the driver to add pages of data to the crash dump file.
  • KbCallbackDumpIo: This callback function is executed each time the system writes data to a crash dump file.
  • KbCallbackSecondaryDumpData: This callback function provides data to the system to append to the crash dump file when the system issues a bug check.

Record

A pointer to the KBUGCHECK_REASON_CALLBACK_RECORD structure that the driver supplied when it registered this callback. For more information, see the description of the CallbackRecord parameter in KeRegisterBugCheckCallback.

ReasonSpecificData

A pointer to a KBUGCHECK_ADD_PAGES structure. This pointer is cast to type PVOID. Certain members of this structure are filled in by the operating system before it calls the callback routine, and other members must be filled in by the callback routine. For more information, see the following Remarks section.

ReasonSpecificDataLength

Specifies the size, in bytes, of the buffer that the ReasonSpecificData parameter points to.

  • KbCallbackAddPages: sizeof(KBUGCHECK_ADD_PAGES).
  • KbCallbackDumpIo: sizeof(KBUGCHECK_DUMP_IO).
  • KbCallbackSecondaryDumpData: sizeof(KBUGCHECK_SECONDARY_DUMP_DATA).

Return Value

None.

Remarks

About implementing BugCheckAddPagesCallback: A kernel-mode driver can implement a BugCheckAddPagesCallback callback routine to add one or more pages of data to a crash dump file when a bug check occurs. To register this routine with the operating system, the driver calls the KeRegisterBugCheckReasonCallback routine. Before the driver unloads, it must call the KeDeregisterBugCheckReasonCallback routine to remove the registration.

Starting with Windows 8, a registered BugCheckAddPagesCallback routine is called during a kernel memory dump or a complete memory dump. In earlier versions of Windows, a registered BugCheckAddPagesCallback routine is called during a kernel memory dump, but not during a complete memory dump. By default, a kernel memory dump includes only the physical pages that are being used by the Windows kernel at the time that the bug check occurs, whereas a complete memory dump includes all of the physical memory that is used by Windows. A complete memory dump does not, by default, include physical memory that is used by the platform firmware.

Your BugCheckAddPagesCallback routine can supply driver-specific data to add to the dump file. For example, for a kernel memory dump, this additional data can include physical pages that are not mapped to the system address range in virtual memory but that contain information that can help you to debug your driver. The BugCheckAddPagesCallback routine might add to the dump file any driver-owned physical pages that are unmapped or that are mapped to user-mode addresses in virtual memory.

When a bug check occurs, the operating system calls all the registered BugCheckAddPagesCallback routines to poll drivers for data to add to the crash dump file. Each call adds one or more pages of contiguous data to the crash dump file. A BugCheckAddPagesCallback routine can supply either a virtual address or a physical address for the starting page. If more than one page is supplied during a call, the pages are contiguous in either virtual or physical memory, depending on whether the starting address is virtual or physical. To supply noncontiguous pages, the BugCheckAddPagesCallback routine can set a flag in the KBUGCHECK_ADD_PAGES structure to indicate that it has additional data and has to be called again. For more information, see KBUGCHECK_ADD_PAGES.

Unlike a BugCheckSecondaryDumpDataCallback routine, which appends data to the secondary crash dump region, a BugCheckAddPagesCallback routine adds pages of data to the primary crash dump region. During debugging, primary crash dump data is easier to access than secondary crash dump data.

Before the operating system calls a BugCheckAddPagesCallback routine, it fills in the BugCheckCode member of the KBUGCHECK_ADD_PAGES structure that ReasonSpecificData points to. During the call, the BugCheckAddPagesCallback routine must set the values of the Flags, Address, and Count members of this structure. If the BugCheckAddPagesCallback routine is called more than one time, the operating system preserves the value that the callback routine wrote to the Context member in the previous call. Before the first call, the operating system initializes Context to NULL.

A BugCheckAddPagesCallback routine is very restricted in the actions it can take. For more information, see Writing a Bug Check Callback Routine.

About implementing BugCheckDumpIoCallback: The driver's BugCheckDumpIoCallback routine is called each time data is written to the crash dump file. The system passes, in the ReasonSpecificData parameter, a description of the data being written. The Buffer member points to the current data, and the BufferLength member specifies its length. The Type member indicates the type of data currently being written, such as dump file header information, memory state, or data provided by a driver. For a description of the possible types of information, see KBUGCHECK_DUMP_IO_TYPE.

The system can write the crash dump file either sequentially, or out of order. If the system is writing the crash dump file sequentially, then the Offset member of ReasonSpecificData is -1; otherwise, Offset is set to the current offset, in bytes, in the crash dump file.

When the system writes the file sequentially, it calls each BugCheckDumpIoCallback routine one or more times when writing the header information (Type = KbDumpIoHeader), one or more times when writing the main body of the crash dump file (Type = KbDumpIoBody), and one or more times when writing the secondary dump data (Type = KbDumpIoSecondaryDumpData). Once the system has completed writing the crash dump file, it calls the callback with Buffer = NULL, BufferLength = 0, and Type = KbDumpIoComplete.

The main purpose of a BugCheckDumpIoCallback routine is to allow system crash dump data to be written to devices other than the disk. For example, a device that monitors system state can use the callback to report that the system has issued a bug check, and to provide a crash dump for analysis.

Use KeRegisterBugCheckReasonCallback to register a BugCheckDumpIoCallback routine. A driver can subsequently remove the callback by using the KeDeregisterBugCheckReasonCallback routine. If the driver can be unloaded, it must remove any registered callbacks in its Unload routine.

A BugCheckDumpIoCallback routine is strongly restricted in the actions it can take. For more information, see Writing a Bug Check Callback Routine.

About implementing BugCheckSecondaryDumpDataCallback: The system uses BugCheckSecondaryDumpDataCallback routines to poll drivers for crash dump data.

The system sets the InBuffer, InBufferLength, OutBuffer, and MaximumAllowed members of the KBUGCHECK_SECONDARY_DUMP_DATA structure that ReasonSpecificData points to. The MaximumAllowed member specifies the maximum amount of dump data the routine can provide.

The value of the OutBuffer member determines whether the system is requesting the size of the driver's dump data, or the data itself, as follows:

  • If the OutBuffer member of KBUGCHECK_SECONDARY_DUMP_DATA is NULL, the system is only requesting size information. The BugCheckSecondaryDumpDataCallback routine fills in the OutBuffer and OutBufferLength members.

  • If the OutBuffer member of KBUGCHECK_SECONDARY_DUMP_DATA equals the InBuffer member, the system is requesting the driver's secondary dump data. The BugCheckSecondaryDumpDataCallback routine fills in the OutBuffer and OutBufferLength members, and writes the data to the buffer specified by OutBuffer.

The InBuffer member of KBUGCHECK_SECONDARY_DUMP_DATA points to a small buffer for the routine's use. The InBufferLength member specifies the size of the buffer. If the amount of data to be written is less than InBufferLength, the callback routine can use this buffer to supply the crash dump data to the system. The callback routine then sets OutBuffer to InBuffer and OutBufferLength to the actual amount of data written to the buffer.

A driver that must write an amount of data that is larger than InBufferLength can use its own buffer to provide the data. This buffer must have been allocated before the callback routine is executed, and must reside in resident memory (such as nonpaged pool). The callback routine then sets OutBuffer to point to the driver's buffer, and OutBufferLength to the amount of data in the buffer to be written to the crash dump file.

In Windows XP and Windows Server 2003, if OutBuffer is set to point to a driver-allocated buffer, the buffer must begin on a page-aligned boundary in memory. Otherwise, no data is written to the secondary data area of the crash dump file. In Windows Vista and later versions of Windows, there is no such alignment requirement.

Each block of data to be written to the crash dump file is tagged with the value of the Guid member of KBUGCHECK_SECONDARY_DUMP_DATA. The GUID used must be unique to the driver. To display the secondary dump data corresponding to this GUID, you can use the .enumtag command or the IDebugDataSpaces3::ReadTagged method in a debugger extension. For information about debuggers and debugger extensions, see Windows Debugging.

A driver can write multiple blocks with the same GUID to the crash dump file, but this is very poor practice, because only the first block will be accessible to the debugger. Drivers that register multiple BugCheckSecondaryDumpDataCallback routines should allocate a unique GUID for each callback.

Use KeRegisterBugCheckReasonCallback to register a BugCheckSecondaryDumpDataCallback routine. A driver can subsequently remove the callback routine by using the KeDeregisterBugCheckReasonCallback routine. If the driver can be unloaded, then it must remove any registered callback routines in its Unload routine.

A BugCheckSecondaryDumpDataCallback is very restricted in the actions it can take. For more information, see Writing a Bug Check Callback Routine.

Examples

To define the callback routine, you must first provide a function declaration that identifies the type of callback routine you're defining. Windows provides a set of callback function types for drivers. Declaring a function using the callback function types helps Code Analysis for Drivers, Static Driver Verifier (SDV), and other verification tools find errors, and it's a requirement for writing drivers for the Windows operating system.

For example, to define a BugCheckAddPagesCallback callback routine that is named MyBugCheckAddPagesCallback, use the KBUGCHECK_REASON_CALLBACK_ROUTINE type as shown in this code example:

KBUGCHECK_REASON_CALLBACK_ROUTINE MyBugCheckAddPagesCallback;
Then, implement your callback routine as follows:
_Use_decl_annotations_
VOID
  MyBugCheckAddPagesCallback(
    KBUGCHECK_CALLBACK_REASON  Reason,
    struct _KBUGCHECK_REASON_CALLBACK_RECORD  *Record,
    PVOID  ReasonSpecificData,
    ULONG  ReasonSpecificDataLength 
    )
  {
      // Function body
  }
The KBUGCHECK_REASON_CALLBACK_ROUTINE function type is defined in the Wdm.h header file. To more accurately identify errors when you run the code analysis tools, be sure to add the Use_decl_annotations annotation to your function definition. The Use_decl_annotations annotation ensures that the annotations that are applied to the KBUGCHECK_REASON_CALLBACK_ROUTINE function type in the header file are used. For more information about the requirements for function declarations, see Declaring Functions by Using Function Role Types for WDM Drivers. For information about Use_decl_annotations, see Annotating Function Behavior.

Requirements

   
Minimum supported client Supported starting with Windows Server 2008.
Target Platform Desktop
Header wdm.h (include Wdm.h, Ntddk.h, Ntifs.h)
IRQL Called at HIGH_LEVEL.

See Also

BugCheckSecondaryDumpDataCallback

KBUGCHECK_ADD_PAGES

KBUGCHECK_CALLBACK_REASON

KBUGCHECK_REASON_CALLBACK_RECORD

KeDeregisterBugCheckReasonCallback

KeRegisterBugCheckReasonCallback