How can I determine the underlying cause of a EXCEPTION_IN_PAGE_ERROR exception?


A customer was using memory-mapped files and installed an exception handler to log in-page errors in the memory-mapped file region. They wanted to know how they could obtain the real disk error that resulted in the memory manager not being able to page-in the requested data.

Finding the answer isn't that hard. A quick search for EXCEPTION_IN_PAGE_ERROR reveals that the information is provided in the Exception­Information member of the EXCEPTION_RECORD structure.

EXCEPTION_IN_PAGE_ERROR

The first element of the array contains a read-write flag that indicates the type of operation that caused the access violation. If this value is zero, the thread attempted to read the inaccessible data. If this value is 1, the thread attempted to write to an inaccessible address. If this value is 8, the thread causes a user-mode data execution prevention (DEP) violation.

The second array element specifies the virtual address of the inaccessible data.

The third array element specifies the underlying NTSTATUS code that resulted in the exception.

In other words,

if (GetExceptionCode() == EXCEPTION_IN_PAGE_ERROR)
{
    DiskError = GetExceptionInformation()->
                ExceptionRecord->
                ExceptionInformation[2];
}
Comments (12)
  1. Joshua says:

    Fundamental failure to read documentation.

    I guess that's what you get paid for.

  2. dave says:

    Apparently the doc reviewers didn't read the doc either.

    "If this value is 8, the thread causes a user-mode data execution prevention (DEP) violation."

    Should be "caused".

  3. Ricardo C says:

    @Dave

    Apparently you didn't read the doc either. AND you are off topic.

    At the bottom of the documentation you will find "Send comments about this topic to Microsoft"

    Use that to send your proof reading feedback.

  4. Myria says:

    By the way, for the first parameter for which 8 means execution, there are named constants in WinNT.h.  It is a platform-specific value, so you should probably use them instead of the literal 8.

    #define EXCEPTION_READ_FAULT 0          // exception caused by a read

    #define EXCEPTION_WRITE_FAULT 1         // exception caused by a write

    #define EXCEPTION_EXECUTE_FAULT 8       // exception caused by an instruction fetch

  5. Jeroen says:

    When reading the doc part that Raymond copied I wondered why DEP would cause an EXCEPTION_IN_PAGE_ERROR, but Myria's comment explains it. The doc is wrong (as usual).

  6. Untrustworthy computing says:

    Bottom line. You can't trust msdn documentation.

  7. chentiangemalc says:

    A bit overly nit-picky on the MSDN doco above…real issue is devs who haven't learned how to search on the Internet. MSDN had all info needed.  As for ”untrustworthy computing” you're probably one of those devs whose love of undocumented APIs and avoidance of best practice recommendations results in code making you worthy of title ”untrustworthy computing”

  8. jalf says:

    @Malcolm: wow… Ad hominem much? How about growing up a bit?

    Or perhaps these are your psychic powers in action? You don't *need* to know anything about a person other than whether they feel they can trust the msdn documentation, in order to determine that they love to avoid best practice recommendations and undocumented APIs. I am impressed. Perhaps you could also give us next week's lottery numbers?

    The comments above may be too pedantic for your liking, but most of us expect documentation to, well, document things. That is, documentation should implicitly be *correct*.

  9. Mity says:

    @Ricardo C: Perhaps Dave used "Send comments about this topic to Microsoft". You cannot know. I certainly know I did use it multiple times in hope the docs shall be corrected or made unambiguous. However I never got any feedback except some auto-generated generic e-mail and the docs was never corrected. So why should we use it if no one listens on the other side?

  10. "MSDN had all info needed.  As for ”untrustworthy computing” you're probably one of those devs whose love of undocumented APIs and avoidance of best practice recommendations results in code making you worthy of title ”untrustworthy computing”"

    It's not always that simple.  Consider just this scenario:

    * The Windows taskbar uses Aero Peek to allow the user to "peek" at other Windows.  (Aero Peek screenshot at http://www.philoking.com/…/aeropeek1.jpg if you forgot what that is)

    * Windows <= 7 does not directly support having multiple taskbars on a multi-monitor system (i.e. one taskbar per monitor).

    * Windows does not expose the API needed for Aero Peek as a public API.

    * In fact, Raymond explicitly said that Aero Peek was NOT publicly exposed to prevent abuse: blogs.msdn.com/…/10081263.aspx

    * So now there is an array of different 3rd-party software vendors who add auxiliary taskbars to additional monitors due to the absence of this feature from Microsoft.  They would have to use an undocumented API to invoke this effect: stackoverflow.com/…/windows-aero-peek-api

    The API was added to support the new Windows 7 taskbar, but the Windows 7 taskbar did not add taskbars to other monitors.  So the market has created these auxiliary taskbar software packages, but they can't support the same Aero Peek effect that the default taskbar does unless they start using undocumented APIs.

    I would guess that the developers of these packages have to dip into a lot of other undocumented APIs as well.  It is interesting to note that Microsoft has finally admitted that these multiple taskbars are a useful feature after all and are adding the feature to Windows 8.  Only 14 years after the introduction of multiple monitor support in Windows 98, but better late than never, I guess!  I would imagine Microsoft might never have considered this feature had other developers not used undocumented APIs to create these auxiliary taskbars.

    Personally, I can't function properly on a multi-monitor system without multiple taskbars.  Once I have a couple dozen windows open scattered across multiple monitors, I get completely lost if Windows is trying to shoehorn them onto one taskbar (which window was on which monitor again?).

  11. vcsjones says:

    "The second array element specifies the virtual address of the inaccessible data."

    But in the example "ExceptionInformation[2];", it's accessing the 3rd. Or am I misinterpreting something?

  12. Someone says:

    @vcsjones: Because the example is interested in the error code ("The third array element specifies the underlying NTSTATUS code that resulted in the exception."). The name of the variable on the left side should hint you in that direction (DiskError = GetExceptionInformation()->ExceptionRecord->ExceptionInformation[2];) as also the article text ("They wanted to know how they could obtain the real disk error").

Comments are closed.

Skip to main content