Interpreting !pte command output

Hi folks,

Working on a bug that I’ve posted about before, that (not to put too
fine a point on it) is causing me pain.

A bugcheck of this general description:

DRIVER_IRQL_NOT_LESS_OR_EQUAL (d1)
An attempt was made to access a pageable (or completely invalid) address
at an
interrupt request level (IRQL) that is too high. This is usually
caused by drivers using improper addresses.
If kernel debugger is available get stack backtrace.
Arguments:
Arg1: f5ecc000, memory referenced
Arg2: 00000002, IRQL
Arg3: 00000000, value 0 = read operation, 1 = write operation
Arg4: f5ecbffb, address which referenced memory

And the call stack looks something like this:

f6078dac 805aa2b6 8238b884 00000000 00000000 my_driver+0x13ffb
f6078ddc 805319c6 f5ecbd80 8238b884 00000000
nt!PspSystemThreadStartup+0x34
00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x16

Last time I posted this, (to NT Dev I think), we looked at pageability,
and I checked in the map file for the driver, that the function in
question was NOT being put in the pageable section of the driver.

However, this time I got smarter, and decided to use the !pte command to
figure out what is going on, because the address looks suspiciously like
the start of a new page in memory:

kd> !pte f5ecc000
VA f5ecc000
PDE at C0300F5C PTE at C03D7B30
contains 01029163 contains 1C52D860
pfn 1029 -G-DA–KWEV not valid
Transition: 1c52d
Protect: 3 - ExecuteRead

Contrast that with the previous page in memory:

kd> !pte f5ecbfff
VA f5ecbfff
PDE at C0300F5C PTE at C03D7B2C
contains 01029163 contains 1C504161
pfn 1029 -G-DA–KWEV pfn 1c504 -G-DA–KREV

So it looks like the page has indeed been paged out?!?! Could someone
confirm that’s what the output from the PTE command means?

In which case, I am SO confused. I’ve tried putting #pragma code_seg()
in for the file, which should set everything back to .text, and not PAGE
but that doesn’t fix it.

The function in question is “WT_ThreadFn” in my driver, the the relevant
bits of map file look like this:
Start Length Name Class
0001:00000000 000160eeH .text CODE
0002:00000000 000000d8H .idata$5 DATA
0002:000000e0 00000404H .rdata DATA
0002:000004e4 0000005aH .rdata$debug DATA
0003:00000000 00000360H .data DATA
0003:00000360 0000000cH .bss DATA
0004:00000000 000009d6H PAGE CODE
0005:00000000 00000070H PAGECONST DATA
0006:00000000 0000003cH .idata$2 CODE
0006:0000003c 00000014H .idata$3 CODE
0006:00000050 000000d8H .idata$4 CODE
0006:00000128 000004aaH .idata$6 CODE
0007:00000000 000000a0H .rsrc$01 DATA
0007:000000a0 00000480H .rsrc$02 DATA

Static symbols

0001:00011ff0 _WT_ZeroWorkPool@4 000224f0 f
WorkerThreadd:workerthread.obj
0001:00012460 _WT_ZeroWorkEntry@4 00022960 f
WorkerThreadd:workerthread.obj
0001:00012950 _WT_IdleOrClose@12 00022e50 f
WorkerThreadd:workerthread.obj
0001:00012c50 _WT_DestroyWorkEntry@12 00023150 f
WorkerThreadd:workerthread.obj
0001:00012d70 _WT_CheckCountsZero@4 00023270 f
WorkerThreadd:workerthread.obj
0001:00012da0 _WT_QuiescentCheckCountsZero@4 000232a0 f
WorkerThreadd:workerthread.obj
0001:00012de0 _WT_QuiescentNoCounts@4 000232e0 f
WorkerThreadd:workerthread.obj
0001:00013320 _WT_DestroyWorkPool@4 00023820 f
WorkerThreadd:workerthread.obj
0001:00013430 _WT_DpcHandler@16 00023930 f
WorkerThreadd:workerthread.obj
0001:00013880 _WT_ThreadFn@4 00023d80 f WorkerThreadd:workerthread.obj
0001:00013d40 _MINICLOCK_ValidStruct@4 00024240 f
MiniClockd:miniclock.obj
0001:00013db0 _MINICLOCK_ValidMasterClock@4 000242b0 f
MiniClockd:miniclock.obj

