Problem with IoCtl in a virtual modem driver

Hello,

I wrote a virtual modem driver that uses Walter Oney’s Generic driver to manage PnP/Power events. The problem is that the driver sometimes bugchecks while calling GenericUncacheControlRequest at DISPATCH_LEVEL.

Here’s the stack trace:
WARNING: Stack unwind information not available. Following frames may be wrong.
b8e87b8c f8aa1262 badb0d00 00000000 8238d998 nt!Kei386EoiHelper+0x2883
b8e87c00 f8a9f971 00000001 82372a88 82372978 bmmodem!GenericUncacheControlRequest+0x8 [h:\baracodapencil\vcom\vmodem_event\control.cpp @ 160]
b8e87c1c f8a9fa27 00372950 8238dba8 82d2d268 bmmodem!ProcessConnectionStateChange+0x5d [h:\baracodapencil\vcom\vmodem_event\ioctl.cpp @ 720]
b8e87c40 804e13d9 82372898 8237dc20 806ff410 bmmodem!BMModemIoControl+0x81 [h:\baracodapencil\vcom\vmodem_event\ioctl.cpp @ 57]
b8e87c64 80580fb1 82372898 8237dc20 823bc9d8 nt!IofCallDriver+0x32
b8e87d00 8058709e 000008f8 00000000 00000000 nt!RtlUnicodeStringToAnsiString+0x4c4
b8e87d34 804dd99f 000008f8 00000000 00000000 nt!NtDeviceIoControlFile+0x2a
b8e87d64 7c90eb94 badb0d00 0388f2c8 00000000 nt!KiDeliverApc+0xb9e
b8e87d68 badb0d00 0388f2c8 00000000 00000000 0x7c90eb94
b8e87d6c 0388f2c8 00000000 00000000 00000000 0xbadb0d00
b8e87d70 00000000 00000000 00000000 00000000 0x388f2c8

STACK_COMMAND: kb

FOLLOWUP_IP:
bmmodem!GenericUncacheControlRequest+8 [h:\baracodapencil\vcom\vmodem_event\control.cpp @ 160]
f8aa1262 f680d400000010 test byte ptr [eax+0D4h],10h

