How can I force a CreateFile call to hang, in order to test something?


A customer was doing some testing and wanted to know if there was a way to force a call to Create­File to hang, so that they can test their program's hang detection and recovery code.

You can ceate these scenarios with careful use of opportunistic locks (also known as oplocks). The sample program I wrote some time ago can be used, for example, to cause a Create­File call requesting write access to hang until the oplock is released.

To cause a Create­File call requesting read access to hang until the oplock is released, use OPLOCK_LEVEL_CACHE_WRITE; this means that the oplock owner caching writes, so nobody can read from the file until the cached writes are flushed out.

Comments (13)
  1. Kevin says:

    Oh, so *this* is why that crappy app I worked on a while ago needed oplocks turned off to run.  It must have had race conditions all over the place!

  2. anonymouscommenter says:

    @Kevin

    It probably used a flat-file database on a network. Which is still garbage, just a different type of garbage.

    But we already covered that elsewhere.

  3. anonymouscommenter says:

    Step into CreateFile using dissasembly view, freeze that thread, continue running?

    [Good luck writing a unit test that does that. -Raymond]
  4. anonymouscommenter says:

    I can write that unit test.

    #ifdef DEBUG

    #define CreateFileW dbg_CreateFileW

    #endif

    Put freeze code in dbg_CreateFileW by checking global variable set only by unit test.

    [And if the CreateFile is coming from a library your program uses? (Also, I don't know how your team works, but on our team, unit tests do not recompile the code. They link directly to the retail code.) -Raymond]
  5. anonymouscommenter says:

    [And if the CreateFile is coming from a library your program uses?]

    Never seen a case where stepping up to the level where my own code is doesn't produce the needful.

  6. anonymouscommenter says:

    Joshua: I suspect you have a lot less exposure to real-world software than you think.

  7. anonymouscommenter says:

    Then just hook CreateFileW or NtCreateFile?

  8. anonymouscommenter says:

    @Joshua If you start changing the code you're testing the first thing that happens is that you're not longer testing the code you actually want to test.

    I think generally accepted policy for unit tests is to use the same code that you're releasing – same compiler settings, compile flags etc. Anything else just increases the risk

  9. anonymouscommenter says:

    unit tests also need to run automatically with no user input, like putting breakpoints and freezing threads

  10. Zan Lynx' says:

    @Voo: I would call that integration testing myself. When I run a unit test it is almost always compiled in debug mode with all asserts enabled.

    I would consider testing the release candidate code to be higher level than unit testing. Still mostly automated, but at that point we're testing the entire thing from user interface to database backend without any code mocks or other tricks.

  11. anonymouscommenter says:

    @Zan Lynx'

    Your unit tests should run on your debug build, your release build, and anything in-between.

  12. anonymouscommenter says:

    If you aren't testing the exact code you release you might as well not test at all.

  13. Dave Bacher says:

    I have a MFM hard drive they can borrow, that'll get you plenty of failed opens.

Comments are closed.

Skip to main content