The project I did this test on used the production release of VS2015 Enterprise and the production Win 10 WDK. I generated a do nothing KMDF driver with the wizard, and had added a little code to hook up some hardware (the bar and MSI interrupt) for an experiment last week. Except for the listings I turned on, the options should be exactly what the KMDF wizard sets. This was C code not C++ code. I had looked at some strings in non-paged functions, and they were in a different segment (don’t remember which) that looked non-paged (but I didn’t look at the map and the final binary section attributes to be sure). Seems like there used to be a way to get the linkmap to show the section attributes.
This experiment was to see if FILE is ALWAYS safe to access from a paging incompatible context, and to record the steps to determine the correct answer. The experiment produced at least one case where a string constant lived in paged memory. This also was a debug build, so may or may not be the same on a release build. It also doesn’t say anything about how the compiler/linker might merge multiple duplicate strings.
Everybody should be able to follow the steps to determine other cases. I know Microsoft would like us to use paged code when possible. Is this documented someplace that string constants in a paged function will also be paged?
The next level of this experiment, from inside a paged function, store a pointer to the FILE string in the device context, and then access that pointer from a higher IRQL, like the device ISR. This will clearly be bad in the real world, the question is, will any of the Microsoft static analyzer tools detect this is bad. And the answer is, NO. I added the couple lines of code, checked the .asm listing to verify the string was still in PAGE$s and ran both Code Analyzer and SDV. Neither tool detected this was a violation of IRQL rules. On closer examination, the SAL declaration for a KMDF ISR function says it could be PASSIVE_LEVEL, which is true if you specify PassiveHandling in the WDF_INTERRUPT_CONFIG used when creating the WDFINTERRUPT object. It’s also true that nearly every ISR will be running at an elevated IRQL, so it seems like the SAL notation is less that helpful in this case. I manually adjusted the annotation for my ISR to say it ran at higher IRQL, and ran the static analyzer tools again, and they still didn’t detect this reference to paged data from a page fault incompatible function.
Perhaps one of you folks who knows SAL 2.0 really well (I looked at the docs, but came up empty) can tell us if there is any way to inform SDV that a field in a structure has specific IRQL constraints.
I did one more little test:
char * myPagedFunction(void)
{
static char * myString = “pagedOrNonPaged”;
return myString;
}
I found if the static myString was inside the paged function, the string was allocated in paged memory, although the string pointer variable was always non-paged. If I moved the declaration of myString outside the paged function, it became non-paged. It seems like the rule is ANY string literal declared inside a paged function is in paged memory.
It does seem like a usage scenario where this is a problem is if you have some paged (or discardable) function that has string literals that get stored in some non-paged structure, there might be a surprise. This makes me less inclined to use paged functions, as the paged data can leak out. Where might it leak out, say you have a structure to represent your ISR/DPC and you decide it would be useful for debugging/support to have a string label on the structure that tells you which of your 18 MSI-X interrupts it’s for. If you create those structures, even in non-paged pool, from a paged function, the string label may be paged if you don’t pay attention. Say you also have some ETW/WPP trace code in your ISR which among other things writes the label to the trace. The ISR is non-paged, the data structure describing it are from non-paged pool, but oops, that little text label is paged, because you initialized the structure from a paged function.
Jan
On 9/20/15, 3:04 AM, “xxxxx@lists.osr.com on behalf of xxxxx@live.com” wrote:
>strange why ??_C@xxxxx@Device?4c?$xxxxx@NNGAKEGL@ is in PAGE$s segment. by default string constant like this is allocated in CONST segment, which is renamed to .rdata by linker. however i not view .rdata section in you dump. may be you overwrite some linker defaults, as result you have not .rdata section. but say in my test i view some like this
>
>CONST SEGMENT
>??xxxxx@xxxxx@NEBBJFLE@?4?2FltFF?4cpp?$AA@ DB ‘.\FltFF.cpp’, 00H ; `string’
>CONST ENDS
>
>and finally this string in .rdata section (which notpaged)
>however i always use cpp, when you look like use c (‘Device.c’). may be c have some specific