FAULTING_SOURCE_CODE:
156: GENERICAPI PIRP GENERIC_EXPORT GenericUncacheControlRequest(PGENERIC_EXTENSION pdx, PIRP* pIrp)
157: { // GenericUncacheControlRequest
158: ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
159:

160: if (!(pdx->Flags & GENERIC_PENDING_IOCTLS))
161: return NULL;
162:
163: KIRQL oldirql;
164: KeAcquireSpinLock(&pdx->IoctlListLock, &oldirql);
165:

Windbg says that the Flags field of the GENERIC_EXTENSION structure seems to be in paged memory. I don’t understand how this can happen as the structure is part of my device’s DEVICE_EXTENSION which is allocated in non-paged memory. Any ideas of what’s going on here?

What’s the value of EAX? What’s the bugcheck code?

Hello,

Here’s the complete log from WinDbg:

_0: kd> !analyze -v

*******************************************************************************

*                                                                            
*

*                        Bugcheck
Analysis                                    *

*                                                                            
*

*******************************************************************************

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: 000000d4, memory referenced

Arg2: 00000002, IRQL

Arg3: 00000000, value 0 = read operation, 1 = write operation

Arg4: f8ab1262, address which referenced memory

Debugging Details:


MODULE_NAME: bmmodem

FAULTING_MODULE: 804d7000 nt

DEBUG_FLR_IMAGE_TIMESTAMP:  45816ea6

READ_ADDRESS: unable to get nt!MmSpecialPoolStart

unable to get nt!MmSpecialPoolEnd

unable to get nt!MmPoolCodeStart

unable to get nt!MmPoolCodeEnd

 000000d4

CURRENT_IRQL:  2

FAULTING_IP:

bmmodem!GenericUncacheControlRequest+8
[h:\baracodapencil\vcom\vmodem_event\control.cpp @ 160]

f8ab1262 f680d400000010  test    byte ptr [eax+0D4h],10h

DEFAULT_BUCKET_ID:  WRONG_SYMBOLS

BUGCHECK_STR:  0xD1

LAST_CONTROL_TRANSFER:  from f8ab1262 to 804e0aac

STACK_TEXT: 

WARNING: Stack unwind information not available. Following frames may
be wrong.

b8ad4b8c f8ab1262 badb0d00 00000000 81eda358 nt!Kei386EoiHelper+0x2883

b8ad4c00 f8aaf971 00000000 824c89b8 824c88a8
bmmodem!GenericUncacheControlRequest+0x8
[h:\baracodapencil\vcom\vmodem_event\control.cpp @ 160]

b8ad4c1c f8aafa27 004c8880 81eda568 8238a948
bmmodem!ProcessConnectionStateChange+0x5d
[h:\baracodapencil\vcom\vmodem_event\ioctl.cpp @ 720]

b8ad4c40 804e13d9 824c87c8 82e6d478 806ff410
bmmodem!BMModemIoControl+0x81
[h:\baracodapencil\vcom\vmodem_event\ioctl.cpp @ 57]

b8ad4c64 80580fb1 824c87c8 82e6d478 824ec190 nt!IofCallDriver+0x32

b8ad4d00 8058709e 00000968 00000000 00000000
nt!RtlUnicodeStringToAnsiString+0x4c4

b8ad4d34 804dd99f 00000968 00000000 00000000
nt!NtDeviceIoControlFile+0x2a

b8ad4d64 7c90eb94 badb0d00 06eeedc8 00000000 nt!KiDeliverApc+0xb9e

b8ad4d68 badb0d00 06eeedc8 00000000 00000000 0x7c90eb94

b8ad4d6c 06eeedc8 00000000 00000000 00000000 0xbadb0d00

b8ad4d70 00000000 00000000 00000000 00000000 0x6eeedc8

STACK_COMMAND:  kb

FOLLOWUP_IP:

bmmodem!GenericUncacheControlRequest+8
[h:\baracodapencil\vcom\vmodem_event\control.cpp @ 160]

f8ab1262 f680d400000010  test    byte ptr [eax+0D4h],10h

FAULTING_SOURCE_CODE: 

   156: GENERICAPI PIRP GENERIC_EXPORT
GenericUncacheControlRequest(PGENERIC_EXTENSION pdx, PIRP* pIrp)

   157:     {                            // GenericUncacheControlRequest

   158:     ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);

   159:

  160:     if (!(pdx->Flags & GENERIC_PENDING_IOCTLS))

   161:         return NULL;

   162:    

   163:     KIRQL oldirql;

   164:     KeAcquireSpinLock(&pdx->IoctlListLock, &oldirql);

   165:

SYMBOL_STACK_INDEX:  1

SYMBOL_NAME:  bmmodem!GenericUncacheControlRequest+8

FOLLOWUP_NAME:  MachineOwner

IMAGE_NAME:  bmmodem.sys_
Any ideas of what is going on here ?

Thanks,

Alex Palka

Baracoda

xxxxx@yahoo.ca napisał(a):

type=“cite”>

What’s the value of EAX? What’s the bugcheck code?


Questions? First check the Kernel Driver FAQ athttp://www.osronline.com/article.cfm?id=256

To unsubscribe, visit the List Server section of OSR Online athttp://www.osronline.com/page.cfm?name=ListServer

The value of EAX is 0xffdff13c.

Regards,
Aleksander Palka
Baracoda

xxxxx@yahoo.ca napisał(a):

What’s the value of EAX? What’s the bugcheck code?


Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

wrote in message news:xxxxx@ntdev…
> …I don’t understand how this can happen as the structure is part of my device’s DEVICE_EXTENSION which is allocated in
> non-paged memory. Any ideas of what’s going on here?

It looks like your driver is written in c++?
–PA

Pavel A. napisa³(a):

wrote in messagenews:xxxxx@ntdev

…I don’t understand how this can happen as the structure is part of my device’s DEVICE_EXTENSION which is allocated in
non-paged memory. Any ideas of what’s going on here?

It looks like your driver is written in c++?
–PA

Actually, I use C++ only to be able to declare variables wherever I
want, but yes, the driver code is in .cpp files. I used the WDK command
line to compile the driver, not the Visual Studio.

Aleksander Palka


Questions? First check the Kernel Driver FAQ athttp://www.osronline.com/article.cfm?id=256

To unsubscribe, visit the List Server section of OSR Online athttp://www.osronline.com/page.cfm?name=ListServer

PA,

Are you trying to start another endless C++ vs. C debate? C++ has nothing
to do with this particular bugcheck, which is obviously a NULL pointer
dereference. (Arg1: 000000d4, memory referenced)

AP, figure out why you are passing NULL into
GenericUncachedControlRequest, and your bugcheck should go away.

Phil

Philip D. Barila
Seagate Technology LLC
(720) 684-1842

From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of “Pavel A.”

Sent: Friday, December 15, 2006 8:18 AM
To: “Windows System Software Devs Interest List”
Subject: Re:[ntdev] Problem with IoCtl in a virtual modem driver

< xxxxx@baracoda.com> wrote in message news:xxxxx@ntdev…
> …I don’t understand how this can happen as the structure is part
of my device’s DEVICE_EXTENSION which is allocated in
> non-paged memory. Any ideas of what’s going on here?

It looks like your driver is written in c++?
–PA

The EAX register is not 0, so it’s not the case with the NULL pointer. I would check if the initialized extension pointer (whenever still accessible) matches the one passed to make sure it is not trashed. Also, the exact bugcheck info might help to clear things out.

Sorry, I think I gave you the wrong information. I have just checked the
WinDbg output again:

FAULTING_IP:
bmmodem!GenericUncacheControlRequest+8
[h:\baracodapencil\vcom\vmodem_event\control.cpp @ 160]
f8ab1262 f680d400000010 test byte ptr [eax+0D4h],10h

combined with what follows:
Arg1: 000000d4, memory referenced

Looks like EAX is equal to 0…

I used the Registers window of WinDbg to check the EAX value (it was
equal to 0xffdff13c), but I am not sure if that’s the correct way to do
it (given that all I did was to load a crash dump file into WinDbg).

Aleksander Palka

xxxxx@yahoo.ca napisał(a):

The EAX register is not 0, so it’s not the case with the NULL pointer. I would check if the initialized extension pointer (whenever still accessible) matches the one passed to make sure it is not trashed. Also, the exact bugcheck info might help to clear things out.


Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

Using the registers window to check EAX at the time of the bugcheck won’t help you figure out what EAX was at the time the bad instruction occurred.

If you have the context frame (I think it’s listed in the bugcheck data, otherwise you can use kv to see any frames on the stack) you can use .context to load it and then check eax from there.

Still given the instruction and the bugcheck data the most likely explaination is that EAX is indeed zero at the time the instruction runs.

-p

(if you’ve already tried this forgive me - I’m jumping into the middle of the thread)

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Aleksander Palka
Sent: Friday, December 15, 2006 9:33 AM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] Problem with IoCtl in a virtual modem driver

Sorry, I think I gave you the wrong information. I have just checked the
WinDbg output again:

FAULTING_IP:
bmmodem!GenericUncacheControlRequest+8
[h:\baracodapencil\vcom\vmodem_event\control.cpp @ 160]
f8ab1262 f680d400000010 test byte ptr [eax+0D4h],10h

combined with what follows:
Arg1: 000000d4, memory referenced

Looks like EAX is equal to 0…

I used the Registers window of WinDbg to check the EAX value (it was
equal to 0xffdff13c), but I am not sure if that’s the correct way to do
it (given that all I did was to load a crash dump file into WinDbg).

Aleksander Palka

xxxxx@yahoo.ca napisa?(a):
> The EAX register is not 0, so it’s not the case with the NULL pointer. I would check if the initialized extension pointer (whenever still accessible) matches the one passed to make sure it is not trashed. Also, the exact bugcheck info might help to clear things out.
>
> —
> Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256
>
> To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer
>
>
>


Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

Hello everyone,

I’d like to thank you all for the suggestions that put me on the right
track and I have now fixed the problem.

Actually, I have an extra device object attached to the modem’s FDO that
lets me communicate with the device (Windows seems to open the modem,
thus blocking any attempts to connect to the driver FDO directly). In
the code I followed Walter Oney’s scheme with two device extensions
pointing to each other. To distinguish between the two extensions in the
dispatch routines of my driver, I put a ULONG flag as the first field in
both of them. If the IRP is being sent to the FDO, the flag is equal to
0 and it is equal to 1 if the target device is my “extra” device object.
All dispatch routines (with the exception of the IOCTL routine,
obviously) begin with:

