Did you know... How to Debug AddRef/Release Issues in Visual Studio?
Today's Tip of the Day comes from Dylan...
In my short time as a COM programmer, I've found that AddRef/Release issues are some of the toughest, tedious, and difficult problems to track down. For those of you not too familiar with COM programming, I'll give a brief description of what the "AddRef/Release" issue is, because this debugging technique helps out in a lot of places.
COM uses reference counting to keep track of object lifetimes. When you get a COM object, you need to AddRef the object, so that it doesn't get destroyed while you are still using it. When you are finished with the object, you call release. This is a very simple explanation, but the important thing to remember is that every AddRef should be matched with a Release, otherwise the COM object will never be freed.
This brings us to the problem. When someone calls AddRef without calling Release the object won't be freed and when someone calls Release with out calling AddRef the object will be freed before it should. The tricky part is tracking down the culprit. AddRef and Release can be called many times over the course of an object's life and in multi-threaded programs the last person to call Release is not always the culprit. Luckily VS provides some handy features to help you out in this situation.
To do this, first you need to set a break point in your code before AddRef or Release is ever called. The object's constructor is a good place to start.
Now, you will need to set a trace point in the AddRef/Release calls. Do this by setting a break point in the call, and then right clicking on the break point and choose "When Hit..." from the context menu. Then click the "Print a message..." check box. Now, enter one of these messages depending on which function you are putting the break point in:
<AddRef o='{(int)this}' r='{m_dwRef}'><![CDATA[$CALLSTACK]]></AddRef>
<Release o='{(int)this}' r='{m_dwRef}'><![CDATA[$CALLSTACK]]></Release>
This is for C++ and assumes your ref counter for the object is called m_dwRef. You will need to modify these based on the object you are debugging.
Now, let the program run until you reach the problem. In your output window will be a bunch of XML. Copy all of it, and paste it into a new file. If you put an opening tag at the top of the file, and a closing at the bottom you should have a valid XML file. You may need to clean up some of the other text from the output window so that the XML file is valid however.
Then, start pruning AddRef/Release pairs that look like they are related. You can use the XML editor in Visual Studio to collapse the AddRef/Release pairs you think are related.
This debugging technique works not just for COM programs but also any place there are matched pairs of calls where one is missing. A co-worker of mine wrote a little utility to automatically prune the AddRef/Releases so you have fewer to sort through. If there is enough interest I can talk to him about posting it.
Happy Visual Studio’ing