OSRLogoOSRLogoOSRLogo x Subscribe to The NT Insider

Everything Windows Driver Development

GoToHomePage xLoginx

    Thu, 14 Mar 2019     118020 members


  Online Dump Analyzer
OSR Dev Blog
The NT Insider
The Basics
File Systems
ListServer / Forum
  Express Links
  · The NT Insider Digital Edition - May-June 2016 Now Available!
  · Windows 8.1 Update: VS Express Now Supported
  · HCK Client install on Windows N versions
  · There's a WDFSTRING?
  · When CAN You Call WdfIoQueueP...ously

Why Is The IRQL Always 0xFF When I Do !PCR?

There are few people in the Windows system software community as helpful, or as authoritative, as Microsoft's Jake Oshins.  So, when he recently posted on the NTDEV list an explanation of an oft-repeated question, I thought I should memorialize it in a memo (with his permisision, of course).

The famous question: "When I look at a crash dump, or when I stop the debugger, and I look at the IRQL as shown in the PCR (using the !PCR command to WinDbg or KD), the IRQL is always shown as 0xFF!  Why?  Does this mean that interrupts were disabled and that the system was running at IRQL HIGH_LEVEL when the crash occurred?"

Here's Jake's answer, in its entirety:

When you look in the PCR with !pcr in the debugger, you're looking at what has been written into some scratchpad space that may or may not be currently in use by the HAL. Several HALs use the PCR to track IRQL. Other HALs use the TPR (Task Priority Register) in the Local APIC. Still others may have their own implementations. So you should always consider the value of IRQL in the PCR to be suspect, simply because it may not be in use. A value like 0xFF, which corresponds to no actual IRQL should immediately clue you in to the fact that the HAL that you're using ignores the value in the PCR.

Furthermore, you need to understand what, exactly, the debugger really is and what it really does. (This discussion applies to the debugger that is built into the NT kernel, and not Soft-ICE or an Arium or an ITP that is debugging from outside of the kernel.) The debugger is just a piece of code that runs within the kernel, trying to depend on as few services from outside itself as possible. In order to become more deterministic, it disables interrupts whenever it is entered. The NT way of disabling interrupts securely and safely is to raise IRQL to HIGH_LEVEL. Thus, whenever you're in the debugger, IRQL is actually HIGH_LEVEL, regardless of what it was when it was executing the code that you were trying to debug.

Consequently, looking at the IRQL in the PCR from the debugger should always tell you HIGH_LEVEL if the PCR is actually being used to track IRQL. If it tells you anything else, it's meaningless. (This assumes that you actually found some meaning in asking what the current IRQL is while you're in the debugger, as you knew a-priori it should be HIGH_LEVEL.) This point also applies if you try to read the APIC TPR on a HAL that uses the TPR to track IRQL. It should always correspond to HIGH_LEVEL while you're in the debugger.

The only way you can reliably find out what IRQL your code was running at is to look at where the debugger pushed your IRQL onto the stack when the debugger was entered. Interestingly, this is beyond the end of the stack frame that the debugger itself displays to you, as the debugger assumes that you are primarily interested in the code that you wrote, not the debugger itself. So it pretends that the stack ends at your code, not automatically displaying the part of the stack that the debugger itself is currently running on.

Lastly, the WinDbg team has taken note in recent years that lots of people would be interested in knowing what IRQL their code was running at. Unfortunately, they noticed this first for people who were trying to debug crashdumps and only later (at my begging) extended their code to be able to tell you for a running system.

So you can know what IRQL code was running at on Windows XP and later when debugging a crashdump by using !irql. If you are debugging Windows Server 2003 or later, !irql will give you an accurate answer even if you're debugging a live system. !irql does exactly what I suggested above. It looks at the IRQL that the debugger itself stored as it was being entered.

Please, let us never see another posting saying that IRQL was 0xFF.

Of course, Jake provided this posting "as is" with no warranties, and this posting by him confers no rights.

Thanks Jake!


Related Articles
Enabling Debugging on the Local Machine for Windows XP®
You're Testing Me - Testing WDM/Win2K Drivers
Analyze This - Analyzing a Crash Dump
More on Kernel Debugging - KMODE_EXCEPTION_NOT_HANDLED
Making WinDbg Your Friend - Creating Debugger Extensions
Life Support for WinDbg - New Windows NT Support Tools
Life After Death? - Understanding Blue Screens
Special Win2K PnP Tracing and Checks
All About Lint - PC Lint and Windows Drivers
Bagging Bugs — Avoidance and Detection Tips to Consider

User Comments
Rate this article and give us feedback. Do you find anything missing? Share your opinion with the community!
Post Your Comment

"Not available for Windows XP targets"
!irql is only available when debugging Windows 2003 targets. The following promt is taken from WinDbg debugging a Windows XP sp2 target:

kd> !irql nt!_KPRCB.DebuggerSavedIRQL not found. Saved IRQL not available prior to Windows Server 2003

13-Jul-06, Yves Gattegno

Post Your Comments.
Print this article.
Email this article.
bottom nav links