IErrorInfo object is getting cleared in the client process before the client thread retrieves it.

IErrorInfo is an OLE DB interface. It is defined in automation and returns the error message, component name and GUID of the interface where the error occurred. The link msdn.microsoft.com/en-us/library/windows/desktop/ms723041(v=vs.85).aspx describes its use, when to call and the methods on this interface.

You might sometimes face an issue where an IErrorInfo object gets cleared on a client processes’ UI thread before the thread retrieves the error information. This is a timing issue and might not happen all the time. For example you might have a MFC application making COM calls on a Windows 7 machine. This MFC application communicates to a COM+ application on a same or different machine which in turn might communicate to a database. You might get an error return from the database that gets returned to the client but that error might not turn up on the client side. However as said it might be an intermittent issue and this happens on Windows Vista and above OS’s and not on previous OS’s such as Windows XP.

A typical call stack is shown below.

0:001> kL

ChildEBP RetAddr 

002cbc8c 6d24b48a ole32!CoSetErrorInfo

<SNIP>

002cc258 577998ca mfc100d!_AfxDispatchCmdMsg+0x1a9

002cc2bc 578d2b91 mfc100d!CCmdTarget::OnCmdMsg+0x2ea

<SNIP>

002cda68 6f6c85e4
comctl32!CLVDrawManager::_PaintItems+0x291

002cdaa4 6f6c7c95
comctl32!CLVDrawManager::_PaintWorkArea+0xa9

002cdaf0 6f6c7c19 comctl32!CLVDrawManager::_OnPaintWorkAreas+0xda

002cdb64 6f6c7b74
comctl32!CLVDrawManager::_OnPaint+0xea

002cdb78 6f6c7cb2
comctl32!CLVDrawManager::OnPaint+0x69

002cdcec 6f6cfe70 comctl32!CListView::WndProc+0xb68

002cdd14 74f862fa comctl32!CListView::s_WndProc+0x4e8

002cdd40 74f86d3a user32!InternalCallWinProc+0x23

002cddb8 74f90d27 user32!UserCallWinProcCheckWow+0x109

002cddf0 74f9794a user32!CallWindowProcAorW+0xab

002cde10 578ce0b4 user32!CallWindowProcA+0x1b

002cde34 578cc6ad mfc100d!CWnd::DefWindowProcA+0x34

002cde50 578d647c mfc100d!CWnd::Default+0x3d

002cdecc
57c369ee mfc100d!CWnd::OnPaint+0x7c

002cdfb0 578d09d4 icw32!CICListCtrl::OnPaint+0x12e

002ce12c 578cfff2 mfc100d!CWnd::OnWndMsg+0x9a4

002ce14c 578cc523 mfc100d!CWnd::WindowProc+0x32

002ce1cc 578ccb16 mfc100d!AfxCallWndProc+0xf3

<SNIP>

002ce5b8 75412cba
ole32!CRpcChannelBuffer::SendReceive2+0xef

002ce5d4 75429aa1
ole32!CCliModalLoop::SendReceive+0x1e

002ce650 7540792b ole32!CAptRpcChnl::SendReceive+0x73

002ce6a4 7552ce06 ole32!CCtxComChnl::SendReceive+0x95

002ce6c0 7652414b ole32!NdrExtpProxySendReceive+0x49

002ce6cc 765a0149 rpcrt4!NdrpProxySendReceive+0xe

002ceae0 7552c8e2 rpcrt4!NdrClientCall2+0x1a6

 

Root Cause/ Resolution: Dispatching of WM_PAINT messages is a new behavior starting with Windows Vista. So this is going to depend on timing, and code running on STA threads needs to be able to handle re-entrancy issues. This article discusses setting an appCompat flag to revert to the old behavior (community additions): msdn.microsoft.com/en-us/library/ms694352.aspx

More details regarding this issue and resolution can be found at the blog: blogs.msdn.com/b/yvesdolc/archive/2009/08/06/do-you-receive-wm-paint-when-waiting-for-a-com-call-to-return.aspx

To be able to handle re-entrancy issues, avoid making COM calls on an UI thread where there are windows registered and handling WM_PAINT messages. This will reduce the chance of the IErrorInfo object getting reset on this UI thread.