PDEVICE_EXTENSION deviceExtension;
(…)
if(*((ULONG*)DeviceObject->DeviceExtension) == 1)
deviceExtension =
((PPLUGIN_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->pdx;
else
deviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;

Unfortunately, I had forgotten to do the same thing in the routine that
generated blue screens - because the “extra” device’s extension
structure is smaller that the FDO’s and the pointer that I used was == NULL.

Thanks again,
Aleksander Palka
Baracoda

Peter Wieland napisa³(a):

Using the registers window to check EAX at the time of the bugcheck won’t help you figure out what EAX was at the time the bad instruction occurred.

If you have the context frame (I think it’s listed in the bugcheck data, otherwise you can use kv to see any frames on the stack) you can use .context to load it and then check eax from there.
>
> Still given the instruction and the bugcheck data the most likely explaination is that EAX is indeed zero at the time the instruction runs.
>
> -p
>
> (if you’ve already tried this forgive me - I’m jumping into the middle of the thread)
>
> -----Original Message-----
> From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Aleksander Palka
> Sent: Friday, December 15, 2006 9:33 AM
> To: Windows System Software Devs Interest List
> Subject: Re: [ntdev] Problem with IoCtl in a virtual modem driver
>
> Sorry, I think I gave you the wrong information. I have just checked the
> WinDbg output again:
>
> FAULTING_IP:
> bmmodem!GenericUncacheControlRequest+8
> [h:\baracodapencil\vcom\vmodem_event\control.cpp @ 160]
> f8ab1262 f680d400000010 test byte ptr [eax+0D4h],10h
>
> combined with what follows:
> Arg1: 000000d4, memory referenced
>
> Looks like EAX is equal to 0…
>
> I used the Registers window of WinDbg to check the EAX value (it was
> equal to 0xffdff13c), but I am not sure if that’s the correct way to do
> it (given that all I did was to load a crash dump file into WinDbg).
>
> Aleksander Palka
>
> xxxxx@yahoo.ca napisa³(a):
>
>> The EAX register is not 0, so it’s not the case with the NULL pointer. I would check if the initialized extension pointer (whenever still accessible) matches the one passed to make sure it is not trashed. Also, the exact bugcheck info might help to clear things out.
>>
>> —
>> Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256
>>
>> To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer
>>
>>
>>
>>
>
>
> —
> Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256
>
> To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer
>
>
> —
> Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256
>
> To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer
>
>
>

wrote in message news:xxxxx@ntdev…
> PA,
>
> Are you trying to start another endless C++ vs. C debate?

Not at all. I’ve just reacted to the well known pattern:
a driver is written in c++, and some memory that should be resident,
suddenly is pageable.

> C++ has nothing
> to do with this particular bugcheck, which is obviously a NULL pointer
> dereference. (Arg1: 000000d4, memory referenced)

Got it. Thanks a lot.

Regards,
–PA

> AP, figure out why you are passing NULL into
> GenericUncachedControlRequest, and your bugcheck should go away.
>
> Phil
>
> Philip D. Barila
> Seagate Technology LLC
> (720) 684-1842
>
>
> From: xxxxx@lists.osr.com
> [mailto:xxxxx@lists.osr.com] On Behalf Of “Pavel A.”
>
> Sent: Friday, December 15, 2006 8:18 AM
> To: “Windows System Software Devs Interest List”
> Subject: Re:[ntdev] Problem with IoCtl in a virtual modem driver
>
> < xxxxx@baracoda.com> wrote in message news:xxxxx@ntdev…
>> …I don’t understand how this can happen as the structure is part
> of my device’s DEVICE_EXTENSION which is allocated in
>> non-paged memory. Any ideas of what’s going on here?
>
> It looks like your driver is written in c++?
> --PA

The safest way to do C++ in device drivers is to never use pagable code at
all. You can use paged memory for some data, but that is very dependent
upon what data it is and what driver stack is involved. As Doron Holon has
said, the compiler can place some code pieces in places where you will not
expect them so it is just as likely it will go into a paged code segment as
non-paged. We don’t have the source code to the compiler so we can
determine how it is allocated. A map output file can help you find if
routines that should be resident got placed in a paged segment.

“Pavel A.” wrote in message news:xxxxx@ntdev…
> wrote in message news:xxxxx@ntdev…
>> PA,
>>
>> Are you trying to start another endless C++ vs. C debate?
>
> Not at all. I’ve just reacted to the well known pattern:
> a driver is written in c++, and some memory that should be resident,
> suddenly is pageable.
>
>> C++ has nothing
>> to do with this particular bugcheck, which is obviously a NULL pointer
>> dereference. (Arg1: 000000d4, memory referenced)
>
> Got it. Thanks a lot.
>
> Regards,
> --PA
>
>> AP, figure out why you are passing NULL into
>> GenericUncachedControlRequest, and your bugcheck should go away.
>>
>> Phil
>>
>> Philip D. Barila
>> Seagate Technology LLC
>> (720) 684-1842
>>
>>
>> From: xxxxx@lists.osr.com
>> [mailto:xxxxx@lists.osr.com] On Behalf Of “Pavel A.”
>>
>> Sent: Friday, December 15, 2006 8:18 AM
>> To: “Windows System Software Devs Interest List”
>> Subject: Re:[ntdev] Problem with IoCtl in a virtual modem driver
>>
>> < xxxxx@baracoda.com> wrote in message news:xxxxx@ntdev…
>>> …I don’t understand how this can happen as the structure is part
>> of my device’s DEVICE_EXTENSION which is allocated in
>>> non-paged memory. Any ideas of what’s going on here?
>>
>> It looks like your driver is written in c++?
>> --PA
>
>
>