December, 2006

  • The Old New Thing

    A high waiter count on a free critical section may indicate a lock convoy

    • 16 Comments

    If you're debugging a performance problem in your application, you may run across a critical section in a very strange state: A lot of threads are waiting for it, but nobody owns it!

    0:000> !critsec 0x10009C70
    CritSec at 0x10009C70
    LockCount          37
    RecursionCount     0
    OwningThread       0
    

    This state means that the previous owner of the critical section has just exited it and signalled a waiting thread to take it, but that thread hasn't yet gotten a chance to run yet. This is normally a transient condition, but if you see it a lot, then you very likely the victim of a lock convoy.

    Others have written about lock convoys, so I'm just going to refer you to them to get the details.

  • The Old New Thing

    What does an invalid handle exception in LeaveCriticalSection mean?

    • 27 Comments

    Internally, a critical section is a bunch of counters and flags, and possibly an event. (Note that the internal structure of a critical section is subject to change at any time—in fact, it changed between Windows XP and Windows 2003. The information provided here is therefore intended for troubleshooting and debugging purposes and not for production use.) As long as there is no contention, the counters and flags are sufficient because nobody has had to wait for the critical section (and therefore nobody had to be woken up when the critical section became available).

    If a thread needs to be blocked because the critical section it wants is already owned by another thread, the kernel creates an event for the critical section (if there isn't one already) and waits on it. When the owner of the critical section finally releases it, the event is signaled, thereby alerting all the waiters that the critical section is now available and they should try to enter it again. (If there is more than one waiter, then only one will actually enter the critical section and the others will return to the wait loop.)

    If you get an invalid handle exception in LeaveCriticalSection, it means that the critical section code thought that there were other threads waiting for the critical section to become available, so it tried to signal the event, but the event handle was no good.

    Now you get to use your brain to come up with reasons why this might be.

    One possibility is that the critical section has been corrupted, and the memory that normally holds the event handle has been overwritten with some other value that happens not to be a valid handle.

    Another possibility is that some other piece of code passed an uninitialized variable to the CloseHandle function and ended up closing the critical section's handle by mistake. This can also happen if some other piece of code has a double-close bug, and the handle (now closed) just happened to be reused as the critical section's event handle. When the buggy code closes the handle the second time by mistake, it ends up closing the critical section's handle instead.

    Of course, the problem might be that the critical section is not valid because it was never initialized in the first place. The values in the fields are just uninitialized garbage, and when you try to leave this uninitialized critical section, that garbage gets used as an event handle, raising the invalid handle exception.

    Then again, the problem might be that the critical section is not valid because it has already been destroyed. For example, one thread might have code that goes like this:

    EnterCriticalSection(&cs);
    ... do stuff...
    LeaveCriticalSection(&cs);
    

    While that thread is busy doing stuff, another thread calls DeleteCriticalSection(&cs). This destroys the critical section while another thread was still using it. Eventually that thread finishes doing its stuff and calls LeaveCriticalSection, which raises the invalid handle exception because the DeleteCriticalSection already closed the handle.

    All of these are possible reasons for an invalid handle exception in LeaveCriticalSection. To determine which one you're running into will require more debugging, but at least now you know what to be looking for.

    Postscript: One of my colleagues from the kernel team points out that the Locks and Handles checks in Application Verifier are great for debugging issues like this.

  • The Old New Thing

    Throwing things into a blender and seeing what happens

    • 10 Comments

    Manufacturer of commercial and home blenders Blendtec has produced a marketing web site Will It Blend? which features short videos of the company's CEO and new Internet blending icon Tom Dickson throwing all sorts of unusual objects into one of their blenders, to see what happens. (The videos are also on YouTube, and of course they have a blog, cleverly titled Will it Blog?)

    There's a miniature profile of Tom Dickson in Utah Business Magazine.

    When Jamba Juice told Dickson the $14,000 blender package was too expensive, he cut them a deal, asking simply for a nickel of every sale. Now, with 50 million smoothies sold each year, Dickson says it was one of the best deals he ever made.

    "Will It Blend?" is sort of a blender-themed entry in the style of David Letterman's crowd-pleasing stunts such as "Throwing things off the roof," "Crushing things in a pneumatic press," and "Will it Float?" (I suspect that only guys find this stuff fascinating.)

  • The Old New Thing

    Do not overload the E_NOINTERFACE error

    • 26 Comments

    One of the more subtle ways people mess up IUnknown::QueryInterface is returning E_NOINTERFACE when the problem wasn't actually an unsupported interface. The E_NOINTERFACE return value has very specific meaning. Do not use it as your generic "gosh, something went wrong" error. (Use an appropriate error such as E_OUTOFMEMORY or E_ACCESSDENIED.)

    Recall that the rules for IUnknown::QueryInterface are that (in the absence of catastrophic errors such as E_OUTOFMEMORY) if a request for a particular interface succeeds, then it must always succeed in the future for that object. Similarly, if a request fails with E_NOINTERFACE, then it must always fail in the future for that object.

    These rules exist for a reason.

    In the case where COM needs to create a proxy for your object (for example, to marshal the object into a different apartment), the COM infrastructure does a lot of interface caching (and negative caching) for performance reasons. For example, if a request for an interface fails, COM remembers this so that future requests for that interface are failed immediately rather than being marshalled to the original object only to have the request fail anyway. Requests for unsupported interfaces are very common in COM, and optimizing that case yields significant performance improvements.

    If you start returning E_NOINTERFACE for problems other than "The object doesn't support this interface", COM will assume that the object really doesn't support the interface and may not ask for it again even if you do. This in turn leads to very strange bugs that defy debugging: You are at a call to IUnknown::QueryInterface, you set a breakpoint on your object's implementation of IUnknown::QueryInterface to see what the problem is, you step over the call and get E_NOINTERFACE back without your breakpoint ever hitting. Why? Because at some point in the past, you said you didn't support the interface, and COM remembered this and "saved you the trouble" of having to respond to a question you already answered. The COM folks tell me that they and their comrades in product support end up spending hours debugging customer's problems like "When my computer is under load, sometimes I start getting E_NOINTERFACE for interfaces I definitely support."

    Save yourself and the COM folks several hours of frustration. Don't return E_NOINTERFACE unless you really mean it.

  • The Old New Thing

    Okay, I changed my mind, I wrote a book after all

    • 97 Comments

    Back in 2003, I wrote that I'm doing this instead of writing a book. That was true then, but last year I decided to give this book thing another go, only to find that publishers generally aren't interested in this stuff any more.

    "Does the world really need another book on Win32? Nobody buys Win32 books any more, that dinosaur!"

    "A conversational style book? People want books with step-by-step how-to's and comprehensive treatments, not water cooler anecdotes!"

    "Just 200 pages? There isn't enough of an audience for a book that small!"

    Luckily, I found a sympathetic ear from the folks at Addison-Wesley Professional who were willing to take a chance on my unorthodox proposal. But I caved on the length, bringing it up to 500 pages. Actually, I came up with more like 700 pages of stuff, and they cut it back to 500, because 700 pages would take the book into the next price tier, and "There isn't enough of an audience for a book that big!"

    Eighteen months later, we have The Old New Thing: Practical Development Throughout the Evolution of Windows, following in what appears to be the current fad of giving your book a title of the form Catchy Phrase: Longer Explanation of What the Catchy Phrase Means.

    It's a selection of entries from this blog, loosely organized, and with new material sprinkled in. There are also new chapters that go in depth into parts of Win32 you use every day but may not fully understand (the dialog manager, window messages), plus a chapter dedicated to Taxes. (For some reason, the Table of Contents on the book web site is incomplete.)

    Oh, and those 200 pages that got cut? They'll be made available for download as "bonus chapters". (The bonus chapters aren't up yet, so don't all rush over there looking for them.)

    The nominal release date for the book is January 2007, which is roughly in agreement with the book web site which proclaims availability on December 29th. Just in time for Christmas your favorite geek, if your favorite geek can't read a calendar.

    Now I get to see how many people were lying when they said, "If you wrote a book based on this blog, I'd buy it."

    (Update: The bonus chapters are now available.)

    (Update: Now available in Japanese! ISBN 978-4756150004.)

    (Update: Now available in Chinese! ISBN 7111219194.)

  • The Old New Thing

    The wisdom of seventh graders: What to do with a time machine (part 3)

    • 23 Comments

    (Continuing from part 2.)

    Here are more sentences from seventh grade time travel essays. Remember, these sentences are not representative of seventh grade writing in general; these are just the funny bits.

    World History

    • I want to travel to the year 0 "B.E." Before everything
    • My target would be Colorado. At a time of 115 mya (million years ago)
    • I would go to grease.
    • But still, the crusification of Christ is my favorite.
    • You might get rich from your invention, but probably not.
    • I can bring back people that would be dead.
    • I feel bad for them. I mean they are living a life without electronics!
    • They have nice people in Gotenberg, but not as nice at the malls.
    • I would go to the passed to learn about fashion an find a cure for cancer.
    • I want to go to the passed to get some knowlige and invensions to bring back.
    • I chose to travel to Europe for many reasons but the most important reason is because it was one of the first countries of the world.
    • What interests me the most is how all those major cities like: France, London, Italy and Venice all get along under one country.
    • Stealing from weary travellors and garding treasures! What could be more enjoyable than that.
    • One of the most memorable things about this time were the FIGHTS
    • I would tell him that people today are morons...
    • Those questions may never be answered. But one thing's for sure, I would sure like to go back and find out.
    The Future: Most students who travelled to the future wanted to meet themselves.

    • There are thousands and thousands of books that tell about the past but there are much less books that tell about the future.
    • I would go to the future because I already know all about the past from history class.
    • A trip to the future could just as well be a trip to an asylum.
    • I've always wondered what I would look like in the future, I hope I'm not ugly.
    • I'd like to meet [my future self] to see if I've made my lifelong dream of being a doctor/actress a reality.
    • One day I want to play football for a collage.
    • I want to go 1000 years in the future to see if I have children or even grandchildren.
    • Maybe my friend will become a rock star (finally!) like he wants.
    • Most likely by then they would have a day honoring my sicnificence.
    • I want to take it out for a spin in the fucher.
    • Our whole plant could explode, and that might be bad.
    • I would be content with how I will change in the future as long as I will not turn bad!
    • Because I have always dreamed of having a dog team. Then I could compet in the eididorod every year.
    • Creatures and beats will live like we do.

    Letter Format: Some students took advantage of the fact that the essay took the form of a letter.

    • You are a fanominal teacher.
    • Sincerely, Your disco-dancing student

    Best Conclusion

    • But, I have one question before I go. How do I get back?
  • The Old New Thing

    If you let people read a file, then they can copy it

    • 67 Comments

    Here's a question that floated past my view:

    How do I set the ACLs on a file so users can read it but can't copy it? I can't find a "Copy" access mask that I can deny. If I can't deny copying, I'd at least like to audit it, so I can tell who made a copy of the file.

    There is no "Copy" access mask because copying is not a fundamental file operation. Copying a file is just reading it into memory and then writing it out. Once the bytes come off the disk, the file system has no control any more over what the user does with them.

  • The Old New Thing

    The wisdom of seventh graders: What to do with a time machine (part 2)

    • 38 Comments

    (Make sure you've read Part 1 for background information.)

    On the subject of where they would go in a time machine, many students wrote well-thought-out essays, beautifully composed.

    These sentences below did not come from those essays.

    I've categorized the snippets roughly by theme, though I had to guess at some of them since the sentences are taken out of context. (In a futile attempt to assist non-native speakers, I have glossed some of the trickier parts. I've also added editorial comments in italics.)

    Introductions

    • I would be honored to trie the time machine
    • I am highly regarded to be selected to engorge this experimental journey.
    • At the crack of noon, we will begin our mission.

    Personal History: These are essays from students who would travel to their own past.

    • In 5th grade you are at the top of the school, and you feel the power over come you.
    • Now, if we fall asleep in class we get in trouble. But in kindergarten if we didn't fall asleep we would get in trouble.
    • She would work in little orchids picking fruit for her family.
    • I have 4 things in my life. Soccer, family, God, and school. In that order.
    • If I could find a way to impel paranormal powers to ignite in ones body enableing them to do incredible feats, I would be ecstatic to the point of bliss. (This same student wanted Jesus to teach him how to walk on water. This student also wanted control over magnetism. I think he needs to lay off the X-Men comics for a while.)

    The Middle Ages: The students recently studied the Middle Ages, which helps to explain why so many of them chose to go there.

    • And at that time in history, everything was changing either for the good or the bad. (Whoa there, let's not say anything too controversial now.)
    • In Europe during the 1700's there were 5 sections in the social class: 1=Monarchs, 2=Lords & Nobles, 3=knights, 4=pheasants. (What happened to number five?)
    • I find Middle Aged Europe very stimulating.
    • France is near water so I will feel more at home.
    • We have recently disgust the Middle Ages.
    • King Arthur may have won some battles without the use of fiction.
    • In 1550 I would choose to go to Spain because nobody really lived in N. American then.
    • I would learn a lot gong to the Midieval times. I would even come back and write and essay about it!
    • I'd have benefit in watching a mock battle between two knights on horseback with lances. (I may be wrong, but I think the battles in the Middle Ages were for real.)
    • It was sick and grusm but really a thing to remember.
    • And I would go to Britan because Britan was populare back in 1616.

    United States(?) History

    • Also, to investigate how the family worked [in Pilgrim times], to see if they fought less because they had no appliances to fight over.
    • If I could go anywhere I would choose Boston, England.
    • I want to see what happened when Ben Franklin flew his kite in the rain. For this reason I would go to England.
    • Though War is Hell, I still would be anxious to see a real one. (Try watching the evening news.)
    • I wish the great depression, but it did. (Even after you fill in the missing words, it's still funny.)
    • Because California is a very interesting and mindblowing city.
    • In 1961 everything including life was simple.
    • Hopefully the president at their time isn't an idiot and stops the first power plant ever built.
    • I want to se the Great Babino Babe Bruth.
    • Besides the Stealer fans nobody like the Stealers.
    • It was like a family runnun at disneyland.

    I'll stop here before I runnun too much. We'll learn more about seventh graders and time machines in the next installment.

  • The Old New Thing

    How do I find all files with at least one space in their name?

    • 44 Comments

    You already know how to do this, you just don't realize it.

    How do you find files with an "x" in their name? That's right, you use dir *x*.

    Now you just have to change that x to a space. And since spaces are command line delimiters, you need to quote the sequence so it gets treated as a single parameter rather than two "*" parameters:

    dir "* *"
    

    Stick in a /s if you want to search recursively.

  • The Old New Thing

    The wisdom of seventh graders: What to do with a time machine (part 1)

    • 96 Comments

    All the students at a local school were asked to composed an in-class essay on the following topic: "Your science teacher has invented a time machine. You have been selected to take the first trip. Explain in a multi-paragraph letter to your teacher where you will go and why." (Students were given two hours, plus one additional hour upon request. In practice, many students were finished early and almost nobody requested the third hour.)

    (Aside: Sometimes I think my readers believe in time machines. For example, one of them wondered why OLE/COM uses HRESULTs instead of Win32 error codes. Um, when OLE was invented, Win32 didn't exist.)

    The students really enjoyed this topic. Too much so, however, for more than a few of them turned their essays into a narrative rather than sticking to the assignment. One student was so excited that the essay consisted of a single five-page paragraph. Well, technically it was two paragraphs, thereby meeting the letter (if not the spirit) of the "multi-paragraph" requirement. About halfway down page three was this sentence: "The essay continues in the next paragraph."

    Roughly two thirds of the students opted to go into the past; one third chose to go into the future. One student didn't travel in time at all (!), choosing instead to visit Europe in the present day "to see castles and ruins". Psst, you've got a time machine. Why not go and see the ruins before they are ruined? (Actually, some friends pointed out to me that travelling to the present day is still handy. You can use your time machine as a teleporter. And you can even set the time machine to zip you backward, say, eight hours. That way, when you travel from Seattle to Europe, you arrive without any jet lag!)

    Boys were more likely to want to travel back in time to get rich, although their plans for doing so were not necessarily fully thought-out.

    • Go back in time, steal an invention, and then bring it back to the present.
    • Go back in time thirty years and invest all your money in Google, Amazon, and Microsoft.
    • Go back to the time of Jesus and sell a bag of candy to the king in exchange for gold and gemstones.
    • Go to the 1970's buy up land in California, and then return to the present and you'll be filthy rich.
    • Go back in time, bury some everyday objects, then return to the present and dig them up. Bingo, instant antiques! (This one had a chance of working.)

    (Good luck getting anybody in the past to accept today's money.)

    Girls were more likely to travel in time to meet themselves or close ancestors.

    • Go back in time to meet your grandparents who died when you were very young.
    • Go forward in time to see how you did. (These people were very susceptible to lapsing into speculative fiction.)

    A few students confused a time machine with regressive therapy, choosing to go back in time to re-live a cherished moment from a year or two ago. Psst, if you use a time machine to go into the past to visit yourself on that awesome vacation to Hawaii, you won't re-live the vacation. You'll be watching the other copy of yourself enjoy the vacation. (And that's assuming that the other copy of yourself doesn't see you and freak out.)

    Several students wanted to change world history.

    • Go back to Los Alamos and convince the scientists not to detonate the first atomic bomb.
    • Go back to New York City on September 11, 2001.
      • One student has a clever plan: Run into the World Trade Center buildings and pull the fire alarms eleven minutes before the planes collided with the buildings. By the student's calculations, that's enough time to get everybody out of the building but not so much time that the firemen will have arrived.
      • Another student wanted to prevent the planes from crashing into the Empire State Building. (I think he succeeded!)
    • Go back to Phuket in December, 2004 and warn everybody about the coming tsunami. (The student acknowledges that he will likely fail but he wants to try anyway.)

    Many students wanted to go back in time to observe and experience a historical period. One student wanted to ask Jesus to teach him how to walk on water. (Step one: Be the son of God.)

    Coming up in Part 2, selected sentences from student essays.

    Where would you go if you could take one trip in a time machine?

Page 3 of 4 (32 items) 1234