By the way - I haven’t explicitly set the priority of my thread, would
that make a difference - is there something in the paging mechanism for
the O/S which should run at a higher priority than my thread?

MH.

This email and any attachments is confidential, may be legally privileged and is intended for the use of the addressee only. If you are not the intended recipient, please note that any use, disclosure, printing or copying of this email is strictly prohibited and may be unlawful. If received in error, please delete this email and any attachments and confirm this to the sender.

You are reading !pte correctly.

The page is marked “in transition” which means the memory is actually
*there* but the PTE itself is not valid - this often happens when
verifier is running (it aggressively turns off the valid bit for
pageable memory regions). The page may contain code and/or data
(ExecuteRead). You should still be able to examine the memory (“u” or
“dd” should work) since the debugger cleverly notices the page is
“transitional” (so the data is still present).

I can’t honestly tell you why it is pageable, based upon what you’ve
explained. This could be data within your driver - you’d really need to
look at *what* is being accessed here. What does !analyze tell you?
When you look at EIP is it this address? Or is this an address in some
register (oh, like ESI or EDI…)

Regards,

Tony

Tony Mason

Consulting Partner

OSR Open Systems Resources, Inc.

http://www.osr.com http:</http:>


From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Martin C Harvey
Sent: Tuesday, March 01, 2005 11:27 AM
To: Kernel Debugging Interest List
Subject: [windbg] Interpreting !pte command output

Hi folks,

Working on a bug that I’ve posted about before, that (not to put too
fine a point on it) is causing me pain.

A bugcheck of this general description:

DRIVER_IRQL_NOT_LESS_OR_EQUAL (d1)
An attempt was made to access a pageable (or completely invalid) address
at an
interrupt request level (IRQL) that is too high. This is usually
caused by drivers using improper addresses.
If kernel debugger is available get stack backtrace.
Arguments:
Arg1: f5ecc000, memory referenced
Arg2: 00000002, IRQL
Arg3: 00000000, value 0 = read operation, 1 = write operation
Arg4: f5ecbffb, address which referenced memory

And the call stack looks something like this:

f6078dac 805aa2b6 8238b884 00000000 00000000 my_driver+0x13ffb
f6078ddc 805319c6 f5ecbd80 8238b884 00000000
nt!PspSystemThreadStartup+0x34
00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x16

Last time I posted this, (to NT Dev I think), we looked at pageability,
and I checked in the map file for the driver, that the function in
question was NOT being put in the pageable section of the driver.

However, this time I got smarter, and decided to use the !pte command to
figure out what is going on, because the address looks suspiciously like
the start of a new page in memory:

kd> !pte f5ecc000
VA f5ecc000
PDE at C0300F5C PTE at C03D7B30
contains 01029163 contains 1C52D860
pfn 1029 -G-DA–KWEV not valid
Transition: 1c52d
Protect: 3 - ExecuteRead

Contrast that with the previous page in memory:

kd> !pte f5ecbfff
VA f5ecbfff
PDE at C0300F5C PTE at C03D7B2C
contains 01029163 contains 1C504161
pfn 1029 -G-DA–KWEV pfn 1c504 -G-DA–KREV

So it looks like the page has indeed been paged out?!?! Could someone
confirm that’s what the output from the PTE command means?

In which case, I am SO confused. I’ve tried putting #pragma code_seg()
in for the file, which should set everything back to .text, and not PAGE
but that doesn’t fix it.

The function in question is “WT_ThreadFn” in my driver, the the relevant
bits of map file look like this:

Start Length Name Class
0001:00000000 000160eeH .text CODE
0002:00000000 000000d8H .idata$5 DATA
0002:000000e0 00000404H .rdata DATA
0002:000004e4 0000005aH .rdata$debug DATA
0003:00000000 00000360H .data DATA
0003:00000360 0000000cH .bss DATA
0004:00000000 000009d6H PAGE CODE
0005:00000000 00000070H PAGECONST DATA
0006:00000000 0000003cH .idata$2 CODE
0006:0000003c 00000014H .idata$3 CODE
0006:00000050 000000d8H .idata$4 CODE
0006:00000128 000004aaH .idata$6 CODE
0007:00000000 000000a0H .rsrc$01 DATA
0007:000000a0 00000480H .rsrc$02 DATA

Static symbols

