Tuesday, July 08, 2003

I'm at work and havin' a beer! A Boreale Rousse to celebrate. After two days of going crazy, I've found my bug that was crashing Outlook. (Recall we're developing an Outlook COM addin that replaces MS Exchange server). My event handler callback looked like: void __stdcall InspectorCollectionMonitor::OnNewInspector(Outlook::_InspectorPtr pInspector) when it should have looked like void __stdcall InspectorCollectionMonitor::OnNewInspector(Outlook::_Inspector *pInspector) At first glance you'd think that this code would crash right away -- the caller is putting one thing on the stack and you are treating it as something else. But this code worked well in the daily builds for days and days until someone discovered that Outlook would crash when you closed those little sticky note things in the Notes folder. When I reproduced the problem in the debugger, I was unhappy to discover that the crash wasn't in our code, rather it was deep in Outlook's, making the problem not easy to fix. The reason that the code worked at all is that a COM smart pointer class (_InspectorPtr, in the first buggy declaration) is exactly the same size as a raw pointer (4 bytes). The problem is, in the stdcall calling convention, the called function, not the caller, pops the arguments off the stack. So my function was calling the smart pointer destructor for something that was never constructed as a smart pointer. Result: the reference count was incorrectly decremented (and the underlying object possibly destroyed) in my code, only to blow up outlook next time it dereferences it.

No comments: