Thursday, March 27, 2008

System.ComponentModel.Win32Exception is NOT my friend

We've been trying to track down a really sneaky problem for months. Every now and then, at seemingly random times, our application crashes. Very aggravating for the users, especially when they have a patient in the CT scanner when this happens.

Aggravating also for us, as the stack traces are very light on detail. And the detail they do provide is alarmingly down in the bowels.

There are two frequent offenders, both of them System.ComponentModel.Win32Exceptions. "The operation completed successfully" and "Not enough storage is available to process this command".

System.ComponentModel.Win32Exception: The operation completed successfully
at System.Windows.Forms.DibGraphicsBufferManager.CreateCompatibleDIB(IntPtr hdc, IntPtr hpal, Int32 ulWidth, Int32 ulHeight, IntPtr& ppvBits)
at System.Windows.Forms.DibGraphicsBufferManager.CreateBuffer(IntPtr src, Int32 offsetX, Int32 offsetY, Int32 width, Int32 height)
at System.Windows.Forms.DibGraphicsBufferManager.AllocBuffer(Graphics targetGraphics, IntPtr targetDC, Rectangle targetBounds)
at System.Windows.Forms.DibGraphicsBufferManager.AllocBufferInTempManager(Graphics targetGraphics, IntPtr targetDC, Rectangle targetBounds)
at System.Windows.Forms.DibGraphicsBufferManager.AllocBuffer(IntPtr target, Rectangle targetBounds)
at System.Windows.Forms.Control.WmPaint(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
at System.Windows.Forms.ContainerControl.WndProc(Message& m)
at System.Windows.Forms.UserControl.WndProc(Message& m)
at System.Windows.Forms.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)



