Post-initialization is the phase of the crash dump process in which final initialization occurs before the crash dump stack is actually used to carry out dump file creation or system hibernation.  This phase is depicted in the beige box in the illustration below.



Post-initialization is triggered by a bugcheck (a faulty operation in kernel mode code that results in a system crash, i.e, blue screen of death) or a power event to transition the machine into hibernation.  For crashes, the kernel’s KeBugCheck2 function is called either directly by a driver or indirectly as a result of some fault or trap.  KeBugCheck2 calls IoWriteCrashDump, which utilizes crashdmp.sys’s callback table and the global control block structure setup during pre-initialization to write the crash dump file.

Post-initialization is the process of finalizing certain data structures before the kernel (through crashdmp.sys) can send I/O requests through the crash dump stack.  The primary tasks for this phase are:

  • Notify crash dump filter drivers of the crash/hibernate event by invoking their DumpStart callback
  • Notify the dump port driver to prepare for I/O requests by calling its DriverEntry routine
    • It in turn stores pointers to its read/write routines in crashdmp.sys’s control block, making them available for I/O requests
  • Store debugging information (such as bugcheck code and register state) in a context structure, to be used in diagnosis when the crash dump file is analyzed.
  • Generate dump data of the preconfigured type (kernel dump, minidump, triage, etc)

The call stack for post-initialization is shown below.

  • nt!KeBugCheck2()
    • nt!IoWriteCrashDump()
      • crashdmp!CrashDmpWrite() callback table entry
        • crashdmp!CrashdmpInitDumpStack()
          • crashdmp!StartFilterDrivers() – calls the DumpStart callback of each crash dump filter driver
          • crashdmp!InitializeDumpDriver() – calls the dump driver entry point; calls the DiskDumpOpen callback provided by the dump port driver; fills dump context structure with callback pointers CrashdmpWriteRoutine, CrashdmpWritePendingRoutine, CrashdmpFinishRoutine

With post-initialization complete, the kernel then calls the entry in the crashdmp.sys callback table to issue write requests to the dump port driver.  This is done iteratively until all data is written to the dump or hibernation file.  Crash dump filter drivers have an opportunity to modify the contents of the dump or hibernation file inline (example use is a whole disk encryption driver).  The call stack for the dump file creation is shown below.

  • nt!KeBugCheck2()
    • nt!IoWriteCrashDump()
      • crashdmp!CrashDmpWrite() callback table entry
        • crashdmp!CrashdmpInitDumpStack()
          • crashdmp!DumpWrite() – creates dump file based on configuration:
            • crashdmp!FillDumpHeader()
            • Calls one of
              • crashdmp!WriteFullDump()
              • crashdmp!WriteKernelDump()
              • crashdmp!WriteMiniDump()
          • crashdmp!InvokeSecondaryDumpCallbacks() – Invokes all BugCheckSecondaryDumpDataCallback callbacks to allow drivers to append data to the completed crash dump file.
          • crashdmp!InvokeDumpCallbacks() – Invokes all BugCheckDumpIoCallback callbacks, informing them crash dump is complete.

Once this is finished, the system reboots.

Note that some aspects of the process described on this page are specific to Vista+ operating systems.  Windows XP behaves a little differently (in fact there is no crashdmp.sys driver).  For more details, please see one of my whitepapers listed on the Publications page.

%d bloggers like this: