Tips for debugging COM AddRef/Release leaks

In Windows environment, adding an accessibility support to a program means you’ll have to do a lot of COM coding. For example, IRawElementProviderSimple is the most fundamental interface you should implement for every provider. So at first I started developing providers with ATL and throughout the process I learned few tips I’d like to share here:

1. Add the ‘_ATL_DEBUG_INTERFACES’ macro

_ATL_DEBUG_INTERFACES

MSDN link: http://msdn.microsoft.com/en-us/library/vstudio/sycfy8ec(v=vs.110).aspx

One thing should remember. If you add the _ATL_DEBUG_INTERFACES to your project, then you cannot use ‘static_cast’ to get an interface pointer between interfaces you inherited and always should get it via QueryInterface. If not, the code will crash instantly. Please refer to following forum quote more details:

Before using _ATL_DEBUG_INTERFACES, the code did a risky "static_cast"
(which itself should be a crime!) to convert a interface pointer to the
coclass object pointer. It apparently worked fine with AddRef/Release and so
one. However, as soon as _ATL_DEBUG_INTERFACES is defined, the _QI_Thunk
interface goes in between and the simple single inheritance didn't work out
any more. Thus the attempt to AddRef caused first-chance access violations
because the address of the function call was invalid and the reference count
were less than expected since. After you released and released it again, you
got the crash.

The fix for this is never do such cast. If you definitely need to get the
pointer to the class object, use a hidden method or get property to return
the this pointer.

Link: http://marc.info/?l=ms-dcom&m=103440653613791&w=2

2. Use CAdapt to contain CComPtr in std::vector

Consider wrapping CComPtr instances with CAdapt in order to maintain CComPtr instances within std::vector to avoid & operator problem.

CAdapt MSDN Link: http://msdn.microsoft.com/en-us/library/bs6acf5x.aspx

Typically, you will use CAdapt when you want to store CComBSTR, CComPtr, CComQIPtr, or _com_ptr_t objects in a container-style class. This was most commonly necessary for C++ Standard Library containers prior to support for the C++11 Standard, but C++11 Standard Library containers automatically work with types that have overloaded operator&(). The Standard Library achieves this by internally usingstd::addressof() to get the true addresses of objects

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s