Exception: System.ComponentModel.Win32Exception
Message: Not enough storage is available to process this command
Source: System.Windows.Forms
at System.Windows.Forms.DibGraphicsBufferManager.CreateCompatibleDIB(IntPtr hdc, IntPtr hpal, Int32 ulWidth, Int32 ulHeight, IntPtr& ppvBits)
at System.Windows.Forms.DibGraphicsBufferManager.CreateBuffer(IntPtr src, Int32 offsetX, Int32 offsetY, Int32 width, Int32 height)
at System.Windows.Forms.DibGraphicsBufferManager.AllocBuffer(Graphics targetGraphics, IntPtr targetDC, Rectangle targetBounds)
at System.Windows.Forms.DibGraphicsBufferManager.AllocBufferInTempManager(Graphics targetGraphics, IntPtr targetDC, Rectangle targetBounds)
at System.Windows.Forms.DibGraphicsBufferManager.AllocBuffer(IntPtr target, Rectangle targetBounds)
at System.Windows.Forms.Control.WmPaint(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
at System.Windows.Forms.ContainerControl.WndProc(Message& m)
at System.Windows.Forms.UserControl.WndProc(Message& m)
at System.Windows.Forms.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

Leaving aside for a moment the question of why "the operation completed successfully" should crash an application, let's carry on with the investigation.

We grabbed some crash dumps and sent them off to Microsoft for analysis. Microsoft's recomendation for a solution was to turn off double buffering. We tried to disable double buffering, and the performance was atrocious. There was a lot of flickering and the painting was slow and incomplete in some areas. Not a good solution.

Microsoft then told us to try setting a smaller font on a Label control. Also not a good solution, since it didn't work, and didn't really look that good.

One day, while trolling the bug bucket looking for something to do, I found an issue about disposing Graphics objects. That's a good thing to do, I figured, so I dug into the code and looked for CreateGraphics() calls. To my dismay, there were quite a few that were not being disposed, or were not in a using() block.

I added the calls to Dispose(), or put the objects in a using() block, and went on my way.

A couple of weeks later, one of our developers stopped by my desk to ask about a strange thing. He had been working on some automated testing of the application, and he noticed that all of a sudden, it stopped crashing. He had been getting lots of System.ComponentModel.Win32Exceptions after running his automated tests, and in the past few builds, they were gone.

Now, the jury is still out on whether or not the disposing of the Graphics objects fixed these crashes, but it certainly looks that way. The updated software should be installed in the next day or two, and then we should know for sure.

Call it a lucky accident that I made those changes, but it definitely makes me look smarter than I really am. I won't tell anyone if you won't.

Ten thousand whisperin' and nobody listenin'

Well, here I am feeling bad because I've been a little quiet on the blog posting front lately. And yet, sometime in the last few days we ticked over 10,000 visits.

The lucky winner of an autographed "10,000 visits" poster comes to us from Dauphin, Manitoba, and got here from a Google search for nude curling calendars.

Sadly, I don't have one. There wasn't even a 2008 nude curling calendar, but word is there might be one for next year.

So, keep your, er, hopes up, and let me know where to mail the poster.

And thanks for dropping by. I'm here all week - try the meatloaf!

How bad can it be?

You know things are bad at work when you're lying in bed and the phone rings at 3:30am. You roll over, check the clock, and as you pick up the phone you're thinking, "Please let this be a 'relative in a car accident' call..."

Instead, you get an "upgrade disaster" call from the poor bastard at the customer site who's trying to figure out why nothing works.

Tuesday, March 25, 2008

Collective Souls

You've heard, I'm sure, of a flock of birds, and a herd of caribou.  You may even have heard of a murder of crows, or a parliament of owls.  How about a troubling of goldfish?

This has me thinking - the animal world is well represented by collectives.  But how about the working world?  What would we call a group of project managers?  Testers?  Software developers?

How about:

    A slippage of Project managers.
    A panic of Project managers.

    A pursuit of Testers.

    An array of Software developers.
    An exception of Software developers.

    A paralysis of Product managers.

    A bewilderment of Co-op students.

    A cost centre of Accountants.

    A misunderstanding of Technical writers.

Thursday, March 20, 2008

Spring?



Early spring, my ass. I can't see across the parking lot right now, for all the snow in the air.

If anyone sees that Groundhog, run the little bugger over for me, would you?

Sunday, March 16, 2008

2008 Brier Final

Yikes.

Looks like CBC set up a camera at our club's Tuesday night beer-league game. Brutal ice conditions, brutal shot-making. Both hallmarks of our Tuesday night league...

Hopefully there's a decent shot made in the last two ends, to make up for a crappy weekend of what is supposed to be the best curling in the world.

Gotta feel sorry for Pat Simmons, who should be playing tonight, except for one shitty pick on his last shot Friday night.

Anyway, back to the TV for the ninth end...

Tuesday, March 11, 2008

Wrong place, wrong time

A few years ago, one of our developers was working on mining an LDAP directory for user data. Rather than spend a lot of time installing a bunch of new packages and creating dummy users (how big was the cast of the Flintstones anyway? You can only come up with so many fake names...) he decided to ask the IT group for read-only access to the corporate LDAP directory.

Some days later, he's ironing out the final pieces of his solution. Everything is working well. He runs it, gets back a couple hundred hits, tweaks some logging, runs it again. Now he's down about ten hits. What the...? Runs it again. Down another ten.

Frantically, he combs through the code, looking for the bug. Finds nothing. Runs the program again. Down ten more. Pretty high pucker-factor going now. He's scrambling, thinking, "they told me it was read-only! How can I be deleting people from the corporate LDAP?!" Then it dawns on him. SuperMegaCorp is downsizing. And he's watching it live.

As fast as he can, he bails out of his program and tries to erase any evidence that he was snooping through the directory.

A few hours later, it's lunchtime. Heart rate back to normal, he heads out the front door to meet a friend for lunch. The friend is late. Some minutes pass, and our hero thinks maybe he should check his voice mail to see if there was a message left. So he goes back into the building, and into the first meeting room. The room is empty, except for a number of folders on the table. He picks up the phone, dials his extension, and while he's listening to the voice mail prompts he glances at the names on the folders.

Yup, you guessed it. He's wandered into the abattoir. The folders are the "parting gifts" for the folks he was watching being removed from the corporate directory. He drops the phone and runs out of the building before anyone notices him.

And that's being in the wrong place and the wrong time. Twice, in the same day.

Seasons don't fear the reaper

Hey, looks like SuperMegaCorp has a new employee in HR.

Qu'est ce que c'est, "blaster"?

It's been a while since I spoke French on a daily basis. Getting close to thirty years, I guess, since I left Montreal. And I never curled in French. But watching last night's Quebec - Newfoundland game from the Brier, I learned a few new terms.

Like the time Quebec was deciding what weight to throw, and they came up with "back douze".

Or the time they were afraid of grouping rocks too close together, because "Il va blaster!"

Friday, March 07, 2008

RIP, Gary Gygax

I spent a lot of time playing AD&D. Probably too much time, come to think of it.

Today's xkcd comic pays a nice tribute to the man.

Thursday, March 06, 2008

Alberta travel caution

"They told me that they would not be taking the gentleman because he was from Saskatchewan, they had a bed shortage and the beds that they had available were going to go to Albertans"

Unbelievable story about a Calgary hospital refusing to take a patient, according to his doctor, because he was from Saskatchewan.

Note to self: when travelling in Alberta, don't get sick. Or at least provide a local address in case of emergency.

It is what it is? No, it isn't

It isn't what it is, it's what it's not that's the problem.

I stumbled into a conversation between a couple of folks here the other day. Someone was complaining that things weren't going well. The other person said, "It is what it is." And I thought, no, it isn't what it is. You can't just bail out of a problem by saying that. Dig into it, get it done, move on.

If it is what it is, then find out what it's not, and make what it isn't what it is.