0001:00011ff0 _WT_ZeroWorkPool@4 000224f0 f
WorkerThreadd:workerthread.obj
0001:00012460 _WT_ZeroWorkEntry@4 00022960 f
WorkerThreadd:workerthread.obj
0001:00012950 _WT_IdleOrClose@12 00022e50 f
WorkerThreadd:workerthread.obj
0001:00012c50 _WT_DestroyWorkEntry@12 00023150 f
WorkerThreadd:workerthread.obj
0001:00012d70 _WT_CheckCountsZero@4 00023270 f
WorkerThreadd:workerthread.obj
0001:00012da0 _WT_QuiescentCheckCountsZero@4 000232a0 f
WorkerThreadd:workerthread.obj
0001:00012de0 _WT_QuiescentNoCounts@4 000232e0 f
WorkerThreadd:workerthread.obj
0001:00013320 _WT_DestroyWorkPool@4 00023820 f
WorkerThreadd:workerthread.obj
0001:00013430 _WT_DpcHandler@16 00023930 f
WorkerThreadd:workerthread.obj
0001:00013880 _WT_ThreadFn@4 00023d80 f WorkerThreadd:workerthread.obj
0001:00013d40 _MINICLOCK_ValidStruct@4 00024240 f
MiniClockd:miniclock.obj
0001:00013db0 _MINICLOCK_ValidMasterClock@4 000242b0 f
MiniClockd:miniclock.obj

By the way - I haven’t explicitly set the priority of my thread, would
that make a difference - is there something in the paging mechanism for
the O/S which should run at a higher priority than my thread?

MH.

This email and any attachments is confidential, may be legally
privileged and is intended for the use of the addressee only. If you are
not the intended recipient, please note that any use, disclosure,
printing or copying of this email is strictly prohibited and may be
unlawful. If received in error, please delete this email and any
attachments and confirm this to the sender.

You are currently subscribed to windbg as: unknown lmsubst tag argument:
‘’
To unsubscribe send a blank email to xxxxx@lists.osr.com

Thank you Tony,

As far as that page, it contains the code for a worker thread which I
create in my driver - hence why the bugcheck indicates that the memory
address being accessed is (very nearly) the same as the address that
accessed memory.

The bugcheck occurs because the worker thread aquires a spinlock shortly
after it starts - and all this happens very rapidly during driver load.
I actually have about 10 minidrivers which all start almost
simultaneously (created by my own bus driver), and all start threads
(they sometimes need to bulk copy video data around).

I’m wondering whether the driver loading process is allowed to call
functions in the minidriver (running under stream.sys, threads created
under SRB_INITIALIZE_DEVICE) *after* the driver image loading has
started, but *before* all the pages have actually arrived in memory …
and driver verifier seems to make it significantly worse.

A sort of “lazy paging in” on driver load perhaps?

MH.


From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Tony Mason
Sent: 02 March 2005 00:20
To: Kernel Debugging Interest List
Subject: RE: [windbg] Interpreting !pte command output

You are reading !pte correctly.

The page is marked “in transition” which means the memory is actually
*there* but the PTE itself is not valid - this often happens when
verifier is running (it aggressively turns off the valid bit for
pageable memory regions). The page may contain code and/or data
(ExecuteRead). You should still be able to examine the memory (“u” or
“dd” should work) since the debugger cleverly notices the page is
“transitional” (so the data is still present).

I can’t honestly tell you why it is pageable, based upon what you’ve
explained. This could be data within your driver - you’d really need to
look at *what* is being accessed here. What does !analyze tell you?
When you look at EIP is it this address? Or is this an address in some
register (oh, like ESI or EDI…)

Regards,

Tony

Tony Mason

Consulting Partner

OSR Open Systems Resources, Inc.

http://www.osr.com http:</http:>

This email and any attachments is confidential, may be legally privileged and is intended for the use of the addressee only. If you are not the intended recipient, please note that any use, disclosure, printing or copying of this email is strictly prohibited and may be unlawful. If received in error, please delete this email and any attachments and confirm this to the sender.

Solved. Now makes perfect sense. The stream class driver is being smart,
and doesn’t expect me to have a worker thread running at raised IRQL,
because it calls MmPageEntireDriver.

MH.

This email and any attachments is confidential, may be legally privileged and is intended for the use of the addressee only. If you are not the intended recipient, please note that any use, disclosure, printing or copying of this email is strictly prohibited and may be unlawful. If received in error, please delete this email and any attachments and confirm this to the sender.