What is a verifier stop?
I was in the process of writing up a few blog posts to do with debugging specific PrintVerifier stops when I realized that we haven't covered the basic concept of a verifier stop. So let's do that.
======================================= VERIFIER STOP 0000A012 : pid 0xD68: Leaked PrintTicket provider handle detected 03320FE8 : PrintTicket provider handle being leaked. 0312FF48 : Initialization stack trace. Use dps to dump the stack trace if it is not NULL. 00000CC0 : Thread id of the thread that opened the handle. 00000000 : Not used. =======================================
What you see above is what is referred to commonly as a verifier stop. The concept of a verifier stop is common to Application Verifier and not specific to PrintVerifier. All checks/verifications in AppVerifier issue a verifier stop to indicate a problem in the code/component being verified. Let's go over the important pieces of information that are part of a verifier stop.
- Stop code ID: The stop code ID is very important since this is what you use to look up additional information about the stop in the documentation. The numbering scheme will also give you a rough idea about what type of verification caused the stop. For example, all PrintAPI layer stops are numbered starting from 0000A000 and all PrintDriver layer stops are numbered starting from 0000D000. So in the snippet shown above, you can right away tell that it is a PrintAPI layer stop.
- Stop code title: The stop code title gives you rough idea about the root cause of the stop. For example, in the snippet shown above you can tell from the title that the root cause of the stop is the component being verified leaking a PrintTicket provider handle.
- Parameters: The parameters of a verifier stop provide the additional information you need to troubleshoot/debug the stop and pinpoint the root cause. A verifier stop can have a maximum of 4 parameters although not all might be used. For instance, in the snippet shown above you will see that only the first 3 parameters are used. The documentation for each verifier stop lists specific troubleshooting steps (inclusive of debugger commands) that you can take to display the additional information represented by the parameters.
So that's as far as pieces of information that are common to all verifier stops. But there is additional piece of information that only PrintDriver layer stops display.
VERIFIER STOP 0000D006 : pid 0x1644: The plugin driver closed the printer handle.
00000000018F6898 : Printer handle that was closed.
0000000001E733B0 : Stack trace of the closing. Use dps to dump the stack trace if it is not NULL.
0000000000000000 : Not used.
0000000000000000 : Not used.
This verifier stop was caused by the GetSupportedVersions method in the plug-in module at C:\WINDOWS\system32\spool\DRIVERS\x64\3\PTPlug_GetSupVersions_1.dll
In the snippet shown above, you will see the additional line stating that the GetSupportedVersions method in the PTPlug_GetSupVersions_1.dll caused the PrintVerifier stop to occur. This will allow you to isolate the problem area in your driver's code to a small manageable section. This feature is specific to the PrintDriver layer stops. The reason for including this information only for PrintDriver stops is that in most cases, the plug-in/filter being verified is not on the call stack at the time of the stop. As explained here, the PrintDriver hooks perform checks both before and after calling the plug-in/filter's COM interface methods. Since a number of checks are performed (and stops issued) after the plug-in/filter method has returned, the module being verified is no longer on the call stack. Therefore, the need to display the additional information for PrintDriver stops.