- Properly configuring dump types and event logging is key to accurately diagnosing any BSOD in Windows.
- WinDbg, along with the Microsoft symbol path and commands such as !analyze -v, .bugcheck, !thread or !irp, allows you to identify drivers and resources involved in the failure.
- Errors such as RESOURCE_NOT_OWNED, DRIVER_IRQL_NOT_LESS_OR_EQUAL or MULTIPLE_IRP_COMPLETE_REQUESTS usually reveal driver conflicts and are clarified by detailed IRP and stack analysis.
- The combined use of Driver Verifier, Sysinternals, and good troubleshooting practices helps isolate faulty hardware or software and drastically reduce blue screens.

When a Windows computer freezes with a blue screen, it's not just annoying: there's often valuable information hidden in the memory dump that tells us exactly what happened in the kernel. Instead of blaming the RAM, the BIOS, or immediately reformatting, it's worth learning how to read that data.
With a little practice, tools like WinDbg and functions like !analyze -v, .bugcheck, or the correct use of symbols allow us to go from "I get a blue screen error" to "I know which driver, resource, or device caused the BSOD." In this article, we'll break down, step by step and in considerable detail, how to analyze a BSOD using its kernel dump, what types of dumps exist, how to prepare everything, and which commands to use to get the most out of the analysis.
What is a BSOD and what information does it contain?
When Windows encounters a condition that compromises system integrity and cannot recover safely, it makes an internal kernel call called KeBugCheckEx . This call is what triggers the infamous Blue Screen of Death (BSOD).
KeBugCheckEx always receives five arguments: a STOP code (bugcheck code) and four additional parameters that provide technical context to the error. This same data is what we can then consult.
- On the blue screen classic, if the system is not configured to restart automatically.
- In the Windows event log, within the Event Viewer (system log).
- In the memory dump file (minidump, kernel dump or full dump), using WinDbg and commands like
!analyze -vo.bugcheck.
Each bug check code has a symbolic name and an associated hexadecimal value . For example, the bug check DRIVER_POWER_STATE_FAILURE has the code 0x9F , while RESOURCE_NOT_OWNED corresponds to 0xE3 . These codes and their parameters are documented in the Microsoft bug check code reference, which you should always keep handy.
In addition to the code, the blue screen may display the name of a potentially involved .sys driver . If it's a third-party driver (antivirus, network card, graphics card, etc.), we often have a clear suspect. If a generic system component (ntoskrnl.exe, win32k.sys, etc.) appears, or if nothing appears at all, we'll need to perform a memory dump and use WinDbg to investigate further.
Types of memory dumps in Windows
To analyze a BSOD in any depth, we need Windows to generate a memory dump file (DMP) when the failure occurs. This file captures the system state at the time of the error and can be of different types.
In the "Startup and Recovery" options (right-click on "This PC / My Computer" → Properties → Advanced system settings → "Advanced" tab → "Settings" button under "Startup and Recovery"), you can choose between several types of dumps. Each has its advantages and disadvantages.
Small Memory Dump (Minidump)
The minidump format is the smallest (around 64 KB) and also the most limited for advanced debugging. However, it remains useful for obtaining a quick diagnosis in many BSOD scenarios.
A minidump stores, among other data:
- The stop message, the bugcheck code, and its parameters.
- The processor context (PRCB) of the processor that caused the failure.
- Kernel process information (EPROSS) of the active process at the time of the crash.
- Thread information in kernel (ETHREAD) of the thread that caused the crash.
- The kernel-mode call stack for that thread (up to 16 KB).
- List of loaded drivers at the time of the ruling.
- List of loaded and downloaded modules.
- A debugging data block with basic system information.
This type of dump is typically saved in %SystemRoot%\Minidump (for example, C:\Windows\Minidump ). For many basic support or diagnostic cases, a minidump thoroughly analyzed with !analyze -v may be more than sufficient.
Kernel Memory Dump
The kernel memory dump contains the kernel memory contents at the time of the crash, excluding user process memory spaces. It offers a valuable balance between size and detail and is often the recommended option for diagnosing most BSODs.
This dump is saved as MEMORY.DMP in %SystemRoot% (by default, C:\Windows\MEMORY.DMP ). Its size depends on the memory used by the kernel, but it is usually much larger than a minidump and much more manageable than a full dump.
Complete Memory Dump
A full memory dump saves virtually all the contents of RAM at the time of the error: kernel, user processes, etc. It is the most detailed but also the one that takes up the most space and is the most demanding in terms of configuration.
For a complete dump to be valid, several requirements must be met:
- El paging file must be in the same partition where Windows is installed.
- there must be disk space at least equal to the size of the physical memory of the machine.
- Do not move the pagefile to another physical disk if you want to avoid corrupted dumps.
In production environments with a lot of RAM, a full dump may be impractical, but for very complex or intermittent cases it can make all the difference in locating the problem.
Configure Windows to capture and log BSODs
Before we get down to business with WinDbg, it is essential to ensure that the system is correctly generating the dumps and logging the blue screen event.
In the "Start and Recovery" window we find several relevant options:
- Write an event to the system log: must be enabled for the bugcheck to be recorded in the Event Viewer.
- Write debugging information: here we choose Minidump, Kernel memory dump or Complete memory dump.
- dump file path: default %SystemRoot%\MEMORY.DMP for kernel/full.
- Reboot automatically: it's advisable to uncheck it if we want calmly watch the blue screen and take note of what appears.
For some manufacturers or support departments, such as in the case of certain network adapters, the user is asked to submit the dump file . It is usually located in C:\Windows\memory.dmp , and it is recommended to locate it by date/time to identify the one corresponding to the last failure.
If what we want is to be able to force a dump even when the system is frozen (without keyboard or mouse responding), there is also a very useful trick for PS/2 keyboards (not USB/Bluetooth), which consists of configuring the registry to trigger a dump with a key combination.
Force a dump using the keyboard in case of freezing
To generate a memory dump even if the screen is completely frozen, you can use the CrashOnCtrlScroll option on PS/2 keyboards. This method is not valid for USB or Bluetooth keyboards.
In the registry, we must create or modify the following key:
HKEY_LOCAL_MACHINE
System
CurrentControlSet
Services
i8042prt
Parameters
Nombre: CrashOnCtrlScroll
Tipo: REG_DWORD
Valor: 1
After restarting, at any time (even with the screen frozen) you can trigger a controlled crash and have the system generate a memory dump by pressing the right CTRL key and then the Scroll Lock key twice . This is very useful for investigating hard crashes that don't display a BSOD on their own.
Introduction to WinDbg for analyzing kernel dumps
WinDbg is Microsoft's premier tool for kernel debugging and memory dump analysis . It's available for free (currently also in the Microsoft Store as WinDbg Preview) and, although it might seem daunting at first glance, for an initial BSOD analysis you only need to understand a few basic options.
We can install WinDbg on the affected machine itself or on any other computer ; the .dmp file can be copied over the network, via USB, or even compressed into a CAB file. The processor and Windows version where we analyze the dump do not necessarily have to match those of the machine that crashed.
Start WinDbg with a dump from the command line
A classic way to open a memory dump in WinDbg is to use the command line with the `-z` parameter , specifying the path to the dump file. This can be combined with other parameters such as the symbol or binary path.
windbg -y <RutaSimbolos> -i <RutaBinarios> -z <RutaDump>
The -v modifier activates verbose mode , which is very useful for seeing more context. Besides WinDbg, there is also kd.exe , a console-based debugger that allows you to do practically the same thing but without a graphical interface.
kd.exe -z "Ruta\al\volcado.dmp" -y "Ruta\simbolos" -i "Ruta\busqueda\binarios"
Open a dump from the graphical interface
If WinDbg is already open in passive mode, you can load a crash dump file using the File → Open Crash Dump menu or the shortcut Ctrl+D . Select the .dmp file (or even a .cab file containing it) and WinDbg will load the crash information.
Another alternative is to launch WinDbg, and once inside, run the command .opendump specifying the path to the dump file and then the command g (Go) to start the dump debugging session:
.opendump C:\Windows\Memory.dmp
g
WinDbg even allows clean up multiple dumps at onceadding several parameters -z on the command line or by repeating .opendump with different routes and managing the multi-destination session.
Configure the symbol path in WinDbg
Without symbols, WinDbg operates almost blindly. Symbols (.pdb) contain debugging information about functions, internal structures, variables, offsets, etc. , and are essential for reliable analysis, especially when working with the kernel.
To use Microsoft's public symbols without having to download them manually, the best practice is to configure a symbol server pointing to the official Microsoft server and a local cache directory. For example, we can first create a folder C:\symbols and then, in WinDbg, configure the symbol path as follows:
SRV*c:\symbols*https://msdl.microsoft.com/download/symbols
This can be done from the File → Symbol File Path menu or, in WinDbg Preview, from File → Settings → Debugging settings by adjusting the “Default symbol path”. The first time you analyze a dump from a specific system, the debugger will automatically download the necessary symbols from the internet, which may take a few minutes depending on your connection.
It's important to note that Microsoft's public symbols sometimes don't include all the internal type information , and you might see warnings like "Your debugger is not using the correct symbols" or references to unresolvable types. For basic BSOD analysis, public symbols are usually sufficient, but if you need more detail, there will be limitations.
First analysis: basic commands and bug check
Once the dump is loaded and the symbols are configured, WinDbg usually displays a header with system information and a warning such as "Use !analyze -v to get detailed debugging information." That's our first stop for an initial analysis.
The !analyze -v command performs an automatic analysis of the dump and usually provides:
- The bugcheck code (for example, 0xE3, 0xD1, 0x9F, 0x44…).
- The parameters Arg1, Arg2, Arg3 and Arg4 from the bugcheck.
- The most likely module or driver cause of the failure (
Probably caused by). - The associated process at that moment (for example, Teams.exe).
- The call stack (stack trace) of the thread that triggered the crash.
- Bucket information and failure hashes, useful for correlating repeated errors.
For example, in a real-world bugcheck case RESOURCE_NOT_OWNED (0xE3) , the analysis might indicate that a thread attempted to release a resource it doesn't own , showing Teams.exe as the process and pointing to win32kbase.sys in a function like DrvEnumDisplaySettings . This suggests that the failing thread was querying or manipulating display settings from user space through the Windows graphics layer.
To delve a little deeper into the details of the stop code and its parameters, we also have the command .bugcheckwhich again displays the bugcheck and the four arguments, which is useful if we want to repeat that information without re-running everything. !analyze -v.
Practical cases: drivers and typical conflicts
BSOD analysis typically revolves around identifying faulty or malfunctioning drivers , driver conflicts, improper memory access, incorrect handling of IRPs (I/O Request Packets), and so on. Let's look at some practical examples from real-world cases to better understand the process.
RESOURCE_NOT_OWNED (0xE3) associated with Teams and win32kbase.sys
In a Windows 10 scenario where, after several days of uptime, a BSOD appears with bugcheck 0xE3 (RESOURCE_NOT_OWNED) , the minikernel dump shows something similar to:
RESOURCE_NOT_OWNED (e3)
A thread tried to release a resource it did not own.
Arguments:
Arg1: <dirección recurso>
Arg2: <dirección thread>
Arg3: 0
Arg4: 0
PROCESS_NAME: Teams.exe
STACK_TEXT:
...
win32kbase!DrvEnumDisplaySettings+0x356
win32kbase!NtUserEnumDisplaySettings+0x59
win32k!NtUserEnumDisplaySettings+0x15
nt!KiSystemServiceCopyEnd+0x28
...
Here, the debugger indicates that the bug check is triggered by a thread associated with Teams.exe , but the code actually on the stack at the critical moment belongs to win32kbase.sys , specifically the DrvEnumDisplaySettings function . This doesn't necessarily mean that Teams is the direct culprit, but rather that Teams is calling a user API that results in a synchronization or resource release bug in the graphics subsystem.
In these types of diagnoses, the conclusion is often that it's a bug in the Windows graphics stack, a specific video driver , or the interaction between the application and the drivers. The actual solution may involve updating GPU drivers, updating Teams, or even applying specific Windows patches , rather than simply waiting for it to fix itself.
DRIVER_IRQL_NOT_LESS_OR_EQUAL (0xD1) with NotMyFault
Sysinternals' NotMyFault utility is an educational tool that allows you to generate kernel errors in a controlled manner to learn how to analyze screenshots. For example, if you launch the High IRQL fault (kernel mode) option from NotMyFault and click "Do Bug", you will force a DRIVER_IRQL_NOT_LESS_OR_EQUAL (0xD1) error.
On the blue screen, we'll see something like DRIVER_IRQL_NOT_LESS_OR_EQUAL and possibly a candidate driver (for example, MyFault.sys , the driver used by the tool). Once the dump is generated and opened with WinDbg, the initial output might look something like this:
Use !analyze -v to get detailed debugging information.
BugCheck D1, {e1071800, 1c, 0, f7cda403}
*** ERROR: Module load completed but symbols could not be loaded for myfault.sys
Probably caused by : memory_corruption
Followup: memory_corruption
Although the debugger points to memory corruption , we know the real cause is related to NotMyFault and its driver. To confirm this, we can continue tracing with commands like !thread to see what calls the thread makes at the time of the failure, and !irp to analyze the IRP involved if the bug check is related to I/O operations.
For example, with `!thread <dir_thread>` we can see the thread's stack trace and locate the instruction where `myfault+0x403` appears , indicating where the test driver has gone wrong. From there, we can examine IRP, memory status, and so on, just as we would with a real bug.
MULTIPLE_IRP_COMPLETE_REQUESTS (0x44) and USB conflicts
Another very illustrative case is the bugcheck MULTIPLE_IRP_COMPLETE_REQUESTS (0x44)This error occurs when An IRP (I/O Request Packet) is completed more than once, usually because two different drivers believe they own the same IRP and both call IoCompleteRequest().
The analysis with !analyze -v might yield a description similar to this:
MULTIPLE_IRP_COMPLETE_REQUESTS (44)
A driver has requested that an IRP be completed (IoCompleteRequest()), but
the packet has already been completed.
...
Arguments:
Arg1: <IRP_ADDRESS>
Arg2: 00000d75
Arg3: 00000000
Arg4: 00000000
Probably caused by : usbehci.sys
Initially, the suspect appears to be usbehci.sys , a Microsoft driver for USB EHCI controllers. However, it's relatively rare for a bug to actually be caused by a native Windows driver without any third-party interaction. To get to the point, we use the IRP address provided by the bugcheck (Arg1) and run !irp <IRP_ADDRESS> :
!irp 87e5a490
Irp is active with 3 stacks 3 is current (= 0x87e5a548)
...
> [ f, 0] 0 c0 8a055618 00000000 b69de300-00000000 Success Error
\Driver\usbehci ax88172
Args: b70989c0 00000000 00220003 00000000
In the last line, we clearly see the string \Driver\usbehci ax88172 , revealing that the IRP has passed through both usbehci.sys and a driver called ax88172.sys , associated with a specific USB network chipset (AX88172). Therefore, we can conclude that the conflict originates from this third-party USB NIC driver , not from Microsoft's generic EHCI driver.
In that case, the solution involves updating the USB adapter driver, replacing the device, or, if necessary, removing it . This type of IRP analysis is especially useful for BSODs related to USB, storage, network cards, and, in general, any component that uses intensive I/O.
Useful WinDbg commands in kernel mode
Beyond !analyze -v and .bugcheck , there are several WinDbg extensions and commands that are very useful when we want to delve a little deeper into kernel dumping.
Some of the most common ones are:
- !thread: Displays detailed information about a thread, including its call stack, state, associated IRPs, etc. It allows you to see the "last actions" of the thread that was running when the system crashed.
- !process 0 0This lists all active processes at the time of the crash. It is useful for identifying if there were any suspicious processes, services, EDR, antivirus, etc., running on the machine.
- !irp: analyzes a specific IRP and shows the trace of the drivers it has gone throughThe I/O command, flags, etc., are key in bugs related to MULTIPLE_IRP_COMPLETE_REQUESTS and other I/O errors.
- !cpuinfo: provides information about the processor (manufacturer, MHz, signatures, characteristics), useful for verifying hardware environments.
- !peb: displays details of the PEB (Process Environment Block), such as computer name, Windows installation path, number of processors, etc.
- !token: provides information about security tokens, permissions, and security context of the process or thread.
- .cls: clears the command window, as in a regular console.
In addition, many specific file system extensions (e.g., for PnP, NTFS, etc.) allow you to extract even more information from the dumps. In some cases, WinDbg will indicate the presence of BLACKBOX* (BLACKBOXBSD, BLACKBOXNTFS, BLACKBOXPNP, BLACKBOXWINLOGON), which are additional data blocks captured during the bug check to facilitate the diagnosis of specific system areas.
Using Driver Verifier to find problematic drivers
A very high proportion of Windows Blue Screen of Death (BSOD) errors are caused by faulty or poorly programmed drivers . To proactively detect these types of problems, the system includes a powerful tool: Driver Verifier.
The Driver Verifier runs in real time and subjects selected drivers to a series of tests and stress tests: it checks for correct memory usage, kernel pool usage, IRQL, IRP, etc. If it detects that a driver is misbehaving, it can force a controlled BSOD so we can analyze a much clearer dump, where the culprit is usually easily identified.
To launch the Driver Verifier manager, simply open a command prompt with administrator privileges and type:
verifier
From there, we can choose which drivers we want to verify. It's wise to be cautious: the Verifier adds overhead to the system and can degrade performance , so it's recommended to enable verification only for the fewest possible suspect drivers instead of indiscriminately selecting everything.
Once Verifier triggers a BSOD upon detecting incorrect behavior, we can analyze the kernel dump with WinDbg and, hopefully, clearly see which driver was caught and what it did wrong. Microsoft's reference articles on Driver Verifier explain the various options and usage strategies in detail.
Practical advice for engineers and technicians
Whether you're a driver developer, a software developer that interacts with the kernel, or simply the go-to technician who receives all the blue screens of death, there are some guidelines worth internalizing to avoid getting lost in the jungle of BSODs.
The first step, when the error is related to your own code, is to systematically use the kernel debugger to reproduce and analyze the problem . By connecting a debugger to the target machine (via network, serial, etc.), a bugcheck will cause the system to stop inside the debugger instead of displaying the blue screen directly. From there, you can inspect memory, stacks, structures, and correct the code.
In other scenarios, bug checks may be due to third-party drivers, hardware, or software that we don't control. In those cases, the goal shifts from "fixing the code" to isolating and mitigating the problem.
- Identify the suspect driver or hardware component using WinDbg and dump analysis.
- Update or revert driver versions, BIOS, firmware, or related applications.
- Remove or replace USB devices, graphics cards, network adapters conflictive.
- To lean on the Event viewer, Sysinternals, network monitoring and analysis tools for additional context.
Many seemingly mysterious problems are resolved with basic troubleshooting procedures : reviewing documentation, checking file versions and dates, reinstalling key components, or disabling conflicting modules. Analyzing the dump gives us a clear direction on where to look and often saves us hours of trial and error.
It's also important to remember that, in environments like the one that caused the CrowdStrike Falcon incident and other EDRs, the most common questions revolve around what triggered the BSOD and how to quickly identify it . Having WinDbg properly configured, with symbols and a clear procedure for opening and analyzing dumps, allows you to narrow down in minutes what might otherwise end in a "format and reinstall" without truly understanding the cause.
In short, combining a good memory dump configuration, the disciplined use of tools like WinDbg, Driver Verifier, and Sysinternals, and the habit of methodically reviewing logs and stacks turns the blue screens of an unpredictable enemy into a very accurate source of information about what has failed in the kernel , helping us to make much more informed technical decisions.