none
How to get WdfRequestMarkCancelableEx to not crash the system? RRS feed

  • Question

  • Now that I got the locking in place, the driver works.

    Next thing to solve is that when an application opens a stream and aborts for whatever reason (e.g. cancel overlapped IO of simply exit the application) the application will hang (and the system won't shut down).

    The trouble is that the device is waiting for an interrupt to complete the request, which won't happen if there's no data.

    Cancelling a request in my hardware is easy, just don't wait for the interrupt and complete the request.

    I changed my code to call "WdfRequestMarkCancelableEx()" in the EvtIoRead before triggering the DPC that will do the actual transfer. On failure (which never happens) it completes the request with that error code and doesn't submit it to the DPC.

    This causes the whole system to crash (BSOD) at rather random times, when opening the device for example. I changed the cancel callback routine into an empty stub, hoping to get the previous behavior of "simply hanging" back, but that does not make a difference.

    Is there some hidden extra thing that I need to do? The documentation on WdfRequestMarkCancelableEx doesn't imply that, but apparently "something" is calling into my driver and causing things to explode.

    (and a related question: My development system is supposedly debugging the test target, so why doesn't it break into the debugger when the target crashes?)

    Tuesday, April 26, 2016 1:54 PM

Answers

  • Apparently, calling WdfRequestUnmarkCancelable before completing the request prevents the BSOD. That's regardless of whether we're canceling or successfully completing the request.

    Just ignoring the result from WdfRequestUnmarkCancelable works best. Once all the IO has been done, there's no point in aborting any more, so we might as well complete the request with "OK" instead, even if some late cancel request arrived. And when canceling, the result from WdfRequestUnmarkCancelable is usually the STATUS_CANCELLED error code, but we still have to complete the request anyway.

    Thursday, April 28, 2016 7:57 AM

All replies

  • First question is why do you think you need this call at all?  If the request is in a WDF request queue it can be canceled without the call.  What the call does is allow the driver to handle the cancel for a request that is going to be out of a request queue for a long time for processing. 

    From the other questions you have asked on the forum, your device is supposed to be very responsive, so this should not be the case.  And nothing in your description above indicates that the request will be held for a long time in a state that needs a custom cancel.


    Don Burn Windows Driver Consulting Website: http://www.windrvr.com

    Tuesday, April 26, 2016 2:06 PM
  • I thought I explained the "why". Because the system won't shut down and because applications will hang if I don't.

    You can read from the device, but something else is providing the data. If no data comes in, the read blocks indefinitely. Once data arrives, the driver gets a hardware interrupt, but it may wait forever for that to happen.

    Tuesday, April 26, 2016 2:57 PM
  • So you are not holding the read request in a WDK request queue till there is data for it to process?  This is normally the way this would be designed, so that the framework could handle the messy stuff like cancel.


    Don Burn Windows Driver Consulting Website: http://www.windrvr.com

    Tuesday, April 26, 2016 3:08 PM
  • I don't have a clue as to what you mean.

    How do I "hold a request in a .. queue"?

    I need the information from the request in order to ask the hardware what to deliver. If the user application wants to read 16 bytes of data, I'll tell the hardware to send me an interrupt when there's 16 bytes of data available in its internal queue (or, if the hardware cannot buffer that much data, I'll ask it to send an interrupt at some point earlier and then re-arm it later).

    So in the EvtIoRead, i set up things, and then just do nothing until the ISR triggers the DPC for this stream, which in turn will complete the Request at some point in future.

    I don't know where the Request goes after it got delivered to my EvtIoRead callback. Is that relevant?

    Tuesday, April 26, 2016 3:21 PM
  • have you turned on driver verifier to see if the mistake can be caught that way?

    d -- This posting is provided "AS IS" with no warranties, and confers no rights.

    Tuesday, April 26, 2016 5:18 PM
  • (and a related question: My development system is supposedly debugging the test target, so why doesn't it break into the debugger when the target crashes?)

    The old good Windbg will break when a BSOD occurs - because of a hardcoded break instruction in the BSOD handler. Not sure about the VS integrated debugger. Try to use windbg.


    Wednesday, April 27, 2016 12:16 AM
  • I use "Install and Verify" as driver deployment option. I ticked the "Enable Driver Verification" box, but that doesn't really have any effect apparently. How's that supposed to work?
    Thursday, April 28, 2016 5:28 AM
  • Apparently, calling WdfRequestUnmarkCancelable before completing the request prevents the BSOD. That's regardless of whether we're canceling or successfully completing the request.

    Just ignoring the result from WdfRequestUnmarkCancelable works best. Once all the IO has been done, there's no point in aborting any more, so we might as well complete the request with "OK" instead, even if some late cancel request arrived. And when canceling, the result from WdfRequestUnmarkCancelable is usually the STATUS_CANCELLED error code, but we still have to complete the request anyway.

    Thursday, April 28, 2016 7:57 AM